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