analysis: Allow SegementStoreContentProvider to accept Collection<ISegment>
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / timegraph / AbstractTimeGraphView.java
CommitLineData
4999a196 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
4999a196
GB
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 * Bernd Hufmann - Updated signal handling
12 * Geneviève Bastien - Move code to provide base classes for time graph view
c1cd9635 13 * Marc-Andre Laperle - Add time zone preference
bec1f1ac 14 * Geneviève Bastien - Add event links between entries
4999a196
GB
15 *******************************************************************************/
16
2bdf0193 17package org.eclipse.tracecompass.tmf.ui.views.timegraph;
4999a196 18
24333461
PT
19import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
20
4999a196 21import java.util.ArrayList;
4999a196
GB
22import java.util.Collections;
23import java.util.Comparator;
24import java.util.HashMap;
91512088 25import java.util.HashSet;
4999a196
GB
26import java.util.List;
27import java.util.Map;
91512088 28import java.util.Set;
1cf25311 29import java.util.concurrent.CopyOnWriteArrayList;
156e9ead 30import java.util.concurrent.atomic.AtomicInteger;
9c274768
PT
31import java.util.regex.Matcher;
32import java.util.regex.Pattern;
33
34import org.eclipse.core.resources.IFile;
35import org.eclipse.core.resources.IMarker;
36import org.eclipse.core.resources.IMarkerDelta;
37import org.eclipse.core.resources.IResource;
38import org.eclipse.core.resources.IResourceChangeEvent;
39import org.eclipse.core.resources.IResourceChangeListener;
40import org.eclipse.core.resources.IWorkspaceRunnable;
41import org.eclipse.core.resources.ResourcesPlugin;
42import org.eclipse.core.runtime.CoreException;
4999a196
GB
43import org.eclipse.core.runtime.IProgressMonitor;
44import org.eclipse.core.runtime.NullProgressMonitor;
dfa0ef96 45import org.eclipse.jdt.annotation.NonNull;
d2120fb6 46import org.eclipse.jdt.annotation.Nullable;
4999a196 47import org.eclipse.jface.action.Action;
747adf5c 48import org.eclipse.jface.action.IAction;
91512088 49import org.eclipse.jface.action.IMenuManager;
0fcf3b09 50import org.eclipse.jface.action.IStatusLineManager;
4999a196
GB
51import org.eclipse.jface.action.IToolBarManager;
52import org.eclipse.jface.action.Separator;
5d021ccf 53import org.eclipse.jface.viewers.AbstractTreeViewer;
40b7b614 54import org.eclipse.jface.viewers.ILabelProvider;
4999a196 55import org.eclipse.jface.viewers.ILabelProviderListener;
747adf5c 56import org.eclipse.jface.viewers.ISelectionProvider;
4999a196 57import org.eclipse.jface.viewers.ITableLabelProvider;
cfcfd964 58import org.eclipse.jface.viewers.ITreeContentProvider;
747adf5c 59import org.eclipse.jface.viewers.TreeViewer;
4923d7b9 60import org.eclipse.jface.viewers.ViewerFilter;
7697e148 61import org.eclipse.osgi.util.NLS;
4999a196 62import org.eclipse.swt.SWT;
9c274768 63import org.eclipse.swt.graphics.Color;
4999a196
GB
64import org.eclipse.swt.graphics.Image;
65import org.eclipse.swt.widgets.Composite;
66import org.eclipse.swt.widgets.Display;
67import org.eclipse.swt.widgets.TreeColumn;
9c274768 68import org.eclipse.tracecompass.internal.tmf.ui.Activator;
7697e148 69import org.eclipse.tracecompass.tmf.core.resources.ITmfMarker;
97c71024 70import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
d2e4afa7 71import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
2bdf0193
AM
72import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
73import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
74import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
75import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
d2e4afa7 76import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
2bdf0193
AM
77import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
78import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
79import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
80import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
24333461 81import org.eclipse.tracecompass.tmf.core.trace.TmfTraceAdapterManager;
21852dfa 82import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
2bdf0193
AM
83import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
84import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler;
d2e4afa7
MAL
85import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
86import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
2bdf0193 87import org.eclipse.tracecompass.tmf.ui.views.TmfView;
9c274768 88import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphBookmarkListener;
2bdf0193
AM
89import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphContentProvider;
90import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2;
91import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
92import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener;
93import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
9c274768 94import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphBookmarkEvent;
2bdf0193 95import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphCombo;
d8a230f8 96import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphContentProvider;
2bdf0193
AM
97import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
98import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
99import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
100import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer;
101import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
e790b877 102import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
24333461 103import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEventSource;
2bdf0193
AM
104import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
105import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
9c274768 106import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent;
2bdf0193
AM
107import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
108import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
4999a196
GB
109import org.eclipse.ui.IActionBars;
110
111/**
112 * An abstract view all time graph views can inherit
113 *
747adf5c
PT
114 * This view contains either a time graph viewer, or a time graph combo which is
115 * divided between a tree viewer on the left and a time graph viewer on the right.
4999a196 116 */
9c274768 117public abstract class AbstractTimeGraphView extends TmfView implements ITmfTimeAligned, IResourceChangeListener {
4999a196 118
5d021ccf
GB
119 /** Constant indicating that all levels of the time graph should be expanded */
120 protected static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
121
9c274768
PT
122 private static final Pattern RGBA_PATTERN = Pattern.compile("RGBA \\{(\\d+), (\\d+), (\\d+), (\\d+)\\}"); //$NON-NLS-1$
123
4999a196
GB
124 /**
125 * Redraw state enum
126 */
127 private enum State {
128 IDLE, BUSY, PENDING
129 }
130
131 // ------------------------------------------------------------------------
132 // Fields
133 // ------------------------------------------------------------------------
134
747adf5c
PT
135 /** The timegraph wrapper */
136 private ITimeGraphWrapper fTimeGraphWrapper;
4999a196 137
156e9ead
MAL
138 private AtomicInteger fDirty = new AtomicInteger();
139
4999a196
GB
140 /** The selected trace */
141 private ITmfTrace fTrace;
142
9c274768
PT
143 /** The selected trace editor file*/
144 private IFile fEditorFile;
145
4999a196
GB
146 /** The timegraph entry list */
147 private List<TimeGraphEntry> fEntryList;
148
149 /** The trace to entry list hash map */
507b1336 150 private final Map<ITmfTrace, List<TimeGraphEntry>> fEntryListMap = new HashMap<>();
4999a196 151
4923d7b9
PT
152 /** The trace to filters hash map */
153 private final Map<ITmfTrace, ViewerFilter[]> fFiltersMap = new HashMap<>();
154
24333461
PT
155 /** The trace to marker event sources hash map */
156 private final Map<ITmfTrace, List<IMarkerEventSource>> fMarkerEventSourcesMap = new HashMap<>();
157
1cf25311 158 /** The trace to build thread hash map */
507b1336 159 private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
4999a196
GB
160
161 /** The start time */
335b04e6 162 private long fStartTime = SWT.DEFAULT;
4999a196
GB
163
164 /** The end time */
335b04e6 165 private long fEndTime = SWT.DEFAULT;
4999a196
GB
166
167 /** The display width */
168 private final int fDisplayWidth;
169
170 /** The zoom thread */
171 private ZoomThread fZoomThread;
172
173 /** The next resource action */
174 private Action fNextResourceAction;
175
176 /** The previous resource action */
177 private Action fPreviousResourceAction;
178
4999a196
GB
179 /** A comparator class */
180 private Comparator<ITimeGraphEntry> fEntryComparator = null;
181
1cf25311 182 /** The redraw state used to prevent unnecessary queuing of display runnables */
4999a196
GB
183 private State fRedrawState = State.IDLE;
184
185 /** The redraw synchronization object */
186 private final Object fSyncObj = new Object();
187
188 /** The presentation provider for this view */
189 private final TimeGraphPresentationProvider fPresentation;
190
747adf5c
PT
191 /** The tree column label array, or null if combo is not used */
192 private String[] fColumns;
193
194 /** The tree label provider, or null if combo is not used */
195 private TreeLabelProvider fLabelProvider = null;
196
a12aae87
GB
197 /** The time graph content provider */
198 private @NonNull ITimeGraphContentProvider fTimeGraphContentProvider = new TimeGraphContentProvider();
199
747adf5c 200 /** The relative weight of the sash, ignored if combo is not used */
59387be3 201 private int[] fWeight = { 1, 3 };
747adf5c
PT
202
203 /** The filter column label array, or null if filter is not used */
204 private String[] fFilterColumns;
4999a196 205
1cf25311
PT
206 /** The pack done flag */
207 private boolean fPackDone = false;
208
737792b6
PT
209 /** The filter content provider, or null if filter is not used */
210 private ITreeContentProvider fFilterContentProvider;
211
a03b7ee4
PT
212 /** The filter label provider, or null if filter is not used */
213 private TreeLabelProvider fFilterLabelProvider;
214
5d021ccf
GB
215 private int fAutoExpandLevel = ALL_LEVELS;
216
9c274768
PT
217 /** The list of color resources created by this view */
218 private final List<Color> fColors = new ArrayList<>();
219
4999a196 220 // ------------------------------------------------------------------------
747adf5c 221 // Classes
4999a196
GB
222 // ------------------------------------------------------------------------
223
747adf5c 224 private interface ITimeGraphWrapper {
4999a196 225
cfcfd964
PT
226 void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider);
227
228 void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider);
4999a196 229
747adf5c 230 TimeGraphViewer getTimeGraphViewer();
4999a196 231
cfcfd964 232 void addSelectionListener(ITimeGraphSelectionListener listener);
4999a196 233
747adf5c 234 ISelectionProvider getSelectionProvider();
4999a196 235
747adf5c 236 void setFocus();
4999a196 237
747adf5c 238 boolean isDisposed();
4999a196 239
747adf5c 240 void refresh();
4999a196 241
1cf25311
PT
242 void setInput(Object input);
243
244 Object getInput();
4999a196 245
4923d7b9
PT
246 void setFilters(ViewerFilter[] filters);
247
248 ViewerFilter[] getFilters();
249
747adf5c 250 void redraw();
4999a196 251
747adf5c 252 void update();
4999a196 253
5d021ccf
GB
254 void setAutoExpandLevel(int level);
255
cfcfd964
PT
256 void setFilterColumns(String[] columnNames);
257
258 void setFilterContentProvider(ITreeContentProvider contentProvider);
259
260 void setFilterLabelProvider(ITableLabelProvider labelProvider);
261
262 IAction getShowFilterDialogAction();
263
d2e4afa7
MAL
264 void performAlign(int offset, int width);
265
266 TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo();
267
268 int getAvailableWidth(int requestedOffset);
4999a196
GB
269 }
270
747adf5c
PT
271 private class TimeGraphViewerWrapper implements ITimeGraphWrapper {
272 private TimeGraphViewer viewer;
4999a196 273
747adf5c
PT
274 private TimeGraphViewerWrapper(Composite parent, int style) {
275 viewer = new TimeGraphViewer(parent, style);
4999a196 276 }
4999a196 277
747adf5c 278 @Override
cfcfd964
PT
279 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
280 viewer.setTimeGraphContentProvider(timeGraphContentProvider);
281 }
282
283 @Override
284 public void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider) {
285 viewer.setTimeGraphProvider(timeGraphPresentationProvider);
747adf5c 286 }
4999a196 287
747adf5c
PT
288 @Override
289 public TimeGraphViewer getTimeGraphViewer() {
290 return viewer;
291 }
4999a196 292
747adf5c
PT
293 @Override
294 public void addSelectionListener(ITimeGraphSelectionListener listener) {
295 viewer.addSelectionListener(listener);
296 }
4999a196 297
747adf5c
PT
298 @Override
299 public ISelectionProvider getSelectionProvider() {
300 return viewer.getSelectionProvider();
301 }
302
303 @Override
304 public void setFocus() {
305 viewer.setFocus();
306 }
307
308 @Override
309 public boolean isDisposed() {
310 return viewer.getControl().isDisposed();
311 }
312
313 @Override
1cf25311 314 public void setInput(Object input) {
747adf5c
PT
315 viewer.setInput(input);
316 }
317
1cf25311
PT
318 @Override
319 public Object getInput() {
320 return viewer.getInput();
321 }
322
cfcfd964
PT
323 @Override
324 public void setFilterColumns(String[] columnNames) {
325 viewer.setFilterColumns(columnNames);
326 }
327
328 @Override
329 public void setFilterContentProvider(ITreeContentProvider contentProvider) {
330 viewer.setFilterContentProvider(contentProvider);
331 }
332
333 @Override
334 public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
335 viewer.setFilterLabelProvider(labelProvider);
336 }
337
4923d7b9
PT
338 @Override
339 public void setFilters(ViewerFilter[] filters) {
340 viewer.setFilters(filters);
341 }
342
343 @Override
344 public ViewerFilter[] getFilters() {
345 return viewer.getFilters();
346 }
347
cfcfd964
PT
348 @Override
349 public IAction getShowFilterDialogAction() {
350 return viewer.getShowFilterDialogAction();
351 }
352
747adf5c
PT
353 @Override
354 public void refresh() {
355 viewer.refresh();
356 }
357
358 @Override
359 public void redraw() {
360 viewer.getControl().redraw();
361 }
362
363 @Override
364 public void update() {
365 viewer.getControl().update();
366 }
5d021ccf
GB
367
368 @Override
369 public void setAutoExpandLevel(int level) {
370 viewer.setAutoExpandLevel(level);
371 }
d2e4afa7
MAL
372
373 @Override
374 public void performAlign(int offset, int width) {
375 viewer.performAlign(offset, width);
376 }
377
378 @Override
379 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
380 return viewer.getTimeViewAlignmentInfo();
381 }
382
383 @Override
384 public int getAvailableWidth(int requestedOffset) {
385 return viewer.getAvailableWidth(requestedOffset);
386 }
4999a196
GB
387 }
388
747adf5c
PT
389 private class TimeGraphComboWrapper implements ITimeGraphWrapper {
390 private TimeGraphCombo combo;
391
392 private TimeGraphComboWrapper(Composite parent, int style) {
393 combo = new TimeGraphCombo(parent, style, fWeight);
394 }
395
396 @Override
cfcfd964
PT
397 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
398 combo.setTimeGraphContentProvider(timeGraphContentProvider);
399 }
400
401 @Override
402 public void setTimeGraphPresentationProvider(TimeGraphPresentationProvider timeGraphPresentationProvider) {
403 combo.setTimeGraphProvider(timeGraphPresentationProvider);
747adf5c
PT
404 }
405
406 @Override
407 public TimeGraphViewer getTimeGraphViewer() {
408 return combo.getTimeGraphViewer();
409 }
410
411 @Override
412 public void addSelectionListener(ITimeGraphSelectionListener listener) {
413 combo.addSelectionListener(listener);
414 }
415
416 @Override
417 public ISelectionProvider getSelectionProvider() {
418 return combo.getTreeViewer();
419 }
420
421 @Override
422 public void setFocus() {
423 combo.setFocus();
424 }
425
426 @Override
427 public boolean isDisposed() {
428 return combo.isDisposed();
429 }
430
431 @Override
1cf25311 432 public void setInput(Object input) {
747adf5c
PT
433 combo.setInput(input);
434 }
435
1cf25311
PT
436 @Override
437 public Object getInput() {
438 return combo.getInput();
439 }
440
cfcfd964
PT
441 @Override
442 public void setFilterColumns(String[] columnNames) {
443 combo.setFilterColumns(columnNames);
444 }
445
446 @Override
447 public void setFilterContentProvider(ITreeContentProvider contentProvider) {
448 combo.setFilterContentProvider(contentProvider);
449 }
450
451 @Override
452 public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
453 combo.setFilterLabelProvider(labelProvider);
454 }
455
4923d7b9
PT
456 @Override
457 public void setFilters(ViewerFilter[] filters) {
458 combo.setFilters(filters);
459 }
460
461 @Override
462 public ViewerFilter[] getFilters() {
463 return combo.getFilters();
464 }
465
cfcfd964
PT
466 @Override
467 public IAction getShowFilterDialogAction() {
468 return combo.getShowFilterDialogAction();
469 }
470
747adf5c
PT
471 @Override
472 public void refresh() {
473 combo.refresh();
474 }
475
476 @Override
477 public void redraw() {
478 combo.redraw();
479 }
480
481 @Override
482 public void update() {
483 combo.update();
484 }
485
5d021ccf
GB
486 @Override
487 public void setAutoExpandLevel(int level) {
488 combo.setAutoExpandLevel(level);
489 }
490
747adf5c
PT
491 TimeGraphCombo getTimeGraphCombo() {
492 return combo;
493 }
494
495 TreeViewer getTreeViewer() {
496 return combo.getTreeViewer();
497 }
498
d2e4afa7
MAL
499 @Override
500 public void performAlign(int offset, int width) {
501 combo.performAlign(offset, width);
502 }
503
504 @Override
505 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
506 return combo.getTimeViewAlignmentInfo();
507 }
508
509 @Override
510 public int getAvailableWidth(int requestedOffset) {
511 return combo.getAvailableWidth(requestedOffset);
512 }
747adf5c 513 }
4999a196 514
4999a196 515 /**
747adf5c
PT
516 * Base class to provide the labels for the tree viewer. Views extending
517 * this class typically need to override the getColumnText method if they
518 * have more than one column to display
4999a196 519 */
40b7b614 520 protected static class TreeLabelProvider implements ITableLabelProvider, ILabelProvider {
4999a196
GB
521
522 @Override
523 public void addListener(ILabelProviderListener listener) {
524 }
525
526 @Override
527 public void dispose() {
528 }
529
530 @Override
531 public boolean isLabelProperty(Object element, String property) {
532 return false;
533 }
534
535 @Override
536 public void removeListener(ILabelProviderListener listener) {
537 }
538
539 @Override
540 public Image getColumnImage(Object element, int columnIndex) {
541 return null;
542 }
543
544 @Override
545 public String getColumnText(Object element, int columnIndex) {
546 TimeGraphEntry entry = (TimeGraphEntry) element;
547 if (columnIndex == 0) {
548 return entry.getName();
549 }
76fccfb0 550 return new String();
4999a196
GB
551 }
552
40b7b614
GP
553 @Override
554 public Image getImage(Object element) {
555 return null;
556 }
557
40b7b614
GP
558 @Override
559 public String getText(Object element) {
560 TimeGraphEntry entry = (TimeGraphEntry) element;
561 return entry.getName();
562 }
563
4999a196
GB
564 }
565
566 private class BuildThread extends Thread {
dfa0ef96
GB
567 private final @NonNull ITmfTrace fBuildTrace;
568 private final @NonNull ITmfTrace fParentTrace;
569 private final @NonNull IProgressMonitor fMonitor;
4999a196 570
dfa0ef96 571 public BuildThread(final @NonNull ITmfTrace trace, final @NonNull ITmfTrace parentTrace, final String name) {
4999a196
GB
572 super(name + " build"); //$NON-NLS-1$
573 fBuildTrace = trace;
1cf25311 574 fParentTrace = parentTrace;
4999a196
GB
575 fMonitor = new NullProgressMonitor();
576 }
577
578 @Override
579 public void run() {
1cf25311 580 buildEventList(fBuildTrace, fParentTrace, fMonitor);
4999a196 581 synchronized (fBuildThreadMap) {
1cf25311 582 fBuildThreadMap.remove(fBuildTrace);
4999a196
GB
583 }
584 }
585
586 public void cancel() {
587 fMonitor.setCanceled(true);
588 }
589 }
590
6ae6c5bd
PT
591 /**
592 * Zoom thread
0336f981 593 * @since 1.1
6ae6c5bd
PT
594 */
595 protected abstract class ZoomThread extends Thread {
4999a196
GB
596 private final long fZoomStartTime;
597 private final long fZoomEndTime;
598 private final long fResolution;
dfa0ef96 599 private final @NonNull IProgressMonitor fMonitor;
4999a196 600
6ae6c5bd
PT
601 /**
602 * Constructor
603 *
604 * @param startTime
605 * the start time
606 * @param endTime
607 * the end time
608 * @param resolution
609 * the resolution
610 */
611 public ZoomThread(long startTime, long endTime, long resolution) {
612 super(AbstractTimeGraphView.this.getName() + " zoom"); //$NON-NLS-1$
4999a196
GB
613 fZoomStartTime = startTime;
614 fZoomEndTime = endTime;
6ae6c5bd 615 fResolution = resolution;
4999a196
GB
616 fMonitor = new NullProgressMonitor();
617 }
618
6ae6c5bd
PT
619 /**
620 * @return the zoom start time
621 */
622 public long getZoomStartTime() {
623 return fZoomStartTime;
624 }
625
626 /**
627 * @return the zoom end time
628 */
629 public long getZoomEndTime() {
630 return fZoomEndTime;
631 }
632
633 /**
634 * @return the resolution
635 */
636 public long getResolution() {
637 return fResolution;
638 }
639
640 /**
641 * @return the monitor
642 */
643 public @NonNull IProgressMonitor getMonitor() {
644 return fMonitor;
645 }
646
647 /**
648 * Cancel the zoom thread
649 */
650 public void cancel() {
651 fMonitor.setCanceled(true);
652 }
156e9ead
MAL
653
654 @Override
655 public final void run() {
656 doRun();
657 fDirty.decrementAndGet();
658 }
659
660 /**
661 * Run the zoom operation.
662 */
663 public abstract void doRun();
6ae6c5bd
PT
664 }
665
666 private class ZoomThreadByEntry extends ZoomThread {
667 private final @NonNull List<TimeGraphEntry> fZoomEntryList;
668
669 public ZoomThreadByEntry(@NonNull List<TimeGraphEntry> entryList, long startTime, long endTime, long resolution) {
670 super(startTime, endTime, resolution);
671 fZoomEntryList = entryList;
672 }
673
4999a196 674 @Override
156e9ead 675 public void doRun() {
4999a196 676 for (TimeGraphEntry entry : fZoomEntryList) {
6ae6c5bd 677 if (getMonitor().isCanceled()) {
79ec0b89 678 return;
4999a196 679 }
dfa0ef96
GB
680 if (entry == null) {
681 break;
682 }
6ae6c5bd 683 zoom(entry, getMonitor());
4999a196 684 }
bec1f1ac 685 /* Refresh the arrows when zooming */
6ae6c5bd 686 List<ILinkEvent> events = getLinkList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor());
79ec0b89 687 if (events != null) {
747adf5c 688 fTimeGraphWrapper.getTimeGraphViewer().setLinks(events);
79ec0b89
PT
689 redraw();
690 }
24333461
PT
691 /* Refresh the view-specific markers when zooming */
692 List<IMarkerEvent> markers = new ArrayList<>(getViewMarkerList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor()));
693 /* Refresh the trace-specific markers when zooming */
694 markers.addAll(getTraceMarkerList(getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor()));
f72cd563 695 fTimeGraphWrapper.getTimeGraphViewer().setMarkers(markers);
24333461 696 redraw();
4999a196
GB
697 }
698
dfa0ef96 699 private void zoom(@NonNull TimeGraphEntry entry, @NonNull IProgressMonitor monitor) {
6ae6c5bd 700 if (getZoomStartTime() <= fStartTime && getZoomEndTime() >= fEndTime) {
4999a196
GB
701 entry.setZoomedEventList(null);
702 } else {
6ae6c5bd 703 List<ITimeEvent> zoomedEventList = getEventList(entry, getZoomStartTime(), getZoomEndTime(), getResolution(), monitor);
4999a196
GB
704 if (zoomedEventList != null) {
705 entry.setZoomedEventList(zoomedEventList);
706 }
707 }
708 redraw();
a3188982 709 for (ITimeGraphEntry child : entry.getChildren()) {
6ae6c5bd 710 if (monitor.isCanceled()) {
4999a196
GB
711 return;
712 }
a3188982
PT
713 if (child instanceof TimeGraphEntry) {
714 zoom((TimeGraphEntry) child, monitor);
715 }
4999a196
GB
716 }
717 }
718
4999a196
GB
719 }
720
721 // ------------------------------------------------------------------------
722 // Constructors
723 // ------------------------------------------------------------------------
724
725 /**
747adf5c
PT
726 * Constructs a time graph view that contains either a time graph viewer or
727 * a time graph combo.
728 *
729 * By default, the view uses a time graph viewer. To use a time graph combo,
730 * the subclass constructor must call {@link #setTreeColumns(String[])} and
731 * {@link #setTreeLabelProvider(TreeLabelProvider)}.
4999a196
GB
732 *
733 * @param id
734 * The id of the view
4999a196
GB
735 * @param pres
736 * The presentation provider
737 */
747adf5c 738 public AbstractTimeGraphView(String id, TimeGraphPresentationProvider pres) {
4999a196 739 super(id);
4999a196
GB
740 fPresentation = pres;
741 fDisplayWidth = Display.getDefault().getBounds().width;
742 }
743
744 // ------------------------------------------------------------------------
747adf5c 745 // Getters and setters
4999a196
GB
746 // ------------------------------------------------------------------------
747
747adf5c
PT
748 /**
749 * Getter for the time graph combo
750 *
751 * @return The time graph combo, or null if combo is not used
752 */
753 protected TimeGraphCombo getTimeGraphCombo() {
754 if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) {
755 return ((TimeGraphComboWrapper) fTimeGraphWrapper).getTimeGraphCombo();
756 }
757 return null;
758 }
4999a196 759
747adf5c
PT
760 /**
761 * Getter for the time graph viewer
762 *
763 * @return The time graph viewer
764 */
765 protected TimeGraphViewer getTimeGraphViewer() {
766 return fTimeGraphWrapper.getTimeGraphViewer();
767 }
768
50c2da9e
GB
769 /**
770 * Getter for the presentation provider
771 *
772 * @return The time graph presentation provider
50c2da9e
GB
773 */
774 protected ITimeGraphPresentationProvider2 getPresentationProvider() {
775 return fPresentation;
776 }
777
747adf5c
PT
778 /**
779 * Sets the tree column labels.
f088b5ae 780 * <p>
747adf5c
PT
781 * This should be called from the constructor.
782 *
783 * @param columns
784 * The array of tree column labels
785 */
786 protected void setTreeColumns(final String[] columns) {
f088b5ae 787 checkPartNotCreated();
747adf5c
PT
788 fColumns = columns;
789 }
790
791 /**
792 * Sets the tree label provider.
f088b5ae 793 * <p>
747adf5c
PT
794 * This should be called from the constructor.
795 *
796 * @param tlp
797 * The tree label provider
798 */
799 protected void setTreeLabelProvider(final TreeLabelProvider tlp) {
f088b5ae 800 checkPartNotCreated();
747adf5c
PT
801 fLabelProvider = tlp;
802 }
803
a12aae87 804 /**
f088b5ae
PT
805 * Sets the time graph content provider.
806 * <p>
807 * This should be called from the constructor.
a12aae87
GB
808 *
809 * @param tgcp
810 * The time graph content provider
811 * @since 1.0
812 */
813 protected void setTimeGraphContentProvider(final @NonNull ITimeGraphContentProvider tgcp) {
f088b5ae 814 checkPartNotCreated();
a12aae87
GB
815 fTimeGraphContentProvider = tgcp;
816 }
817
747adf5c
PT
818 /**
819 * Sets the relative weight of each part of the time graph combo.
f088b5ae 820 * <p>
747adf5c
PT
821 * This should be called from the constructor.
822 *
823 * @param weights
824 * The array (length 2) of relative weights of each part of the combo
825 */
826 protected void setWeight(final int[] weights) {
f088b5ae 827 checkPartNotCreated();
747adf5c
PT
828 fWeight = weights;
829 }
4999a196 830
747adf5c
PT
831 /**
832 * Sets the filter column labels.
f088b5ae 833 * <p>
747adf5c
PT
834 * This should be called from the constructor.
835 *
836 * @param filterColumns
837 * The array of filter column labels
838 */
839 protected void setFilterColumns(final String[] filterColumns) {
f088b5ae 840 checkPartNotCreated();
747adf5c
PT
841 fFilterColumns = filterColumns;
842 }
4999a196 843
737792b6
PT
844 /**
845 * Sets the filter content provider.
f088b5ae 846 * <p>
737792b6
PT
847 * This should be called from the constructor.
848 *
849 * @param contentProvider
850 * The filter content provider
851 * @since 2.0
852 */
853 protected void setFilterContentProvider(final ITreeContentProvider contentProvider) {
f088b5ae 854 checkPartNotCreated();
737792b6
PT
855 fFilterContentProvider = contentProvider;
856 }
857
a03b7ee4
PT
858 /**
859 * Sets the filter label provider.
f088b5ae 860 * <p>
a03b7ee4
PT
861 * This should be called from the constructor.
862 *
863 * @param labelProvider
864 * The filter label provider
a03b7ee4
PT
865 */
866 protected void setFilterLabelProvider(final TreeLabelProvider labelProvider) {
f088b5ae 867 checkPartNotCreated();
a03b7ee4
PT
868 fFilterLabelProvider = labelProvider;
869 }
870
f088b5ae
PT
871 private void checkPartNotCreated() {
872 if (getParentComposite() != null) {
873 throw new IllegalStateException("This method must be called before createPartControl."); //$NON-NLS-1$
874 }
875 }
876
747adf5c
PT
877 /**
878 * Gets the display width
879 *
880 * @return the display width
881 */
882 protected int getDisplayWidth() {
883 return fDisplayWidth;
884 }
4999a196 885
747adf5c
PT
886 /**
887 * Gets the comparator for the entries
888 *
889 * @return The entry comparator
890 */
891 protected Comparator<ITimeGraphEntry> getEntryComparator() {
892 return fEntryComparator;
893 }
4999a196 894
747adf5c 895 /**
304e446c
PT
896 * Sets the comparator class for the entries.
897 * <p>
898 * This comparator will apply recursively to entries that implement
899 * {@link TimeGraphEntry#sortChildren(Comparator)}.
747adf5c
PT
900 *
901 * @param comparator
902 * A comparator object
903 */
904 protected void setEntryComparator(final Comparator<ITimeGraphEntry> comparator) {
905 fEntryComparator = comparator;
906 }
4999a196 907
747adf5c
PT
908 /**
909 * Gets the trace displayed in the view
910 *
911 * @return The trace
912 */
913 protected ITmfTrace getTrace() {
914 return fTrace;
915 }
4999a196 916
747adf5c
PT
917 /**
918 * Gets the start time
919 *
920 * @return The start time
921 */
922 protected long getStartTime() {
923 return fStartTime;
924 }
4999a196 925
747adf5c
PT
926 /**
927 * Sets the start time
928 *
929 * @param time
930 * The start time
931 */
932 protected void setStartTime(long time) {
933 fStartTime = time;
934 }
935
936 /**
937 * Gets the end time
938 *
939 * @return The end time
940 */
941 protected long getEndTime() {
942 return fEndTime;
943 }
944
945 /**
946 * Sets the end time
947 *
948 * @param time
949 * The end time
950 */
951 protected void setEndTime(long time) {
952 fEndTime = time;
953 }
954
5d021ccf
GB
955 /**
956 * Sets the auto-expand level to be used for the input of the view. The
957 * value 0 means that there is no auto-expand; 1 means that top-level
958 * elements are expanded, but not their children; 2 means that top-level
959 * elements are expanded, and their children, but not grand-children; and so
960 * on.
961 * <p>
962 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
963 * </p>
964 *
965 * @param level
966 * non-negative level, or <code>ALL_LEVELS</code> to expand all
967 * levels of the tree
968 */
969 protected void setAutoExpandLevel(int level) {
970 fAutoExpandLevel = level;
971 ITimeGraphWrapper tgWrapper = fTimeGraphWrapper;
972 if (tgWrapper != null) {
973 tgWrapper.setAutoExpandLevel(level);
974 }
975 }
976
747adf5c 977 /**
1cf25311
PT
978 * Gets the entry list for a trace
979 *
980 * @param trace
981 * the trace
747adf5c
PT
982 *
983 * @return the entry list map
984 */
1cf25311
PT
985 protected List<TimeGraphEntry> getEntryList(ITmfTrace trace) {
986 synchronized (fEntryListMap) {
987 return fEntryListMap.get(trace);
988 }
747adf5c
PT
989 }
990
991 /**
1cf25311 992 * Adds a trace entry list to the entry list map
747adf5c
PT
993 *
994 * @param trace
995 * the trace to add
996 * @param list
1cf25311 997 * the list of time graph entries
747adf5c
PT
998 */
999 protected void putEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
1cf25311
PT
1000 synchronized (fEntryListMap) {
1001 fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list));
1002 }
1003 }
1004
1005 /**
1006 * Adds a list of entries to a trace's entry list
1007 *
1008 * @param trace
1009 * the trace
1010 * @param list
1011 * the list of time graph entries to add
1cf25311
PT
1012 */
1013 protected void addToEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
1014 synchronized (fEntryListMap) {
1015 List<TimeGraphEntry> entryList = fEntryListMap.get(trace);
1016 if (entryList == null) {
1017 fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list));
1018 } else {
1019 entryList.addAll(list);
1020 }
1021 }
1022 }
1023
1024 /**
1025 * Removes a list of entries from a trace's entry list
1026 *
1027 * @param trace
1028 * the trace
1029 * @param list
1030 * the list of time graph entries to remove
1cf25311
PT
1031 */
1032 protected void removeFromEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
1033 synchronized (fEntryListMap) {
1034 List<TimeGraphEntry> entryList = fEntryListMap.get(trace);
1035 if (entryList != null) {
1036 entryList.removeAll(list);
1037 }
747adf5c
PT
1038 }
1039 }
4999a196 1040
747adf5c
PT
1041 /**
1042 * Text for the "next" button
1043 *
1044 * @return The "next" button text
1045 */
1046 protected String getNextText() {
1047 return Messages.AbstractTimeGraphtView_NextText;
1048 }
4999a196 1049
747adf5c
PT
1050 /**
1051 * Tooltip for the "next" button
1052 *
1053 * @return Tooltip for the "next" button
1054 */
1055 protected String getNextTooltip() {
1056 return Messages.AbstractTimeGraphView_NextTooltip;
1057 }
4999a196 1058
747adf5c
PT
1059 /**
1060 * Text for the "Previous" button
1061 *
1062 * @return The "Previous" button text
1063 */
1064 protected String getPrevText() {
1065 return Messages.AbstractTimeGraphView_PreviousText;
1066 }
4999a196 1067
747adf5c
PT
1068 /**
1069 * Tooltip for the "previous" button
1070 *
1071 * @return Tooltip for the "previous" button
1072 */
1073 protected String getPrevTooltip() {
1074 return Messages.AbstractTimeGraphView_PreviousTooltip;
1075 }
4999a196 1076
747adf5c
PT
1077 // ------------------------------------------------------------------------
1078 // ViewPart
1079 // ------------------------------------------------------------------------
4999a196 1080
747adf5c
PT
1081 @Override
1082 public void createPartControl(Composite parent) {
d2e4afa7 1083 super.createPartControl(parent);
747adf5c
PT
1084 if (fColumns == null || fLabelProvider == null) {
1085 fTimeGraphWrapper = new TimeGraphViewerWrapper(parent, SWT.NONE);
1086 } else {
1087 TimeGraphComboWrapper wrapper = new TimeGraphComboWrapper(parent, SWT.NONE);
1088 fTimeGraphWrapper = wrapper;
1089 TimeGraphCombo combo = wrapper.getTimeGraphCombo();
a12aae87 1090 combo.setTreeContentProvider(fTimeGraphContentProvider);
747adf5c
PT
1091 combo.setTreeLabelProvider(fLabelProvider);
1092 combo.setTreeColumns(fColumns);
747adf5c 1093 }
cfcfd964 1094 fTimeGraphWrapper.setTimeGraphContentProvider(fTimeGraphContentProvider);
737792b6 1095 fTimeGraphWrapper.setFilterContentProvider(fFilterContentProvider != null ? fFilterContentProvider : fTimeGraphContentProvider);
cfcfd964
PT
1096 fTimeGraphWrapper.setFilterLabelProvider(fFilterLabelProvider);
1097 fTimeGraphWrapper.setFilterColumns(fFilterColumns);
4999a196 1098
cfcfd964 1099 fTimeGraphWrapper.setTimeGraphPresentationProvider(fPresentation);
5d021ccf 1100 fTimeGraphWrapper.setAutoExpandLevel(fAutoExpandLevel);
4999a196 1101
747adf5c 1102 fTimeGraphWrapper.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
4999a196
GB
1103 @Override
1104 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
1105 final long startTime = event.getStartTime();
1106 final long endTime = event.getEndTime();
f566d40a 1107 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
97c71024 1108 broadcast(new TmfWindowRangeUpdatedSignal(AbstractTimeGraphView.this, range));
4999a196
GB
1109 startZoomThread(startTime, endTime);
1110 }
1111 });
1112
747adf5c 1113 fTimeGraphWrapper.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
4999a196
GB
1114 @Override
1115 public void timeSelected(TimeGraphTimeEvent event) {
f566d40a
PT
1116 TmfNanoTimestamp startTime = new TmfNanoTimestamp(event.getBeginTime());
1117 TmfNanoTimestamp endTime = new TmfNanoTimestamp(event.getEndTime());
97c71024 1118 broadcast(new TmfSelectionRangeUpdatedSignal(AbstractTimeGraphView.this, startTime, endTime));
4999a196
GB
1119 }
1120 });
1121
9c274768
PT
1122 fTimeGraphWrapper.getTimeGraphViewer().addBookmarkListener(new ITimeGraphBookmarkListener() {
1123 @Override
1124 public void bookmarkAdded(final TimeGraphBookmarkEvent event) {
1125 try {
1126 ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
1127 @Override
1128 public void run(IProgressMonitor monitor) throws CoreException {
1129 IMarkerEvent bookmark = event.getBookmark();
1130 IMarker marker = fEditorFile.createMarker(IMarker.BOOKMARK);
1131 marker.setAttribute(IMarker.MESSAGE, bookmark.getLabel());
7697e148 1132 marker.setAttribute(ITmfMarker.MARKER_TIME, Long.toString(bookmark.getTime()));
9c274768 1133 if (bookmark.getDuration() > 0) {
7697e148 1134 marker.setAttribute(ITmfMarker.MARKER_DURATION, Long.toString(bookmark.getDuration()));
9c274768 1135 marker.setAttribute(IMarker.LOCATION,
7697e148
PT
1136 NLS.bind(org.eclipse.tracecompass.internal.tmf.ui.Messages.TmfMarker_LocationTimeRange,
1137 new TmfNanoTimestamp(bookmark.getTime()),
1138 new TmfNanoTimestamp(bookmark.getTime() + bookmark.getDuration())));
9c274768
PT
1139 } else {
1140 marker.setAttribute(IMarker.LOCATION,
7697e148
PT
1141 NLS.bind(org.eclipse.tracecompass.internal.tmf.ui.Messages.TmfMarker_LocationTime,
1142 new TmfNanoTimestamp(bookmark.getTime())));
9c274768 1143 }
7697e148 1144 marker.setAttribute(ITmfMarker.MARKER_COLOR, bookmark.getColor().getRGBA().toString());
9c274768
PT
1145 }
1146 }, null);
1147 } catch (CoreException e) {
1148 Activator.getDefault().logError(e.getMessage());
1149 }
1150 }
1151
1152 @Override
1153 public void bookmarkRemoved(TimeGraphBookmarkEvent event) {
1154 try {
1155 IMarkerEvent bookmark = event.getBookmark();
1156 IMarker[] markers = fEditorFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO);
1157 for (IMarker marker : markers) {
1158 if (bookmark.getLabel().equals(marker.getAttribute(IMarker.MESSAGE)) &&
7697e148
PT
1159 Long.toString(bookmark.getTime()).equals(marker.getAttribute(ITmfMarker.MARKER_TIME, (String) null)) &&
1160 Long.toString(bookmark.getDuration()).equals(marker.getAttribute(ITmfMarker.MARKER_DURATION, Long.toString(0))) &&
1161 bookmark.getColor().getRGBA().toString().equals(marker.getAttribute(ITmfMarker.MARKER_COLOR))) {
9c274768
PT
1162 marker.delete();
1163 break;
1164 }
1165 }
1166 } catch (CoreException e) {
1167 Activator.getDefault().logError(e.getMessage());
1168 }
1169 }
1170 });
1171
747adf5c 1172 fTimeGraphWrapper.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
4999a196 1173
0fcf3b09 1174 IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
747adf5c 1175 fTimeGraphWrapper.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager);
0fcf3b09 1176
4999a196
GB
1177 // View Action Handling
1178 makeActions();
1179 contributeToActionBars();
1180
21852dfa 1181 ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
4999a196
GB
1182 if (trace != null) {
1183 traceSelected(new TmfTraceSelectedSignal(this, trace));
1184 }
1185
1186 // make selection available to other views
747adf5c 1187 getSite().setSelectionProvider(fTimeGraphWrapper.getSelectionProvider());
9c274768
PT
1188
1189 ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
4999a196
GB
1190 }
1191
1192 @Override
1193 public void setFocus() {
747adf5c 1194 fTimeGraphWrapper.setFocus();
4999a196
GB
1195 }
1196
9c274768
PT
1197 @Override
1198 public void dispose() {
1199 super.dispose();
1200 ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
1201 }
1202
1203 /**
1204 * @since 2.0
1205 */
1206 @Override
1207 public void resourceChanged(final IResourceChangeEvent event) {
1208 for (final IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) {
1209 if (delta.getResource().equals(fEditorFile)) {
1210 fTimeGraphWrapper.getTimeGraphViewer().setBookmarks(refreshBookmarks(fEditorFile));
1211 redraw();
1212 return;
1213 }
1214 }
1215 }
1216
1217 private List<IMarkerEvent> refreshBookmarks(final IFile editorFile) {
1218 List<IMarkerEvent> bookmarks = new ArrayList<>();
7697e148
PT
1219 for (Color color : fColors) {
1220 color.dispose();
1221 }
1222 fColors.clear();
1223 if (editorFile == null || !editorFile.exists()) {
1224 return bookmarks;
1225 }
9c274768 1226 try {
9c274768
PT
1227 IMarker[] markers = editorFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO);
1228 for (IMarker marker : markers) {
1229 String label = marker.getAttribute(IMarker.MESSAGE, (String) null);
7697e148
PT
1230 String time = marker.getAttribute(ITmfMarker.MARKER_TIME, (String) null);
1231 String duration = marker.getAttribute(ITmfMarker.MARKER_DURATION, Long.toString(0));
1232 String rgba = marker.getAttribute(ITmfMarker.MARKER_COLOR, (String) null);
9c274768
PT
1233 if (label != null && time != null && rgba != null) {
1234 Matcher matcher = RGBA_PATTERN.matcher(rgba);
1235 if (matcher.matches()) {
1236 try {
1237 int red = Integer.valueOf(matcher.group(1));
1238 int green = Integer.valueOf(matcher.group(2));
1239 int blue = Integer.valueOf(matcher.group(3));
1240 int alpha = Integer.valueOf(matcher.group(4));
1241 Color color = new Color(Display.getDefault(), red, green, blue, alpha);
1242 fColors.add(color);
91512088 1243 bookmarks.add(new MarkerEvent(null, Long.valueOf(time), Long.valueOf(duration), IMarkerEvent.BOOKMARKS, color, label, true));
9c274768
PT
1244 } catch (NumberFormatException e) {
1245 Activator.getDefault().logError(e.getMessage());
1246 }
1247 }
1248 }
1249 }
1250 } catch (CoreException e) {
1251 Activator.getDefault().logError(e.getMessage());
1252 }
1253 return bookmarks;
1254 }
1255
4999a196
GB
1256 // ------------------------------------------------------------------------
1257 // Signal handlers
1258 // ------------------------------------------------------------------------
1259
1260 /**
1261 * Handler for the trace opened signal.
1262 *
1263 * @param signal
1264 * The incoming signal
4999a196
GB
1265 */
1266 @TmfSignalHandler
1267 public void traceOpened(TmfTraceOpenedSignal signal) {
4923d7b9 1268 loadTrace(signal.getTrace());
4999a196
GB
1269 }
1270
1271 /**
1272 * Handler for the trace selected signal
1273 *
1274 * @param signal
1275 * The incoming signal
1276 */
1277 @TmfSignalHandler
1278 public void traceSelected(final TmfTraceSelectedSignal signal) {
1279 if (signal.getTrace() == fTrace) {
1280 return;
1281 }
4923d7b9 1282 loadTrace(signal.getTrace());
4999a196
GB
1283 }
1284
1285 /**
1286 * Trace is closed: clear the data structures and the view
1287 *
1288 * @param signal
1289 * the signal received
1290 */
1291 @TmfSignalHandler
1292 public void traceClosed(final TmfTraceClosedSignal signal) {
1293 synchronized (fBuildThreadMap) {
41cc4f90 1294 for (ITmfTrace trace : getTracesToBuild(signal.getTrace())) {
1cf25311
PT
1295 BuildThread buildThread = fBuildThreadMap.remove(trace);
1296 if (buildThread != null) {
1297 buildThread.cancel();
1298 }
4999a196
GB
1299 }
1300 }
4e94ae24 1301 fMarkerEventSourcesMap.remove(signal.getTrace());
4999a196
GB
1302 synchronized (fEntryListMap) {
1303 fEntryListMap.remove(signal.getTrace());
1304 }
4923d7b9 1305 fFiltersMap.remove(signal.getTrace());
4999a196
GB
1306 if (signal.getTrace() == fTrace) {
1307 fTrace = null;
7697e148 1308 fEditorFile = null;
335b04e6
PT
1309 fStartTime = SWT.DEFAULT;
1310 fEndTime = SWT.DEFAULT;
4999a196
GB
1311 if (fZoomThread != null) {
1312 fZoomThread.cancel();
6ae6c5bd 1313 fZoomThread = null;
4999a196
GB
1314 }
1315 refresh();
1316 }
1317 }
1318
1319 /**
97c71024 1320 * Handler for the selection range signal.
4999a196
GB
1321 *
1322 * @param signal
1323 * The signal that's received
97c71024 1324 * @since 1.0
4999a196
GB
1325 */
1326 @TmfSignalHandler
97c71024 1327 public void selectionRangeUpdated(final TmfSelectionRangeUpdatedSignal signal) {
4999a196
GB
1328 if (signal.getSource() == this || fTrace == null) {
1329 return;
1330 }
0fcf3b09
PT
1331 final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1332 final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
4999a196
GB
1333
1334 Display.getDefault().asyncExec(new Runnable() {
1335 @Override
1336 public void run() {
747adf5c 1337 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
1338 return;
1339 }
0fcf3b09 1340 if (beginTime == endTime) {
747adf5c 1341 fTimeGraphWrapper.getTimeGraphViewer().setSelectedTime(beginTime, true);
0fcf3b09 1342 } else {
84c8aef7 1343 fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(beginTime, endTime, true);
0fcf3b09 1344 }
64de182d 1345 synchingToTime(fTimeGraphWrapper.getTimeGraphViewer().getSelectionBegin());
4999a196
GB
1346 }
1347 });
1348 }
1349
1350 /**
97c71024 1351 * Handler for the window range signal.
4999a196
GB
1352 *
1353 * @param signal
1354 * The signal that's received
97c71024 1355 * @since 1.0
4999a196
GB
1356 */
1357 @TmfSignalHandler
97c71024 1358 public void windowRangeUpdated(final TmfWindowRangeUpdatedSignal signal) {
4999a196
GB
1359 if (signal.getSource() == this || fTrace == null) {
1360 return;
1361 }
1362 if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) {
1363 return;
1364 }
1365 final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1366 final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
4999a196
GB
1367 Display.getDefault().asyncExec(new Runnable() {
1368 @Override
1369 public void run() {
747adf5c 1370 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
1371 return;
1372 }
747adf5c 1373 fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
4999a196
GB
1374 startZoomThread(startTime, endTime);
1375 }
1376 });
1377 }
1378
c1cd9635
MAL
1379 /**
1380 * @param signal the format of the timestamps was updated.
1381 */
1382 @TmfSignalHandler
1383 public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal){
747adf5c 1384 fTimeGraphWrapper.refresh();
c1cd9635
MAL
1385 }
1386
4999a196
GB
1387 // ------------------------------------------------------------------------
1388 // Internal
1389 // ------------------------------------------------------------------------
1390
4923d7b9 1391 private void loadTrace(final ITmfTrace trace) {
6ae6c5bd
PT
1392 if (fZoomThread != null) {
1393 fZoomThread.cancel();
1394 fZoomThread = null;
1395 }
4923d7b9
PT
1396 if (fTrace != null) {
1397 /* save the filters of the previous trace */
1398 fFiltersMap.put(fTrace, fTimeGraphWrapper.getFilters());
1399 }
1400 fTrace = trace;
9c274768 1401 fEditorFile = TmfTraceManager.getInstance().getTraceEditorFile(trace);
4999a196
GB
1402 synchronized (fEntryListMap) {
1403 fEntryList = fEntryListMap.get(fTrace);
1404 if (fEntryList == null) {
50c2da9e 1405 rebuild();
4999a196
GB
1406 } else {
1407 fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1408 fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1409 refresh();
1410 }
1411 }
1412 }
1413
50c2da9e
GB
1414 /**
1415 * Forces a rebuild of the entries list, even if entries already exist for this trace
50c2da9e
GB
1416 */
1417 protected void rebuild() {
1418 setStartTime(Long.MAX_VALUE);
1419 setEndTime(Long.MIN_VALUE);
6b8d11bd 1420 refresh();
dfa0ef96
GB
1421 ITmfTrace viewTrace = fTrace;
1422 if (viewTrace == null) {
1423 return;
1424 }
4e94ae24 1425 List<IMarkerEventSource> markerEventSources = new ArrayList<>();
50c2da9e 1426 synchronized (fBuildThreadMap) {
dfa0ef96
GB
1427 for (ITmfTrace trace : getTracesToBuild(viewTrace)) {
1428 if (trace == null) {
1429 break;
1430 }
4e94ae24 1431 markerEventSources.addAll(TmfTraceAdapterManager.getAdapters(trace, IMarkerEventSource.class));
dfa0ef96 1432 BuildThread buildThread = new BuildThread(trace, viewTrace, getName());
50c2da9e
GB
1433 fBuildThreadMap.put(trace, buildThread);
1434 buildThread.start();
1435 }
1436 }
4e94ae24 1437 fMarkerEventSourcesMap.put(viewTrace, markerEventSources);
50c2da9e
GB
1438 }
1439
4999a196
GB
1440 /**
1441 * Method called when synching to a given timestamp. Inheriting classes can
1442 * perform actions here to update the view at the given timestamp.
1443 *
1444 * @param time
1445 * The currently selected time
1446 */
1447 protected void synchingToTime(long time) {
1448
1449 }
1450
41cc4f90
GB
1451 /**
1452 * Return the list of traces whose data or analysis results will be used to
1453 * populate the view. By default, if the trace is an experiment, the traces
1454 * under it will be returned, otherwise, the trace itself is returned.
1455 *
1456 * A build thread will be started for each trace returned by this method,
1457 * some of which may receive events in live streaming mode.
1458 *
1459 * @param trace
1460 * The trace associated with this view
1461 * @return List of traces with data to display
41cc4f90 1462 */
dfa0ef96 1463 protected @NonNull Iterable<ITmfTrace> getTracesToBuild(@NonNull ITmfTrace trace) {
c14c0757 1464 return TmfTraceManager.getTraceSet(trace);
41cc4f90
GB
1465 }
1466
4999a196
GB
1467 /**
1468 * Build the entries list to show in this time graph
1469 *
1470 * Called from the BuildThread
1471 *
1472 * @param trace
1473 * The trace being built
1cf25311
PT
1474 * @param parentTrace
1475 * The parent of the trace set, or the trace itself
4999a196
GB
1476 * @param monitor
1477 * The progress monitor object
1478 */
dfa0ef96 1479 protected abstract void buildEventList(@NonNull ITmfTrace trace, @NonNull ITmfTrace parentTrace, @NonNull IProgressMonitor monitor);
4999a196
GB
1480
1481 /**
1482 * Gets the list of event for an entry in a given timerange
1483 *
1484 * @param entry
1485 * The entry to get events for
1486 * @param startTime
1487 * Start of the time range
1488 * @param endTime
1489 * End of the time range
1490 * @param resolution
1491 * The resolution
1492 * @param monitor
1493 * The progress monitor object
1494 * @return The list of events for the entry
1495 */
4c4e2816 1496 protected abstract @Nullable List<@NonNull ITimeEvent> getEventList(@NonNull TimeGraphEntry entry,
4999a196 1497 long startTime, long endTime, long resolution,
dfa0ef96 1498 @NonNull IProgressMonitor monitor);
4999a196 1499
bec1f1ac
GB
1500 /**
1501 * Gets the list of links (displayed as arrows) for a trace in a given
1502 * timerange. Default implementation returns an empty list.
1503 *
1504 * @param startTime
1505 * Start of the time range
1506 * @param endTime
1507 * End of the time range
1508 * @param resolution
1509 * The resolution
1510 * @param monitor
1511 * The progress monitor object
1512 * @return The list of link events
bec1f1ac 1513 */
4c4e2816 1514 protected @Nullable List<@NonNull ILinkEvent> getLinkList(long startTime, long endTime,
dfa0ef96 1515 long resolution, @NonNull IProgressMonitor monitor) {
507b1336 1516 return new ArrayList<>();
bec1f1ac
GB
1517 }
1518
91512088
PT
1519 /**
1520 * Gets the list of view-specific marker categories. Default implementation
1521 * returns an empty list.
1522 *
1523 * @return The list of marker categories
1524 * @since 2.0
1525 */
1526 protected @NonNull List<String> getViewMarkerCategories() {
1527 return new ArrayList<>();
1528 }
1529
e790b877 1530 /**
24333461
PT
1531 * Gets the list of view-specific markers for a trace in a given time range.
1532 * Default implementation returns an empty list.
e790b877
PT
1533 *
1534 * @param startTime
1535 * Start of the time range
1536 * @param endTime
1537 * End of the time range
1538 * @param resolution
1539 * The resolution
1540 * @param monitor
1541 * The progress monitor object
1542 * @return The list of marker events
1543 * @since 2.0
1544 */
24333461 1545 protected @NonNull List<IMarkerEvent> getViewMarkerList(long startTime, long endTime,
e790b877
PT
1546 long resolution, @NonNull IProgressMonitor monitor) {
1547 return new ArrayList<>();
1548 }
bec1f1ac 1549
24333461
PT
1550 /**
1551 * Gets the list of trace-specific markers for a trace in a given time range.
1552 *
1553 * @param startTime
1554 * Start of the time range
1555 * @param endTime
1556 * End of the time range
1557 * @param resolution
1558 * The resolution
1559 * @param monitor
1560 * The progress monitor object
1561 * @return The list of marker events
1562 * @since 2.0
1563 */
1564 protected @NonNull List<IMarkerEvent> getTraceMarkerList(long startTime, long endTime,
1565 long resolution, @NonNull IProgressMonitor monitor) {
1566 List<IMarkerEvent> markers = new ArrayList<>();
4e94ae24 1567 for (IMarkerEventSource markerEventSource : getMarkerEventSources(fTrace)) {
2f72084f
PT
1568 for (String category : markerEventSource.getMarkerCategories()) {
1569 if (monitor.isCanceled()) {
1570 break;
1571 }
1572 markers.addAll(markerEventSource.getMarkerList(checkNotNull(category), startTime, endTime, resolution, monitor));
24333461 1573 }
24333461
PT
1574 }
1575 return markers;
1576 }
1577
91512088
PT
1578 /**
1579 * Get the list of current marker categories.
1580 *
1581 * @return The list of marker categories
1582 * @since 2.0
1583 */
1584 private @NonNull List<String> getMarkerCategories() {
1585 Set<String> categories = new HashSet<>(getViewMarkerCategories());
1586 for (IMarkerEventSource markerEventSource : getMarkerEventSources(fTrace)) {
1587 categories.addAll(markerEventSource.getMarkerCategories());
1588 }
1589 return new ArrayList<>(categories);
1590 }
1591
24333461
PT
1592 /**
1593 * Gets the list of marker event sources for a given trace.
1594 *
1595 * @param trace
1596 * The trace
1597 * @return The list of marker event sources
1598 * @since 2.0
1599 */
91512088 1600 private @NonNull List<IMarkerEventSource> getMarkerEventSources(ITmfTrace trace) {
24333461
PT
1601 List<IMarkerEventSource> markerEventSources = fMarkerEventSourcesMap.get(trace);
1602 if (markerEventSources == null) {
1603 markerEventSources = checkNotNull(Collections.<IMarkerEventSource>emptyList());
1604 }
1605 return markerEventSources;
1606 }
1607
4999a196
GB
1608 /**
1609 * Refresh the display
1610 */
1611 protected void refresh() {
6ae6c5bd 1612 final boolean zoomThread = Thread.currentThread() instanceof ZoomThread;
08593856 1613 TmfUiRefreshHandler.getInstance().queueUpdate(this, new Runnable() {
4999a196
GB
1614 @Override
1615 public void run() {
747adf5c 1616 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
1617 return;
1618 }
1cf25311 1619 boolean hasEntries = false;
4999a196
GB
1620 synchronized (fEntryListMap) {
1621 fEntryList = fEntryListMap.get(fTrace);
1622 if (fEntryList == null) {
1cf25311
PT
1623 fEntryList = new CopyOnWriteArrayList<>();
1624 } else if (fEntryComparator != null) {
1625 List<TimeGraphEntry> list = new ArrayList<>(fEntryList);
1626 Collections.sort(list, fEntryComparator);
304e446c
PT
1627 for (ITimeGraphEntry entry : list) {
1628 sortChildren(entry, fEntryComparator);
1629 }
1cf25311
PT
1630 fEntryList.clear();
1631 fEntryList.addAll(list);
4999a196 1632 }
f3e09aa6 1633 hasEntries = !fEntryList.isEmpty();
4999a196 1634 }
f3e09aa6
PT
1635 boolean inputChanged = fEntryList != fTimeGraphWrapper.getInput();
1636 if (inputChanged) {
1cf25311 1637 fTimeGraphWrapper.setInput(fEntryList);
4923d7b9
PT
1638 /* restore the previously saved filters, if any */
1639 fTimeGraphWrapper.setFilters(fFiltersMap.get(fTrace));
6ae6c5bd 1640 fTimeGraphWrapper.getTimeGraphViewer().setLinks(null);
9c274768 1641 fTimeGraphWrapper.getTimeGraphViewer().setBookmarks(refreshBookmarks(fEditorFile));
91512088 1642 fTimeGraphWrapper.getTimeGraphViewer().setMarkerCategories(getMarkerCategories());
6d5b0ba1 1643 fTimeGraphWrapper.getTimeGraphViewer().setMarkers(null);
1cf25311
PT
1644 } else {
1645 fTimeGraphWrapper.refresh();
4999a196 1646 }
335b04e6
PT
1647 long startBound = (fStartTime == Long.MAX_VALUE ? SWT.DEFAULT : fStartTime);
1648 long endBound = (fEndTime == Long.MIN_VALUE ? SWT.DEFAULT : fEndTime);
1649 fTimeGraphWrapper.getTimeGraphViewer().setTimeBounds(startBound, endBound);
4999a196 1650
21852dfa 1651 TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
335b04e6
PT
1652 long selectionBeginTime = fTrace == null ? SWT.DEFAULT : ctx.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1653 long selectionEndTime = fTrace == null ? SWT.DEFAULT : ctx.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1654 long startTime = fTrace == null ? SWT.DEFAULT : ctx.getWindowRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1655 long endTime = fTrace == null ? SWT.DEFAULT : ctx.getWindowRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1656 startTime = (fStartTime == Long.MAX_VALUE ? SWT.DEFAULT : Math.max(startTime, fStartTime));
1657 endTime = (fEndTime == Long.MIN_VALUE ? SWT.DEFAULT : Math.min(endTime, fEndTime));
84c8aef7 1658 fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime, false);
747adf5c 1659 fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
4999a196 1660
f3e09aa6
PT
1661 if (inputChanged && selectionBeginTime != SWT.DEFAULT) {
1662 synchingToTime(selectionBeginTime);
1663 }
1664
1cf25311 1665 if (fTimeGraphWrapper instanceof TimeGraphComboWrapper && !fPackDone) {
747adf5c
PT
1666 for (TreeColumn column : ((TimeGraphComboWrapper) fTimeGraphWrapper).getTreeViewer().getTree().getColumns()) {
1667 column.pack();
1668 }
1cf25311
PT
1669 if (hasEntries) {
1670 fPackDone = true;
1671 }
4999a196
GB
1672 }
1673
6ae6c5bd
PT
1674 if (!zoomThread) {
1675 startZoomThread(startTime, endTime);
1676 }
4999a196
GB
1677 }
1678 });
1679 }
1680
1681 /**
1682 * Redraw the canvas
1683 */
1684 protected void redraw() {
1685 synchronized (fSyncObj) {
1686 if (fRedrawState == State.IDLE) {
1687 fRedrawState = State.BUSY;
1688 } else {
1689 fRedrawState = State.PENDING;
1690 return;
1691 }
1692 }
1693 Display.getDefault().asyncExec(new Runnable() {
1694 @Override
1695 public void run() {
747adf5c 1696 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
1697 return;
1698 }
747adf5c
PT
1699 fTimeGraphWrapper.redraw();
1700 fTimeGraphWrapper.update();
4999a196
GB
1701 synchronized (fSyncObj) {
1702 if (fRedrawState == State.PENDING) {
1703 fRedrawState = State.IDLE;
1704 redraw();
1705 } else {
1706 fRedrawState = State.IDLE;
1707 }
1708 }
1709 }
1710 });
1711 }
1712
304e446c
PT
1713 private static void sortChildren(ITimeGraphEntry entry, Comparator<ITimeGraphEntry> comparator) {
1714 if (entry instanceof TimeGraphEntry) {
1715 ((TimeGraphEntry) entry).sortChildren(comparator);
1716 }
1717 for (ITimeGraphEntry child : entry.getChildren()) {
1718 sortChildren(child, comparator);
1719 }
1720 }
1721
0c283816
PT
1722 /**
1723 * Start or restart the zoom thread.
1724 *
1725 * @param startTime
1726 * the zoom start time
1727 * @param endTime
1728 * the zoom end time
1729 * @since 2.0
1730 */
156e9ead
MAL
1731 protected final void startZoomThread(long startTime, long endTime) {
1732 fDirty.incrementAndGet();
6ae6c5bd 1733 boolean restart = false;
4999a196
GB
1734 if (fZoomThread != null) {
1735 fZoomThread.cancel();
6ae6c5bd
PT
1736 if (fZoomThread.fZoomStartTime == startTime && fZoomThread.fZoomEndTime == endTime) {
1737 restart = true;
1738 }
1739 }
1740 long resolution = Math.max(1, (endTime - startTime) / fDisplayWidth);
1741 fZoomThread = createZoomThread(startTime, endTime, resolution, restart);
1742 if (fZoomThread != null) {
1743 fZoomThread.start();
156e9ead
MAL
1744 } else {
1745 fDirty.decrementAndGet();
4999a196 1746 }
6ae6c5bd
PT
1747 }
1748
1749 /**
1750 * Create a zoom thread.
1751 *
1752 * @param startTime
1753 * the zoom start time
1754 * @param endTime
1755 * the zoom end time
1756 * @param resolution
1757 * the resolution
1758 * @param restart
1759 * true if restarting zoom for the same time range
1760 * @return a zoom thread
0336f981 1761 * @since 1.1
6ae6c5bd
PT
1762 */
1763 protected @Nullable ZoomThread createZoomThread(long startTime, long endTime, long resolution, boolean restart) {
dfa0ef96
GB
1764 final List<TimeGraphEntry> entryList = fEntryList;
1765 if (entryList == null) {
6ae6c5bd 1766 return null;
dfa0ef96 1767 }
6ae6c5bd 1768 return new ZoomThreadByEntry(entryList, startTime, endTime, resolution);
4999a196
GB
1769 }
1770
1771 private void makeActions() {
747adf5c 1772 fPreviousResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getPreviousItemAction();
4999a196
GB
1773 fPreviousResourceAction.setText(getPrevText());
1774 fPreviousResourceAction.setToolTipText(getPrevTooltip());
747adf5c 1775 fNextResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getNextItemAction();
4999a196
GB
1776 fNextResourceAction.setText(getNextText());
1777 fNextResourceAction.setToolTipText(getNextTooltip());
1778 }
1779
1780 private void contributeToActionBars() {
1781 IActionBars bars = getViewSite().getActionBars();
1782 fillLocalToolBar(bars.getToolBarManager());
91512088 1783 fillLocalMenu(bars.getMenuManager());
4999a196
GB
1784 }
1785
79ec0b89
PT
1786 /**
1787 * Add actions to local tool bar manager
1788 *
1789 * @param manager the tool bar manager
1790 */
1791 protected void fillLocalToolBar(IToolBarManager manager) {
cfcfd964
PT
1792 if (fFilterColumns != null && fFilterLabelProvider != null && fFilterColumns.length > 0) {
1793 manager.add(fTimeGraphWrapper.getShowFilterDialogAction());
4999a196 1794 }
747adf5c 1795 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getShowLegendAction());
4999a196 1796 manager.add(new Separator());
747adf5c
PT
1797 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getResetScaleAction());
1798 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousEventAction());
1799 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextEventAction());
91512088 1800 manager.add(new Separator());
1d012443 1801 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getToggleBookmarkAction());
f72cd563
PT
1802 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousMarkerAction());
1803 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextMarkerAction());
91512088 1804 manager.add(new Separator());
4999a196
GB
1805 manager.add(fPreviousResourceAction);
1806 manager.add(fNextResourceAction);
747adf5c
PT
1807 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomInAction());
1808 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomOutAction());
4999a196
GB
1809 manager.add(new Separator());
1810 }
d2e4afa7 1811
91512088
PT
1812 /**
1813 * Add actions to local menu manager
1814 *
1815 * @param manager the tool bar manager
1816 * @since 2.0
1817 */
1818 protected void fillLocalMenu(IMenuManager manager) {
1819 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getMarkersMenu());
1820 }
1821
d2e4afa7
MAL
1822 /**
1823 * @since 1.0
1824 */
1825 @Override
1826 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
1827 if (fTimeGraphWrapper == null) {
1828 return null;
1829 }
1830 return fTimeGraphWrapper.getTimeViewAlignmentInfo();
1831 }
1832
1833 /**
1834 * @since 1.0
1835 */
1836 @Override
1837 public int getAvailableWidth(int requestedOffset) {
1838 if (fTimeGraphWrapper == null) {
1839 return 0;
1840 }
1841 return fTimeGraphWrapper.getAvailableWidth(requestedOffset);
1842 }
1843
1844 /**
1845 * @since 1.0
1846 */
1847 @Override
1848 public void performAlign(int offset, int width) {
1849 if (fTimeGraphWrapper != null) {
1850 fTimeGraphWrapper.performAlign(offset, width);
1851 }
1852 }
156e9ead
MAL
1853
1854 /**
1855 * Returns whether or not the time graph view is dirty. The time graph view
1856 * is considered dirty if it has yet to completely update its model.
1857 *
1858 * @return true if the time graph view has yet to completely update its
1859 * model, false otherwise
1860 * @since 2.0
1861 */
1862 public boolean isDirty() {
1863 if (fZoomThread == null) {
1864 return false;
1865 }
1866 return fDirty.get() != 0 || fZoomThread.getZoomStartTime() != fTimeGraphWrapper.getTimeGraphViewer().getTime0() || fZoomThread.getZoomEndTime() != fTimeGraphWrapper.getTimeGraphViewer().getTime1();
1867 }
1868
4999a196 1869}
This page took 0.173753 seconds and 5 git commands to generate.