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