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