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