1 /*****************************************************************************
2 * Copyright (c) 2007, 2008 Intel Corporation.
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 * Alvaro Sanchex-Leon - Udpated for TMF
13 * $Id: ThreadStatesCtrl.java,v 1.15 2008/07/11 13:49:01 aalexeev Exp $
14 *****************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
;
18 import java
.util
.ArrayList
;
19 import java
.util
.Arrays
;
20 import java
.util
.HashMap
;
21 import java
.util
.Iterator
;
22 import java
.util
.List
;
24 import java
.util
.Vector
;
26 import org
.eclipse
.jface
.viewers
.ISelection
;
27 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
28 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.Messages
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeAnalysisProvider
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITimeEvent
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.TimeEvent
;
34 import org
.eclipse
.osgi
.util
.NLS
;
35 import org
.eclipse
.swt
.SWT
;
36 import org
.eclipse
.swt
.events
.ControlEvent
;
37 import org
.eclipse
.swt
.events
.ControlListener
;
38 import org
.eclipse
.swt
.events
.FocusEvent
;
39 import org
.eclipse
.swt
.events
.FocusListener
;
40 import org
.eclipse
.swt
.events
.KeyEvent
;
41 import org
.eclipse
.swt
.events
.KeyListener
;
42 import org
.eclipse
.swt
.events
.MouseEvent
;
43 import org
.eclipse
.swt
.events
.MouseListener
;
44 import org
.eclipse
.swt
.events
.MouseMoveListener
;
45 import org
.eclipse
.swt
.events
.MouseTrackListener
;
46 import org
.eclipse
.swt
.events
.MouseWheelListener
;
47 import org
.eclipse
.swt
.events
.PaintEvent
;
48 import org
.eclipse
.swt
.events
.SelectionEvent
;
49 import org
.eclipse
.swt
.events
.SelectionListener
;
50 import org
.eclipse
.swt
.events
.TraverseEvent
;
51 import org
.eclipse
.swt
.events
.TraverseListener
;
52 import org
.eclipse
.swt
.graphics
.Cursor
;
53 import org
.eclipse
.swt
.graphics
.GC
;
54 import org
.eclipse
.swt
.graphics
.Image
;
55 import org
.eclipse
.swt
.graphics
.Point
;
56 import org
.eclipse
.swt
.graphics
.Rectangle
;
57 import org
.eclipse
.swt
.widgets
.Composite
;
58 import org
.eclipse
.swt
.widgets
.ScrollBar
;
60 public class TmfTimeStatesCtrl
extends TraceCtrl
implements FocusListener
,
61 KeyListener
, MouseMoveListener
, MouseListener
, MouseWheelListener
,
62 ControlListener
, SelectionListener
, MouseTrackListener
,
63 TraverseListener
, ISelectionProvider
{
65 public static final boolean DEFAULT_DRAW_THREAD_JOIN
= true;
66 public static final boolean DEFAULT_DRAW_THREAD_WAIT
= true;
67 public static final boolean DEFAULT_DRAW_THREAD_RELEASE
= true;
69 private final double zoomCoeff
= 1.5;
71 private ITimeDataProvider _timeProvider
;
72 private boolean _isInFocus
= false;
73 private boolean _isDragCursor3
= false;
74 private boolean _mouseHover
= false;
75 private int _itemHeightDefault
= 18;
76 private int _itemHeight
= _itemHeightDefault
;
77 private int _topItem
= 0;
78 private int _dragState
= 0;
79 private int _hitIdx
= 0;
80 private int _dragX0
= 0;
81 private int _dragX
= 0;
82 private int _idealNameWidth
= 0;
84 private double _timeStep
= 0.001;
85 // private double _timeStep = 10000000;
86 private long _time0bak
;
87 private long _time1bak
;
88 private TmfTimeAnalysisProvider utilImpl
= null;
89 private ItemData _data
= null;
90 private List
<SelectionListener
> _selectionListeners
;
91 private List
<ISelectionChangedListener
> _selectionChangedListeners
= new ArrayList
<ISelectionChangedListener
>();
92 private Rectangle _rect0
= new Rectangle(0, 0, 0, 0);
93 private Rectangle _rect1
= new Rectangle(0, 0, 0, 0);
94 private Cursor _dragCursor3
;
95 private boolean drawTracesInteraction
= false;
96 private boolean drawTraceJoins
= DEFAULT_DRAW_THREAD_JOIN
;
97 private boolean drawTraceWaits
= DEFAULT_DRAW_THREAD_WAIT
;
98 private boolean drawTraceReleases
= DEFAULT_DRAW_THREAD_RELEASE
;
100 // Vertical formatting formatting for the state control view
101 private boolean _visibleVerticalScroll
= true;
102 private int _borderWidth
= 0;
103 private int _headerHeight
= 0;
105 public TmfTimeStatesCtrl(Composite parent
, TraceColorScheme colors
,
106 TmfTimeAnalysisProvider rutilImp
) {
108 super(parent
, colors
, SWT
.NO_BACKGROUND
| SWT
.V_SCROLL
| SWT
.H_SCROLL
109 | SWT
.DOUBLE_BUFFERED
);
111 this.utilImpl
= rutilImp
;
112 _data
= new ItemData(utilImpl
);
114 addFocusListener(this);
115 addMouseListener(this);
116 addMouseMoveListener(this);
117 addMouseTrackListener(this);
118 addMouseWheelListener(this);
119 addTraverseListener(this);
120 addKeyListener(this);
121 addControlListener(this);
122 ScrollBar scrollVer
= getVerticalBar();
123 ScrollBar scrollHor
= getHorizontalBar();
124 if (scrollVer
!= null) {
125 scrollVer
.addSelectionListener(this);
126 scrollVer
.setVisible(_visibleVerticalScroll
);
129 if (scrollHor
!= null) {
130 scrollHor
.addSelectionListener(this);
133 _dragCursor3
= new Cursor(super.getDisplay(), SWT
.CURSOR_SIZEWE
);
137 public void dispose() {
139 _dragCursor3
.dispose();
142 public void setTimeProvider(ITimeDataProvider timeProvider
) {
143 _timeProvider
= timeProvider
;
148 public void addSelectionListener(SelectionListener listener
) {
149 if (listener
== null)
150 SWT
.error(SWT
.ERROR_NULL_ARGUMENT
);
151 if (null == _selectionListeners
)
152 _selectionListeners
= new ArrayList
<SelectionListener
>();
153 _selectionListeners
.add(listener
);
156 public void removeSelectionListener(SelectionListener listener
) {
157 if (null != _selectionListeners
)
158 _selectionListeners
.remove(listener
);
161 public void fireSelectionChanged() {
162 if (null != _selectionListeners
) {
163 Iterator
<SelectionListener
> it
= _selectionListeners
.iterator();
164 while (it
.hasNext()) {
165 SelectionListener listener
= it
.next();
166 listener
.widgetSelected(null);
171 public void fireDefaultSelection() {
172 if (null != _selectionListeners
) {
173 Iterator
<SelectionListener
> it
= _selectionListeners
.iterator();
174 while (it
.hasNext()) {
175 SelectionListener listener
= it
.next();
176 listener
.widgetDefaultSelected(null);
181 public Object
[] getTraces() {
182 return _data
.getTraces();
185 public boolean[] getTraceFilter() {
186 return _data
.getTraceFilter();
189 public void refreshData() {
195 public void refreshData(Object traces
[]) {
196 _data
.refreshData(traces
);
201 public void refreshPartial(ITmfTimeAnalysisEntry parent
, TimeEvent item
) {
202 _data
.refreshPartial(parent
, item
);
207 public void adjustScrolls() {
208 if (null == _timeProvider
) {
209 getVerticalBar().setValues(0, 1, 1, 1, 1, 1);
210 getHorizontalBar().setValues(0, 1, 1, 1, 1, 1);
213 int page
= countPerPage();
214 if (_topItem
+ page
> _data
._items
.length
)
215 _topItem
= _data
._items
.length
- page
;
218 getVerticalBar().setValues(_topItem
, 0, _data
._items
.length
, page
, 1,
220 long time0
= _timeProvider
.getTime0();
221 long time1
= _timeProvider
.getTime1();
222 long timeMin
= _timeProvider
.getMinTime();
223 long timeMax
= _timeProvider
.getMaxTime();
225 // int timePage = (int) ((time1 - time0) / _timeStep);
226 // int timePos = (int) (time0 / _timeStep);
227 // int minimum = (int) (timeMin / _timeStep);
228 // int maximum = (int) (timeMax / _timeStep);
230 long delta
= timeMax
- timeMin
;
234 // Trace.debug("time0 - time1 = " + (time0 - timeMin));
236 timePage
= (int) (((double) (time1
- time0
) / _timeStep
) / delta
);
237 timePos
= (int) (((double) (time0
- timeMin
) / _timeStep
) / delta
);
242 // Trace.debug("time0:" + time0 + " time1:" + time1 + " timeStep:"
243 // + _timeStep + " delta:" + delta);
244 // Trace.debug("selection:" + timePos + " min:" + minimum + " maximum:"
245 // + maximum + " Page:" + timePage);
246 getHorizontalBar().setValues(timePos
, minimum
, maximum
, timePage
, 1,
250 boolean ensureVisibleItem(int idx
, boolean redraw
) {
251 boolean changed
= false;
253 for (idx
= 0; idx
< _data
._items
.length
; idx
++) {
254 if (((Item
) _data
._items
[idx
])._selected
)
258 if (idx
>= _data
._items
.length
)
260 if (idx
< _topItem
) {
262 getVerticalBar().setSelection(_topItem
);
267 int page
= countPerPage();
268 if (idx
>= _topItem
+ page
) {
269 _topItem
= idx
- page
+ 1;
270 getVerticalBar().setSelection(_topItem
);
279 public ISelection
getSelection() {
280 PlainSelection sel
= new PlainSelection();
281 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
282 if (null != trace
&& null != _timeProvider
) {
283 long selectedTime
= _timeProvider
.getSelectedTime();
284 ITimeEvent event
= Utils
.findEvent(trace
, selectedTime
, 0);
293 public ISelection
getSelectionTrace() {
294 PlainSelection sel
= new PlainSelection();
295 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
302 public void selectTrace(int n
) {
303 if (n
!= 1 && n
!= -1)
305 boolean changed
= false;
306 int lastSelection
= -1;
307 for (int i
= 0; i
< _data
._items
.length
; i
++) {
308 Item item
= (Item
) _data
._items
[i
];
309 if (item
._selected
) {
311 if (1 == n
&& i
< _data
._items
.length
- 1) {
312 item
._selected
= false;
313 if (item
._hasChildren
)
314 _data
.expandItem(i
, true);
315 item
= (Item
) _data
._items
[i
+ 1];
316 if (item
._hasChildren
) {
317 _data
.expandItem(i
+ 1, true);
318 item
= (Item
) _data
._items
[i
+ 2];
320 item
._selected
= true;
322 } else if (-1 == n
&& i
> 0) {
324 Item prevItem
= (Item
) _data
._items
[i
];
325 if (prevItem
._hasChildren
) {
326 if (prevItem
._expanded
) {
329 prevItem
= (Item
) _data
._items
[i
];
332 if (!prevItem
._expanded
) {
333 int added
= _data
.expandItem(i
, true);
334 prevItem
= (Item
) _data
._items
[i
+ added
];
335 item
._selected
= false;
336 prevItem
._selected
= true;
340 item
._selected
= false;
341 prevItem
._selected
= true;
348 if (lastSelection
< 0 && _data
._items
.length
> 0) {
349 Item item
= (Item
) _data
._items
[0];
350 if (item
._hasChildren
) {
351 _data
.expandItem(0, true);
352 item
= (Item
) _data
._items
[1];
353 item
._selected
= true;
356 item
._selected
= true;
361 ensureVisibleItem(-1, false);
363 fireSelectionChanged();
367 public void selectEvent(int n
) {
368 if (null == _timeProvider
)
370 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
371 if (trace
== _timeProvider
)
373 long selectedTime
= _timeProvider
.getSelectedTime();
374 long endTime
= _timeProvider
.getEndTime();
375 ITimeEvent nextEvent
;
376 if (-1 == n
&& selectedTime
>= endTime
)
377 nextEvent
= Utils
.findEvent(trace
, selectedTime
, 0);
379 nextEvent
= Utils
.findEvent(trace
, selectedTime
, n
);
380 if (null == nextEvent
&& -1 == n
)
381 nextEvent
= Utils
.getFirstEvent(trace
);
382 if (null != nextEvent
) {
383 _timeProvider
.setSelectedTimeInt(nextEvent
.getTime(), true);
384 fireSelectionChanged();
386 _timeProvider
.setSelectedTimeInt(endTime
, true);
387 fireSelectionChanged();
391 public void selectNextEvent() {
395 public void selectPrevEvent() {
399 public void selectNextTrace() {
403 public void selectPrevTrace() {
407 public void zoomIn() {
408 long _time0
= _timeProvider
.getTime0();
409 long _time1
= _timeProvider
.getTime1();
410 long _range
= _time1
- _time0
;
411 long selTime
= _timeProvider
.getSelectedTime();
412 if (selTime
<= _time0
|| selTime
>= _time1
) {
413 selTime
= (_time0
+ _time1
) / 2;
415 long time0
= selTime
- (long) ((selTime
- _time0
) / zoomCoeff
);
416 long time1
= selTime
+ (long) ((_time1
- selTime
) / zoomCoeff
);
418 long inaccuracy
= (_timeProvider
.getMaxTime() - _timeProvider
422 // Trace.debug("selTime:" + selTime + " time0:" + time0 + " time1:"
423 // + time1 + " inaccuracy:" + inaccuracy);
425 if (inaccuracy
> 0 && inaccuracy
< 100) {
426 _timeProvider
.setStartFinishTime(_timeProvider
.getMinTime(),
427 _timeProvider
.getMaxTime());
431 long m
= _timeProvider
.getMinTimeInterval();
432 if ((time1
- time0
) < m
) {
433 time0
= selTime
- (long) ((selTime
- _time0
) * m
/ _range
);
437 _timeProvider
.setStartFinishTime(time0
, time1
);
440 public void zoomOut() {
441 long _time0
= _timeProvider
.getTime0();
442 long _time1
= _timeProvider
.getTime1();
443 long selTime
= _timeProvider
.getSelectedTime();
444 if (selTime
<= _time0
|| selTime
>= _time1
) {
445 selTime
= (_time0
+ _time1
) / 2;
447 long time0
= (long) (selTime
- (selTime
- _time0
) * zoomCoeff
);
448 long time1
= (long) (selTime
+ (_time1
- selTime
) * zoomCoeff
);
450 long inaccuracy
= (_timeProvider
.getMaxTime() - _timeProvider
453 if (inaccuracy
> 0 && inaccuracy
< 100) {
454 _timeProvider
.setStartFinishTime(_timeProvider
.getMinTime(),
455 _timeProvider
.getMaxTime());
459 _timeProvider
.setStartFinishTime(time0
, time1
);
462 public void groupTraces(boolean on
) {
463 _data
.groupTraces(on
);
468 public void toggleTraceInteractionDrawing() {
469 drawTracesInteraction
= !drawTracesInteraction
;
473 public void setTraceJoinDrawing(boolean on
) {
475 drawTracesInteraction
= true;
479 public void setTraceWaitDrawing(boolean on
) {
481 drawTracesInteraction
= true;
485 public void setTraceReleaseDrawing(boolean on
) {
486 drawTraceReleases
= on
;
487 drawTracesInteraction
= true;
491 public boolean getTracesInteractionDrawing() {
492 return drawTracesInteraction
;
495 public boolean getTraceJoinDrawing() {
496 return drawTraceJoins
;
499 public boolean getTraceWaitDrawing() {
500 return drawTraceWaits
;
503 public boolean getTraceReleaseDrawing() {
504 return drawTraceReleases
;
507 public ITmfTimeAnalysisEntry
getSelectedTrace() {
508 ITmfTimeAnalysisEntry trace
= null;
509 int idx
= getSelectedIndex();
510 if (idx
>= 0 && _data
._items
[idx
] instanceof TraceItem
)
511 trace
= ((TraceItem
) _data
._items
[idx
])._trace
;
515 public int getSelectedIndex() {
517 for (int i
= 0; i
< _data
._items
.length
; i
++) {
518 Item item
= (Item
) _data
._items
[i
];
519 if (item
._selected
) {
527 boolean toggle(int idx
) {
528 boolean toggled
= false;
529 if (idx
>= 0 && idx
< _data
._items
.length
) {
530 Item item
= (Item
) _data
._items
[idx
];
531 if (item
._hasChildren
) {
532 item
._expanded
= !item
._expanded
;
542 int hitTest(int x
, int y
) {
546 int idx
= y
/ _itemHeight
;
548 if (idx
< _data
._items
.length
)
553 int hitSplitTest(int x
, int y
) {
554 if (x
< 0 || y
< 0 || null == _timeProvider
)
558 int nameWidth
= _timeProvider
.getNameSpace();
559 if (x
> nameWidth
- w
&& x
< nameWidth
+ w
)
564 public Item
getItem(Point pt
) {
565 int idx
= hitTest(pt
.x
, pt
.y
);
566 return idx
>= 0 ?
(Item
) _data
._items
[idx
] : null;
569 long hitTimeTest(int x
, int y
) {
570 if (null == _timeProvider
)
573 Point size
= getCtrlSize();
574 long time0
= _timeProvider
.getTime0();
575 long time1
= _timeProvider
.getTime1();
576 int nameWidth
= _timeProvider
.getNameSpace();
578 if (x
>= 0 && size
.x
>= nameWidth
) {
579 hitTime
= time0
+ ((time1
- time0
) * x
) / (size
.x
- nameWidth
);
584 void selectItem(int idx
, boolean addSelection
) {
586 if (idx
>= 0 && idx
< _data
._items
.length
) {
587 Item item
= (Item
) _data
._items
[idx
];
588 item
._selected
= true;
591 for (int i
= 0; i
< _data
._items
.length
; i
++) {
592 Item item
= (Item
) _data
._items
[i
];
593 item
._selected
= i
== idx
;
596 boolean changed
= ensureVisibleItem(idx
, true);
601 public void selectItem(ITmfTimeAnalysisEntry trace
, boolean addSelection
) {
602 Integer idx
= _data
.findTraceItemIndex(trace
);
603 selectItem(idx
, addSelection
);
606 public int countPerPage() {
607 int height
= getCtrlSize().y
;
610 count
= height
/ _itemHeight
;
614 public int getTopIndex() {
616 if (_data
._items
.length
> 0)
621 public int getBottomIndex() {
622 int idx
= _data
._items
.length
- 1;
626 Point
getCtrlSize() {
627 Point size
= getSize();
628 size
.x
-= getVerticalBar().getSize().x
;
629 size
.y
-= getHorizontalBar().getSize().y
;
633 void getNameRect(Rectangle rect
, Rectangle bound
, int idx
, int nameWidth
) {
636 rect
.y
= bound
.y
+ idx
* _itemHeight
;
637 rect
.width
= nameWidth
;
638 rect
.height
= _itemHeight
;
641 void getStatesRect(Rectangle rect
, Rectangle bound
, int idx
, int nameWidth
) {
643 rect
.x
= bound
.x
+ nameWidth
;
644 rect
.y
= bound
.y
+ idx
* _itemHeight
;
645 rect
.width
= bound
.width
- rect
.x
;
646 rect
.height
= _itemHeight
;
649 // private int getTraceNumber(int tid) {
652 // Object[] items = _data._items;
653 // for (int i = _topItem; i < items.length; i++) {
654 // Item item = (Item) items[i];
655 // if ((item instanceof TraceItem)) {
656 // TsfTmTrace trace = ((TraceItem) item)._trace;
657 // if (trace != null && trace.getId() == tid) {
667 // private void drawArrow(GC gc, int x0, int y0, int x1, int y1, Color c) {
668 // gc.setForeground(c);
669 // gc.drawLine(x0, y0, x1, y1);
672 // gc.drawLine(x1 - 3, y1 - 3, x1, y1);
673 // gc.drawLine(x1 + 3, y1 - 3, x1, y1);
675 // gc.drawLine(x1 - 3, y1 + 3, x1, y1);
676 // gc.drawLine(x1 + 3, y1 + 3, x1, y1);
680 // TODO: CC: used in the removed functionality to draw thread interactions.
681 // private void drawTraceThreadEvent(Rectangle bound, TsfTmEvent e,
682 // TsfTmTrace trace, int nItem, int color, GC gc) {
683 // if (trace == null)
686 // int tid = trace.getId();
687 // if (tid < 0 || getTraceNumber(tid) == -1)
690 // int nameWidth = _timeProvider.getNameSpace();
692 // double time0 = _timeProvider.getTime0();
693 // double time1 = _timeProvider.getTime1();
694 // if (time0 == time1)
697 // int xr = bound.x + nameWidth;
698 // double K = (double) (bound.width - xr) / (time1 - time0);
700 // int x0 = xr + (int) ((e.getTime() - time0) * K);
704 // int x1 = xr + (int) ((trace.getStartTime() - time0) * K);
708 // int y0 = bound.y + (nItem - _topItem) * _itemHeight + 3
709 // + (_itemHeight - 6) / 2;
710 // int y1 = bound.y + (getTraceNumber(tid) - _topItem) * _itemHeight + 3
711 // + (_itemHeight - 6) / 2;
713 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));
716 public void drawTraceEvent(Rectangle bound
, ITimeEvent e
, int nItem
,
718 int nameWidth
= _timeProvider
.getNameSpace();
720 long time0
= _timeProvider
.getTime0();
721 long time1
= _timeProvider
.getTime1();
725 int xr
= bound
.x
+ nameWidth
;
726 double K
= (double) (bound
.width
- xr
) / (time1
- time0
);
728 int x0
= xr
+ (int) ((e
.getTime() - time0
) * K
);
732 int y0
= bound
.y
+ (nItem
- _topItem
) * _itemHeight
+ 3;
734 gc
.setBackground(_colors
.getColor(color
));
735 int c
[] = { x0
- 3, y0
- 3, x0
, y0
, x0
+ 3, y0
- 3 };
740 // private void drawExecEvent(Rectangle bound, TsfTmTraceExecEventImpl e,
741 // int nitem, int color, GC gc) {
742 // List runnings = e.getRunningEvents();
743 // if (runnings == null)
746 // int nameWidth = _timeProvider.getNameSpace();
748 // double time0 = _timeProvider.getTime0();
749 // double time1 = _timeProvider.getTime1();
750 // if (time0 == time1)
753 // int xr = bound.x + nameWidth;
754 // double K = (double) (bound.width - xr) / (time1 - time0);
756 // int x0 = xr + (int) ((e.getTime() - time0) * K);
760 // Iterator it = runnings.iterator();
761 // while (it.hasNext()) {
762 // TsfTmTraceRunningEventImpl re = (TsfTmTraceRunningEventImpl) it
764 // int tid = re.getThread().getId();
765 // if (tid < 0 || getThreadNumber(tid) == -1)
768 // int x1 = xr + (int) ((re.getTime() - time0) * K);
772 // int y0 = bound.y + (nitem - _topItem) * _itemHeight + 3
773 // + (_itemHeight - 6) / 2;
774 // int y1 = bound.y + (getThreadNumber(tid) - _topItem) * _itemHeight
775 // + 3 + (_itemHeight - 6) / 2;
777 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));
781 public void drawTraceInteractions(Rectangle bound
, GC gc
) {
782 // int nameWidth = _timeProvider.getNameSpace();
783 // Object[] items = _data._items;
785 // double time0 = _timeProvider.getTime0();
786 // double time1 = _timeProvider.getTime1();
788 // if (time0 == time1)
791 // int xr = bound.x + nameWidth;
792 // double K = (double) (bound.width - xr) / (time1 - time0);
794 // for (int i = 0; i < items.length; i++) {
795 // Item item = (Item) items[i];
796 // if (!(item instanceof TraceItem))
799 // TsfTmTrace trace = ((TraceItem) item)._trace;
800 // if (trace == null)
803 // List<TsfTmEvent> list = trace.getTraceEvents();
804 // Iterator<TsfTmEvent> it = list.iterator();
805 // while (it.hasNext()) {
806 // TsfTmEvent te = (TsfTmEvent) it.next();
807 // TODO: CC: Thread Interactions,
808 // This needs to be accessed externally via a specific
810 // if (te instanceof TsfTmTraceStartThreadEventImpl) {
811 // TsfTmTrace child = ((TsfTmTraceStartThreadEventImpl) te)
812 // .getStartedThread();
813 // drawThreadThreadEvent(bound, te, child, i,
814 // TraceColorScheme.TI_START_THREAD, gc);
815 // } else if (te instanceof TsfTmTraceHandoffLockEventImpl) {
816 // if (drawThreadReleases)
817 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
818 // TraceColorScheme.TI_HANDOFF_LOCK, gc);
819 // } else if (te instanceof TsfTmTraceNotifyAllEventImpl) {
820 // if (drawThreadWaits)
821 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
822 // TraceColorScheme.TI_NOTIFY_ALL, gc);
823 // } else if (te instanceof TsfTmTraceNotifyEventImpl) {
824 // if (drawThreadWaits)
825 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
826 // TraceColorScheme.TI_NOTIFY, gc);
827 // } else if (te instanceof
828 // TsfTmTraceDeadAndNotifyJoinedEventImpl) {
829 // if (drawThreadJoins)
830 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
831 // TraceColorScheme.TI_NOTIFY_JOINED, gc);
832 // } else if (te instanceof TsfTmTraceInterruptThreadEventImpl)
834 // if (drawThreadWaits)
835 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
836 // TraceColorScheme.TI_INTERRUPT, gc);
837 // } else if (te instanceof
838 // TsfTmTraceWaitTimeoutExceedEventImpl) {
839 // drawThreadEvent(bound, te, i,
840 // TraceColorScheme.TI_WAIT_EXCEEDED, gc);
847 void paint(Rectangle bound
, PaintEvent e
) {
848 // If no user preference defined for item height
849 if (_itemHeight
== _itemHeightDefault
) {
850 _itemHeight
= getFontHeight() + 6;
853 if (bound
.width
< 2 || bound
.height
< 2 || null == _timeProvider
)
858 int nameWidth
= _timeProvider
.getNameSpace();
859 long time0
= _timeProvider
.getTime0();
860 long time1
= _timeProvider
.getTime1();
861 long endTime
= _timeProvider
.getEndTime();
862 long selectedTime
= _timeProvider
.getSelectedTime();
864 Object
[] items
= _data
._items
;
865 for (int i
= _topItem
; i
< items
.length
; i
++) {
866 Item item
= (Item
) items
[i
];
867 getNameRect(_rect0
, bound
, i
, nameWidth
);
868 if (_rect0
.y
>= bound
.y
+ bound
.height
)
871 if (item
instanceof GroupItem
) {
872 getStatesRect(_rect1
, bound
, i
, nameWidth
);
873 _rect0
.width
+= _rect1
.width
;
874 drawName(item
, _rect0
, gc
);
876 drawName(item
, _rect0
, gc
);
878 getStatesRect(_rect0
, bound
, i
, nameWidth
);
879 drawItemDataDurations(item
, _rect0
, time0
, time1
, endTime
,
883 if (drawTracesInteraction
)
884 drawTraceInteractions(bound
, e
.gc
);
886 // fill free canvas area
888 _rect0
.y
+= _rect0
.height
;
889 _rect0
.width
= bound
.width
;
890 _rect0
.height
= bound
.y
+ bound
.height
- _rect0
.y
;
891 if (_rect0
.y
< bound
.y
+ bound
.height
) {
892 gc
.setBackground(_colors
.getColor(TraceColorScheme
.BACKGROUND
));
893 gc
.fillRectangle(_rect0
);
895 // draw drag line, no line if name space is 0.
896 if (3 == _dragState
) {
897 gc
.setForeground(_colors
.getColor(TraceColorScheme
.BLACK
));
898 gc
.drawLine(bound
.x
+ nameWidth
, bound
.y
, bound
.x
+ nameWidth
,
899 bound
.y
+ bound
.height
- 1);
900 } else if (0 == _dragState
&& _mouseHover
901 && _timeProvider
.getNameSpace() > 0) {
902 gc
.setForeground(_colors
.getColor(TraceColorScheme
.RED
));
903 gc
.drawLine(bound
.x
+ nameWidth
, bound
.y
, bound
.x
+ nameWidth
,
904 bound
.y
+ bound
.height
- 1);
908 void drawName(Item item
, Rectangle rect
, GC gc
) {
909 // No name to be drawn
910 if (_timeProvider
.getNameSpace() == 0)
912 boolean group
= item
instanceof GroupItem
;
914 int elemHeight
= rect
.height
/ 2;
915 int elemWidth
= elemHeight
;
916 String name
= item
._name
;
918 gc
.setBackground(_colors
919 .getBkColorGroup(item
._selected
, _isInFocus
));
920 gc
.fillRectangle(rect
);
921 if (item
._selected
&& _isInFocus
) {
922 gc
.setForeground(_colors
.getBkColor(item
._selected
, _isInFocus
,
924 gc
.drawRectangle(rect
.x
, rect
.y
, rect
.width
- 2,
927 gc
.setForeground(_colors
.getBkColor(false, false, false));
928 gc
.drawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.width
- 1,
929 rect
.y
+ rect
.height
- 1);
930 gc
.setForeground(_colors
.getFgColorGroup(false, false));
931 gc
.setBackground(_colors
.getBkColor(false, false, false));
932 Utils
.init(_rect1
, rect
);
934 _rect1
.y
+= (rect
.height
- elemHeight
) / 2;
935 _rect1
.width
= elemWidth
;
936 _rect1
.height
= elemHeight
;
937 // Get the icon rectangle in the group items
938 gc
.fillRectangle(_rect1
);
939 gc
.drawRectangle(_rect1
.x
, _rect1
.y
, _rect1
.width
- 1,
941 int p
= _rect1
.y
+ _rect1
.height
/ 2;
942 gc
.drawLine(_rect1
.x
+ 2, p
, _rect1
.x
+ _rect1
.width
- 3, p
);
943 if (!item
._expanded
) {
944 p
= _rect1
.x
+ _rect1
.width
/ 2;
945 gc
.drawLine(p
, _rect1
.y
+ 2, p
, _rect1
.y
+ _rect1
.height
- 3);
947 gc
.setForeground(_colors
948 .getFgColorGroup(item
._selected
, _isInFocus
));
951 gc
.setBackground(_colors
.getBkColor(item
._selected
, _isInFocus
,
953 gc
.setForeground(_colors
.getFgColor(item
._selected
, _isInFocus
));
954 gc
.fillRectangle(rect
);
955 Utils
.init(_rect1
, rect
);
958 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
959 Image img
= utilImpl
.getItemImage(trace
);
961 _rect1
.y
+= (rect
.height
- img
.getImageData().height
) / 2;
962 gc
.drawImage(img
, _rect1
.x
, _rect1
.y
);
964 elemWidth
= SMALL_ICON_SIZE
;
965 // cut long string with "..."
966 Point size
= gc
.stringExtent(name
);
967 if (_idealNameWidth
< size
.x
)
968 _idealNameWidth
= size
.x
;
969 int width
= rect
.width
- MARGIN
- MARGIN
- elemWidth
;
971 while (size
.x
> width
&& name
.length() > 1) {
973 name
= name
.substring(0, name
.length() - 1);
974 size
= gc
.stringExtent(name
+ "...");
980 Utils
.init(_rect1
, rect
);
981 int leftMargin
= MARGIN
+ elemWidth
;
982 _rect1
.x
+= leftMargin
;
983 _rect1
.width
-= leftMargin
;
986 if (_rect1
.width
> 0) {
988 textWidth
= Utils
.drawText(gc
, name
, _rect1
, true) + 8;
992 if (_rect1
.width
> 0 && !group
) {
993 Utils
.init(_rect1
, rect
);
994 _rect1
.x
+= leftMargin
+ textWidth
;
995 _rect1
.width
-= textWidth
;
996 gc
.setForeground(_colors
.getColor(TraceColorScheme
.MID_LINE
));
997 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
998 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1000 // gc.drawLine(_rect1.x + _rect1.width - 1, _rect1.y, _rect1.x +
1001 // _rect1.width - 1, _rect1.y + _rect1.height);
1004 void drawItemData(Item item
, Rectangle rect
, long time0
, long time1
,
1005 long endTime
, long selectedTime
, GC gc
) {
1008 if (time1
<= time0
) {
1009 gc
.setBackground(_colors
.getBkColor(false, false, false));
1010 gc
.fillRectangle(rect
);
1014 Utils
.init(_rect1
, rect
);
1015 boolean selected
= item
._selected
;
1016 double K
= (double) rect
.width
/ (time1
- time0
);
1017 boolean group
= item
instanceof GroupItem
;
1020 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1021 // gc.fillRectangle(rect);
1022 } else if (item
instanceof TraceItem
) {
1023 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1026 List
<TimeEvent
> list
= trace
.getTraceEvents();
1027 // Iterator it = list.iterator();
1028 int count
= list
.size();
1029 ITimeEvent lastEvent
= null;
1031 ITimeEvent currEvent
= list
.get(0);
1032 ITimeEvent nextEvent
= null;
1033 long currEventTime
= currEvent
.getTime();
1034 long nextEventTime
= currEventTime
;
1035 x0
= rect
.x
+ (int) ((currEventTime
- time0
) * K
);
1036 int xEnd
= rect
.x
+ (int) ((time1
- time0
) * K
);
1043 fillSpace(rect
, gc
, selected
, _rect1
.x
, x0
, xEnd
);
1045 // draw event states
1046 while (x0
<= xEnd
&& null != currEvent
) {
1047 boolean stopped
= false;// currEvent instanceof
1048 // TsfTmTraceDeadEvent;
1050 nextEvent
= list
.get(idx
);
1051 nextEventTime
= nextEvent
.getTime();
1053 } else if (stopped
) {
1055 nextEventTime
= time1
;
1058 nextEventTime
= endTime
;
1060 x1
= rect
.x
+ (int) ((nextEventTime
- time0
) * K
);
1062 _rect1
.x
= x0
>= rect
.x ? x0
: rect
.x
;
1063 _rect1
.width
= (x1
<= xEnd ? x1
: xEnd
) - _rect1
.x
;
1064 boolean timeSelected
= currEventTime
<= selectedTime
1065 && selectedTime
< nextEventTime
;
1066 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1067 // + _rect1.y + "," + _rect1.height + ", "
1068 // + _rect1.width + "-->"
1069 // + ((int) _rect1.x + (int) _rect1.width));
1070 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1071 selected
, false, timeSelected
);
1073 lastEvent
= currEvent
;
1074 currEvent
= nextEvent
;
1075 currEventTime
= nextEventTime
;
1080 // fill space after last event
1081 int xEnd
= rect
.x
+ rect
.width
;
1083 _rect1
.x
= x0
>= rect
.x ? x0
: rect
.x
;
1084 _rect1
.width
= xEnd
- _rect1
.x
;
1085 gc
.setBackground(_colors
1086 .getBkColor(selected
, _isInFocus
, false));
1087 gc
.fillRectangle(_rect1
);
1089 gc
.setForeground(_colors
.getColor(utilImpl
1090 .getEventColorVal(lastEvent
)));
1091 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1092 int lw
= gc
.getLineWidth();
1094 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1095 gc
.setLineWidth(lw
);
1099 Utils
.init(_rect1
, rect
);
1100 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1102 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1104 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1106 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1107 y
= _rect1
.y
+ _rect1
.height
- 1;
1108 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1110 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1112 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1115 // draw selected time
1116 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1117 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1118 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1120 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1123 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1128 * Represent the event in series of bursts rather than sequence of states
1132 * - The container rectangle to be colored to different states
1134 * - Base time of all events
1136 * - End time of all events
1138 * @param selectedTime
1141 void drawItemDataBurst(Item item
, Rectangle rect
, long time0
, long time1
,
1142 long endTime
, long selectedTime
, GC gc
) {
1145 if (time1
<= time0
) {
1146 gc
.setBackground(_colors
.getBkColor(false, false, false));
1147 gc
.fillRectangle(rect
);
1151 // Initialize _rect1 to same values as enclosing rectangle rect
1152 Utils
.init(_rect1
, rect
);
1153 boolean selected
= item
._selected
;
1154 // K pixels per second
1155 double K
= (double) rect
.width
/ (time1
- time0
);
1156 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "
1157 // + time0 + " time1:" + time1 + " endTime: " + endTime);
1159 boolean group
= item
instanceof GroupItem
;
1162 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1163 // gc.fillRectangle(rect);
1164 // if (Trace.isDEBUG()) {
1165 // Trace.debug("Group");
1167 } else if (item
instanceof TraceItem
) {
1168 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1171 List
<TimeEvent
> list
= trace
.getTraceEvents();
1172 // Iterator it = list.iterator();
1173 int count
= list
.size();
1174 ITimeEvent lastEvent
= null;
1175 // Trace.debug("count is: " + count);
1177 ITimeEvent currEvent
= list
.get(0);
1178 ITimeEvent nextEvent
= null;
1179 long currEventTime
= currEvent
.getTime();
1180 long nextEventTime
= currEventTime
;
1181 // x0 - Points to the beginning of the event being drawn
1182 double step
= (double) ((currEventTime
- time0
) * K
);
1184 // xEnd - Points to the end of the events rectangle
1185 double xEnd
= rect
.x
+ (double) ((time1
- time0
) * K
);
1190 // Drawing rectangle is smaller than reserved space
1194 // Clean up to empty line to draw on top
1195 fillSpace(rect
, gc
, selected
, _rect1
.x
, xEnd
, xEnd
);
1196 // draw event states
1197 while (x0
<= xEnd
&& null != currEvent
) {
1198 boolean stopped
= false;// currEvent instanceof
1199 // TsfTmTraceDeadEvent;
1201 nextEvent
= list
.get(idx
);
1202 nextEventTime
= nextEvent
.getTime();
1204 } else if (stopped
) {
1206 nextEventTime
= time1
;
1209 nextEventTime
= endTime
;
1211 // .debug("nexEventTime is endTime: "
1212 // + nextEventTime);
1215 // Draw it as a burst, one unit of width.
1217 if (x1
>= rect
.x
&& x0
<= xEnd
) {
1218 // Fill with space until x0
1219 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1220 _rect1
.width
= (int) ((x1
<= xEnd ? x1
: xEnd
) - _rect1
.x
);
1221 boolean timeSelected
= currEventTime
<= selectedTime
1222 && selectedTime
< nextEventTime
;
1223 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1224 selected
, false, timeSelected
);
1225 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1226 // + _rect1.y + "," + _rect1.height + ", "
1227 // + _rect1.width + "-->"
1228 // + ((int) _rect1.x + (int) _rect1.width));
1229 // Advance rectangle to next start position and Fill
1230 // with space until next event
1231 _rect1
.x
+= _rect1
.width
;
1233 xNext
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1235 // Fill space till next event
1236 fillSpace(rect
, gc
, selected
, x0
, xNext
, xEnd
);
1238 lastEvent
= currEvent
;
1239 currEvent
= nextEvent
;
1240 currEventTime
= nextEventTime
;
1241 // Move x0 to the beginning of next event
1242 x0
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1243 // Trace.debug("rect.x: " + rect.x + " + " +
1244 // "(nextEvenTime: "
1245 // + nextEventTime + "- time0: " + time0 + ") * K: "
1246 // + K + " = " + x0);
1250 // fill space after last event
1251 int xEnd
= rect
.x
+ rect
.width
;
1253 // Trace.debug("Space after last event, x0: " + x0 + ", xEnd: "
1255 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1256 _rect1
.width
= xEnd
- _rect1
.x
;
1257 gc
.setBackground(_colors
1258 .getBkColor(selected
, _isInFocus
, false));
1259 gc
.fillRectangle(_rect1
);
1261 gc
.setForeground(_colors
.getColor(utilImpl
1262 .getEventColorVal(lastEvent
)));
1263 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1264 int lw
= gc
.getLineWidth();
1266 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1267 gc
.setLineWidth(lw
);
1271 Utils
.init(_rect1
, rect
);
1272 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1274 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1276 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1278 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1279 y
= _rect1
.y
+ _rect1
.height
- 1;
1280 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1282 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1284 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1287 // draw selected time
1288 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1289 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1290 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1292 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1295 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1300 * Represent the series of events with specified durations
1304 * - The container rectangle to be colored to different states
1306 * - Base time of all events - start of visible window
1308 * - End time of visible events - end time of visible window
1310 * - End time of all events - may not be visible in selected
1312 * @param selectedTime
1315 void drawItemDataDurations(Item item
, Rectangle rect
, long time0
,
1316 long time1
, long endTime
, long selectedTime
, GC gc
) {
1319 if (time1
<= time0
) {
1320 gc
.setBackground(_colors
.getBkColor(false, false, false));
1321 gc
.fillRectangle(rect
);
1325 // Initialize _rect1 to same values as enclosing rectangle rect
1326 Utils
.init(_rect1
, rect
);
1327 boolean selected
= item
._selected
;
1328 // K pixels per second
1329 double K
= (double) rect
.width
/ (time1
- time0
);
1330 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "
1331 // + time0 + " time1:" + time1 + " endTime: " + endTime);
1333 boolean group
= item
instanceof GroupItem
;
1336 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1337 // gc.fillRectangle(rect);
1338 // if (Trace.isDEBUG()) {
1339 // Trace.debug("\n\t\t\tGroup: " + ((GroupItem) item)._name);
1341 } else if (item
instanceof TraceItem
) {
1342 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1345 List
<TimeEvent
> list
= trace
.getTraceEvents();
1346 // Iterator it = list.iterator();
1347 int count
= list
.size();
1348 ITimeEvent lastEvent
= null;
1349 // if (Trace.isDEBUG()) {
1350 // Trace.debug("\n\t\t\tTrace: " + trace.getName()
1351 // + utilImpl.getTraceClassName(trace));
1353 // Trace.debug("count is: " + count);
1355 ITimeEvent currEvent
= list
.get(0);
1356 ITimeEvent nextEvent
= null;
1357 long currEventTime
= currEvent
.getTime();
1358 long currEventDuration
= currEvent
.getDuration();
1360 long nextEventTime
= currEventTime
;
1361 // x0 - Points to the beginning of the event being drawn
1362 double step
= (double) ((currEventTime
- time0
) * K
);
1364 // xEnd - Points to the end of the events rectangle
1365 double xEnd
= rect
.x
+ (double) ((time1
- time0
) * K
);
1370 // Drawing rectangle is smaller than reserved space
1374 // Clean up to empty line to draw on top
1375 fillSpace(rect
, gc
, selected
, _rect1
.x
, xEnd
, xEnd
);
1376 // draw event states
1377 while (x0
<= xEnd
&& null != currEvent
) {
1378 boolean stopped
= false;// currEvent instanceof
1379 // refresh current event duration as the loop moves
1380 currEventDuration
= currEvent
.getDuration();
1381 // TsfTmTraceDeadEvent;
1383 nextEvent
= list
.get(idx
);
1384 nextEventTime
= nextEvent
.getTime();
1386 } else if (stopped
) {
1388 nextEventTime
= time1
;
1391 nextEventTime
= endTime
;
1393 // .debug("nexEventTime is endTime: "
1394 // + nextEventTime);
1397 // Calculate position to next event
1398 xNext
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1400 // Calculate end position of current event
1401 if (currEventDuration
< 0) {
1402 x1
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1404 x1
= currEventDuration
== 0 ?
(x0
+ 2)
1405 : (x0
+ (double) ((currEventDuration
) * K
));
1408 // If event end position x1 further away than start position
1410 // next event, cut width till next event
1411 // Trace.debug("Next Event Pos: " + xNext
1412 // + " End Of Current at: " + x1 + " Event Duration: "
1413 // + currEventDuration);
1414 x1
= x1
> xNext ? xNext
: x1
;
1415 // if event end boundary is within time range
1416 if (x1
>= rect
.x
&& x0
<= xEnd
) {
1417 // Fill with space until x0
1418 x0
= (double) (x0
>= rect
.x ? x0
: rect
.x
);
1419 _rect1
.width
= (int) ((x1
<= xEnd ? x1
: xEnd
) - x0
);
1420 _rect1
.x
= (int) x0
;
1421 boolean timeSelected
= currEventTime
<= selectedTime
1422 && selectedTime
< nextEventTime
;
1423 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1424 selected
, false, timeSelected
);
1425 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1426 // + _rect1.y + "," + _rect1.height + ", "
1427 // + _rect1.width + "-->"
1428 // + ((int) _rect1.x + (int) _rect1.width));
1429 // Advance rectangle to next start position and Fill
1430 // with space until next event
1431 _rect1
.x
+= _rect1
.width
;
1435 // Fill space till next event
1436 fillSpace(rect
, gc
, selected
, x0
, xNext
, xEnd
);
1438 lastEvent
= currEvent
;
1439 currEvent
= nextEvent
;
1440 currEventTime
= nextEventTime
;
1441 // Move x0 to the beginning of next event
1442 x0
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1443 // Trace.debug("rect.x: " + rect.x + " + " +
1444 // "(nextEvenTime: "
1445 // + nextEventTime + "- time0: " + time0 + ") * K: "
1446 // + K + " = " + x0);
1450 // fill space after last event
1451 int xEnd
= rect
.x
+ rect
.width
;
1453 // Trace.debug("Space after last event, x0: " + x0 + ", xEnd: "
1455 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1456 _rect1
.width
= xEnd
- _rect1
.x
;
1457 gc
.setBackground(_colors
1458 .getBkColor(selected
, _isInFocus
, false));
1459 gc
.fillRectangle(_rect1
);
1461 gc
.setForeground(_colors
.getColor(utilImpl
1462 .getEventColorVal(lastEvent
)));
1463 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1464 int lw
= gc
.getLineWidth();
1466 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1467 gc
.setLineWidth(lw
);
1471 Utils
.init(_rect1
, rect
);
1472 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1474 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1476 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1478 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1479 y
= _rect1
.y
+ _rect1
.height
- 1;
1480 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1482 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1484 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1487 // draw selected time
1488 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1489 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1490 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1492 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1495 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1499 private void fillSpace(Rectangle rect
, GC gc
, boolean selected
, double x0
,
1500 double x1
, double xEnd
) {
1501 // fill space before first event
1502 if (x0
>= rect
.x
&& x0
< xEnd
) {
1503 // _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - x0);
1504 // Trace.debug("Drawing Space: " + _rect1.x + "," + _rect1.y + ","
1505 // + _rect1.height + ", " + _rect1.width + "--> "
1506 // + ((int) _rect1.x + (int) _rect1.width));
1508 // if (_rect1.width < 0) {
1509 // Trace.debug("Incorrect width:" + _rect1.width);
1511 gc
.setBackground(_colors
.getBkColor(selected
, _isInFocus
, false));
1512 gc
.fillRectangle(_rect1
);
1514 gc
.setForeground(_colors
.getColor(TraceColorScheme
.MID_LINE
));
1515 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1516 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1518 // Trace.debug("No space added since, x0 is out of range " + x0
1519 // + " rect.x: " + rect.x + " xEnd: " + xEnd);
1523 public void keyTraversed(TraverseEvent e
) {
1524 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
)
1525 || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
))
1529 public void keyPressed(KeyEvent e
) {
1531 if (SWT
.HOME
== e
.keyCode
) {
1532 idx
= getTopIndex();
1533 } else if (SWT
.END
== e
.keyCode
) {
1534 idx
= getBottomIndex();
1535 } else if (SWT
.ARROW_DOWN
== e
.keyCode
) {
1536 idx
= getSelectedIndex();
1539 else if (idx
< _data
._items
.length
- 1)
1541 } else if (SWT
.ARROW_UP
== e
.keyCode
) {
1542 idx
= getSelectedIndex();
1547 } else if (SWT
.ARROW_LEFT
== e
.keyCode
) {
1549 } else if (SWT
.ARROW_RIGHT
== e
.keyCode
) {
1551 } else if (SWT
.PAGE_DOWN
== e
.keyCode
) {
1552 int page
= countPerPage();
1553 idx
= getSelectedIndex();
1557 if (idx
>= _data
._items
.length
)
1558 idx
= _data
._items
.length
- 1;
1559 } else if (SWT
.PAGE_UP
== e
.keyCode
) {
1560 int page
= countPerPage();
1561 idx
= getSelectedIndex();
1567 } else if (SWT
.CR
== e
.keyCode
) {
1568 idx
= getSelectedIndex();
1570 if (_data
._items
[idx
] instanceof TraceItem
)
1571 fireDefaultSelection();
1572 else if (_data
._items
[idx
] instanceof GroupItem
)
1578 selectItem(idx
, false);
1579 fireSelectionChanged();
1583 public void keyReleased(KeyEvent e
) {
1586 public void focusGained(FocusEvent e
) {
1591 public void focusLost(FocusEvent e
) {
1593 if (0 != _dragState
) {
1600 public boolean isInFocus() {
1604 public void mouseMove(MouseEvent e
) {
1605 if (null == _timeProvider
)
1607 Point size
= getCtrlSize();
1608 if (1 == _dragState
) {
1609 int nameWidth
= _timeProvider
.getNameSpace();
1610 int x
= e
.x
- nameWidth
;
1611 if (x
> 0 && size
.x
> nameWidth
&& _dragX
!= x
) {
1613 double K
= (double) (size
.x
- nameWidth
)
1614 / (_time1bak
- _time0bak
);
1615 long timeDelta
= (long) ((_dragX
- _dragX0
) / K
);
1616 long time1
= _time1bak
- timeDelta
;
1617 long maxTime
= _timeProvider
.getMaxTime();
1618 if (time1
> maxTime
)
1620 long time0
= time1
- (_time1bak
- _time0bak
);
1621 if (time0
< _timeProvider
.getMinTime()) {
1622 time0
= _timeProvider
.getMinTime();
1623 time1
= time0
+ (_time1bak
- _time0bak
);
1625 _timeProvider
.setStartFinishTime(time0
, time1
);
1627 } else if (3 == _dragState
) {
1629 _timeProvider
.setNameSpace(_hitIdx
+ _dragX
- _dragX0
);
1630 } else if (0 == _dragState
) {
1631 boolean mouseHover
= hitSplitTest(e
.x
, e
.y
) > 0;
1632 if (_mouseHover
!= mouseHover
)
1634 _mouseHover
= mouseHover
;
1636 updateCursor(e
.x
, e
.y
);
1639 public void mouseDoubleClick(MouseEvent e
) {
1640 if (null == _timeProvider
)
1642 if (1 == e
.button
) {
1643 int idx
= hitSplitTest(e
.x
, e
.y
);
1645 _timeProvider
.setNameSpace(_idealNameWidth
+ 3 * MARGIN
1649 idx
= hitTest(e
.x
, e
.y
);
1651 selectItem(idx
, false);
1652 if (_data
._items
[idx
] instanceof TraceItem
) {
1653 fireDefaultSelection();
1659 void updateCursor(int x
, int y
) {
1660 int idx
= hitSplitTest(x
, y
);
1661 // No dragcursor is name space is fixed to zero
1662 if (idx
> 0 && !_isDragCursor3
&& _timeProvider
.getNameSpace() > 0) {
1663 setCursor(_dragCursor3
);
1664 _isDragCursor3
= true;
1665 } else if (idx
<= 0 && _isDragCursor3
) {
1667 _isDragCursor3
= false;
1671 public void mouseDown(MouseEvent e
) {
1672 if (null == _timeProvider
)
1675 if (1 == e
.button
) {
1676 int namewidth
= _timeProvider
.getNameSpace();
1677 if (namewidth
!= 0) {
1678 idx
= hitSplitTest(e
.x
, e
.y
);
1681 _dragX
= _dragX0
= e
.x
;
1682 _hitIdx
= _timeProvider
.getNameSpace();
1684 _time0bak
= _timeProvider
.getTime0();
1685 _time1bak
= _timeProvider
.getTime1();
1691 idx
= hitTest(e
.x
, e
.y
);
1693 if (_data
._items
[idx
] instanceof TraceItem
) {
1694 long hitTime
= hitTimeTest(e
.x
, e
.y
);
1696 _timeProvider
.setSelectedTimeInt(hitTime
, false);
1699 _dragX
= _dragX0
= e
.x
- _timeProvider
.getNameSpace();
1700 _time0bak
= _timeProvider
.getTime0();
1701 _time1bak
= _timeProvider
.getTime1();
1703 } else if (_data
._items
[idx
] instanceof GroupItem
) {
1707 selectItem(idx
, false);
1708 fireSelectionChanged();
1713 public void mouseUp(MouseEvent e
) {
1714 if (0 != _dragState
) {
1716 if (2 == _dragState
) {
1717 if (hitTest(e
.x
, e
.y
) == _hitIdx
)
1719 } else if (3 == _dragState
) {
1726 public void controlMoved(ControlEvent e
) {
1729 public void controlResized(ControlEvent e
) {
1733 public void widgetDefaultSelected(SelectionEvent e
) {
1736 public void widgetSelected(SelectionEvent e
) {
1737 if (e
.widget
== getVerticalBar()) {
1738 _topItem
= getVerticalBar().getSelection();
1742 } else if (e
.widget
== getHorizontalBar() && null != _timeProvider
) {
1743 int startTime
= getHorizontalBar().getSelection();
1744 long time0
= _timeProvider
.getTime0();
1745 long time1
= _timeProvider
.getTime1();
1746 long timeMin
= _timeProvider
.getMinTime();
1747 long timeMax
= _timeProvider
.getMaxTime();
1748 long delta
= timeMax
- timeMin
;
1750 long range
= time1
- time0
;
1751 // _timeRangeFixed = true;
1752 time0
= timeMin
+ (long) ((double) (startTime
* _timeStep
) * delta
);
1753 time1
= time0
+ range
;
1754 // Trace.debug("\nstartTime:" + startTime + " time0:" + time0
1755 // + " time1:" + time1 + " Delta:" + delta);
1756 _timeProvider
.setStartFinishTime(time0
, time1
);
1760 public void mouseEnter(MouseEvent e
) {
1763 public void mouseExit(MouseEvent e
) {
1765 _mouseHover
= false;
1770 public void mouseHover(MouseEvent e
) {
1773 public void mouseScrolled(MouseEvent e
) {
1776 } else if (e
.count
< 0) {
1781 public boolean isVisibleVerticalScroll() {
1782 return _visibleVerticalScroll
;
1785 public void setVisibleVerticalScroll(boolean visibleVerticalScroll
) {
1786 ScrollBar scrollVer
= getVerticalBar();
1787 if (scrollVer
!= null) {
1788 scrollVer
.setVisible(visibleVerticalScroll
);
1790 this._visibleVerticalScroll
= visibleVerticalScroll
;
1794 public int getBorderWidth() {
1795 return _borderWidth
;
1798 public void setBorderWidth(int borderWidth
) {
1799 this._borderWidth
= borderWidth
;
1802 public int getHeaderHeight() {
1803 return _headerHeight
;
1806 public void setHeaderHeight(int headerHeight
) {
1807 this._headerHeight
= headerHeight
;
1810 public int getItemHeight() {
1814 public void setItemHeight(int rowHeight
) {
1815 this._itemHeight
= rowHeight
;
1818 public Vector
<ITmfTimeAnalysisEntry
> getFilteredOut() {
1819 return _data
.getFilteredOut();
1823 public void addSelectionChangedListener(ISelectionChangedListener listener
) {
1824 if (listener
!= null) {
1825 if (!_selectionChangedListeners
.contains(listener
)) {
1826 _selectionChangedListeners
.add(listener
);
1832 public void removeSelectionChangedListener(
1833 ISelectionChangedListener listener
) {
1834 if (listener
!= null) {
1835 _selectionChangedListeners
.remove(listener
);
1840 public void setSelection(ISelection selection
) {
1841 if (selection
instanceof PlainSelection
) {
1842 PlainSelection sel
= (PlainSelection
) selection
;
1843 Object ob
= sel
.getFirstElement();
1844 if (ob
instanceof ITmfTimeAnalysisEntry
) {
1845 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) ob
;
1846 selectItem(trace
, false);
1854 public boolean _expanded
;
1855 public boolean _selected
;
1856 public boolean _hasChildren
;
1857 public String _name
;
1864 public String
toString() {
1869 class TraceItem
extends Item
{
1870 public ITmfTimeAnalysisEntry _trace
;
1872 TraceItem(ITmfTimeAnalysisEntry trace
, String name
) {
1878 class GroupItem
extends Item
{
1879 public List
<ITmfTimeAnalysisEntry
> _traces
;
1881 GroupItem(String name
) {
1883 _traces
= new ArrayList
<ITmfTimeAnalysisEntry
>();
1884 _hasChildren
= true;
1887 void add(ITmfTimeAnalysisEntry trace
) {
1893 public Object
[] _items
= new Object
[0];
1894 private Object _traces
[] = new Object
[0];
1895 private boolean traceFilter
[] = new boolean[0];
1896 private Map
<String
, GroupItem
> _groupTable
= new HashMap
<String
, GroupItem
>();
1897 private boolean _flatList
= false;
1898 private TmfTimeAnalysisProvider utilsImp
;
1899 private Vector
<ITmfTimeAnalysisEntry
> filteredOut
= new Vector
<ITmfTimeAnalysisEntry
>();
1901 public ItemData(TmfTimeAnalysisProvider utils
) {
1902 this.utilsImp
= utils
;
1905 protected void groupTraces(boolean on
) {
1906 if (_flatList
== on
) {
1912 void clearGroups() {
1913 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
1914 while (it
.hasNext()) {
1915 GroupItem group
= it
.next();
1916 group
._traces
.clear();
1920 void deleteEmptyGroups() {
1921 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
1922 while (it
.hasNext()) {
1923 GroupItem group
= it
.next();
1924 if (group
._traces
.size() == 0)
1929 TraceItem
findTraceItem(ITmfTimeAnalysisEntry trace
) {
1933 int traceId
= trace
.getId();
1934 TraceItem traceItem
= null;
1936 for (int i
= 0; i
< _items
.length
; i
++) {
1937 Object item
= _items
[i
];
1938 if (item
instanceof TraceItem
) {
1939 TraceItem ti
= (TraceItem
) item
;
1940 if (ti
._trace
.getId() == traceId
) {
1950 Integer
findTraceItemIndex(ITmfTimeAnalysisEntry trace
) {
1954 int traceId
= trace
.getId();
1957 for (int i
= 0; i
< _items
.length
; i
++) {
1959 Object item
= _items
[i
];
1960 if (item
instanceof TraceItem
) {
1961 TraceItem ti
= (TraceItem
) item
;
1962 if (ti
._trace
.getId() == traceId
) {
1971 public void updateItems() {
1972 List
<Item
> itemList
= new ArrayList
<Item
>();
1975 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
1976 while (it
.hasNext()) {
1977 GroupItem group
= it
.next();
1979 itemList
.add(group
);
1981 if (_flatList
|| group
._expanded
) {
1982 Iterator
<ITmfTimeAnalysisEntry
> it2
= group
._traces
.iterator();
1983 while (it2
.hasNext()) {
1984 ITmfTimeAnalysisEntry trace
= it2
.next();
1985 TraceItem traceItem
= findTraceItem(trace
);
1986 name
= utilsImp
.composeTraceName(trace
, false);
1987 traceItem
= new TraceItem(trace
, name
);
1988 itemList
.add(traceItem
);
1992 _items
= itemList
.toArray();
1995 public int expandItem(int idx
, boolean expand
) {
1996 if (idx
< 0 || idx
>= _items
.length
)
1999 Item item
= (Item
) _items
[idx
];
2000 if (item
._hasChildren
&& !item
._expanded
) {
2001 item
._expanded
= expand
;
2002 ret
= _items
.length
;
2004 ret
= _items
.length
- ret
;
2009 public void refreshData(Object traces
[]) {
2010 if (traces
== null || traces
.length
== 0) {
2012 } else if (traceFilter
== null || traces
.length
!= traceFilter
.length
) {
2013 traceFilter
= new boolean[traces
.length
];
2014 java
.util
.Arrays
.fill(traceFilter
, true);
2022 * Allows to update the GUI from a stream of events handling addition one by
2023 * one over known TmfTaTrace parents.
2028 public void refreshPartial(ITmfTimeAnalysisEntry parent
, TimeEvent childItem
) {
2029 // Find the Trace item within the current list
2030 TraceItem item
= findTraceItem(parent
);
2033 // If the parent item is not found, make room for it in the current
2037 if (_traces
!= null) {
2038 length
= _traces
.length
+ 1;
2039 traces
= Arrays
.copyOf(_traces
, length
);
2041 traces
= new Object
[length
];
2044 // Add the new parent element to the end of the array.
2045 traces
[length
- 1] = parent
;
2047 // update the filter array to accomodate a postion to the new
2049 traceFilter
= new boolean[traces
.length
];
2050 java
.util
.Arrays
.fill(traceFilter
, true);
2052 // rebuild internal data
2056 // item must be there
2057 item
= findTraceItem(parent
);
2060 ITmfTimeAnalysisEntry localTraceItem
= item
._trace
;
2061 // Local trace found
2062 Vector
<TimeEvent
> children
= localTraceItem
.getTraceEvents();
2063 TimeEvent lastChildIn
= children
.lastElement();
2064 long lastChildSTime
= lastChildIn
.getTime();
2065 long newChildSTime
= childItem
.getTime();
2066 if (newChildSTime
< lastChildSTime
) {
2067 // The children are expected to arrive sorted by time
2068 // since the new time is earlier than the last child
2069 // The infomation is being refreshed from start, remove all
2070 // children and start over
2074 children
.add(childItem
);
2078 public void refreshData() {
2080 filteredOut
.clear();
2081 String undef
= Messages
._UNDEFINED_GROUP
;
2082 List
<GroupItem
> groupList
= new ArrayList
<GroupItem
>();
2083 for (int i
= 0; i
< _traces
.length
; i
++) {
2084 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) _traces
[i
];
2085 if (!traceFilter
[i
]) {
2086 filteredOut
.add(trace
);
2090 String groupName
= trace
.getGroupName();
2091 if (null == groupName
)
2094 GroupItem group
= _groupTable
.get(groupName
);
2095 if (null == group
) {
2096 group
= new GroupItem(NLS
.bind(Messages
._TRACE_GROUP_LABEL
,
2098 group
._expanded
= !groupName
.equalsIgnoreCase("system")
2099 && !groupName
.equalsIgnoreCase(undef
);
2100 _groupTable
.put(groupName
, group
);
2101 groupList
.add(group
);
2106 deleteEmptyGroups();
2110 public Object
[] getTraces() {
2114 public boolean[] getTraceFilter() {
2118 public Vector
<ITmfTimeAnalysisEntry
> getFilteredOut() {