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