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