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