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
<ITmfTimeScaleSelectionListener
> widgetTimeScaleSelectionListners
= new Vector
<ITmfTimeScaleSelectionListener
>();
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() {
176 public void controlResized(ControlEvent event
) {
181 _dataViewer
.update();
182 _threadTip
= new TmfTimeTipHandler(parent
.getShell(), _utilImplm
, this);
183 _threadTip
.activateHoverHelp(_stateCtrl
);
187 public void dispose() {
189 _stateCtrl
.dispose();
190 _dataViewer
.dispose();
194 public void resizeControls() {
195 Rectangle r
= _dataViewer
.getClientArea();
199 // System.out.println("Client Area:" + r);
200 // timeScaleBoderWidth = 8;
201 // timeScaleHeight = 22;
202 _timeScaleCtrl
.setBounds(r
.x
, r
.y
+ timeScaleBoderWidth
, r
.width
,
204 _stateCtrl
.setBounds(r
.x
, r
.y
+ timeScaleBoderWidth
+ timeScaleHeight
,
205 r
.width
, r
.height
- timeScaleBoderWidth
- timeScaleHeight
);
207 if (_nameWidth
> width
- _minNameWidth
)
208 _nameWidth
= width
- _minNameWidth
;
209 if (_nameWidth
< _minNameWidth
)
210 _nameWidth
= _minNameWidth
;
213 /** Tries to set most convinient time range for display. */
214 void setTimeRange(Object traces
[]) {
218 for (int i
= 0; i
< traces
.length
; i
++) {
219 ITmfTimeAnalysisEntry thread
= (ITmfTimeAnalysisEntry
) traces
[i
];
220 long lastEventTime
= thread
.getStopTime();
221 if (lastEventTime
> thread
.getStartTime()) {
222 if (lastEventTime
> _endTime
)
223 _endTime
= lastEventTime
;
225 List
<TimeEvent
> list
= thread
.getTraceEvents();
226 int len
= list
.size();
228 event
= (ITimeEvent
) list
.get(list
.size() - 1);
229 lastEventTime
= event
.getTime();
230 if (lastEventTime
> _endTime
) {
231 _endTime
= lastEventTime
;
232 long duration
= event
.getDuration();
233 _endTime
+= duration
> 0 ? duration
: 1000000;
235 event
= (ITimeEvent
) list
.get(0);
236 if (_beginTime
< 0 || _beginTime
> event
.getTime())
237 _beginTime
= event
.getTime();
245 void setTimeBounds() {
246 _time0_
= _beginTime
- (long) ((_endTime
- _beginTime
) * 0.05);
249 // _time1_ = _time0_ + (_endTime - _time0_) * 1.05;
251 // _time0_ = Math.floor(_time0_);
252 // _time1_ = Math.ceil(_time1_);
253 if (!_timeRangeFixed
) {
262 void updateInternalData(ITmfTimeAnalysisEntry
[] traces
) {
264 traces
= new ITmfTimeAnalysisEntry
[0];
265 setTimeRange(traces
);
266 refreshAllData(traces
);
274 void updateInternalData(ITmfTimeAnalysisEntry
[] traces
, long start
, long end
) {
276 traces
= new ITmfTimeAnalysisEntry
[0];
277 if (end
< 1 || start
< 1) {
278 // End or start time are unspecified
279 setTimeRange(traces
);
285 refreshAllData(traces
);
291 private void refreshAllData(ITmfTimeAnalysisEntry
[] traces
) {
293 if (_selectedTime
< 0 || _selectedTime
> _endTime
)
294 _selectedTime
= _endTime
;
295 _stateCtrl
.refreshData(traces
);
296 filterOutNotification();
299 public void setFocus() {
300 if (null != _stateCtrl
)
301 _stateCtrl
.setFocus();
304 public boolean isInFocus() {
305 return _stateCtrl
.isInFocus();
308 public ITmfTimeAnalysisEntry
getSelectedTrace() {
309 return _stateCtrl
.getSelectedTrace();
312 public ISelection
getSelection() {
313 return _stateCtrl
.getSelection();
316 public ISelection
getSelectionTrace() {
317 return _stateCtrl
.getSelectionTrace();
320 public long getTime0() {
324 public long getTime1() {
328 public long getMinTimeInterval() {
329 return _minTimeInterval
;
332 public int getNameSpace() {
336 public void setNameSpace(int width
) {
338 width
= _stateCtrl
.getClientArea().width
;
339 if (_nameWidth
> width
- 6)
340 _nameWidth
= width
- 6;
343 _stateCtrl
.adjustScrolls();
345 _timeScaleCtrl
.redraw();
348 public int getTimeSpace() {
349 int w
= _stateCtrl
.getClientArea().width
;
350 return w
- _nameWidth
;
353 public long getSelectedTime() {
354 return _selectedTime
;
357 public long getBeginTime() {
361 public long getEndTime() {
365 public long getMaxTime() {
369 public long getMinTime() {
373 public void setStartFinishTime(long time0
, long time1
) {
374 setStartFinishTimeExt(time0
, time1
);
375 notifyStartFinishTimeSelectionListeners(time0
, time1
);
378 public void setStartFinishTimeExt(long time0
, long time1
) {
380 if (_time0
< _time0_
)
383 if (_time1
- _time0
< _minTimeInterval
)
384 _time1
= _time0
+ _minTimeInterval
;
385 if (_time1
> _time1_
)
387 _timeRangeFixed
= true;
388 _stateCtrl
.adjustScrolls();
390 _timeScaleCtrl
.redraw();
393 public void resetStartFinishTime() {
394 setStartFinishTime(_time0_
, _time1_
);
395 _timeRangeFixed
= false;
398 public void setSelectedTimeInt(long time
, boolean ensureVisible
) {
399 // Trace.debug("currentTime:" + _selectedTime + " new time:" + time);
400 _selectedTime
= time
;
401 if (_selectedTime
> _endTime
)
402 _selectedTime
= _endTime
;
403 if (_selectedTime
< _beginTime
)
404 _selectedTime
= _beginTime
;
406 double timeSpace
= (_time1
- _time0
) * .02;
407 double timeMid
= (_time1
- _time0
) * .1;
408 if (_selectedTime
< _time0
+ timeSpace
) {
409 double dt
= _time0
- _selectedTime
+ timeMid
;
412 } else if (_selectedTime
> _time1
- timeSpace
) {
413 double dt
= _selectedTime
- _time1
+ timeMid
;
420 } else if (_time1
> _time1_
) {
421 _time0
-= _time1
- _time1_
;
425 _stateCtrl
.adjustScrolls();
427 _timeScaleCtrl
.redraw();
430 public void widgetDefaultSelected(SelectionEvent e
) {
431 // TODO: Opening call stack shall be replaced to a configurable view
432 // new OpenCallStackViewAction().openView(false);
433 // Replaced by event notification
434 // updateModelSelection();
435 notifySelectionListeners(TmfTimeSelectionEvent
.type
.WIDGET_DEF_SEL
);
438 public void widgetSelected(SelectionEvent e
) {
439 // Replace by event notification
440 // updateModelSelection();
441 notifySelectionListeners(TmfTimeSelectionEvent
.type
.WIDGET_SEL
);
444 public void selectNextEvent() {
445 _stateCtrl
.selectNextEvent();
448 public void selectPrevEvent() {
449 _stateCtrl
.selectPrevEvent();
452 public void selectNextTrace() {
453 _stateCtrl
.selectNextTrace();
456 public void selectPrevTrace() {
457 _stateCtrl
.selectPrevTrace();
460 public void groupTraces(boolean on
) {
461 _stateCtrl
.groupTraces(on
);
464 public void filterTraces() {
465 if (_dataViewer
== null || _dataViewer
.isDisposed())
468 if (TmfTimeFilterDialog
.getTraceFilter(_dataViewer
.getShell(), _stateCtrl
469 .getTraces(), _stateCtrl
.getTraceFilter())) {
470 _stateCtrl
.refreshData();
471 filterOutNotification();
475 public void showLegend() {
476 if (_dataViewer
== null || _dataViewer
.isDisposed())
479 TmfTimeLegend
.open(_dataViewer
.getShell(), _utilImplm
);
482 public void toggleThreadsInteractionDrawing() {
483 _stateCtrl
.toggleTraceInteractionDrawing();
486 public void setThreadJoinDrawing(boolean on
) {
487 _stateCtrl
.setTraceJoinDrawing(on
);
490 public void setThreadWaitDrawing(boolean on
) {
491 _stateCtrl
.setTraceWaitDrawing(on
);
494 public void setThreadReleaseDrawing(boolean on
) {
495 _stateCtrl
.setTraceReleaseDrawing(on
);
498 public boolean getThreadInteractionDrawing() {
499 return _stateCtrl
.getTracesInteractionDrawing();
502 public boolean getThreadJoinDrawing() {
503 return _stateCtrl
.getTraceJoinDrawing();
506 public boolean getThreadWaitDrawing() {
507 return _stateCtrl
.getTraceWaitDrawing();
510 public boolean getThreadReleaseDrawing() {
511 return _stateCtrl
.getTraceReleaseDrawing();
514 protected void select(Object obj
) {
517 // TODO: ThreadDetails Adaption removed, might need replacement
518 // if (obj instanceof ThreadDetails) {
519 // obj = ((ThreadDetails) obj).getThread();
521 if (obj
instanceof ITmfTimeAnalysisEntry
) {
522 // _stateCtrl.selectThread((TsfTmTrace) obj);
526 public void zoomIn() {
530 public void zoomOut() {
531 _stateCtrl
.zoomOut();
534 private String
getPreferenceString(String string
) {
535 return getViewTypeStr() + "." + string
;
538 public void addWidgetSelectionListner(ITmfTimeSelectionListener listener
) {
539 widgetSelectionListners
.add(listener
);
542 public void removeWidgetSelectionListner(ITmfTimeSelectionListener listener
) {
543 widgetSelectionListners
.removeElement(listener
);
546 public void addWidgetTimeScaleSelectionListner(
547 ITmfTimeScaleSelectionListener listener
) {
548 widgetTimeScaleSelectionListners
.add(listener
);
551 public void removeWidgetTimeScaleSelectionListner(
552 ITmfTimeScaleSelectionListener listener
) {
553 widgetTimeScaleSelectionListners
.removeElement(listener
);
556 public void setSelectedTime(long time
, boolean ensureVisible
, Object source
) {
557 if (_acceptSetSelAPICalls
== false || this == source
) {
561 setSelectedTimeInt(time
, ensureVisible
);
564 public void setSelectedEvent(ITimeEvent event
, Object source
) {
565 if (_acceptSetSelAPICalls
== false || event
== null || source
== this) {
568 ITmfTimeAnalysisEntry trace
= event
.getEntry();
570 _stateCtrl
.selectItem(trace
, false);
573 setSelectedTimeInt(event
.getTime(), true);
576 public void setSelectedTraceTime(ITmfTimeAnalysisEntry trace
, long time
, Object source
) {
577 if (_acceptSetSelAPICalls
== false || trace
== null || source
== this) {
582 _stateCtrl
.selectItem(trace
, false);
585 setSelectedTimeInt(time
, true);
588 public void setSelectedTrace(ITmfTimeAnalysisEntry trace
) {
593 _stateCtrl
.selectItem(trace
, false);
596 public void setSelectVisTimeWindow(long time0
, long time1
, Object source
) {
597 if (_acceptSetSelAPICalls
== false || source
== this) {
601 setStartFinishTimeExt(time0
, time1
);
604 public void setAcceptSelectionAPIcalls(boolean acceptCalls
) {
605 _acceptSetSelAPICalls
= acceptCalls
;
608 private synchronized void notifySelectionListeners(
609 TmfTimeSelectionEvent
.type rtype
) {
610 // Any listeners out there ?
611 if (widgetSelectionListners
.size() > 0) {
612 // Locate the event selected
613 ISelection selection
= getSelection();
615 if (selection
!= null && !selection
.isEmpty()) {
616 sel
= ((IStructuredSelection
) selection
).getFirstElement();
620 // Notify Selection Listeners
621 TmfTimeSelectionEvent event
= new TmfTimeSelectionEvent(this,
622 rtype
, sel
, getSelectedTime());
624 for (Iterator
<ITmfTimeSelectionListener
> iter
= widgetSelectionListners
625 .iterator(); iter
.hasNext();) {
626 ITmfTimeSelectionListener listener
= (ITmfTimeSelectionListener
) iter
628 listener
.tsfTmProcessSelEvent(event
);
634 public void notifyStartFinishTimeSelectionListeners(long _time0
, long _time1
) {
635 if (widgetTimeScaleSelectionListners
.size() > 0) {
636 // Notify Time Scale Selection Listeners
637 TmfTimeScaleSelectionEvent event
= new TmfTimeScaleSelectionEvent(
638 this, _time0
, _time1
, getTimeSpace(), getSelectedTime());
640 for (Iterator
<ITmfTimeScaleSelectionListener
> iter
= widgetTimeScaleSelectionListners
641 .iterator(); iter
.hasNext();) {
642 ITmfTimeScaleSelectionListener listener
= (ITmfTimeScaleSelectionListener
) iter
644 listener
.tsfTmProcessTimeScaleEvent(event
);
649 public void setTimeCalendarFormat(boolean toAbsoluteCaltime
) {
650 calendarTimeFormat
= toAbsoluteCaltime
;
653 public boolean isCalendarFormat() {
654 return calendarTimeFormat
;
657 public int getBorderWidth() {
658 return timeScaleBoderWidth
;
661 public void setBorderWidth(int borderWidth
) {
662 if (borderWidth
> -1) {
663 this.timeScaleBoderWidth
= borderWidth
;
667 public int getHeaderHeight() {
668 return timeScaleHeight
;
671 public void setHeaderHeight(int headerHeight
) {
672 if (headerHeight
> -1) {
673 this.timeScaleHeight
= headerHeight
;
677 public int getItemHeight() {
678 if (_stateCtrl
!= null) {
679 return _stateCtrl
.getItemHeight();
684 public void setItemHeight(int rowHeight
) {
685 if (_stateCtrl
!= null) {
686 _stateCtrl
.setItemHeight(rowHeight
);
690 public boolean isVisibleVerticalScroll() {
691 if (_stateCtrl
!= null) {
692 _stateCtrl
.isVisibleVerticalScroll();
697 public void setVisibleVerticalScroll(boolean visibleVerticalScroll
) {
698 if (_stateCtrl
!= null) {
699 _stateCtrl
.setVisibleVerticalScroll(visibleVerticalScroll
);
703 public void setNameWidthPref(int width
) {
704 _nameWidthPref
= width
;
710 public int getNameWidthPref(int width
) {
711 return _nameWidthPref
;
714 public void addFilterSelectionListner(ITmfTimeFilterSelectionListener listener
) {
715 widgetFilterSelectionListeners
.add(listener
);
718 public void removeFilterSelectionListner(
719 ITmfTimeFilterSelectionListener listener
) {
720 widgetFilterSelectionListeners
.remove(listener
);
723 private void filterOutNotification() {
724 TmfTimeFilterSelectionEvent event
= new TmfTimeFilterSelectionEvent(this);
725 event
.setFilteredOut(_stateCtrl
.getFilteredOut());
726 for (ITmfTimeFilterSelectionListener listener
: widgetFilterSelectionListeners
) {
727 listener
.tmfTaProcessFilterSelection(event
);
732 * needed in case there's a need to associate a context menu
736 public Control
getControl() {
741 * Get the selection provider
745 public ISelectionProvider
getSelectionProvider() {