tmf: Support navigation for all markers in time graph viewer
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / TimeGraphViewer.java
1 /*****************************************************************************
2 * Copyright (c) 2007, 2015 Intel Corporation, Ericsson, others
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alexander N. Alexeev, Intel - Add monitors statistics support
12 * Alvaro Sanchez-Leon - Adapted for TMF
13 * Patrick Tasse - Refactoring
14 * Geneviève Bastien - Add event links between entries
15 *****************************************************************************/
16
17 package org.eclipse.tracecompass.tmf.ui.widgets.timegraph;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.Comparator;
22 import java.util.List;
23
24 import org.eclipse.jface.action.Action;
25 import org.eclipse.jface.action.IAction;
26 import org.eclipse.jface.dialogs.IDialogSettings;
27 import org.eclipse.jface.resource.ImageDescriptor;
28 import org.eclipse.jface.viewers.AbstractTreeViewer;
29 import org.eclipse.jface.viewers.ISelectionProvider;
30 import org.eclipse.jface.viewers.ITableLabelProvider;
31 import org.eclipse.jface.viewers.ITreeContentProvider;
32 import org.eclipse.jface.viewers.ViewerFilter;
33 import org.eclipse.jface.window.Window;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.events.ControlAdapter;
36 import org.eclipse.swt.events.ControlEvent;
37 import org.eclipse.swt.events.DisposeEvent;
38 import org.eclipse.swt.events.DisposeListener;
39 import org.eclipse.swt.events.KeyAdapter;
40 import org.eclipse.swt.events.KeyEvent;
41 import org.eclipse.swt.events.MenuDetectListener;
42 import org.eclipse.swt.events.MouseEvent;
43 import org.eclipse.swt.events.MouseWheelListener;
44 import org.eclipse.swt.events.SelectionAdapter;
45 import org.eclipse.swt.events.SelectionEvent;
46 import org.eclipse.swt.events.SelectionListener;
47 import org.eclipse.swt.graphics.Color;
48 import org.eclipse.swt.graphics.RGBA;
49 import org.eclipse.swt.graphics.Rectangle;
50 import org.eclipse.swt.layout.FillLayout;
51 import org.eclipse.swt.layout.GridData;
52 import org.eclipse.swt.layout.GridLayout;
53 import org.eclipse.swt.widgets.Composite;
54 import org.eclipse.swt.widgets.Control;
55 import org.eclipse.swt.widgets.Display;
56 import org.eclipse.swt.widgets.Event;
57 import org.eclipse.swt.widgets.Listener;
58 import org.eclipse.swt.widgets.Slider;
59 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
60 import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
61 import org.eclipse.tracecompass.internal.tmf.ui.Messages;
62 import org.eclipse.tracecompass.internal.tmf.ui.dialogs.AddBookmarkDialog;
63 import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
64 import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
65 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ShowFilterDialogAction;
66 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend;
67 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
68 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
69 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
70 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
71 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent;
72 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider;
73 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter;
74 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme;
75 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
76 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphScale;
77 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphTooltipHandler;
78 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
79 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
80 import org.eclipse.ui.PlatformUI;
81
82 /**
83 * Generic time graph viewer implementation
84 *
85 * @author Patrick Tasse, and others
86 */
87 public class TimeGraphViewer implements ITimeDataProvider, SelectionListener {
88
89 /** Constant indicating that all levels of the time graph should be expanded */
90 public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
91
92 private static final int DEFAULT_NAME_WIDTH = 200;
93 private static final int MIN_NAME_WIDTH = 6;
94 private static final int MAX_NAME_WIDTH = 1000;
95 private static final int DEFAULT_HEIGHT = 22;
96 private static final String HIDE_ARROWS_KEY = "hide.arrows"; //$NON-NLS-1$
97 private static final long DEFAULT_FREQUENCY = 1000000000L;
98 private static final int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1;
99
100 private static ImageDescriptor ADD_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ADD_BOOKMARK);
101 private static ImageDescriptor NEXT_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_BOOKMARK);
102 private static ImageDescriptor PREVIOUS_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREVIOUS_BOOKMARK);
103 private static ImageDescriptor REMOVE_BOOKMARK = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_REMOVE_BOOKMARK);
104
105 private long fMinTimeInterval;
106 private ITimeGraphEntry fSelectedEntry;
107 private long fBeginTime = SWT.DEFAULT; // The user-specified bounds start time
108 private long fEndTime = SWT.DEFAULT; // The user-specified bounds end time
109 private long fTime0 = SWT.DEFAULT; // The current window start time
110 private long fTime1 = SWT.DEFAULT; // The current window end time
111 private long fSelectionBegin = SWT.DEFAULT;
112 private long fSelectionEnd = SWT.DEFAULT;
113 private long fTime0Bound = SWT.DEFAULT; // The bounds start time
114 private long fTime1Bound = SWT.DEFAULT; // The bounds end time
115 private long fTime0ExtSynch = SWT.DEFAULT;
116 private long fTime1ExtSynch = SWT.DEFAULT;
117 private boolean fTimeRangeFixed;
118 private int fNameWidthPref = DEFAULT_NAME_WIDTH;
119 private int fMinNameWidth = MIN_NAME_WIDTH;
120 private int fNameWidth;
121 private Composite fDataViewer;
122
123 private TimeGraphControl fTimeGraphCtrl;
124 private TimeGraphScale fTimeScaleCtrl;
125 private Slider fHorizontalScrollBar;
126 private Slider fVerticalScrollBar;
127 private TimeGraphColorScheme fColorScheme;
128 private Object fInputElement;
129 private ITimeGraphContentProvider fTimeGraphContentProvider;
130 private ITimeGraphPresentationProvider fTimeGraphProvider;
131 private ITimeDataProvider fTimeDataProvider = this;
132 private TimeGraphTooltipHandler fToolTipHandler;
133
134 private List<ITimeGraphSelectionListener> fSelectionListeners = new ArrayList<>();
135 private List<ITimeGraphTimeListener> fTimeListeners = new ArrayList<>();
136 private List<ITimeGraphRangeListener> fRangeListeners = new ArrayList<>();
137 private List<ITimeGraphBookmarkListener> fBookmarkListeners = new ArrayList<>();
138
139 // Time format, using Epoch reference, Relative time format(default),
140 // Number, or Cycles
141 private TimeFormat fTimeFormat = TimeFormat.RELATIVE;
142 // Clock frequency to use for Cycles time format
143 private long fClockFrequency = DEFAULT_FREQUENCY;
144 private int fBorderWidth = 0;
145 private int fTimeScaleHeight = DEFAULT_HEIGHT;
146
147 private Action fResetScaleAction;
148 private Action fShowLegendAction;
149 private Action fNextEventAction;
150 private Action fPrevEventAction;
151 private Action fNextItemAction;
152 private Action fPreviousItemAction;
153 private Action fZoomInAction;
154 private Action fZoomOutAction;
155 private Action fHideArrowsAction;
156 private Action fFollowArrowFwdAction;
157 private Action fFollowArrowBwdAction;
158 private ShowFilterDialogAction fShowFilterDialogAction;
159 private Action fToggleBookmarkAction;
160 private Action fNextMarkerAction;
161 private Action fPreviousMarkerAction;
162
163 /** The list of bookmarks */
164 private final List<IMarkerEvent> fBookmarks = new ArrayList<>();
165
166 /** The list of markers */
167 private final List<IMarkerEvent> fMarkers = new ArrayList<>();
168
169 /** The list of color resources created by this viewer */
170 private final List<Color> fColors = new ArrayList<>();
171
172 private ListenerNotifier fListenerNotifier;
173
174 private Composite fTimeAlignedComposite;
175
176 private class ListenerNotifier extends Thread {
177 private static final long DELAY = 400L;
178 private static final long POLLING_INTERVAL = 10L;
179 private long fLastUpdateTime = Long.MAX_VALUE;
180 private boolean fSelectionChanged = false;
181 private boolean fTimeRangeUpdated = false;
182 private boolean fTimeSelected = false;
183
184 @Override
185 public void run() {
186 while ((System.currentTimeMillis() - fLastUpdateTime) < DELAY) {
187 try {
188 Thread.sleep(POLLING_INTERVAL);
189 } catch (Exception e) {
190 return;
191 }
192 }
193 Display.getDefault().asyncExec(new Runnable() {
194 @Override
195 public void run() {
196 if (fListenerNotifier != ListenerNotifier.this) {
197 return;
198 }
199 fListenerNotifier = null;
200 if (ListenerNotifier.this.isInterrupted() || fDataViewer.isDisposed()) {
201 return;
202 }
203 if (fSelectionChanged) {
204 fireSelectionChanged(fSelectedEntry);
205 }
206 if (fTimeRangeUpdated) {
207 fireTimeRangeUpdated(fTime0, fTime1);
208 }
209 if (fTimeSelected) {
210 fireTimeSelected(fSelectionBegin, fSelectionEnd);
211 }
212 }
213 });
214 }
215
216 public void selectionChanged() {
217 fSelectionChanged = true;
218 fLastUpdateTime = System.currentTimeMillis();
219 }
220
221 public void timeRangeUpdated() {
222 fTimeRangeUpdated = true;
223 fLastUpdateTime = System.currentTimeMillis();
224 }
225
226 public void timeSelected() {
227 fTimeSelected = true;
228 fLastUpdateTime = System.currentTimeMillis();
229 }
230
231 public boolean hasSelectionChanged() {
232 return fSelectionChanged;
233 }
234
235 public boolean hasTimeRangeUpdated() {
236 return fTimeRangeUpdated;
237 }
238
239 public boolean hasTimeSelected() {
240 return fTimeSelected;
241 }
242 }
243
244 private final static class MarkerComparator implements Comparator<IMarkerEvent> {
245 @Override
246 public int compare(IMarkerEvent o1, IMarkerEvent o2) {
247 int res = Long.compare(o1.getTime(), o2.getTime());
248 if (res != 0) {
249 return res;
250 }
251 return Long.compare(o1.getDuration(), o2.getDuration());
252 }
253 }
254
255 /**
256 * Standard constructor.
257 * <p>
258 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
259 *
260 * @param parent
261 * The parent UI composite object
262 * @param style
263 * The style to use
264 */
265 public TimeGraphViewer(Composite parent, int style) {
266 createDataViewer(parent, style);
267 fTimeGraphContentProvider = new TimeGraphContentProvider();
268 }
269
270 /**
271 * Sets the timegraph content provider used by this timegraph viewer.
272 *
273 * @param timeGraphContentProvider
274 * the timegraph content provider
275 */
276 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
277 fTimeGraphContentProvider = timeGraphContentProvider;
278 }
279
280 /**
281 * Gets the timegraph content provider used by this timegraph viewer.
282 *
283 * @return the timegraph content provider
284 */
285 public ITimeGraphContentProvider getTimeGraphContentProvider() {
286 return fTimeGraphContentProvider;
287 }
288
289 /**
290 * Sets the timegraph presentation provider used by this timegraph viewer.
291 *
292 * @param timeGraphProvider
293 * the timegraph provider
294 */
295 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {
296 fTimeGraphProvider = timeGraphProvider;
297 fTimeGraphCtrl.setTimeGraphProvider(timeGraphProvider);
298 fToolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, fTimeDataProvider);
299 fToolTipHandler.activateHoverHelp(fTimeGraphCtrl);
300 }
301
302 /**
303 * Sets the tree columns for this time graph combo's filter dialog.
304 *
305 * @param columnNames the tree column names
306 * @since 2.0
307 */
308 public void setFilterColumns(String[] columnNames) {
309 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames);
310 }
311
312 /**
313 * Sets the tree content provider used by the filter dialog
314 *
315 * @param contentProvider the tree content provider
316 * @since 2.0
317 */
318 public void setFilterContentProvider(ITreeContentProvider contentProvider) {
319 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider);
320 }
321
322 /**
323 * Sets the tree label provider used by the filter dialog
324 *
325 * @param labelProvider the tree label provider
326 * @since 2.0
327 */
328 public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
329 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider);
330 }
331
332 /**
333 * Sets or clears the input for this time graph viewer.
334 *
335 * @param inputElement
336 * The input of this time graph viewer, or <code>null</code> if
337 * none
338 */
339 public void setInput(Object inputElement) {
340 fInputElement = inputElement;
341 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(inputElement);
342 fListenerNotifier = null;
343 if (fTimeGraphCtrl != null) {
344 setTimeRange(input);
345 setTopIndex(0);
346 fSelectionBegin = SWT.DEFAULT;
347 fSelectionEnd = SWT.DEFAULT;
348 updateMarkerActions();
349 fSelectedEntry = null;
350 refreshAllData(input);
351 }
352 }
353
354 /**
355 * Gets the input for this time graph viewer.
356 *
357 * @return The input of this time graph viewer, or <code>null</code> if none
358 */
359 public Object getInput() {
360 return fInputElement;
361 }
362
363 /**
364 * Sets (or clears if null) the list of links to display on this combo
365 *
366 * @param links
367 * the links to display in this time graph combo
368 */
369 public void setLinks(List<ILinkEvent> links) {
370 if (fTimeGraphCtrl != null) {
371 fTimeGraphCtrl.refreshArrows(links);
372 }
373 }
374
375 /**
376 * Refresh the view
377 */
378 public void refresh() {
379 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(fInputElement);
380 setTimeRange(input);
381 refreshAllData(input);
382 }
383
384 /**
385 * Callback for when the control is moved
386 *
387 * @param e
388 * The caller event
389 */
390 public void controlMoved(ControlEvent e) {
391 }
392
393 /**
394 * Callback for when the control is resized
395 *
396 * @param e
397 * The caller event
398 */
399 public void controlResized(ControlEvent e) {
400 resizeControls();
401 }
402
403 /**
404 * @return The string representing the view type
405 */
406 protected String getViewTypeStr() {
407 return "viewoption.threads"; //$NON-NLS-1$
408 }
409
410 int getMarginWidth() {
411 return 0;
412 }
413
414 int getMarginHeight() {
415 return 0;
416 }
417
418 void loadOptions() {
419 fMinTimeInterval = 1;
420 fSelectionBegin = SWT.DEFAULT;
421 fSelectionEnd = SWT.DEFAULT;
422 fNameWidth = Utils.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
423 fNameWidthPref, fMinNameWidth, MAX_NAME_WIDTH);
424 }
425
426 void saveOptions() {
427 Utils.saveIntOption(getPreferenceString("namewidth"), fNameWidth); //$NON-NLS-1$
428 }
429
430 /**
431 * Create a data viewer.
432 *
433 * @param parent
434 * Parent composite
435 * @param style
436 * Style to use
437 * @return The new data viewer
438 */
439 protected Control createDataViewer(Composite parent, int style) {
440 loadOptions();
441 fColorScheme = new TimeGraphColorScheme();
442 fDataViewer = new Composite(parent, style) {
443 @Override
444 public void redraw() {
445 fTimeScaleCtrl.redraw();
446 fTimeGraphCtrl.redraw();
447 super.redraw();
448 }
449 };
450 fDataViewer.addDisposeListener(new DisposeListener() {
451 @Override
452 public void widgetDisposed(DisposeEvent e) {
453 for (Color color : fColors) {
454 color.dispose();
455 }
456 }
457 });
458 GridLayout gl = new GridLayout(2, false);
459 gl.marginHeight = fBorderWidth;
460 gl.marginWidth = 0;
461 gl.verticalSpacing = 0;
462 gl.horizontalSpacing = 0;
463 fDataViewer.setLayout(gl);
464
465 fTimeAlignedComposite = new Composite(fDataViewer, style) {
466 @Override
467 public void redraw() {
468 fDataViewer.redraw();
469 super.redraw();
470 }
471 };
472 GridLayout gl2 = new GridLayout(1, false);
473 gl2.marginHeight = fBorderWidth;
474 gl2.marginWidth = 0;
475 gl2.verticalSpacing = 0;
476 gl2.horizontalSpacing = 0;
477 fTimeAlignedComposite.setLayout(gl2);
478 fTimeAlignedComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
479
480 fTimeScaleCtrl = new TimeGraphScale(fTimeAlignedComposite, fColorScheme);
481 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
482 fTimeScaleCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
483 fTimeScaleCtrl.setHeight(fTimeScaleHeight);
484 fTimeScaleCtrl.addMouseWheelListener(new MouseWheelListener() {
485 @Override
486 public void mouseScrolled(MouseEvent e) {
487 fTimeGraphCtrl.zoom(e.count > 0);
488 }
489 });
490
491 fTimeGraphCtrl = createTimeGraphControl(fTimeAlignedComposite, fColorScheme);
492
493 fTimeGraphCtrl.setTimeProvider(this);
494 fTimeGraphCtrl.setTimeGraphScale(fTimeScaleCtrl);
495 fTimeGraphCtrl.addSelectionListener(this);
496 fTimeGraphCtrl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
497 fTimeGraphCtrl.addMouseWheelListener(new MouseWheelListener() {
498 @Override
499 public void mouseScrolled(MouseEvent e) {
500 adjustVerticalScrollBar();
501 }
502 });
503 fTimeGraphCtrl.addKeyListener(new KeyAdapter() {
504 @Override
505 public void keyPressed(KeyEvent e) {
506 if (e.character == '+') {
507 zoomIn();
508 } else if (e.character == '-') {
509 zoomOut();
510 }
511 adjustVerticalScrollBar();
512 }
513 });
514
515 fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS);
516 fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 1));
517 fVerticalScrollBar.addSelectionListener(new SelectionAdapter() {
518 @Override
519 public void widgetSelected(SelectionEvent e) {
520 setTopIndex(fVerticalScrollBar.getSelection());
521 }
522 });
523
524 fHorizontalScrollBar = new Slider(fDataViewer, SWT.HORIZONTAL | SWT.NO_FOCUS);
525 fHorizontalScrollBar.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
526 fHorizontalScrollBar.addListener(SWT.MouseWheel, new Listener() {
527 @Override
528 public void handleEvent(Event event) {
529 if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) {
530 getTimeGraphControl().zoom(event.count > 0);
531 } else {
532 getTimeGraphControl().horizontalScroll(event.count > 0);
533 }
534 // don't handle the immediately following SWT.Selection event
535 event.doit = false;
536 }
537 });
538 fHorizontalScrollBar.addListener(SWT.Selection, new Listener() {
539 @Override
540 public void handleEvent(Event event) {
541 int start = fHorizontalScrollBar.getSelection();
542 long time0 = getTime0();
543 long time1 = getTime1();
544 long timeMin = getMinTime();
545 long timeMax = getMaxTime();
546 long delta = timeMax - timeMin;
547
548 long range = time1 - time0;
549 time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX));
550 time1 = time0 + range;
551
552 setStartFinishTimeNotify(time0, time1);
553 }
554 });
555
556 Composite filler = new Composite(fDataViewer, SWT.NONE);
557 GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
558 gd.heightHint = fHorizontalScrollBar.getSize().y;
559 filler.setLayoutData(gd);
560 filler.setLayout(new FillLayout());
561
562 fTimeGraphCtrl.addControlListener(new ControlAdapter() {
563 @Override
564 public void controlResized(ControlEvent event) {
565 resizeControls();
566 }
567 });
568 resizeControls();
569 fDataViewer.update();
570 adjustHorizontalScrollBar();
571 adjustVerticalScrollBar();
572 return fDataViewer;
573 }
574
575 /**
576 * Dispose the view.
577 */
578 public void dispose() {
579 saveOptions();
580 fTimeGraphCtrl.dispose();
581 fDataViewer.dispose();
582 fColorScheme.dispose();
583 }
584
585 /**
586 * Create a new time graph control.
587 *
588 * @param parent
589 * The parent composite
590 * @param colors
591 * The color scheme
592 * @return The new TimeGraphControl
593 */
594 protected TimeGraphControl createTimeGraphControl(Composite parent,
595 TimeGraphColorScheme colors) {
596 return new TimeGraphControl(parent, colors);
597 }
598
599 /**
600 * Resize the controls
601 */
602 public void resizeControls() {
603 Rectangle r = fDataViewer.getClientArea();
604 if (r.isEmpty()) {
605 return;
606 }
607
608 int width = r.width;
609 if (fNameWidth > width - fMinNameWidth) {
610 fNameWidth = width - fMinNameWidth;
611 }
612 if (fNameWidth < fMinNameWidth) {
613 fNameWidth = fMinNameWidth;
614 }
615 adjustHorizontalScrollBar();
616 adjustVerticalScrollBar();
617 }
618
619 /**
620 * Recalculate the time bounds based on the time graph entries,
621 * if the user-specified bound is set to SWT.DEFAULT.
622 *
623 * @param entries
624 * The root time graph entries in the model
625 */
626 public void setTimeRange(ITimeGraphEntry entries[]) {
627 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
628 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
629 if (fBeginTime != SWT.DEFAULT && fEndTime != SWT.DEFAULT) {
630 return;
631 }
632 if (entries == null || entries.length == 0) {
633 return;
634 }
635 if (fTime0Bound == SWT.DEFAULT) {
636 fTime0Bound = Long.MAX_VALUE;
637 }
638 if (fTime1Bound == SWT.DEFAULT) {
639 fTime1Bound = Long.MIN_VALUE;
640 }
641 for (ITimeGraphEntry entry : entries) {
642 setTimeRange(entry);
643 }
644 }
645
646 private void setTimeRange(ITimeGraphEntry entry) {
647 if (fBeginTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getStartTime() != SWT.DEFAULT) {
648 fTime0Bound = Math.min(entry.getStartTime(), fTime0Bound);
649 }
650 if (fEndTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getEndTime() != SWT.DEFAULT) {
651 fTime1Bound = Math.max(entry.getEndTime(), fTime1Bound);
652 }
653 if (entry.hasChildren()) {
654 for (ITimeGraphEntry child : entry.getChildren()) {
655 setTimeRange(child);
656 }
657 }
658 }
659
660 /**
661 * Set the time bounds to the provided values.
662 *
663 * @param beginTime
664 * The bounds begin time, or SWT.DEFAULT to use the input bounds
665 * @param endTime
666 * The bounds end time, or SWT.DEFAULT to use the input bounds
667 */
668 public void setTimeBounds(long beginTime, long endTime) {
669 fBeginTime = beginTime;
670 fEndTime = endTime;
671 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
672 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
673 if (fTime0Bound > fTime1Bound) {
674 // only possible if both are not default
675 fBeginTime = endTime;
676 fEndTime = beginTime;
677 fTime0Bound = fBeginTime;
678 fTime1Bound = fEndTime;
679 }
680 adjustHorizontalScrollBar();
681 }
682
683 /**
684 * Recalculate the current time window when bounds have changed.
685 */
686 public void setTimeBounds() {
687 if (!fTimeRangeFixed) {
688 fTime0 = fTime0Bound;
689 fTime1 = fTime1Bound;
690 }
691 fTime0 = Math.max(fTime0Bound, Math.min(fTime0, fTime1Bound));
692 fTime1 = Math.max(fTime0Bound, Math.min(fTime1, fTime1Bound));
693 if (fTime1 - fTime0 < fMinTimeInterval) {
694 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
695 }
696 }
697
698 /**
699 * @param traces
700 */
701 private void refreshAllData(ITimeGraphEntry[] traces) {
702 setTimeBounds();
703 if (fSelectionBegin < fBeginTime) {
704 fSelectionBegin = fBeginTime;
705 } else if (fSelectionBegin > fEndTime) {
706 fSelectionBegin = fEndTime;
707 }
708 if (fSelectionEnd < fBeginTime) {
709 fSelectionEnd = fBeginTime;
710 } else if (fSelectionEnd > fEndTime) {
711 fSelectionEnd = fEndTime;
712 }
713 fTimeGraphCtrl.refreshData(traces);
714 fTimeScaleCtrl.redraw();
715 updateMarkerActions();
716 adjustVerticalScrollBar();
717 }
718
719 /**
720 * Callback for when this view is focused
721 */
722 public void setFocus() {
723 if (null != fTimeGraphCtrl) {
724 fTimeGraphCtrl.setFocus();
725 }
726 }
727
728 /**
729 * Get the current focus status of this view.
730 *
731 * @return If the view is currently focused, or not
732 */
733 public boolean isInFocus() {
734 return fTimeGraphCtrl.isInFocus();
735 }
736
737 /**
738 * Get the view's current selection
739 *
740 * @return The entry that is selected
741 */
742 public ITimeGraphEntry getSelection() {
743 return fTimeGraphCtrl.getSelectedTrace();
744 }
745
746 /**
747 * Get the index of the current selection
748 *
749 * @return The index
750 */
751 public int getSelectionIndex() {
752 return fTimeGraphCtrl.getSelectedIndex();
753 }
754
755 @Override
756 public long getTime0() {
757 return fTime0;
758 }
759
760 @Override
761 public long getTime1() {
762 return fTime1;
763 }
764
765 @Override
766 public long getMinTimeInterval() {
767 return fMinTimeInterval;
768 }
769
770 @Override
771 public int getNameSpace() {
772 return fNameWidth;
773 }
774
775 @Override
776 public void setNameSpace(int width) {
777 fNameWidth = width;
778 int w = fTimeGraphCtrl.getClientArea().width;
779 if (fNameWidth > w - MIN_NAME_WIDTH) {
780 fNameWidth = w - MIN_NAME_WIDTH;
781 }
782 if (fNameWidth < MIN_NAME_WIDTH) {
783 fNameWidth = MIN_NAME_WIDTH;
784 }
785 fTimeGraphCtrl.redraw();
786 fTimeScaleCtrl.redraw();
787 }
788
789 @Override
790 public int getTimeSpace() {
791 int w = fTimeGraphCtrl.getClientArea().width;
792 return w - fNameWidth;
793 }
794
795 @Override
796 public long getBeginTime() {
797 return fBeginTime;
798 }
799
800 @Override
801 public long getEndTime() {
802 return fEndTime;
803 }
804
805 @Override
806 public long getMaxTime() {
807 return fTime1Bound;
808 }
809
810 @Override
811 public long getMinTime() {
812 return fTime0Bound;
813 }
814
815 @Override
816 public long getSelectionBegin() {
817 return fSelectionBegin;
818 }
819
820 @Override
821 public long getSelectionEnd() {
822 return fSelectionEnd;
823 }
824
825 @Override
826 public void setStartFinishTimeNotify(long time0, long time1) {
827 setStartFinishTimeInt(time0, time1);
828 notifyRangeListeners();
829 }
830
831 @Override
832 public void notifyStartFinishTime() {
833 notifyRangeListeners();
834 }
835
836 @Override
837 public void setStartFinishTime(long time0, long time1) {
838 /* if there is a pending time range, ignore this one */
839 if (fListenerNotifier != null && fListenerNotifier.hasTimeRangeUpdated()) {
840 return;
841 }
842 setStartFinishTimeInt(time0, time1);
843 updateExtSynchValues();
844 }
845
846 private void setStartFinishTimeInt(long time0, long time1) {
847 fTime0 = time0;
848 if (fTime0 < fTime0Bound) {
849 fTime0 = fTime0Bound;
850 }
851 if (fTime0 > fTime1Bound) {
852 fTime0 = fTime1Bound;
853 }
854 fTime1 = time1;
855 if (fTime1 < fTime0Bound) {
856 fTime1 = fTime0Bound;
857 }
858 if (fTime1 > fTime1Bound) {
859 fTime1 = fTime1Bound;
860 }
861 if (fTime1 - fTime0 < fMinTimeInterval) {
862 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
863 }
864 fTimeRangeFixed = true;
865 adjustHorizontalScrollBar();
866 fTimeGraphCtrl.redraw();
867 fTimeScaleCtrl.redraw();
868 }
869
870 @Override
871 public void resetStartFinishTime() {
872 setStartFinishTimeNotify(fTime0Bound, fTime1Bound);
873 fTimeRangeFixed = false;
874 }
875
876 @Override
877 public void setSelectedTimeNotify(long time, boolean ensureVisible) {
878 setSelectedTimeInt(time, ensureVisible, true);
879 }
880
881 @Override
882 public void setSelectedTime(long time, boolean ensureVisible) {
883 /* if there is a pending time selection, ignore this one */
884 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
885 return;
886 }
887 setSelectedTimeInt(time, ensureVisible, false);
888 }
889
890 @Override
891 public void setSelectionRangeNotify(long beginTime, long endTime) {
892 long time0 = fTime0;
893 long time1 = fTime1;
894 long selectionBegin = fSelectionBegin;
895 long selectionEnd = fSelectionEnd;
896 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
897 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
898 boolean changed = (selectionBegin != fSelectionBegin || selectionEnd != fSelectionEnd);
899 ensureVisible(fSelectionEnd);
900 fTimeGraphCtrl.redraw();
901 fTimeScaleCtrl.redraw();
902 updateMarkerActions();
903 if ((time0 != fTime0) || (time1 != fTime1)) {
904 notifyRangeListeners();
905 }
906 if (changed) {
907 notifyTimeListeners();
908 }
909 }
910
911 @Override
912 public void setSelectionRange(long beginTime, long endTime) {
913 /* if there is a pending time selection, ignore this one */
914 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
915 return;
916 }
917 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
918 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
919 fTimeGraphCtrl.redraw();
920 fTimeScaleCtrl.redraw();
921 updateMarkerActions();
922 }
923
924 private void setSelectedTimeInt(long time, boolean ensureVisible, boolean doNotify) {
925 long selection = Math.max(fTime0Bound, Math.min(fTime1Bound, time));
926 long time0 = fTime0;
927 long time1 = fTime1;
928 if (ensureVisible) {
929 ensureVisible(selection);
930 }
931 fTimeGraphCtrl.redraw();
932 fTimeScaleCtrl.redraw();
933
934 boolean notifySelectedTime = (selection != fSelectionBegin || selection != fSelectionEnd);
935 fSelectionBegin = selection;
936 fSelectionEnd = selection;
937 updateMarkerActions();
938
939 if ((time0 != fTime0) || (time1 != fTime1)) {
940 notifyRangeListeners();
941 }
942
943 if (doNotify && notifySelectedTime) {
944 notifyTimeListeners();
945 }
946 }
947
948 private void ensureVisible(long time) {
949 long timeMid = (fTime1 - fTime0) / 2;
950 if (time < fTime0) {
951 long dt = fTime0 - time + timeMid;
952 fTime0 -= dt;
953 fTime1 -= dt;
954 } else if (time > fTime1) {
955 long dt = time - fTime1 + timeMid;
956 fTime0 += dt;
957 fTime1 += dt;
958 }
959 if (fTime0 < fTime0Bound) {
960 fTime1 = Math.min(fTime1Bound, fTime1 + (fTime0Bound - fTime0));
961 fTime0 = fTime0Bound;
962 } else if (fTime1 > fTime1Bound) {
963 fTime0 = Math.max(fTime0Bound, fTime0 - (fTime1 - fTime1Bound));
964 fTime1 = fTime1Bound;
965 }
966 if (fTime1 - fTime0 < fMinTimeInterval) {
967 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
968 }
969 adjustHorizontalScrollBar();
970 }
971
972 @Override
973 public void widgetDefaultSelected(SelectionEvent e) {
974 if (fSelectedEntry != getSelection()) {
975 fSelectedEntry = getSelection();
976 notifySelectionListeners();
977 }
978 }
979
980 @Override
981 public void widgetSelected(SelectionEvent e) {
982 if (fSelectedEntry != getSelection()) {
983 fSelectedEntry = getSelection();
984 notifySelectionListeners();
985 }
986 }
987
988 /**
989 * Callback for when the next event is selected
990 *
991 * @param extend
992 * true to extend selection range, false for single selection
993 * @since 1.0
994 */
995 public void selectNextEvent(boolean extend) {
996 fTimeGraphCtrl.selectNextEvent(extend);
997 adjustVerticalScrollBar();
998 }
999
1000 /**
1001 * Callback for when the previous event is selected
1002 *
1003 * @param extend
1004 * true to extend selection range, false for single selection
1005 * @since 1.0
1006 */
1007 public void selectPrevEvent(boolean extend) {
1008 fTimeGraphCtrl.selectPrevEvent(extend);
1009 adjustVerticalScrollBar();
1010 }
1011
1012 /**
1013 * Callback for when the next item is selected
1014 */
1015 public void selectNextItem() {
1016 fTimeGraphCtrl.selectNextTrace();
1017 adjustVerticalScrollBar();
1018 }
1019
1020 /**
1021 * Callback for when the previous item is selected
1022 */
1023 public void selectPrevItem() {
1024 fTimeGraphCtrl.selectPrevTrace();
1025 adjustVerticalScrollBar();
1026 }
1027
1028 /**
1029 * Callback for the show legend action
1030 */
1031 public void showLegend() {
1032 if (fDataViewer == null || fDataViewer.isDisposed()) {
1033 return;
1034 }
1035
1036 TimeGraphLegend.open(fDataViewer.getShell(), fTimeGraphProvider);
1037 }
1038
1039 /**
1040 * Callback for the Zoom In action
1041 */
1042 public void zoomIn() {
1043 fTimeGraphCtrl.zoomIn();
1044 }
1045
1046 /**
1047 * Callback for the Zoom Out action
1048 */
1049 public void zoomOut() {
1050 fTimeGraphCtrl.zoomOut();
1051 }
1052
1053 private String getPreferenceString(String string) {
1054 return getViewTypeStr() + "." + string; //$NON-NLS-1$
1055 }
1056
1057 /**
1058 * Add a selection listener
1059 *
1060 * @param listener
1061 * The listener to add
1062 */
1063 public void addSelectionListener(ITimeGraphSelectionListener listener) {
1064 fSelectionListeners.add(listener);
1065 }
1066
1067 /**
1068 * Remove a selection listener
1069 *
1070 * @param listener
1071 * The listener to remove
1072 */
1073 public void removeSelectionListener(ITimeGraphSelectionListener listener) {
1074 fSelectionListeners.remove(listener);
1075 }
1076
1077 private void notifySelectionListeners() {
1078 if (fListenerNotifier == null) {
1079 fListenerNotifier = new ListenerNotifier();
1080 fListenerNotifier.start();
1081 }
1082 fListenerNotifier.selectionChanged();
1083 }
1084
1085 private void fireSelectionChanged(ITimeGraphEntry selection) {
1086 TimeGraphSelectionEvent event = new TimeGraphSelectionEvent(this, selection);
1087
1088 for (ITimeGraphSelectionListener listener : fSelectionListeners) {
1089 listener.selectionChanged(event);
1090 }
1091 }
1092
1093 /**
1094 * Add a time listener
1095 *
1096 * @param listener
1097 * The listener to add
1098 */
1099 public void addTimeListener(ITimeGraphTimeListener listener) {
1100 fTimeListeners.add(listener);
1101 }
1102
1103 /**
1104 * Remove a time listener
1105 *
1106 * @param listener
1107 * The listener to remove
1108 */
1109 public void removeTimeListener(ITimeGraphTimeListener listener) {
1110 fTimeListeners.remove(listener);
1111 }
1112
1113 private void notifyTimeListeners() {
1114 if (fListenerNotifier == null) {
1115 fListenerNotifier = new ListenerNotifier();
1116 fListenerNotifier.start();
1117 }
1118 fListenerNotifier.timeSelected();
1119 }
1120
1121 private void fireTimeSelected(long startTime, long endTime) {
1122 TimeGraphTimeEvent event = new TimeGraphTimeEvent(this, startTime, endTime);
1123
1124 for (ITimeGraphTimeListener listener : fTimeListeners) {
1125 listener.timeSelected(event);
1126 }
1127 }
1128
1129 /**
1130 * Add a range listener
1131 *
1132 * @param listener
1133 * The listener to add
1134 */
1135 public void addRangeListener(ITimeGraphRangeListener listener) {
1136 fRangeListeners.add(listener);
1137 }
1138
1139 /**
1140 * Remove a range listener
1141 *
1142 * @param listener
1143 * The listener to remove
1144 */
1145 public void removeRangeListener(ITimeGraphRangeListener listener) {
1146 fRangeListeners.remove(listener);
1147 }
1148
1149 private void notifyRangeListeners() {
1150 if (fListenerNotifier == null) {
1151 fListenerNotifier = new ListenerNotifier();
1152 fListenerNotifier.start();
1153 }
1154 fListenerNotifier.timeRangeUpdated();
1155 }
1156
1157 private void fireTimeRangeUpdated(long startTime, long endTime) {
1158 // Check if the time has actually changed from last notification
1159 if (startTime != fTime0ExtSynch || endTime != fTime1ExtSynch) {
1160 // Notify Time Scale Selection Listeners
1161 TimeGraphRangeUpdateEvent event = new TimeGraphRangeUpdateEvent(this, startTime, endTime);
1162
1163 for (ITimeGraphRangeListener listener : fRangeListeners) {
1164 listener.timeRangeUpdated(event);
1165 }
1166
1167 // update external synch values
1168 updateExtSynchValues();
1169 }
1170 }
1171
1172 /**
1173 * Add a bookmark listener
1174 *
1175 * @param listener
1176 * The listener to add
1177 * @since 2.0
1178 */
1179 public void addBookmarkListener(ITimeGraphBookmarkListener listener) {
1180 fBookmarkListeners.add(listener);
1181 }
1182
1183 /**
1184 * Remove a bookmark listener
1185 *
1186 * @param listener
1187 * The listener to remove
1188 * @since 2.0
1189 */
1190 public void removeBookmarkListener(ITimeGraphBookmarkListener listener) {
1191 fBookmarkListeners.remove(listener);
1192 }
1193
1194 private void fireBookmarkAdded(IMarkerEvent bookmark) {
1195 TimeGraphBookmarkEvent event = new TimeGraphBookmarkEvent(this, bookmark);
1196
1197 for (ITimeGraphBookmarkListener listener : fBookmarkListeners) {
1198 listener.bookmarkAdded(event);
1199 }
1200 }
1201
1202 private void fireBookmarkRemoved(IMarkerEvent bookmark) {
1203 TimeGraphBookmarkEvent event = new TimeGraphBookmarkEvent(this, bookmark);
1204
1205 for (ITimeGraphBookmarkListener listener : fBookmarkListeners) {
1206 listener.bookmarkRemoved(event);
1207 }
1208 }
1209
1210 /**
1211 * Set the bookmarks list.
1212 *
1213 * @param bookmarks
1214 * The bookmarks list, or null
1215 * @since 2.0
1216 */
1217 public void setBookmarks(List<IMarkerEvent> bookmarks) {
1218 for (IMarkerEvent bookmark : fBookmarks) {
1219 checkDisposeColor(bookmark.getColor());
1220 }
1221 fBookmarks.clear();
1222 if (bookmarks != null) {
1223 fBookmarks.addAll(bookmarks);
1224 }
1225 updateMarkerList();
1226 updateMarkerActions();
1227 }
1228
1229 /**
1230 * Get the bookmarks list.
1231 *
1232 * @return The bookmarks list
1233 * @since 2.0
1234 */
1235 public List<IMarkerEvent> getBookmarks() {
1236 return Collections.unmodifiableList(fBookmarks);
1237 }
1238
1239 /**
1240 * Set the markers list.
1241 *
1242 * @param markers
1243 * The markers list, or null
1244 * @since 2.0
1245 */
1246 public void setMarkers(List<IMarkerEvent> markers) {
1247 fMarkers.clear();
1248 if (markers != null) {
1249 fMarkers.addAll(markers);
1250 }
1251 updateMarkerList();
1252 updateMarkerActions();
1253 }
1254
1255 /**
1256 * Get the markers list.
1257 *
1258 * @return The markers list, or null
1259 * @since 2.0
1260 */
1261 public List<IMarkerEvent> getMarkers() {
1262 return Collections.unmodifiableList(fMarkers);
1263 }
1264
1265 /**
1266 * Dispose the color resource if and only if it was created by this viewer.
1267 *
1268 * @param color
1269 * the color
1270 */
1271 private void checkDisposeColor(Color color) {
1272 for (int i = 0; i < fColors.size(); i++) {
1273 /* check for identity, not equality */
1274 if (fColors.get(i) == color) {
1275 color.dispose();
1276 fColors.remove(i);
1277 break;
1278 }
1279 }
1280 }
1281
1282 /**
1283 * Callback to set a selected event in the view
1284 *
1285 * @param event
1286 * The event that was selected
1287 * @param source
1288 * The source of this selection event
1289 */
1290 public void setSelectedEvent(ITimeEvent event, Object source) {
1291 if (event == null || source == this) {
1292 return;
1293 }
1294 fSelectedEntry = event.getEntry();
1295 fTimeGraphCtrl.selectItem(fSelectedEntry, false);
1296
1297 setSelectedTimeInt(event.getTime(), true, true);
1298 adjustVerticalScrollBar();
1299 }
1300
1301 /**
1302 * Set the seeked time of a trace
1303 *
1304 * @param trace
1305 * The trace that was seeked
1306 * @param time
1307 * The target time
1308 * @param source
1309 * The source of this seek event
1310 */
1311 public void setSelectedTraceTime(ITimeGraphEntry trace, long time, Object source) {
1312 if (trace == null || source == this) {
1313 return;
1314 }
1315 fSelectedEntry = trace;
1316 fTimeGraphCtrl.selectItem(trace, false);
1317
1318 setSelectedTimeInt(time, true, true);
1319 }
1320
1321 /**
1322 * Callback for a trace selection
1323 *
1324 * @param trace
1325 * The trace that was selected
1326 */
1327 public void setSelection(ITimeGraphEntry trace) {
1328 /* if there is a pending selection, ignore this one */
1329 if (fListenerNotifier != null && fListenerNotifier.hasSelectionChanged()) {
1330 return;
1331 }
1332 fSelectedEntry = trace;
1333 fTimeGraphCtrl.selectItem(trace, false);
1334 adjustVerticalScrollBar();
1335 }
1336
1337 /**
1338 * Callback for a time window selection
1339 *
1340 * @param time0
1341 * Start time of the range
1342 * @param time1
1343 * End time of the range
1344 * @param source
1345 * Source of the event
1346 */
1347 public void setSelectVisTimeWindow(long time0, long time1, Object source) {
1348 if (source == this) {
1349 return;
1350 }
1351
1352 setStartFinishTimeInt(time0, time1);
1353
1354 // update notification time values since we are now in synch with the
1355 // external application
1356 updateExtSynchValues();
1357 }
1358
1359 /**
1360 * update the cache values used to identify the need to send a time window
1361 * update to external registered listeners
1362 */
1363 private void updateExtSynchValues() {
1364 // last time notification cache
1365 fTime0ExtSynch = fTime0;
1366 fTime1ExtSynch = fTime1;
1367 }
1368
1369 @Override
1370 public TimeFormat getTimeFormat() {
1371 return fTimeFormat;
1372 }
1373
1374 /**
1375 * @param tf
1376 * the {@link TimeFormat} used to display timestamps
1377 */
1378 public void setTimeFormat(TimeFormat tf) {
1379 this.fTimeFormat = tf;
1380 if (tf == TimeFormat.CYCLES) {
1381 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1382 } else {
1383 fTimeDataProvider = this;
1384 }
1385 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1386 if (fToolTipHandler != null) {
1387 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1388 }
1389 }
1390
1391 /**
1392 * Sets the clock frequency. Used when the time format is set to CYCLES.
1393 *
1394 * @param clockFrequency
1395 * the clock frequency in Hz
1396 */
1397 public void setClockFrequency(long clockFrequency) {
1398 fClockFrequency = clockFrequency;
1399 if (fTimeFormat == TimeFormat.CYCLES) {
1400 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1401 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1402 if (fToolTipHandler != null) {
1403 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1404 }
1405 }
1406 }
1407
1408 /**
1409 * Retrieve the border width
1410 *
1411 * @return The width
1412 */
1413 public int getBorderWidth() {
1414 return fBorderWidth;
1415 }
1416
1417 /**
1418 * Set the border width
1419 *
1420 * @param borderWidth
1421 * The width
1422 */
1423 public void setBorderWidth(int borderWidth) {
1424 if (borderWidth > -1) {
1425 this.fBorderWidth = borderWidth;
1426 GridLayout gl = (GridLayout) fDataViewer.getLayout();
1427 gl.marginHeight = borderWidth;
1428 }
1429 }
1430
1431 /**
1432 * Retrieve the height of the header
1433 *
1434 * @return The height
1435 */
1436 public int getHeaderHeight() {
1437 return fTimeScaleHeight;
1438 }
1439
1440 /**
1441 * Set the height of the header
1442 *
1443 * @param headerHeight
1444 * The height to set
1445 */
1446 public void setHeaderHeight(int headerHeight) {
1447 if (headerHeight > -1) {
1448 this.fTimeScaleHeight = headerHeight;
1449 fTimeScaleCtrl.setHeight(headerHeight);
1450 }
1451 }
1452
1453 /**
1454 * Retrieve the height of an item row
1455 *
1456 * @return The height
1457 */
1458 public int getItemHeight() {
1459 if (fTimeGraphCtrl != null) {
1460 return fTimeGraphCtrl.getItemHeight();
1461 }
1462 return 0;
1463 }
1464
1465 /**
1466 * Set the height of an item row
1467 *
1468 * @param rowHeight
1469 * The height to set
1470 */
1471 public void setItemHeight(int rowHeight) {
1472 if (fTimeGraphCtrl != null) {
1473 fTimeGraphCtrl.setItemHeight(rowHeight);
1474 }
1475 }
1476
1477 /**
1478 * Set the minimum item width
1479 *
1480 * @param width
1481 * The min width
1482 */
1483 public void setMinimumItemWidth(int width) {
1484 if (fTimeGraphCtrl != null) {
1485 fTimeGraphCtrl.setMinimumItemWidth(width);
1486 }
1487 }
1488
1489 /**
1490 * Set the width for the name column
1491 *
1492 * @param width
1493 * The width
1494 */
1495 public void setNameWidthPref(int width) {
1496 fNameWidthPref = width;
1497 if (width == 0) {
1498 fMinNameWidth = 0;
1499 fNameWidth = 0;
1500 }
1501 }
1502
1503 /**
1504 * Retrieve the configure width for the name column
1505 *
1506 * @param width
1507 * Unused?
1508 * @return The width
1509 */
1510 public int getNameWidthPref(int width) {
1511 return fNameWidthPref;
1512 }
1513
1514 /**
1515 * Returns the primary control associated with this viewer.
1516 *
1517 * @return the SWT control which displays this viewer's content
1518 */
1519 public Control getControl() {
1520 return fDataViewer;
1521 }
1522
1523 /**
1524 * Returns the time graph control associated with this viewer.
1525 *
1526 * @return the time graph control
1527 */
1528 public TimeGraphControl getTimeGraphControl() {
1529 return fTimeGraphCtrl;
1530 }
1531
1532 /**
1533 * Returns the time graph scale associated with this viewer.
1534 *
1535 * @return the time graph scale
1536 */
1537 public TimeGraphScale getTimeGraphScale() {
1538 return fTimeScaleCtrl;
1539 }
1540
1541 /**
1542 * Returns the composite containing all the controls that are time aligned,
1543 * i.e. TimeGraphScale, TimeGraphControl.
1544 *
1545 * @return the time based composite
1546 * @since 1.0
1547 */
1548 public Composite getTimeAlignedComposite() {
1549 return fTimeAlignedComposite;
1550 }
1551
1552 /**
1553 * Return the x coordinate corresponding to a time
1554 *
1555 * @param time
1556 * the time
1557 * @return the x coordinate corresponding to the time
1558 */
1559 public int getXForTime(long time) {
1560 return fTimeGraphCtrl.getXForTime(time);
1561 }
1562
1563 /**
1564 * Return the time corresponding to an x coordinate
1565 *
1566 * @param x
1567 * the x coordinate
1568 * @return the time corresponding to the x coordinate
1569 */
1570 public long getTimeAtX(int x) {
1571 return fTimeGraphCtrl.getTimeAtX(x);
1572 }
1573
1574 /**
1575 * Get the selection provider
1576 *
1577 * @return the selection provider
1578 */
1579 public ISelectionProvider getSelectionProvider() {
1580 return fTimeGraphCtrl;
1581 }
1582
1583 /**
1584 * Wait for the cursor
1585 *
1586 * @param waitInd
1587 * Wait indefinitely?
1588 */
1589 public void waitCursor(boolean waitInd) {
1590 fTimeGraphCtrl.waitCursor(waitInd);
1591 }
1592
1593 /**
1594 * Get the horizontal scroll bar object
1595 *
1596 * @return The scroll bar
1597 */
1598 public Slider getHorizontalBar() {
1599 return fHorizontalScrollBar;
1600 }
1601
1602 /**
1603 * Get the vertical scroll bar object
1604 *
1605 * @return The scroll bar
1606 */
1607 public Slider getVerticalBar() {
1608 return fVerticalScrollBar;
1609 }
1610
1611 /**
1612 * Set the given index as the top one
1613 *
1614 * @param index
1615 * The index that will go to the top
1616 */
1617 public void setTopIndex(int index) {
1618 fTimeGraphCtrl.setTopIndex(index);
1619 adjustVerticalScrollBar();
1620 }
1621
1622 /**
1623 * Retrieve the current top index
1624 *
1625 * @return The top index
1626 */
1627 public int getTopIndex() {
1628 return fTimeGraphCtrl.getTopIndex();
1629 }
1630
1631 /**
1632 * Sets the auto-expand level to be used for new entries discovered when
1633 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1634 * means that there is no auto-expand; 1 means that top-level entries are
1635 * expanded, but not their children; 2 means that top-level entries are
1636 * expanded, and their children, but not grand-children; and so on.
1637 * <p>
1638 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1639 * </p>
1640 *
1641 * @param level
1642 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1643 * levels of the tree
1644 */
1645 public void setAutoExpandLevel(int level) {
1646 fTimeGraphCtrl.setAutoExpandLevel(level);
1647 }
1648
1649 /**
1650 * Returns the auto-expand level.
1651 *
1652 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1653 * the tree are expanded automatically
1654 * @see #setAutoExpandLevel
1655 */
1656 public int getAutoExpandLevel() {
1657 return fTimeGraphCtrl.getAutoExpandLevel();
1658 }
1659
1660 /**
1661 * Get the expanded state of an entry.
1662 *
1663 * @param entry
1664 * The entry
1665 * @return true if the entry is expanded, false if collapsed
1666 * @since 1.1
1667 */
1668 public boolean getExpandedState(ITimeGraphEntry entry) {
1669 return fTimeGraphCtrl.getExpandedState(entry);
1670 }
1671
1672 /**
1673 * Set the expanded state of an entry
1674 *
1675 * @param entry
1676 * The entry to expand/collapse
1677 * @param expanded
1678 * True for expanded, false for collapsed
1679 */
1680 public void setExpandedState(ITimeGraphEntry entry, boolean expanded) {
1681 fTimeGraphCtrl.setExpandedState(entry, expanded);
1682 adjustVerticalScrollBar();
1683 }
1684
1685 /**
1686 * Collapses all nodes of the viewer's tree, starting with the root.
1687 */
1688 public void collapseAll() {
1689 fTimeGraphCtrl.collapseAll();
1690 adjustVerticalScrollBar();
1691 }
1692
1693 /**
1694 * Expands all entries of the viewer's tree, starting with the root.
1695 */
1696 public void expandAll() {
1697 fTimeGraphCtrl.expandAll();
1698 adjustVerticalScrollBar();
1699 }
1700
1701 /**
1702 * Get the number of expanded (visible) time graph entries. This includes
1703 * leafs and does not include filtered-out entries.
1704 *
1705 * @return The number of expanded (visible) time graph entries
1706 */
1707 public int getExpandedElementCount() {
1708 return fTimeGraphCtrl.getExpandedElementCount();
1709 }
1710
1711 /**
1712 * Get the expanded (visible) time graph entries. This includes leafs and
1713 * does not include filtered-out entries.
1714 *
1715 * @return The array of expanded (visible) time graph entries
1716 */
1717 public ITimeGraphEntry[] getExpandedElements() {
1718 return fTimeGraphCtrl.getExpandedElements();
1719 }
1720
1721 /**
1722 * Add a tree listener
1723 *
1724 * @param listener
1725 * The listener to add
1726 */
1727 public void addTreeListener(ITimeGraphTreeListener listener) {
1728 fTimeGraphCtrl.addTreeListener(listener);
1729 }
1730
1731 /**
1732 * Remove a tree listener
1733 *
1734 * @param listener
1735 * The listener to remove
1736 */
1737 public void removeTreeListener(ITimeGraphTreeListener listener) {
1738 fTimeGraphCtrl.removeTreeListener(listener);
1739 }
1740
1741 /**
1742 * Get the reset scale action.
1743 *
1744 * @return The Action object
1745 */
1746 public Action getResetScaleAction() {
1747 if (fResetScaleAction == null) {
1748 // resetScale
1749 fResetScaleAction = new Action() {
1750 @Override
1751 public void run() {
1752 resetStartFinishTime();
1753 }
1754 };
1755 fResetScaleAction.setText(Messages.TmfTimeGraphViewer_ResetScaleActionNameText);
1756 fResetScaleAction.setToolTipText(Messages.TmfTimeGraphViewer_ResetScaleActionToolTipText);
1757 fResetScaleAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU));
1758 }
1759 return fResetScaleAction;
1760 }
1761
1762 /**
1763 * Get the show legend action.
1764 *
1765 * @return The Action object
1766 */
1767 public Action getShowLegendAction() {
1768 if (fShowLegendAction == null) {
1769 // showLegend
1770 fShowLegendAction = new Action() {
1771 @Override
1772 public void run() {
1773 showLegend();
1774 }
1775 };
1776 fShowLegendAction.setText(Messages.TmfTimeGraphViewer_LegendActionNameText);
1777 fShowLegendAction.setToolTipText(Messages.TmfTimeGraphViewer_LegendActionToolTipText);
1778 fShowLegendAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LEGEND));
1779 }
1780
1781 return fShowLegendAction;
1782 }
1783
1784 /**
1785 * Get the the next event action.
1786 *
1787 * @return The action object
1788 */
1789 public Action getNextEventAction() {
1790 if (fNextEventAction == null) {
1791 fNextEventAction = new Action() {
1792 @Override
1793 public void runWithEvent(Event event) {
1794 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1795 selectNextEvent(extend);
1796 }
1797 };
1798
1799 fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText);
1800 fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText);
1801 fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT));
1802 }
1803
1804 return fNextEventAction;
1805 }
1806
1807 /**
1808 * Get the previous event action.
1809 *
1810 * @return The Action object
1811 */
1812 public Action getPreviousEventAction() {
1813 if (fPrevEventAction == null) {
1814 fPrevEventAction = new Action() {
1815 @Override
1816 public void runWithEvent(Event event) {
1817 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1818 selectPrevEvent(extend);
1819 }
1820 };
1821
1822 fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText);
1823 fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText);
1824 fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT));
1825 }
1826
1827 return fPrevEventAction;
1828 }
1829
1830 /**
1831 * Get the next item action.
1832 *
1833 * @return The Action object
1834 */
1835 public Action getNextItemAction() {
1836 if (fNextItemAction == null) {
1837
1838 fNextItemAction = new Action() {
1839 @Override
1840 public void run() {
1841 selectNextItem();
1842 }
1843 };
1844 fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText);
1845 fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText);
1846 fNextItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_ITEM));
1847 }
1848 return fNextItemAction;
1849 }
1850
1851 /**
1852 * Get the previous item action.
1853 *
1854 * @return The Action object
1855 */
1856 public Action getPreviousItemAction() {
1857 if (fPreviousItemAction == null) {
1858
1859 fPreviousItemAction = new Action() {
1860 @Override
1861 public void run() {
1862 selectPrevItem();
1863 }
1864 };
1865 fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
1866 fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText);
1867 fPreviousItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_ITEM));
1868 }
1869 return fPreviousItemAction;
1870 }
1871
1872 /**
1873 * Get the zoom in action
1874 *
1875 * @return The Action object
1876 */
1877 public Action getZoomInAction() {
1878 if (fZoomInAction == null) {
1879 fZoomInAction = new Action() {
1880 @Override
1881 public void run() {
1882 zoomIn();
1883 }
1884 };
1885 fZoomInAction.setText(Messages.TmfTimeGraphViewer_ZoomInActionNameText);
1886 fZoomInAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomInActionToolTipText);
1887 fZoomInAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU));
1888 }
1889 return fZoomInAction;
1890 }
1891
1892 /**
1893 * Get the zoom out action
1894 *
1895 * @return The Action object
1896 */
1897 public Action getZoomOutAction() {
1898 if (fZoomOutAction == null) {
1899 fZoomOutAction = new Action() {
1900 @Override
1901 public void run() {
1902 zoomOut();
1903 }
1904 };
1905 fZoomOutAction.setText(Messages.TmfTimeGraphViewer_ZoomOutActionNameText);
1906 fZoomOutAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomOutActionToolTipText);
1907 fZoomOutAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU));
1908 }
1909 return fZoomOutAction;
1910 }
1911
1912 /**
1913 * Get the hide arrows action
1914 *
1915 * @param dialogSettings
1916 * The dialog settings section where the state should be stored,
1917 * or null
1918 *
1919 * @return The Action object
1920 */
1921 public Action getHideArrowsAction(final IDialogSettings dialogSettings) {
1922 if (fHideArrowsAction == null) {
1923 fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) {
1924 @Override
1925 public void run() {
1926 boolean hideArrows = fHideArrowsAction.isChecked();
1927 fTimeGraphCtrl.hideArrows(hideArrows);
1928 refresh();
1929 if (dialogSettings != null) {
1930 dialogSettings.put(HIDE_ARROWS_KEY, hideArrows);
1931 }
1932 if (fFollowArrowFwdAction != null) {
1933 fFollowArrowFwdAction.setEnabled(!hideArrows);
1934 }
1935 if (fFollowArrowBwdAction != null) {
1936 fFollowArrowBwdAction.setEnabled(!hideArrows);
1937 }
1938 }
1939 };
1940 fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText);
1941 fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS));
1942 if (dialogSettings != null) {
1943 boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY);
1944 fTimeGraphCtrl.hideArrows(hideArrows);
1945 fHideArrowsAction.setChecked(hideArrows);
1946 if (fFollowArrowFwdAction != null) {
1947 fFollowArrowFwdAction.setEnabled(!hideArrows);
1948 }
1949 if (fFollowArrowBwdAction != null) {
1950 fFollowArrowBwdAction.setEnabled(!hideArrows);
1951 }
1952 }
1953 }
1954 return fHideArrowsAction;
1955 }
1956
1957 /**
1958 * Get the follow arrow forward action.
1959 *
1960 * @return The Action object
1961 */
1962 public Action getFollowArrowFwdAction() {
1963 if (fFollowArrowFwdAction == null) {
1964 fFollowArrowFwdAction = new Action() {
1965 @Override
1966 public void runWithEvent(Event event) {
1967 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1968 fTimeGraphCtrl.followArrowFwd(extend);
1969 adjustVerticalScrollBar();
1970 }
1971 };
1972 fFollowArrowFwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionNameText);
1973 fFollowArrowFwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText);
1974 fFollowArrowFwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_FORWARD));
1975 if (fHideArrowsAction != null) {
1976 fFollowArrowFwdAction.setEnabled(!fHideArrowsAction.isChecked());
1977 }
1978 }
1979 return fFollowArrowFwdAction;
1980 }
1981
1982 /**
1983 * Get the follow arrow backward action.
1984 *
1985 * @return The Action object
1986 */
1987 public Action getFollowArrowBwdAction() {
1988 if (fFollowArrowBwdAction == null) {
1989 fFollowArrowBwdAction = new Action() {
1990 @Override
1991 public void runWithEvent(Event event) {
1992 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1993 fTimeGraphCtrl.followArrowBwd(extend);
1994 adjustVerticalScrollBar();
1995 }
1996 };
1997 fFollowArrowBwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionNameText);
1998 fFollowArrowBwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText);
1999 fFollowArrowBwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_BACKWARD));
2000 if (fHideArrowsAction != null) {
2001 fFollowArrowBwdAction.setEnabled(!fHideArrowsAction.isChecked());
2002 }
2003 }
2004 return fFollowArrowBwdAction;
2005 }
2006
2007 /**
2008 * Get the show filter dialog action.
2009 *
2010 * @return The Action object
2011 * @since 2.0
2012 */
2013 public ShowFilterDialogAction getShowFilterDialogAction() {
2014 if (fShowFilterDialogAction == null) {
2015 fShowFilterDialogAction = new ShowFilterDialogAction(this);
2016 }
2017 return fShowFilterDialogAction;
2018 }
2019
2020 /**
2021 * Get the toggle bookmark action.
2022 *
2023 * @return The Action object
2024 * @since 2.0
2025 */
2026 public Action getToggleBookmarkAction() {
2027 if (fToggleBookmarkAction == null) {
2028 fToggleBookmarkAction = new Action() {
2029 @Override
2030 public void runWithEvent(Event event) {
2031 IMarkerEvent selectedBookmark = getBookmarkAtSelection();
2032 if (selectedBookmark == null) {
2033 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2034 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2035 final AddBookmarkDialog dialog = new AddBookmarkDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), null);
2036 if (dialog.open() == Window.OK) {
2037 final String label = dialog.getValue();
2038 final RGBA rgba = dialog.getColorValue();
2039 Color color = new Color(Display.getDefault(), rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
2040 fColors.add(color);
2041 IMarkerEvent bookmark = new MarkerEvent(null, time, duration, IMarkerEvent.BOOKMARK, color, label, true);
2042 fBookmarks.add(bookmark);
2043 updateMarkerList();
2044 getControl().redraw();
2045 fireBookmarkAdded(bookmark);
2046 }
2047 } else {
2048 checkDisposeColor(selectedBookmark.getColor());
2049 fBookmarks.remove(selectedBookmark);
2050 updateMarkerList();
2051 getControl().redraw();
2052 fireBookmarkRemoved(selectedBookmark);
2053 }
2054 updateMarkerActions();
2055 }
2056 };
2057 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2058 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2059 fToggleBookmarkAction.setImageDescriptor(ADD_BOOKMARK);
2060 }
2061 return fToggleBookmarkAction;
2062 }
2063
2064 /**
2065 * Get the next marker action.
2066 *
2067 * @return The Action object
2068 * @since 2.0
2069 */
2070 public Action getNextMarkerAction() {
2071 if (fNextMarkerAction == null) {
2072 fNextMarkerAction = new Action() {
2073 @Override
2074 public void runWithEvent(Event event) {
2075 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2076 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2077 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2078 if (markers == null) {
2079 return;
2080 }
2081 for (IMarkerEvent marker : markers) {
2082 if (marker.getTime() > time ||
2083 (marker.getTime() == time && marker.getDuration() > duration)) {
2084 setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration());
2085 return;
2086 }
2087 }
2088 }
2089 };
2090 fNextMarkerAction.setText(Messages.TmfTimeGraphViewer_NextMarkerActionText);
2091 fNextMarkerAction.setToolTipText(Messages.TmfTimeGraphViewer_NextMarkerActionText);
2092 fNextMarkerAction.setImageDescriptor(NEXT_BOOKMARK);
2093 }
2094 return fNextMarkerAction;
2095 }
2096
2097 /**
2098 * Get the previous marker action.
2099 *
2100 * @return The Action object
2101 * @since 2.0
2102 */
2103 public Action getPreviousMarkerAction() {
2104 if (fPreviousMarkerAction == null) {
2105 fPreviousMarkerAction = new Action() {
2106 @Override
2107 public void runWithEvent(Event event) {
2108 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2109 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2110 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2111 if (markers == null) {
2112 return;
2113 }
2114 for (int i = markers.size() - 1; i >= 0; i--) {
2115 IMarkerEvent marker = markers.get(i);
2116 if (marker.getTime() < time ||
2117 (marker.getTime() == time && marker.getDuration() < duration)) {
2118 setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration());
2119 return;
2120 }
2121 }
2122 }
2123 };
2124 fPreviousMarkerAction.setText(Messages.TmfTimeGraphViewer_PreviousMarkerActionText);
2125 fPreviousMarkerAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousMarkerActionText);
2126 fPreviousMarkerAction.setImageDescriptor(PREVIOUS_BOOKMARK);
2127 }
2128 return fPreviousMarkerAction;
2129 }
2130
2131 private IMarkerEvent getBookmarkAtSelection() {
2132 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2133 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2134 for (IMarkerEvent bookmark : fBookmarks) {
2135 if (bookmark.getTime() == time && bookmark.getDuration() == duration) {
2136 return bookmark;
2137 }
2138 }
2139 return null;
2140 }
2141
2142 private void updateMarkerActions() {
2143 if (fToggleBookmarkAction != null) {
2144 if (getBookmarkAtSelection() != null) {
2145 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionRemoveText);
2146 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionRemoveText);
2147 fToggleBookmarkAction.setImageDescriptor(REMOVE_BOOKMARK);
2148 } else {
2149 fToggleBookmarkAction.setText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2150 fToggleBookmarkAction.setToolTipText(Messages.TmfTimeGraphViewer_BookmarkActionAddText);
2151 fToggleBookmarkAction.setImageDescriptor(ADD_BOOKMARK);
2152 }
2153 }
2154 final long time = Math.min(fSelectionBegin, fSelectionEnd);
2155 final long duration = Math.max(fSelectionBegin, fSelectionEnd) - time;
2156 List<IMarkerEvent> markers = getTimeGraphControl().getMarkers();
2157 if (markers == null) {
2158 markers = Collections.emptyList();
2159 }
2160 if (fPreviousMarkerAction != null) {
2161 fPreviousMarkerAction.setEnabled(!markers.isEmpty() &&
2162 (time > markers.get(0).getTime() || (time == markers.get(0).getTime() && duration > markers.get(0).getDuration())));
2163 }
2164 if (fNextMarkerAction != null) {
2165 int last = markers.size() - 1;
2166 fNextMarkerAction.setEnabled(!markers.isEmpty() &&
2167 (time < markers.get(last).getTime() || (time == markers.get(last).getTime() && duration < markers.get(last).getDuration())));
2168 }
2169 }
2170
2171 private void updateMarkerList() {
2172 List<IMarkerEvent> markers = new ArrayList<>(fMarkers);
2173 markers.addAll(fBookmarks);
2174 Collections.sort(markers, new MarkerComparator());
2175 getTimeGraphControl().setMarkers(markers);
2176 }
2177
2178 private void adjustHorizontalScrollBar() {
2179 long time0 = getTime0();
2180 long time1 = getTime1();
2181 long timeMin = getMinTime();
2182 long timeMax = getMaxTime();
2183 long delta = timeMax - timeMin;
2184 int timePos = 0;
2185 int thumb = H_SCROLLBAR_MAX;
2186 if (delta != 0) {
2187 // Thumb size (page size)
2188 thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta)));
2189 // At the beginning of visible window
2190 timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta));
2191 }
2192 fHorizontalScrollBar.setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb));
2193 }
2194
2195 private void adjustVerticalScrollBar() {
2196 int topIndex = fTimeGraphCtrl.getTopIndex();
2197 int countPerPage = fTimeGraphCtrl.countPerPage();
2198 int expandedElementCount = fTimeGraphCtrl.getExpandedElementCount();
2199 if (topIndex + countPerPage > expandedElementCount) {
2200 fTimeGraphCtrl.setTopIndex(Math.max(0, expandedElementCount - countPerPage));
2201 }
2202
2203 int selection = fTimeGraphCtrl.getTopIndex();
2204 int min = 0;
2205 int max = Math.max(1, expandedElementCount - 1);
2206 int thumb = Math.min(max, Math.max(1, countPerPage - 1));
2207 int increment = 1;
2208 int pageIncrement = Math.max(1, countPerPage);
2209 fVerticalScrollBar.setValues(selection, min, max, thumb, increment, pageIncrement);
2210 }
2211
2212 /**
2213 * @param listener
2214 * a {@link MenuDetectListener}
2215 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2216 */
2217 public void addTimeGraphEntryMenuListener(MenuDetectListener listener) {
2218 fTimeGraphCtrl.addTimeGraphEntryMenuListener(listener);
2219 }
2220
2221 /**
2222 * @param listener
2223 * a {@link MenuDetectListener}
2224 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
2225 */
2226 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) {
2227 fTimeGraphCtrl.removeTimeGraphEntryMenuListener(listener);
2228 }
2229
2230 /**
2231 * @param listener
2232 * a {@link MenuDetectListener}
2233 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2234 */
2235 public void addTimeEventMenuListener(MenuDetectListener listener) {
2236 fTimeGraphCtrl.addTimeEventMenuListener(listener);
2237 }
2238
2239 /**
2240 * @param listener
2241 * a {@link MenuDetectListener}
2242 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
2243 */
2244 public void removeTimeEventMenuListener(MenuDetectListener listener) {
2245 fTimeGraphCtrl.removeTimeEventMenuListener(listener);
2246 }
2247
2248 /**
2249 * @param filter
2250 * The filter object to be attached to the view
2251 */
2252 public void addFilter(ViewerFilter filter) {
2253 fTimeGraphCtrl.addFilter(filter);
2254 refresh();
2255 }
2256
2257 /**
2258 * @param filter
2259 * The filter object to be attached to the view
2260 */
2261 public void removeFilter(ViewerFilter filter) {
2262 fTimeGraphCtrl.removeFilter(filter);
2263 refresh();
2264 }
2265
2266 /**
2267 * Returns this viewer's filters.
2268 *
2269 * @return an array of viewer filters
2270 * @since 2.0
2271 */
2272 public ViewerFilter[] getFilters() {
2273 return fTimeGraphCtrl.getFilters();
2274 }
2275
2276 /**
2277 * Sets the filters, replacing any previous filters, and triggers
2278 * refiltering of the elements.
2279 *
2280 * @param filters
2281 * an array of viewer filters, or null
2282 * @since 2.0
2283 */
2284 public void setFilters(ViewerFilter[] filters) {
2285 fTimeGraphCtrl.setFilters(filters);
2286 refresh();
2287 }
2288
2289 /**
2290 * Return the time alignment information
2291 *
2292 * @return the time alignment information
2293 *
2294 * @see ITmfTimeAligned
2295 *
2296 * @since 1.0
2297 */
2298 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
2299 return fTimeGraphCtrl.getTimeViewAlignmentInfo();
2300 }
2301
2302 /**
2303 * Return the available width for the time-axis.
2304 *
2305 * @see ITmfTimeAligned
2306 *
2307 * @param requestedOffset
2308 * the requested offset
2309 * @return the available width for the time-axis
2310 *
2311 * @since 1.0
2312 */
2313 public int getAvailableWidth(int requestedOffset) {
2314 int totalWidth = fTimeAlignedComposite.getSize().x;
2315 return Math.min(totalWidth, Math.max(0, totalWidth - requestedOffset));
2316 }
2317
2318 /**
2319 * Perform the alignment operation.
2320 *
2321 * @param offset
2322 * the alignment offset
2323 * @param width
2324 * the alignment width
2325 *
2326 * @see ITmfTimeAligned
2327 *
2328 * @since 1.0
2329 */
2330 public void performAlign(int offset, int width) {
2331 fTimeGraphCtrl.performAlign(offset);
2332 int alignmentWidth = width;
2333 int size = fTimeAlignedComposite.getSize().x;
2334 GridLayout layout = (GridLayout) fTimeAlignedComposite.getLayout();
2335 int marginSize = size - alignmentWidth - offset;
2336 layout.marginRight = Math.max(0, marginSize);
2337 fTimeAlignedComposite.layout();
2338 }
2339
2340 }
This page took 0.119525 seconds and 6 git commands to generate.