1 /*****************************************************************************
2 * Copyright (c) 2007, 2008, 2009 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
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
14 * $Id: ThreadStatesView.java,v 1.7 2008/05/19 15:07:21 jkubasta Exp $
15 *****************************************************************************/
17 package org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
;
19 import java
.util
.Iterator
;
20 import java
.util
.List
;
21 import java
.util
.Vector
;
23 import org
.eclipse
.jface
.viewers
.ISelection
;
24 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
25 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
26 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.dialogs
.TmfTimeFilterDialog
;
27 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.dialogs
.TmfTimeLegend
;
28 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.TimeEvent
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITimeEvent
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.ITimeDataProvider
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.TimeScaleCtrl
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.TmfTimeTipHandler
;
34 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.TmfTimeStatesCtrl
;
35 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.TraceColorScheme
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.Utils
;
37 import org
.eclipse
.swt
.SWT
;
38 import org
.eclipse
.swt
.events
.ControlAdapter
;
39 import org
.eclipse
.swt
.events
.ControlEvent
;
40 import org
.eclipse
.swt
.events
.SelectionEvent
;
41 import org
.eclipse
.swt
.events
.SelectionListener
;
42 import org
.eclipse
.swt
.graphics
.Rectangle
;
43 import org
.eclipse
.swt
.widgets
.Composite
;
44 import org
.eclipse
.swt
.widgets
.Control
;
46 public class TmfTimeAnalysisViewer
implements ITimeAnalysisViewer
, ITimeDataProvider
, SelectionListener
{
49 private long _minTimeInterval
;
50 private long _selectedTime
;
51 private long _beginTime
;
52 private long _endTime
;
57 private boolean _timeRangeFixed
;
58 private int _nameWidthPref
= 200;
59 private int _minNameWidth
= 6;
60 private int _nameWidth
;
61 private Composite _dataViewer
;
63 private TmfTimeStatesCtrl _stateCtrl
;
64 private TimeScaleCtrl _timeScaleCtrl
;
65 private TmfTimeTipHandler _threadTip
;
66 private TraceColorScheme _colors
;
67 private TmfTimeAnalysisProvider _utilImplm
;
69 private boolean _acceptSetSelAPICalls
= false;
70 Vector
<ITmfTimeSelectionListener
> widgetSelectionListners
= new Vector
<ITmfTimeSelectionListener
>();
71 Vector
<ITmfTimeTimeScaleSelectionListener
> widgetTimeScaleSelectionListners
= new Vector
<ITmfTimeTimeScaleSelectionListener
>();
72 Vector
<ITmfTimeFilterSelectionListener
> widgetFilterSelectionListeners
= new Vector
<ITmfTimeFilterSelectionListener
>();
74 // Calender Time format, using Epoch reference or Relative time
76 private boolean calendarTimeFormat
= false;
77 private int timeScaleBoderWidth
= 4;
78 private int timeScaleHeight
= 22;
81 public TmfTimeAnalysisViewer(Composite parent
, TmfTimeAnalysisProvider provider
) {
82 createDataViewer(parent
, provider
);
86 * @see org.eclipse.linuxtools.tmf.ui.widgets.timeAnalysis.api.ITimeAnalysisWidget#display(org.eclipse.linuxtools.tmf.ui.widgets.timeAnalysis.model.TmfTaTrace[])
88 public void display(ITmfTimeAnalysisEntry
[] traceArr
) {
89 modelUpdate(traceArr
);
92 public void display(ITmfTimeAnalysisEntry
[] traceArr
, long start
, long end
) {
93 modelUpdate(traceArr
, start
, end
);
96 public void controlMoved(ControlEvent e
) {
99 public void controlResized(ControlEvent e
) {
103 // called from the display order in the API
104 public void modelUpdate(ITmfTimeAnalysisEntry
[] traces
) {
105 if (null != _stateCtrl
) {
107 updateInternalData(traces
);
109 _timeScaleCtrl
.redraw();
113 // called from the display order in the API
114 public void modelUpdate(ITmfTimeAnalysisEntry
[] traces
, long start
, long end
) {
115 if (null != _stateCtrl
) {
117 updateInternalData(traces
, start
, end
);
119 _timeScaleCtrl
.redraw();
123 public void itemUpdate(ITmfTimeAnalysisEntry parent
, TimeEvent item
) {
124 if (null != parent
&& null != item
) {
125 _stateCtrl
.refreshPartial(parent
, item
);
127 _timeScaleCtrl
.redraw();
131 public void selectionChanged() {
134 protected String
getViewTypeStr() {
135 return "viewoption.threads";
138 int getMarginWidth(int idx
) {
142 int getMarginHeight(int idx
) {
147 _minTimeInterval
= 500;
149 _nameWidth
= Utils
.loadIntOption(getPreferenceString("namewidth"),
150 _nameWidthPref
, _minNameWidth
, 1000);
154 Utils
.saveIntOption(getPreferenceString("namewidth"), _nameWidth
);
157 protected Control
createDataViewer(Composite parent
,
158 TmfTimeAnalysisProvider utilImplm
) {
160 _utilImplm
= utilImplm
;
161 _colors
= new TraceColorScheme();
162 _dataViewer
= new Composite(parent
, SWT
.NULL
);
163 _dataViewer
.setLayoutData(GridUtil
.createFill());
165 _timeScaleCtrl
= new TimeScaleCtrl(_dataViewer
, _colors
);
166 _timeScaleCtrl
.setTimeProvider(this);
167 _timeScaleCtrl
.setLayoutData(GridUtil
.createFill());
169 _stateCtrl
= new TmfTimeStatesCtrl(_dataViewer
, _colors
, _utilImplm
);
171 _stateCtrl
.setTimeProvider(this);
172 _stateCtrl
.addSelectionListener(this);
173 _stateCtrl
.setLayoutData(GridUtil
.createFill());
174 _dataViewer
.addControlListener(new ControlAdapter() {
175 public void controlResized(ControlEvent event
) {
180 _dataViewer
.update();
181 _threadTip
= new TmfTimeTipHandler(parent
.getShell(), _utilImplm
, this);
182 _threadTip
.activateHoverHelp(_stateCtrl
);
186 public void dispose() {
188 _stateCtrl
.dispose();
189 _dataViewer
.dispose();
193 public void resizeControls() {
194 Rectangle r
= _dataViewer
.getClientArea();
198 // System.out.println("Client Area:" + r);
199 // timeScaleBoderWidth = 8;
200 // timeScaleHeight = 22;
201 _timeScaleCtrl
.setBounds(r
.x
, r
.y
+ timeScaleBoderWidth
, r
.width
,
203 _stateCtrl
.setBounds(r
.x
, r
.y
+ timeScaleBoderWidth
+ timeScaleHeight
,
204 r
.width
, r
.height
- timeScaleBoderWidth
- timeScaleHeight
);
206 if (_nameWidth
> width
- _minNameWidth
)
207 _nameWidth
= width
- _minNameWidth
;
208 if (_nameWidth
< _minNameWidth
)
209 _nameWidth
= _minNameWidth
;
212 /** Tries to set most convinient time range for display. */
213 void setTimeRange(Object traces
[]) {
217 for (int i
= 0; i
< traces
.length
; i
++) {
218 ITmfTimeAnalysisEntry thread
= (ITmfTimeAnalysisEntry
) traces
[i
];
219 long lastEventTime
= thread
.getStopTime();
220 if (lastEventTime
> thread
.getStartTime()) {
221 if (lastEventTime
> _endTime
)
222 _endTime
= lastEventTime
;
224 List
<TimeEvent
> list
= thread
.getTraceEvents();
225 int len
= list
.size();
227 event
= (ITimeEvent
) list
.get(list
.size() - 1);
228 lastEventTime
= event
.getTime();
229 if (lastEventTime
> _endTime
) {
230 _endTime
= lastEventTime
;
231 long duration
= event
.getDuration();
232 _endTime
+= duration
> 0 ? duration
: 1000000;
234 event
= (ITimeEvent
) list
.get(0);
235 if (_beginTime
< 0 || _beginTime
> event
.getTime())
236 _beginTime
= event
.getTime();
244 void setTimeBounds() {
245 _time0_
= _beginTime
- (long) ((_endTime
- _beginTime
) * 0.05);
248 // _time1_ = _time0_ + (_endTime - _time0_) * 1.05;
250 // _time0_ = Math.floor(_time0_);
251 // _time1_ = Math.ceil(_time1_);
252 if (!_timeRangeFixed
) {
261 void updateInternalData(ITmfTimeAnalysisEntry
[] traces
) {
263 traces
= new ITmfTimeAnalysisEntry
[0];
264 setTimeRange(traces
);
265 refreshAllData(traces
);
273 void updateInternalData(ITmfTimeAnalysisEntry
[] traces
, long start
, long end
) {
275 traces
= new ITmfTimeAnalysisEntry
[0];
276 if (end
< 1 || start
< 1) {
277 // End or start time are unspecified
278 setTimeRange(traces
);
284 refreshAllData(traces
);
290 private void refreshAllData(ITmfTimeAnalysisEntry
[] traces
) {
292 if (_selectedTime
< 0 || _selectedTime
> _endTime
)
293 _selectedTime
= _endTime
;
294 _stateCtrl
.refreshData(traces
);
295 filterOutNotification();
298 public void setFocus() {
299 if (null != _stateCtrl
)
300 _stateCtrl
.setFocus();
303 public boolean isInFocus() {
304 return _stateCtrl
.isInFocus();
307 public ITmfTimeAnalysisEntry
getSelectedTrace() {
308 return _stateCtrl
.getSelectedTrace();
311 public ISelection
getSelection() {
312 return _stateCtrl
.getSelection();
315 public ISelection
getSelectionTrace() {
316 return _stateCtrl
.getSelectionTrace();
319 public long getTime0() {
323 public long getTime1() {
327 public long getMinTimeInterval() {
328 return _minTimeInterval
;
331 public int getNameSpace() {
335 public void setNameSpace(int width
) {
337 width
= _stateCtrl
.getClientArea().width
;
338 if (_nameWidth
> width
- 6)
339 _nameWidth
= width
- 6;
342 _stateCtrl
.adjustScrolls();
344 _timeScaleCtrl
.redraw();
347 public int getTimeSpace() {
348 int w
= _stateCtrl
.getClientArea().width
;
349 return w
- _nameWidth
;
352 public long getSelectedTime() {
353 return _selectedTime
;
356 public long getBeginTime() {
360 public long getEndTime() {
364 public long getMaxTime() {
368 public long getMinTime() {
372 public void setStartFinishTime(long time0
, long time1
) {
373 setStartFinishTimeExt(time0
, time1
);
374 notifyStartFinishTimeSelectionListeners(time0
, time1
);
377 public void setStartFinishTimeExt(long time0
, long time1
) {
379 if (_time0
< _time0_
)
382 if (_time1
- _time0
< _minTimeInterval
)
383 _time1
= _time0
+ _minTimeInterval
;
384 if (_time1
> _time1_
)
386 _timeRangeFixed
= true;
387 _stateCtrl
.adjustScrolls();
389 _timeScaleCtrl
.redraw();
392 public void resetStartFinishTime() {
393 setStartFinishTime(_time0_
, _time1_
);
394 _timeRangeFixed
= false;
397 public void setSelectedTimeInt(long time
, boolean ensureVisible
) {
398 // Trace.debug("currentTime:" + _selectedTime + " new time:" + time);
399 _selectedTime
= time
;
400 if (_selectedTime
> _endTime
)
401 _selectedTime
= _endTime
;
402 if (_selectedTime
< _beginTime
)
403 _selectedTime
= _beginTime
;
405 double timeSpace
= (_time1
- _time0
) * .02;
406 double timeMid
= (_time1
- _time0
) * .1;
407 if (_selectedTime
< _time0
+ timeSpace
) {
408 double dt
= _time0
- _selectedTime
+ timeMid
;
411 } else if (_selectedTime
> _time1
- timeSpace
) {
412 double dt
= _selectedTime
- _time1
+ timeMid
;
419 } else if (_time1
> _time1_
) {
420 _time0
-= _time1
- _time1_
;
424 _stateCtrl
.adjustScrolls();
426 _timeScaleCtrl
.redraw();
429 public void widgetDefaultSelected(SelectionEvent e
) {
430 // TODO: Opening call stack shall be replaced to a configurable view
431 // new OpenCallStackViewAction().openView(false);
432 // Replaced by event notification
433 // updateModelSelection();
434 notifySelectionListeners(TmfTimeSelectionEvent
.type
.WIDGET_DEF_SEL
);
437 public void widgetSelected(SelectionEvent e
) {
438 // Replace by event notification
439 // updateModelSelection();
440 notifySelectionListeners(TmfTimeSelectionEvent
.type
.WIDGET_SEL
);
443 public void selectNextEvent() {
444 _stateCtrl
.selectNextEvent();
447 public void selectPrevEvent() {
448 _stateCtrl
.selectPrevEvent();
451 public void selectNextTrace() {
452 _stateCtrl
.selectNextTrace();
455 public void selectPrevTrace() {
456 _stateCtrl
.selectPrevTrace();
459 public void groupTraces(boolean on
) {
460 _stateCtrl
.groupTraces(on
);
463 public void filterTraces() {
464 if (_dataViewer
== null || _dataViewer
.isDisposed())
467 if (TmfTimeFilterDialog
.getTraceFilter(_dataViewer
.getShell(), _stateCtrl
468 .getTraces(), _stateCtrl
.getTraceFilter())) {
469 _stateCtrl
.refreshData();
470 filterOutNotification();
474 public void showLegend() {
475 if (_dataViewer
== null || _dataViewer
.isDisposed())
478 TmfTimeLegend
.open(_dataViewer
.getShell(), _utilImplm
);
481 public void toggleThreadsInteractionDrawing() {
482 _stateCtrl
.toggleTraceInteractionDrawing();
485 public void setThreadJoinDrawing(boolean on
) {
486 _stateCtrl
.setTraceJoinDrawing(on
);
489 public void setThreadWaitDrawing(boolean on
) {
490 _stateCtrl
.setTraceWaitDrawing(on
);
493 public void setThreadReleaseDrawing(boolean on
) {
494 _stateCtrl
.setTraceReleaseDrawing(on
);
497 public boolean getThreadInteractionDrawing() {
498 return _stateCtrl
.getTracesInteractionDrawing();
501 public boolean getThreadJoinDrawing() {
502 return _stateCtrl
.getTraceJoinDrawing();
505 public boolean getThreadWaitDrawing() {
506 return _stateCtrl
.getTraceWaitDrawing();
509 public boolean getThreadReleaseDrawing() {
510 return _stateCtrl
.getTraceReleaseDrawing();
513 protected void select(Object obj
) {
516 // TODO: ThreadDetails Adaption removed, might need replacement
517 // if (obj instanceof ThreadDetails) {
518 // obj = ((ThreadDetails) obj).getThread();
520 if (obj
instanceof ITmfTimeAnalysisEntry
) {
521 // _stateCtrl.selectThread((TsfTmTrace) obj);
525 public void zoomIn() {
529 public void zoomOut() {
530 _stateCtrl
.zoomOut();
533 private String
getPreferenceString(String string
) {
534 return getViewTypeStr() + "." + string
;
537 public void addWidgetSelectionListner(ITmfTimeSelectionListener listener
) {
538 widgetSelectionListners
.add(listener
);
541 public void removeWidgetSelectionListner(ITmfTimeSelectionListener listener
) {
542 widgetSelectionListners
.removeElement(listener
);
545 public void addWidgetTimeScaleSelectionListner(
546 ITmfTimeTimeScaleSelectionListener listener
) {
547 widgetTimeScaleSelectionListners
.add(listener
);
550 public void removeWidgetTimeScaleSelectionListner(
551 ITmfTimeTimeScaleSelectionListener listener
) {
552 widgetTimeScaleSelectionListners
.removeElement(listener
);
555 public void setSelectedTime(long time
, boolean ensureVisible
, Object source
) {
556 if (_acceptSetSelAPICalls
== false || this == source
) {
560 setSelectedTimeInt(time
, ensureVisible
);
563 public void setSelectedEvent(ITimeEvent event
, Object source
) {
564 if (_acceptSetSelAPICalls
== false || event
== null || source
== this) {
567 ITmfTimeAnalysisEntry trace
= event
.getEntry();
569 _stateCtrl
.selectItem(trace
, false);
572 setSelectedTimeInt(event
.getTime(), true);
575 public void setSelectedTraceTime(ITmfTimeAnalysisEntry trace
, long time
, Object source
) {
576 if (_acceptSetSelAPICalls
== false || trace
== null || source
== this) {
581 _stateCtrl
.selectItem(trace
, false);
584 setSelectedTimeInt(time
, true);
587 public void setSelectedTrace(ITmfTimeAnalysisEntry trace
) {
592 _stateCtrl
.selectItem(trace
, false);
595 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
596 if (_acceptSetSelAPICalls
== false || source
== this) {
600 setStartFinishTimeExt(time0
, time1
);
603 public void setAcceptSelectionAPIcalls(boolean acceptCalls
) {
604 _acceptSetSelAPICalls
= acceptCalls
;
607 private synchronized void notifySelectionListeners(
608 TmfTimeSelectionEvent
.type rtype
) {
609 // Any listeners out there ?
610 if (widgetSelectionListners
.size() > 0) {
611 // Locate the event selected
612 ISelection selection
= getSelection();
614 if (selection
!= null && !selection
.isEmpty()) {
615 sel
= ((IStructuredSelection
) selection
).getFirstElement();
619 // Notify Selection Listeners
620 TmfTimeSelectionEvent event
= new TmfTimeSelectionEvent(this,
621 rtype
, sel
, getSelectedTime());
623 for (Iterator
<ITmfTimeSelectionListener
> iter
= widgetSelectionListners
624 .iterator(); iter
.hasNext();) {
625 ITmfTimeSelectionListener listener
= (ITmfTimeSelectionListener
) iter
627 listener
.tsfTmProcessSelEvent(event
);
633 public void notifyStartFinishTimeSelectionListeners(long _time0
, long _time1
) {
634 if (widgetTimeScaleSelectionListners
.size() > 0) {
635 // Notify Time Scale Selection Listeners
636 TmfTimeTimeScaleSelectionEvent event
= new TmfTimeTimeScaleSelectionEvent(
637 this, _time0
, _time1
, getTimeSpace(), getSelectedTime());
639 for (Iterator
<ITmfTimeTimeScaleSelectionListener
> iter
= widgetTimeScaleSelectionListners
640 .iterator(); iter
.hasNext();) {
641 ITmfTimeTimeScaleSelectionListener listener
= (ITmfTimeTimeScaleSelectionListener
) iter
643 listener
.tsfTmProcessTimeScaleEvent(event
);
648 public void setTimeCalendarFormat(boolean toAbsoluteCaltime
) {
649 calendarTimeFormat
= toAbsoluteCaltime
;
652 public boolean isCalendarFormat() {
653 return calendarTimeFormat
;
656 public int getBorderWidth() {
657 return timeScaleBoderWidth
;
660 public void setBorderWidth(int borderWidth
) {
661 if (borderWidth
> -1) {
662 this.timeScaleBoderWidth
= borderWidth
;
666 public int getHeaderHeight() {
667 return timeScaleHeight
;
670 public void setHeaderHeight(int headerHeight
) {
671 if (headerHeight
> -1) {
672 this.timeScaleHeight
= headerHeight
;
676 public int getItemHeight() {
677 if (_stateCtrl
!= null) {
678 return _stateCtrl
.getItemHeight();
683 public void setItemHeight(int rowHeight
) {
684 if (_stateCtrl
!= null) {
685 _stateCtrl
.setItemHeight(rowHeight
);
689 public boolean isVisibleVerticalScroll() {
690 if (_stateCtrl
!= null) {
691 _stateCtrl
.isVisibleVerticalScroll();
696 public void setVisibleVerticalScroll(boolean visibleVerticalScroll
) {
697 if (_stateCtrl
!= null) {
698 _stateCtrl
.setVisibleVerticalScroll(visibleVerticalScroll
);
702 public void setNameWidthPref(int width
) {
703 _nameWidthPref
= width
;
709 public int getNameWidthPref(int width
) {
710 return _nameWidthPref
;
713 public void addFilterSelectionListner(ITmfTimeFilterSelectionListener listener
) {
714 widgetFilterSelectionListeners
.add(listener
);
717 public void removeFilterSelectionListner(
718 ITmfTimeFilterSelectionListener listener
) {
719 widgetFilterSelectionListeners
.remove(listener
);
722 private void filterOutNotification() {
723 TmfTimeFilterSelectionEvent event
= new TmfTimeFilterSelectionEvent(this);
724 event
.setFilteredOut(_stateCtrl
.getFilteredOut());
725 for (ITmfTimeFilterSelectionListener listener
: widgetFilterSelectionListeners
) {
726 listener
.tmfTaProcessFilterSelection(event
);
731 * needed in case there's a need to associate a context menu
735 public Control
getControl() {
740 * Get the selection provider
744 public ISelectionProvider
getSelectionProvider() {