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