June 29th, 2010
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / viewers / timeAnalysis / widgets / TmfTimeStatesCtrl.java
CommitLineData
b0d3496e
ASL
1/*****************************************************************************\r
2 * Copyright (c) 2007, 2008 Intel Corporation.\r
3 * All rights reserved. This program and the accompanying materials\r
4 * are made available under the terms of the Eclipse Public License v1.0\r
5 * which accompanies this distribution, and is available at\r
6 * http://www.eclipse.org/legal/epl-v10.html\r
7 *\r
8 * Contributors:\r
9 * Intel Corporation - Initial API and implementation\r
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation\r
11 * Alvaro Sanchex-Leon - Udpated for TMF\r
12 *\r
13 * $Id: ThreadStatesCtrl.java,v 1.15 2008/07/11 13:49:01 aalexeev Exp $ \r
14 *****************************************************************************/\r
15\r
16package org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.widgets;\r
17\r
18import java.util.ArrayList;\r
19import java.util.HashMap;\r
20import java.util.Iterator;\r
21import java.util.List;\r
22import java.util.Map;\r
23import java.util.Vector;\r
24\r
25import org.eclipse.jface.viewers.ISelection;\r
26import org.eclipse.jface.viewers.ISelectionChangedListener;\r
27import org.eclipse.jface.viewers.ISelectionProvider;\r
28import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.Messages;\r
29import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeAnalysisProvider;\r
30import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
31import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
32import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.TimeEvent;\r
33import org.eclipse.osgi.util.NLS;\r
34import org.eclipse.swt.SWT;\r
35import org.eclipse.swt.events.ControlEvent;\r
36import org.eclipse.swt.events.ControlListener;\r
37import org.eclipse.swt.events.FocusEvent;\r
38import org.eclipse.swt.events.FocusListener;\r
39import org.eclipse.swt.events.KeyEvent;\r
40import org.eclipse.swt.events.KeyListener;\r
41import org.eclipse.swt.events.MouseEvent;\r
42import org.eclipse.swt.events.MouseListener;\r
43import org.eclipse.swt.events.MouseMoveListener;\r
44import org.eclipse.swt.events.MouseTrackListener;\r
45import org.eclipse.swt.events.MouseWheelListener;\r
46import org.eclipse.swt.events.PaintEvent;\r
47import org.eclipse.swt.events.SelectionEvent;\r
48import org.eclipse.swt.events.SelectionListener;\r
49import org.eclipse.swt.events.TraverseEvent;\r
50import org.eclipse.swt.events.TraverseListener;\r
51import org.eclipse.swt.graphics.Cursor;\r
52import org.eclipse.swt.graphics.GC;\r
53import org.eclipse.swt.graphics.Image;\r
54import org.eclipse.swt.graphics.Point;\r
55import org.eclipse.swt.graphics.Rectangle;\r
56import org.eclipse.swt.widgets.Composite;\r
a5823d5f
ASL
57import org.eclipse.swt.widgets.Event;\r
58import org.eclipse.swt.widgets.Listener;\r
b0d3496e
ASL
59import org.eclipse.swt.widgets.ScrollBar;\r
60\r
41dc35d0
FC
61/**\r
62 * @author alvaro\r
63 * \r
64 */\r
b0d3496e
ASL
65public class TmfTimeStatesCtrl extends TraceCtrl implements FocusListener,\r
66 KeyListener, MouseMoveListener, MouseListener, MouseWheelListener,\r
67 ControlListener, SelectionListener, MouseTrackListener,\r
68 TraverseListener, ISelectionProvider {\r
69\r
70 public static final boolean DEFAULT_DRAW_THREAD_JOIN = true;\r
71 public static final boolean DEFAULT_DRAW_THREAD_WAIT = true;\r
72 public static final boolean DEFAULT_DRAW_THREAD_RELEASE = true;\r
a5823d5f 73 public static int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1;\r
b0d3496e
ASL
74\r
75 private final double zoomCoeff = 1.5;\r
76\r
77 private ITimeDataProvider _timeProvider;\r
78 private boolean _isInFocus = false;\r
79 private boolean _isDragCursor3 = false;\r
41dc35d0 80 private boolean _isWaitCursor = true;\r
b0d3496e 81 private boolean _mouseHover = false;\r
a5823d5f 82 private int _itemHeightDefault = 19;\r
b0d3496e
ASL
83 private int _itemHeight = _itemHeightDefault;\r
84 private int _topItem = 0;\r
85 private int _dragState = 0;\r
86 private int _hitIdx = 0;\r
87 private int _dragX0 = 0;\r
88 private int _dragX = 0;\r
89 private int _idealNameWidth = 0;\r
90 // private double _timeStep = 10000000;\r
91 private long _time0bak;\r
92 private long _time1bak;\r
93 private TmfTimeAnalysisProvider utilImpl = null;\r
94 private ItemData _data = null;\r
95 private List<SelectionListener> _selectionListeners;\r
96 private List<ISelectionChangedListener> _selectionChangedListeners = new ArrayList<ISelectionChangedListener>();\r
97 private Rectangle _rect0 = new Rectangle(0, 0, 0, 0);\r
98 private Rectangle _rect1 = new Rectangle(0, 0, 0, 0);\r
99 private Cursor _dragCursor3;\r
41dc35d0 100 private Cursor _WaitCursor;\r
b0d3496e
ASL
101 private boolean drawTracesInteraction = false;\r
102 private boolean drawTraceJoins = DEFAULT_DRAW_THREAD_JOIN;\r
103 private boolean drawTraceWaits = DEFAULT_DRAW_THREAD_WAIT;\r
104 private boolean drawTraceReleases = DEFAULT_DRAW_THREAD_RELEASE;\r
105\r
106 // Vertical formatting formatting for the state control view\r
107 private boolean _visibleVerticalScroll = true;\r
108 private int _borderWidth = 0;\r
109 private int _headerHeight = 0;\r
110\r
a5823d5f
ASL
111 private Listener mouseScrollFilterListener;\r
112\r
b0d3496e
ASL
113 public TmfTimeStatesCtrl(Composite parent, TraceColorScheme colors,\r
114 TmfTimeAnalysisProvider rutilImp) {\r
115\r
116 super(parent, colors, SWT.NO_BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL\r
117 | SWT.DOUBLE_BUFFERED);\r
118\r
119 this.utilImpl = rutilImp;\r
120 _data = new ItemData(utilImpl);\r
121\r
122 addFocusListener(this);\r
123 addMouseListener(this);\r
124 addMouseMoveListener(this);\r
125 addMouseTrackListener(this);\r
126 addMouseWheelListener(this);\r
127 addTraverseListener(this);\r
128 addKeyListener(this);\r
129 addControlListener(this);\r
130 ScrollBar scrollVer = getVerticalBar();\r
131 ScrollBar scrollHor = getHorizontalBar();\r
132 if (scrollVer != null) {\r
133 scrollVer.addSelectionListener(this);\r
134 scrollVer.setVisible(_visibleVerticalScroll);\r
135 }\r
136\r
137 if (scrollHor != null) {\r
138 scrollHor.addSelectionListener(this);\r
139 }\r
a5823d5f
ASL
140 mouseScrollFilterListener = new Listener() {\r
141 // This filter is used to prevent scrolling of the view when the\r
142 // mouse wheel is used to zoom\r
143 public void handleEvent(Event event) {\r
144 event.doit = false;\r
145 }\r
146 };\r
b0d3496e
ASL
147\r
148 _dragCursor3 = new Cursor(super.getDisplay(), SWT.CURSOR_SIZEWE);\r
41dc35d0 149 _WaitCursor = new Cursor(super.getDisplay(), SWT.CURSOR_WAIT);\r
b0d3496e
ASL
150 }\r
151\r
4e3aa37d 152 @Override\r
b0d3496e
ASL
153 public void dispose() {\r
154 super.dispose();\r
155 _dragCursor3.dispose();\r
41dc35d0 156 _WaitCursor.dispose();\r
b0d3496e
ASL
157 }\r
158\r
159 public void setTimeProvider(ITimeDataProvider timeProvider) {\r
160 _timeProvider = timeProvider;\r
161 adjustScrolls();\r
162 redraw();\r
163 }\r
164\r
165 public void addSelectionListener(SelectionListener listener) {\r
166 if (listener == null)\r
167 SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
168 if (null == _selectionListeners)\r
169 _selectionListeners = new ArrayList<SelectionListener>();\r
170 _selectionListeners.add(listener);\r
171 }\r
172\r
173 public void removeSelectionListener(SelectionListener listener) {\r
174 if (null != _selectionListeners)\r
175 _selectionListeners.remove(listener);\r
176 }\r
177\r
178 public void fireSelectionChanged() {\r
179 if (null != _selectionListeners) {\r
180 Iterator<SelectionListener> it = _selectionListeners.iterator();\r
181 while (it.hasNext()) {\r
182 SelectionListener listener = it.next();\r
183 listener.widgetSelected(null);\r
184 }\r
185 }\r
186 }\r
187\r
188 public void fireDefaultSelection() {\r
189 if (null != _selectionListeners) {\r
190 Iterator<SelectionListener> it = _selectionListeners.iterator();\r
191 while (it.hasNext()) {\r
192 SelectionListener listener = it.next();\r
193 listener.widgetDefaultSelected(null);\r
194 }\r
195 }\r
196 }\r
197\r
198 public Object[] getTraces() {\r
199 return _data.getTraces();\r
200 }\r
201\r
202 public boolean[] getTraceFilter() {\r
203 return _data.getTraceFilter();\r
204 }\r
205\r
206 public void refreshData() {\r
207 _data.refreshData();\r
208 adjustScrolls();\r
209 redraw();\r
210 }\r
211\r
212 public void refreshData(Object traces[]) {\r
213 _data.refreshData(traces);\r
214 adjustScrolls();\r
215 redraw();\r
216 }\r
217\r
218 public void refreshPartial(ITmfTimeAnalysisEntry parent, TimeEvent item) {\r
219 _data.refreshPartial(parent, item);\r
220 adjustScrolls();\r
221 redraw();\r
222 }\r
223\r
224 public void adjustScrolls() {\r
225 if (null == _timeProvider) {\r
226 getVerticalBar().setValues(0, 1, 1, 1, 1, 1);\r
227 getHorizontalBar().setValues(0, 1, 1, 1, 1, 1);\r
228 return;\r
229 }\r
71c964eb
ASL
230\r
231 // Vertical scroll bar\r
b0d3496e
ASL
232 int page = countPerPage();\r
233 if (_topItem + page > _data._items.length)\r
234 _topItem = _data._items.length - page;\r
235 if (_topItem < 0)\r
236 _topItem = 0;\r
237 getVerticalBar().setValues(_topItem, 0, _data._items.length, page, 1,\r
238 page);\r
71c964eb
ASL
239\r
240 // HORIZONTAL BAR\r
241 // Visible window\r
b0d3496e
ASL
242 long time0 = _timeProvider.getTime0();\r
243 long time1 = _timeProvider.getTime1();\r
71c964eb 244 // Time boundaries\r
b0d3496e
ASL
245 long timeMin = _timeProvider.getMinTime();\r
246 long timeMax = _timeProvider.getMaxTime();\r
247\r
248 long delta = timeMax - timeMin;\r
249\r
250 int timePos = 0;\r
a5823d5f 251 int thumb = H_SCROLLBAR_MAX;\r
71c964eb 252\r
b0d3496e 253 if (delta != 0) {\r
71c964eb 254 // Thumb size (page size)\r
a5823d5f 255 thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta)));\r
71c964eb
ASL
256 // At the beginning of visible window\r
257 timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta));\r
b0d3496e
ASL
258 }\r
259\r
71c964eb
ASL
260 // position, minimum, maximum, thumb size, increment (half page)t, page\r
261 // increment size (full page)\r
262 getHorizontalBar().setValues(timePos, 0, H_SCROLLBAR_MAX, thumb,\r
263 Math.max(1, thumb / 2), Math.max(2, thumb));\r
b0d3496e
ASL
264 }\r
265\r
266 boolean ensureVisibleItem(int idx, boolean redraw) {\r
267 boolean changed = false;\r
268 if (idx < 0) {\r
269 for (idx = 0; idx < _data._items.length; idx++) {\r
270 if (((Item) _data._items[idx])._selected)\r
271 break;\r
272 }\r
273 }\r
274 if (idx >= _data._items.length)\r
275 return changed;\r
276 if (idx < _topItem) {\r
277 _topItem = idx;\r
278 getVerticalBar().setSelection(_topItem);\r
279 if (redraw)\r
280 redraw();\r
281 changed = true;\r
282 } else {\r
283 int page = countPerPage();\r
284 if (idx >= _topItem + page) {\r
285 _topItem = idx - page + 1;\r
286 getVerticalBar().setSelection(_topItem);\r
287 if (redraw)\r
288 redraw();\r
289 changed = true;\r
290 }\r
291 }\r
292 return changed;\r
293 }\r
294\r
295 public ISelection getSelection() {\r
296 PlainSelection sel = new PlainSelection();\r
297 ITmfTimeAnalysisEntry trace = getSelectedTrace();\r
298 if (null != trace && null != _timeProvider) {\r
299 long selectedTime = _timeProvider.getSelectedTime();\r
300 ITimeEvent event = Utils.findEvent(trace, selectedTime, 0);\r
301 if (event != null)\r
302 sel.add(event);\r
303 else\r
304 sel.add(trace);\r
305 }\r
306 return sel;\r
307 }\r
308\r
309 public ISelection getSelectionTrace() {\r
310 PlainSelection sel = new PlainSelection();\r
311 ITmfTimeAnalysisEntry trace = getSelectedTrace();\r
312 if (null != trace) {\r
313 sel.add(trace);\r
314 }\r
315 return sel;\r
316 }\r
317\r
318 public void selectTrace(int n) {\r
319 if (n != 1 && n != -1)\r
320 return;\r
321 boolean changed = false;\r
322 int lastSelection = -1;\r
323 for (int i = 0; i < _data._items.length; i++) {\r
324 Item item = (Item) _data._items[i];\r
325 if (item._selected) {\r
326 lastSelection = i;\r
327 if (1 == n && i < _data._items.length - 1) {\r
328 item._selected = false;\r
329 if (item._hasChildren)\r
330 _data.expandItem(i, true);\r
331 item = (Item) _data._items[i + 1];\r
332 if (item._hasChildren) {\r
333 _data.expandItem(i + 1, true);\r
334 item = (Item) _data._items[i + 2];\r
335 }\r
336 item._selected = true;\r
337 changed = true;\r
338 } else if (-1 == n && i > 0) {\r
339 i--;\r
340 Item prevItem = (Item) _data._items[i];\r
341 if (prevItem._hasChildren) {\r
342 if (prevItem._expanded) {\r
343 if (i > 0) {\r
344 i--;\r
345 prevItem = (Item) _data._items[i];\r
346 }\r
347 }\r
348 if (!prevItem._expanded) {\r
349 int added = _data.expandItem(i, true);\r
350 prevItem = (Item) _data._items[i + added];\r
351 item._selected = false;\r
352 prevItem._selected = true;\r
353 changed = true;\r
354 }\r
355 } else {\r
356 item._selected = false;\r
357 prevItem._selected = true;\r
358 changed = true;\r
359 }\r
360 }\r
361 break;\r
362 }\r
363 }\r
364 if (lastSelection < 0 && _data._items.length > 0) {\r
365 Item item = (Item) _data._items[0];\r
366 if (item._hasChildren) {\r
367 _data.expandItem(0, true);\r
368 item = (Item) _data._items[1];\r
369 item._selected = true;\r
370 changed = true;\r
371 } else {\r
372 item._selected = true;\r
373 changed = true;\r
374 }\r
375 }\r
376 if (changed) {\r
377 ensureVisibleItem(-1, false);\r
378 redraw();\r
379 fireSelectionChanged();\r
380 }\r
381 }\r
382\r
383 public void selectEvent(int n) {\r
384 if (null == _timeProvider)\r
385 return;\r
386 ITmfTimeAnalysisEntry trace = getSelectedTrace();\r
a5823d5f 387 if (trace == _timeProvider || trace == null)\r
b0d3496e
ASL
388 return;\r
389 long selectedTime = _timeProvider.getSelectedTime();\r
390 long endTime = _timeProvider.getEndTime();\r
391 ITimeEvent nextEvent;\r
a5823d5f 392 if (-1 == n && selectedTime > endTime)\r
b0d3496e
ASL
393 nextEvent = Utils.findEvent(trace, selectedTime, 0);\r
394 else\r
395 nextEvent = Utils.findEvent(trace, selectedTime, n);\r
396 if (null == nextEvent && -1 == n)\r
397 nextEvent = Utils.getFirstEvent(trace);\r
398 if (null != nextEvent) {\r
a72a38d9
ASL
399 long nextTime = nextEvent.getTime();\r
400 // If last event detected e.g. going back or not moving to a next event\r
401 if (nextTime <= selectedTime && n == 1) {\r
402 // Select to the end of this last event\r
403 nextTime = nextEvent.getTime() + nextEvent.getDuration();\r
404 // but not beyond the end of the trace\r
405 if (nextTime > endTime) {\r
406 nextTime = endTime;\r
407 }\r
408 }\r
409 _timeProvider.setSelectedTimeInt(nextTime, true);\r
b0d3496e
ASL
410 fireSelectionChanged();\r
411 } else if (1 == n) {\r
412 _timeProvider.setSelectedTimeInt(endTime, true);\r
413 fireSelectionChanged();\r
414 }\r
415 }\r
416\r
417 public void selectNextEvent() {\r
418 selectEvent(1);\r
a72a38d9
ASL
419 // Notify if visible time window has been adjusted\r
420 _timeProvider.setStartFinishTimeNotify(_timeProvider.getTime0(), _timeProvider.getTime1());\r
b0d3496e
ASL
421 }\r
422\r
423 public void selectPrevEvent() {\r
424 selectEvent(-1);\r
a72a38d9
ASL
425 // Notify if visible time window has been adjusted\r
426 _timeProvider.setStartFinishTimeNotify(_timeProvider.getTime0(), _timeProvider.getTime1());\r
b0d3496e
ASL
427 }\r
428\r
429 public void selectNextTrace() {\r
430 selectTrace(1);\r
431 }\r
432\r
433 public void selectPrevTrace() {\r
434 selectTrace(-1);\r
435 }\r
436\r
a5823d5f
ASL
437 /**\r
438 * Zooming based on mouse cursor location with mouse scrolling\r
439 * \r
440 * @param zoomIn\r
441 */\r
442 public void zoom(boolean zoomIn) {\r
443 int globalX = getDisplay().getCursorLocation().x;\r
444 Point p = toControl(globalX, 0);\r
445 int nameSpace = _timeProvider.getNameSpace();\r
446 int timeSpace = _timeProvider.getTimeSpace();\r
447 int xPos = Math.max(nameSpace, Math.min(nameSpace + timeSpace, p.x));\r
448 long time0 = _timeProvider.getTime0();\r
449 long time1 = _timeProvider.getTime1();\r
450 long interval = time1 - time0;\r
451 if (interval == 0) {\r
452 interval = 1;\r
453 } // to allow getting out of single point interval\r
454 long newInterval;\r
455 if (zoomIn) {\r
456 newInterval = Math.max(Math.round((double) interval * 0.8), _timeProvider.getMinTimeInterval());\r
457 } else {\r
458 newInterval = Math.round((double) interval * 1.25);\r
459 }\r
460 long center = time0 + Math.round(((double) (xPos - nameSpace) / timeSpace * interval));\r
461 long newTime0 = center - Math.round((double) newInterval * (center - time0) / interval);\r
462 long newTime1 = newTime0 + newInterval;\r
463 _timeProvider.setStartFinishTime(newTime0, newTime1);\r
464 }\r
465\r
466 /**\r
467 * zoom in using single click\r
468 */\r
b0d3496e
ASL
469 public void zoomIn() {\r
470 long _time0 = _timeProvider.getTime0();\r
471 long _time1 = _timeProvider.getTime1();\r
472 long _range = _time1 - _time0;\r
473 long selTime = _timeProvider.getSelectedTime();\r
474 if (selTime <= _time0 || selTime >= _time1) {\r
475 selTime = (_time0 + _time1) / 2;\r
476 }\r
477 long time0 = selTime - (long) ((selTime - _time0) / zoomCoeff);\r
478 long time1 = selTime + (long) ((_time1 - selTime) / zoomCoeff);\r
479\r
480 long inaccuracy = (_timeProvider.getMaxTime() - _timeProvider\r
481 .getMinTime())\r
482 - (time1 - time0);\r
483\r
484 // Trace.debug("selTime:" + selTime + " time0:" + time0 + " time1:"\r
485 // + time1 + " inaccuracy:" + inaccuracy);\r
486\r
487 if (inaccuracy > 0 && inaccuracy < 100) {\r
71c964eb 488 _timeProvider.setStartFinishTimeNotify(_timeProvider.getMinTime(),\r
b0d3496e
ASL
489 _timeProvider.getMaxTime());\r
490 return;\r
491 }\r
492\r
493 long m = _timeProvider.getMinTimeInterval();\r
494 if ((time1 - time0) < m) {\r
495 time0 = selTime - (long) ((selTime - _time0) * m / _range);\r
496 time1 = time0 + m;\r
497 }\r
498\r
71c964eb 499 _timeProvider.setStartFinishTimeNotify(time0, time1);\r
b0d3496e
ASL
500 }\r
501\r
a5823d5f
ASL
502 /**\r
503 * zoom out using single click\r
504 */\r
b0d3496e
ASL
505 public void zoomOut() {\r
506 long _time0 = _timeProvider.getTime0();\r
507 long _time1 = _timeProvider.getTime1();\r
508 long selTime = _timeProvider.getSelectedTime();\r
509 if (selTime <= _time0 || selTime >= _time1) {\r
510 selTime = (_time0 + _time1) / 2;\r
511 }\r
512 long time0 = (long) (selTime - (selTime - _time0) * zoomCoeff);\r
513 long time1 = (long) (selTime + (_time1 - selTime) * zoomCoeff);\r
514\r
515 long inaccuracy = (_timeProvider.getMaxTime() - _timeProvider\r
516 .getMinTime())\r
517 - (time1 - time0);\r
518 if (inaccuracy > 0 && inaccuracy < 100) {\r
71c964eb 519 _timeProvider.setStartFinishTimeNotify(_timeProvider.getMinTime(),\r
b0d3496e
ASL
520 _timeProvider.getMaxTime());\r
521 return;\r
522 }\r
523\r
71c964eb 524 _timeProvider.setStartFinishTimeNotify(time0, time1);\r
b0d3496e
ASL
525 }\r
526\r
527 public void groupTraces(boolean on) {\r
528 _data.groupTraces(on);\r
529 adjustScrolls();\r
530 redraw();\r
531 }\r
532\r
533 public void toggleTraceInteractionDrawing() {\r
534 drawTracesInteraction = !drawTracesInteraction;\r
535 redraw();\r
536 }\r
537\r
538 public void setTraceJoinDrawing(boolean on) {\r
539 drawTraceJoins = on;\r
540 drawTracesInteraction = true;\r
541 redraw();\r
542 }\r
543\r
544 public void setTraceWaitDrawing(boolean on) {\r
545 drawTraceWaits = on;\r
546 drawTracesInteraction = true;\r
547 redraw();\r
548 }\r
549\r
550 public void setTraceReleaseDrawing(boolean on) {\r
551 drawTraceReleases = on;\r
552 drawTracesInteraction = true;\r
553 redraw();\r
554 }\r
555\r
556 public boolean getTracesInteractionDrawing() {\r
557 return drawTracesInteraction;\r
558 }\r
559\r
560 public boolean getTraceJoinDrawing() {\r
561 return drawTraceJoins;\r
562 }\r
563\r
564 public boolean getTraceWaitDrawing() {\r
565 return drawTraceWaits;\r
566 }\r
567\r
568 public boolean getTraceReleaseDrawing() {\r
569 return drawTraceReleases;\r
570 }\r
571\r
572 public ITmfTimeAnalysisEntry getSelectedTrace() {\r
573 ITmfTimeAnalysisEntry trace = null;\r
574 int idx = getSelectedIndex();\r
575 if (idx >= 0 && _data._items[idx] instanceof TraceItem)\r
576 trace = ((TraceItem) _data._items[idx])._trace;\r
577 return trace;\r
578 }\r
579\r
580 public int getSelectedIndex() {\r
581 int idx = -1;\r
582 for (int i = 0; i < _data._items.length; i++) {\r
583 Item item = (Item) _data._items[i];\r
584 if (item._selected) {\r
585 idx = i;\r
586 break;\r
587 }\r
588 }\r
589 return idx;\r
590 }\r
591\r
592 boolean toggle(int idx) {\r
593 boolean toggled = false;\r
594 if (idx >= 0 && idx < _data._items.length) {\r
595 Item item = (Item) _data._items[idx];\r
596 if (item._hasChildren) {\r
597 item._expanded = !item._expanded;\r
598 _data.updateItems();\r
599 adjustScrolls();\r
600 redraw();\r
601 toggled = true;\r
602 }\r
603 }\r
604 return toggled;\r
605 }\r
606\r
607 int hitTest(int x, int y) {\r
608 if (x < 0 || y < 0)\r
609 return -1;\r
610 int hit = -1;\r
611 int idx = y / _itemHeight;\r
612 idx += _topItem;\r
613 if (idx < _data._items.length)\r
614 hit = idx;\r
615 return hit;\r
616 }\r
617\r
618 int hitSplitTest(int x, int y) {\r
619 if (x < 0 || y < 0 || null == _timeProvider)\r
620 return -1;\r
621 int w = 4;\r
622 int hit = -1;\r
623 int nameWidth = _timeProvider.getNameSpace();\r
624 if (x > nameWidth - w && x < nameWidth + w)\r
625 hit = 1;\r
626 return hit;\r
627 }\r
628\r
629 public Item getItem(Point pt) {\r
630 int idx = hitTest(pt.x, pt.y);\r
631 return idx >= 0 ? (Item) _data._items[idx] : null;\r
632 }\r
633\r
634 long hitTimeTest(int x, int y) {\r
635 if (null == _timeProvider)\r
636 return -1;\r
637 long hitTime = -1;\r
638 Point size = getCtrlSize();\r
639 long time0 = _timeProvider.getTime0();\r
640 long time1 = _timeProvider.getTime1();\r
641 int nameWidth = _timeProvider.getNameSpace();\r
642 x -= nameWidth;\r
643 if (x >= 0 && size.x >= nameWidth) {\r
8b9fa226
ASL
644 if (time1 - time0 > size.x - nameWidth - RIGHT_MARGIN) {\r
645 // get the last possible time represented by the pixel position\r
646 // by taking the time of the next pixel position minus 1 nanosecond\r
647 hitTime = time0 + (long) ((time1 - time0) * ((double) (x + 1) / (size.x - nameWidth - RIGHT_MARGIN))) - 1;\r
648 } else {\r
649 hitTime = time0 + (long) ((time1 - time0) * ((double) (x) / (size.x - nameWidth - RIGHT_MARGIN)));\r
650 }\r
b0d3496e
ASL
651 }\r
652 return hitTime;\r
653 }\r
654\r
655 void selectItem(int idx, boolean addSelection) {\r
656 if (addSelection) {\r
657 if (idx >= 0 && idx < _data._items.length) {\r
658 Item item = (Item) _data._items[idx];\r
659 item._selected = true;\r
660 }\r
661 } else {\r
662 for (int i = 0; i < _data._items.length; i++) {\r
663 Item item = (Item) _data._items[i];\r
664 item._selected = i == idx;\r
665 }\r
666 }\r
667 boolean changed = ensureVisibleItem(idx, true);\r
668 if (!changed)\r
669 redraw();\r
670 }\r
671\r
672 public void selectItem(ITmfTimeAnalysisEntry trace, boolean addSelection) {\r
673 Integer idx = _data.findTraceItemIndex(trace);\r
674 selectItem(idx, addSelection);\r
675 }\r
676\r
677 public int countPerPage() {\r
678 int height = getCtrlSize().y;\r
679 int count = 0;\r
680 if (height > 0)\r
681 count = height / _itemHeight;\r
682 return count;\r
683 }\r
684\r
685 public int getTopIndex() {\r
686 int idx = -1;\r
687 if (_data._items.length > 0)\r
688 idx = 0;\r
689 return idx;\r
690 }\r
691\r
692 public int getBottomIndex() {\r
693 int idx = _data._items.length - 1;\r
694 return idx;\r
695 }\r
696\r
697 Point getCtrlSize() {\r
698 Point size = getSize();\r
8b9fa226
ASL
699 if (getVerticalBar().isVisible()) {\r
700 size.x -= getVerticalBar().getSize().x;\r
701 }\r
702 if (getHorizontalBar().isVisible()) {\r
703 size.y -= getHorizontalBar().getSize().y;\r
704 }\r
b0d3496e
ASL
705 return size;\r
706 }\r
707\r
708 void getNameRect(Rectangle rect, Rectangle bound, int idx, int nameWidth) {\r
709 idx -= _topItem;\r
710 rect.x = bound.x;\r
711 rect.y = bound.y + idx * _itemHeight;\r
712 rect.width = nameWidth;\r
713 rect.height = _itemHeight;\r
714 }\r
715\r
716 void getStatesRect(Rectangle rect, Rectangle bound, int idx, int nameWidth) {\r
717 idx -= _topItem;\r
718 rect.x = bound.x + nameWidth;\r
719 rect.y = bound.y + idx * _itemHeight;\r
720 rect.width = bound.width - rect.x;\r
721 rect.height = _itemHeight;\r
722 }\r
723\r
724 // private int getTraceNumber(int tid) {\r
725 // int num = -1;\r
726 //\r
727 // Object[] items = _data._items;\r
728 // for (int i = _topItem; i < items.length; i++) {\r
729 // Item item = (Item) items[i];\r
730 // if ((item instanceof TraceItem)) {\r
731 // TsfTmTrace trace = ((TraceItem) item)._trace;\r
732 // if (trace != null && trace.getId() == tid) {\r
733 // num = i;\r
734 // break;\r
735 // }\r
736 // }\r
737 // }\r
738 //\r
739 // return num;\r
740 // }\r
741\r
742 // private void drawArrow(GC gc, int x0, int y0, int x1, int y1, Color c) {\r
743 // gc.setForeground(c);\r
744 // gc.drawLine(x0, y0, x1, y1);\r
745 //\r
746 // if (y1 > y0) {\r
747 // gc.drawLine(x1 - 3, y1 - 3, x1, y1);\r
748 // gc.drawLine(x1 + 3, y1 - 3, x1, y1);\r
749 // } else {\r
750 // gc.drawLine(x1 - 3, y1 + 3, x1, y1);\r
751 // gc.drawLine(x1 + 3, y1 + 3, x1, y1);\r
752 // }\r
753 // }\r
754\r
755 // TODO: CC: used in the removed functionality to draw thread interactions.\r
756 // private void drawTraceThreadEvent(Rectangle bound, TsfTmEvent e,\r
757 // TsfTmTrace trace, int nItem, int color, GC gc) {\r
758 // if (trace == null)\r
759 // return;\r
760 //\r
761 // int tid = trace.getId();\r
762 // if (tid < 0 || getTraceNumber(tid) == -1)\r
763 // return;\r
764 //\r
765 // int nameWidth = _timeProvider.getNameSpace();\r
766 //\r
767 // double time0 = _timeProvider.getTime0();\r
768 // double time1 = _timeProvider.getTime1();\r
769 // if (time0 == time1)\r
770 // return;\r
771 //\r
772 // int xr = bound.x + nameWidth;\r
773 // double K = (double) (bound.width - xr) / (time1 - time0);\r
774 //\r
775 // int x0 = xr + (int) ((e.getTime() - time0) * K);\r
776 // if (x0 < xr)\r
777 // x0 = xr;\r
778 //\r
779 // int x1 = xr + (int) ((trace.getStartTime() - time0) * K);\r
780 // if (x1 < xr)\r
781 // return;\r
782 //\r
783 // int y0 = bound.y + (nItem - _topItem) * _itemHeight + 3\r
784 // + (_itemHeight - 6) / 2;\r
785 // int y1 = bound.y + (getTraceNumber(tid) - _topItem) * _itemHeight + 3\r
786 // + (_itemHeight - 6) / 2;\r
787 //\r
788 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));\r
789 // }\r
790\r
791 public void drawTraceEvent(Rectangle bound, ITimeEvent e, int nItem,\r
792 int color, GC gc) {\r
793 int nameWidth = _timeProvider.getNameSpace();\r
794\r
795 long time0 = _timeProvider.getTime0();\r
796 long time1 = _timeProvider.getTime1();\r
797 if (time0 == time1)\r
798 return;\r
799\r
800 int xr = bound.x + nameWidth;\r
8b9fa226
ASL
801 double pixelsPerNanoSec = (bound.width - xr <= RIGHT_MARGIN) ? 0\r
802 : (double) (bound.width - xr - RIGHT_MARGIN) / (time1 - time0);\r
b0d3496e 803\r
a5823d5f 804 int x0 = xr + (int) ((e.getTime() - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
805 if (x0 < xr)\r
806 return;\r
807\r
808 int y0 = bound.y + (nItem - _topItem) * _itemHeight + 3;\r
809\r
810 gc.setBackground(_colors.getColor(color));\r
811 int c[] = { x0 - 3, y0 - 3, x0, y0, x0 + 3, y0 - 3 };\r
812 gc.fillPolygon(c);\r
813 }\r
814\r
815 // TODO: CC:\r
816 // private void drawExecEvent(Rectangle bound, TsfTmTraceExecEventImpl e,\r
817 // int nitem, int color, GC gc) {\r
818 // List runnings = e.getRunningEvents();\r
819 // if (runnings == null)\r
820 // return;\r
821 //\r
822 // int nameWidth = _timeProvider.getNameSpace();\r
823 //\r
824 // double time0 = _timeProvider.getTime0();\r
825 // double time1 = _timeProvider.getTime1();\r
826 // if (time0 == time1)\r
827 // return;\r
828 //\r
829 // int xr = bound.x + nameWidth;\r
830 // double K = (double) (bound.width - xr) / (time1 - time0);\r
831 //\r
832 // int x0 = xr + (int) ((e.getTime() - time0) * K);\r
833 // if (x0 < xr)\r
834 // x0 = xr;\r
835 //\r
836 // Iterator it = runnings.iterator();\r
837 // while (it.hasNext()) {\r
838 // TsfTmTraceRunningEventImpl re = (TsfTmTraceRunningEventImpl) it\r
839 // .next();\r
840 // int tid = re.getThread().getId();\r
841 // if (tid < 0 || getThreadNumber(tid) == -1)\r
842 // continue;\r
843 //\r
844 // int x1 = xr + (int) ((re.getTime() - time0) * K);\r
845 // if (x1 < xr)\r
846 // continue;\r
847 //\r
848 // int y0 = bound.y + (nitem - _topItem) * _itemHeight + 3\r
849 // + (_itemHeight - 6) / 2;\r
850 // int y1 = bound.y + (getThreadNumber(tid) - _topItem) * _itemHeight\r
851 // + 3 + (_itemHeight - 6) / 2;\r
852 //\r
853 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));\r
854 // }\r
855 // }\r
856\r
857 public void drawTraceInteractions(Rectangle bound, GC gc) {\r
858 // int nameWidth = _timeProvider.getNameSpace();\r
859 // Object[] items = _data._items;\r
860 //\r
861 // double time0 = _timeProvider.getTime0();\r
862 // double time1 = _timeProvider.getTime1();\r
863 //\r
864 // if (time0 == time1)\r
865 // return;\r
866 //\r
867 // int xr = bound.x + nameWidth;\r
868 // double K = (double) (bound.width - xr) / (time1 - time0);\r
869\r
870 // for (int i = 0; i < items.length; i++) {\r
871 // Item item = (Item) items[i];\r
872 // if (!(item instanceof TraceItem))\r
873 // continue;\r
874 //\r
875 // TsfTmTrace trace = ((TraceItem) item)._trace;\r
876 // if (trace == null)\r
877 // continue;\r
878 //\r
879 // List<TsfTmEvent> list = trace.getTraceEvents();\r
880 // Iterator<TsfTmEvent> it = list.iterator();\r
881 // while (it.hasNext()) {\r
882 // TsfTmEvent te = (TsfTmEvent) it.next();\r
883 // TODO: CC: Thread Interactions,\r
884 // This needs to be accessed externally via a specific\r
885 // implementation.\r
886 // if (te instanceof TsfTmTraceStartThreadEventImpl) {\r
887 // TsfTmTrace child = ((TsfTmTraceStartThreadEventImpl) te)\r
888 // .getStartedThread();\r
889 // drawThreadThreadEvent(bound, te, child, i,\r
890 // TraceColorScheme.TI_START_THREAD, gc);\r
891 // } else if (te instanceof TsfTmTraceHandoffLockEventImpl) {\r
892 // if (drawThreadReleases)\r
893 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,\r
894 // TraceColorScheme.TI_HANDOFF_LOCK, gc);\r
895 // } else if (te instanceof TsfTmTraceNotifyAllEventImpl) {\r
896 // if (drawThreadWaits)\r
897 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,\r
898 // TraceColorScheme.TI_NOTIFY_ALL, gc);\r
899 // } else if (te instanceof TsfTmTraceNotifyEventImpl) {\r
900 // if (drawThreadWaits)\r
901 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,\r
902 // TraceColorScheme.TI_NOTIFY, gc);\r
903 // } else if (te instanceof\r
904 // TsfTmTraceDeadAndNotifyJoinedEventImpl) {\r
905 // if (drawThreadJoins)\r
906 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,\r
907 // TraceColorScheme.TI_NOTIFY_JOINED, gc);\r
908 // } else if (te instanceof TsfTmTraceInterruptThreadEventImpl)\r
909 // {\r
910 // if (drawThreadWaits)\r
911 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,\r
912 // TraceColorScheme.TI_INTERRUPT, gc);\r
913 // } else if (te instanceof\r
914 // TsfTmTraceWaitTimeoutExceedEventImpl) {\r
915 // drawThreadEvent(bound, te, i,\r
916 // TraceColorScheme.TI_WAIT_EXCEEDED, gc);\r
917 // }\r
918 // }\r
919 // }\r
920 }\r
921\r
4e3aa37d 922 @Override\r
b0d3496e 923 void paint(Rectangle bound, PaintEvent e) {\r
a5823d5f
ASL
924 GC gc = e.gc;\r
925 gc.setBackground(_colors.getColor(TraceColorScheme.BACKGROUND));\r
926 drawBackground(gc, bound.x, bound.y, bound.width, bound.height);\r
b0d3496e
ASL
927\r
928 if (bound.width < 2 || bound.height < 2 || null == _timeProvider)\r
929 return;\r
930\r
931 _idealNameWidth = 0;\r
932 int nameWidth = _timeProvider.getNameSpace();\r
933 long time0 = _timeProvider.getTime0();\r
934 long time1 = _timeProvider.getTime1();\r
935 long endTime = _timeProvider.getEndTime();\r
936 long selectedTime = _timeProvider.getSelectedTime();\r
937 // draw trace states\r
938 Object[] items = _data._items;\r
939 for (int i = _topItem; i < items.length; i++) {\r
940 Item item = (Item) items[i];\r
6b4f40e9 941 \r
b0d3496e
ASL
942 getNameRect(_rect0, bound, i, nameWidth);\r
943 if (_rect0.y >= bound.y + bound.height)\r
944 break;\r
945\r
946 if (item instanceof GroupItem) {\r
947 getStatesRect(_rect1, bound, i, nameWidth);\r
948 _rect0.width += _rect1.width;\r
949 drawName(item, _rect0, gc);\r
950 } else {\r
951 drawName(item, _rect0, gc);\r
952 }\r
953 getStatesRect(_rect0, bound, i, nameWidth);\r
954 drawItemDataDurations(item, _rect0, time0, time1, endTime,\r
955 selectedTime, gc);\r
956 }\r
957\r
958 if (drawTracesInteraction)\r
959 drawTraceInteractions(bound, e.gc);\r
960\r
961 // draw drag line, no line if name space is 0.\r
962 if (3 == _dragState) {\r
963 gc.setForeground(_colors.getColor(TraceColorScheme.BLACK));\r
964 gc.drawLine(bound.x + nameWidth, bound.y, bound.x + nameWidth,\r
965 bound.y + bound.height - 1);\r
966 } else if (0 == _dragState && _mouseHover\r
967 && _timeProvider.getNameSpace() > 0) {\r
968 gc.setForeground(_colors.getColor(TraceColorScheme.RED));\r
969 gc.drawLine(bound.x + nameWidth, bound.y, bound.x + nameWidth,\r
970 bound.y + bound.height - 1);\r
971 }\r
972 }\r
973\r
974 void drawName(Item item, Rectangle rect, GC gc) {\r
975 // No name to be drawn\r
976 if (_timeProvider.getNameSpace() == 0)\r
977 return;\r
978 boolean group = item instanceof GroupItem;\r
979\r
980 int elemHeight = rect.height / 2;\r
981 int elemWidth = elemHeight;\r
982 String name = item._name;\r
983 if (group) {\r
984 gc.setBackground(_colors\r
985 .getBkColorGroup(item._selected, _isInFocus));\r
986 gc.fillRectangle(rect);\r
987 if (item._selected && _isInFocus) {\r
988 gc.setForeground(_colors.getBkColor(item._selected, _isInFocus,\r
989 false));\r
990 gc.drawRectangle(rect.x, rect.y, rect.width - 2,\r
991 rect.height - 2);\r
992 }\r
993 gc.setForeground(_colors.getBkColor(false, false, false));\r
994 gc.drawLine(rect.x, rect.y + rect.height - 1, rect.width - 1,\r
995 rect.y + rect.height - 1);\r
996 gc.setForeground(_colors.getFgColorGroup(false, false));\r
997 gc.setBackground(_colors.getBkColor(false, false, false));\r
998 Utils.init(_rect1, rect);\r
999 _rect1.x += MARGIN;\r
1000 _rect1.y += (rect.height - elemHeight) / 2;\r
1001 _rect1.width = elemWidth;\r
1002 _rect1.height = elemHeight;\r
1003 // Get the icon rectangle in the group items\r
1004 gc.fillRectangle(_rect1);\r
1005 gc.drawRectangle(_rect1.x, _rect1.y, _rect1.width - 1,\r
1006 _rect1.height - 1);\r
1007 int p = _rect1.y + _rect1.height / 2;\r
1008 gc.drawLine(_rect1.x + 2, p, _rect1.x + _rect1.width - 3, p);\r
1009 if (!item._expanded) {\r
1010 p = _rect1.x + _rect1.width / 2;\r
1011 gc.drawLine(p, _rect1.y + 2, p, _rect1.y + _rect1.height - 3);\r
1012 }\r
1013 gc.setForeground(_colors\r
1014 .getFgColorGroup(item._selected, _isInFocus));\r
1015 elemWidth += MARGIN;\r
1016 } else {\r
1017 gc.setBackground(_colors.getBkColor(item._selected, _isInFocus,\r
1018 true));\r
1019 gc.setForeground(_colors.getFgColor(item._selected, _isInFocus));\r
1020 gc.fillRectangle(rect);\r
1021 Utils.init(_rect1, rect);\r
1022 _rect1.x += MARGIN;\r
1023 // draw icon\r
1024 ITmfTimeAnalysisEntry trace = ((TraceItem) item)._trace;\r
1025 Image img = utilImpl.getItemImage(trace);\r
1026 if (null != img) {\r
1027 _rect1.y += (rect.height - img.getImageData().height) / 2;\r
1028 gc.drawImage(img, _rect1.x, _rect1.y);\r
1029 }\r
1030 elemWidth = SMALL_ICON_SIZE;\r
1031 // cut long string with "..."\r
1032 Point size = gc.stringExtent(name);\r
1033 if (_idealNameWidth < size.x)\r
1034 _idealNameWidth = size.x;\r
1035 int width = rect.width - MARGIN - MARGIN - elemWidth;\r
1036 int cuts = 0;\r
1037 while (size.x > width && name.length() > 1) {\r
1038 cuts++;\r
1039 name = name.substring(0, name.length() - 1);\r
1040 size = gc.stringExtent(name + "...");\r
1041 }\r
1042 if (cuts > 0)\r
1043 name += "...";\r
1044 elemWidth += MARGIN;\r
1045 }\r
1046 Utils.init(_rect1, rect);\r
1047 int leftMargin = MARGIN + elemWidth;\r
1048 _rect1.x += leftMargin;\r
1049 _rect1.width -= leftMargin;\r
1050 int textWidth = 0;\r
1051 // draw text\r
1052 if (_rect1.width > 0) {\r
1053 _rect1.y += 2;\r
1054 textWidth = Utils.drawText(gc, name, _rect1, true) + 8;\r
1055 _rect1.y -= 2;\r
1056 }\r
1057 // draw middle line\r
1058 if (_rect1.width > 0 && !group) {\r
1059 Utils.init(_rect1, rect);\r
1060 _rect1.x += leftMargin + textWidth;\r
1061 _rect1.width -= textWidth;\r
1062 gc.setForeground(_colors.getColor(TraceColorScheme.MID_LINE));\r
1063 int midy = _rect1.y + _rect1.height / 2;\r
1064 gc.drawLine(_rect1.x, midy, _rect1.x + _rect1.width, midy);\r
1065 }\r
1066 // gc.drawLine(_rect1.x + _rect1.width - 1, _rect1.y, _rect1.x +\r
1067 // _rect1.width - 1, _rect1.y + _rect1.height);\r
1068 }\r
1069\r
1070 void drawItemData(Item item, Rectangle rect, long time0, long time1,\r
1071 long endTime, long selectedTime, GC gc) {\r
1072 if (rect.isEmpty())\r
1073 return;\r
1074 if (time1 <= time0) {\r
1075 gc.setBackground(_colors.getBkColor(false, false, false));\r
1076 gc.fillRectangle(rect);\r
1077 return;\r
1078 }\r
1079\r
1080 Utils.init(_rect1, rect);\r
1081 boolean selected = item._selected;\r
8b9fa226
ASL
1082 double pixelsPerNanoSec = (rect.width <= RIGHT_MARGIN) ? 0\r
1083 : (double) (rect.width - RIGHT_MARGIN) / (time1 - time0);\r
b0d3496e
ASL
1084 boolean group = item instanceof GroupItem;\r
1085\r
1086 if (group) {\r
1087 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));\r
1088 // gc.fillRectangle(rect);\r
1089 } else if (item instanceof TraceItem) {\r
1090 ITmfTimeAnalysisEntry trace = ((TraceItem) item)._trace;\r
1091\r
1092 int x0 = rect.x;\r
1093 List<TimeEvent> list = trace.getTraceEvents();\r
1094 // Iterator it = list.iterator();\r
1095 int count = list.size();\r
1096 ITimeEvent lastEvent = null;\r
1097 if (count > 0) {\r
1098 ITimeEvent currEvent = list.get(0);\r
1099 ITimeEvent nextEvent = null;\r
1100 long currEventTime = currEvent.getTime();\r
1101 long nextEventTime = currEventTime;\r
a5823d5f
ASL
1102 x0 = rect.x + (int) ((currEventTime - time0) * pixelsPerNanoSec);\r
1103 int xEnd = rect.x + (int) ((time1 - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1104 int x1 = -1;\r
1105 int idx = 1;\r
1106\r
1107 // reduce rect\r
1108 _rect1.y += 3;\r
1109 _rect1.height -= 6;\r
1110 fillSpace(rect, gc, selected, _rect1.x, x0, xEnd);\r
1111\r
1112 // draw event states\r
1113 while (x0 <= xEnd && null != currEvent) {\r
1114 boolean stopped = false;// currEvent instanceof\r
1115 // TsfTmTraceDeadEvent;\r
1116 if (idx < count) {\r
1117 nextEvent = list.get(idx);\r
1118 nextEventTime = nextEvent.getTime();\r
1119 idx++;\r
1120 } else if (stopped) {\r
1121 nextEvent = null;\r
1122 nextEventTime = time1;\r
1123 } else {\r
1124 nextEvent = null;\r
1125 nextEventTime = endTime;\r
1126 }\r
a5823d5f 1127 x1 = rect.x + (int) ((nextEventTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1128 if (x1 >= rect.x) {\r
1129 _rect1.x = x0 >= rect.x ? x0 : rect.x;\r
1130 _rect1.width = (x1 <= xEnd ? x1 : xEnd) - _rect1.x;\r
1131 boolean timeSelected = currEventTime <= selectedTime\r
1132 && selectedTime < nextEventTime;\r
1133 // Trace.debug("Drawing rectangle: " + _rect1.x + ","\r
1134 // + _rect1.y + "," + _rect1.height + ", "\r
1135 // + _rect1.width + "-->"\r
1136 // + ((int) _rect1.x + (int) _rect1.width));\r
1137 utilImpl.drawState(_colors, currEvent, _rect1, gc,\r
1138 selected, false, timeSelected);\r
1139 }\r
1140 lastEvent = currEvent;\r
1141 currEvent = nextEvent;\r
1142 currEventTime = nextEventTime;\r
1143 x0 = x1;\r
1144 }\r
1145 }\r
1146\r
1147 // fill space after last event\r
1148 int xEnd = rect.x + rect.width;\r
1149 if (x0 < xEnd) {\r
1150 _rect1.x = x0 >= rect.x ? x0 : rect.x;\r
1151 _rect1.width = xEnd - _rect1.x;\r
1152 gc.setBackground(_colors\r
1153 .getBkColor(selected, _isInFocus, false));\r
1154 gc.fillRectangle(_rect1);\r
1155 // draw middle line\r
1156 gc.setForeground(_colors.getColor(utilImpl\r
1157 .getEventColorVal(lastEvent)));\r
1158 int midy = _rect1.y + _rect1.height / 2;\r
1159 int lw = gc.getLineWidth();\r
1160 gc.setLineWidth(2);\r
1161 gc.drawLine(_rect1.x, midy, _rect1.x + _rect1.width, midy);\r
1162 gc.setLineWidth(lw);\r
1163 }\r
1164\r
1165 // draw focus ares\r
1166 Utils.init(_rect1, rect);\r
1167 gc.setForeground(_colors.getBkColor(selected, _isInFocus, false));\r
1168 int y = _rect1.y;\r
1169 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1170 y++;\r
1171 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1172 y++;\r
1173 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1174 y = _rect1.y + _rect1.height - 1;\r
1175 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1176 y--;\r
1177 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1178 y--;\r
1179 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1180 }\r
1181\r
1182 // draw selected time\r
a5823d5f 1183 int x = rect.x + (int) ((selectedTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1184 if (x >= rect.x && x < rect.x + rect.width) {\r
1185 gc.setForeground(_colors.getColor(TraceColorScheme.SELECTED_TIME));\r
1186 if (group)\r
1187 gc.drawLine(x, rect.y + rect.height - 1, x, rect.y\r
1188 + rect.height);\r
1189 else\r
1190 gc.drawLine(x, rect.y, x, rect.y + rect.height);\r
1191 }\r
1192 }\r
1193\r
1194 /**\r
1195 * Represent the event in series of bursts rather than sequence of states\r
1196 * \r
1197 * @param item\r
1198 * @param rect\r
1199 * - The container rectangle to be colored to different states\r
1200 * @param time0\r
1201 * - Base time of all events\r
1202 * @param time1\r
1203 * - End time of all events\r
1204 * @param endTime\r
1205 * @param selectedTime\r
1206 * @param gc\r
1207 */\r
1208 void drawItemDataBurst(Item item, Rectangle rect, long time0, long time1,\r
1209 long endTime, long selectedTime, GC gc) {\r
1210 if (rect.isEmpty())\r
1211 return;\r
1212 if (time1 <= time0) {\r
1213 gc.setBackground(_colors.getBkColor(false, false, false));\r
1214 gc.fillRectangle(rect);\r
1215 return;\r
1216 }\r
1217\r
1218 // Initialize _rect1 to same values as enclosing rectangle rect\r
1219 Utils.init(_rect1, rect);\r
1220 boolean selected = item._selected;\r
1221 // K pixels per second\r
8b9fa226
ASL
1222 double pixelsPerNanoSec = (rect.width <= RIGHT_MARGIN) ? 0\r
1223 : (double) (rect.width - RIGHT_MARGIN) / (time1 - time0);\r
b0d3496e
ASL
1224 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "\r
1225 // + time0 + " time1:" + time1 + " endTime: " + endTime);\r
1226\r
1227 boolean group = item instanceof GroupItem;\r
1228\r
1229 if (group) {\r
1230 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));\r
1231 // gc.fillRectangle(rect);\r
1232 // if (Trace.isDEBUG()) {\r
1233 // Trace.debug("Group");\r
1234 // }\r
1235 } else if (item instanceof TraceItem) {\r
1236 ITmfTimeAnalysisEntry trace = ((TraceItem) item)._trace;\r
1237\r
1238 double x0 = rect.x;\r
1239 List<TimeEvent> list = trace.getTraceEvents();\r
1240 // Iterator it = list.iterator();\r
1241 int count = list.size();\r
1242 ITimeEvent lastEvent = null;\r
1243 // Trace.debug("count is: " + count);\r
1244 if (count > 0) {\r
1245 ITimeEvent currEvent = list.get(0);\r
1246 ITimeEvent nextEvent = null;\r
1247 long currEventTime = currEvent.getTime();\r
1248 long nextEventTime = currEventTime;\r
1249 // x0 - Points to the beginning of the event being drawn\r
a5823d5f 1250 double step = (double) ((currEventTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1251 x0 = rect.x + step;\r
1252 // xEnd - Points to the end of the events rectangle\r
a5823d5f 1253 double xEnd = rect.x + (double) ((time1 - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1254 double x1 = -1;\r
1255 int idx = 1;\r
1256 double xNext = 0;\r
1257\r
1258 // Drawing rectangle is smaller than reserved space\r
1259 _rect1.y += 3;\r
1260 _rect1.height -= 6;\r
1261\r
1262 // Clean up to empty line to draw on top\r
1263 fillSpace(rect, gc, selected, _rect1.x, xEnd, xEnd);\r
1264 // draw event states\r
1265 while (x0 <= xEnd && null != currEvent) {\r
1266 boolean stopped = false;// currEvent instanceof\r
1267 // TsfTmTraceDeadEvent;\r
1268 if (idx < count) {\r
1269 nextEvent = list.get(idx);\r
1270 nextEventTime = nextEvent.getTime();\r
1271 idx++;\r
1272 } else if (stopped) {\r
1273 nextEvent = null;\r
1274 nextEventTime = time1;\r
1275 } else {\r
1276 nextEvent = null;\r
1277 nextEventTime = endTime;\r
1278 // Trace\r
1279 // .debug("nexEventTime is endTime: "\r
1280 // + nextEventTime);\r
1281 }\r
1282\r
1283 // Draw it as a burst, one unit of width.\r
1284 x1 = x0 + (int) 2;\r
1285 if (x1 >= rect.x && x0 <= xEnd) {\r
1286 // Fill with space until x0\r
1287 _rect1.x = (int) (x0 >= rect.x ? x0 : rect.x);\r
1288 _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - _rect1.x);\r
1289 boolean timeSelected = currEventTime <= selectedTime\r
1290 && selectedTime < nextEventTime;\r
1291 utilImpl.drawState(_colors, currEvent, _rect1, gc,\r
1292 selected, false, timeSelected);\r
1293 // Trace.debug("Drawing rectangle: " + _rect1.x + ","\r
1294 // + _rect1.y + "," + _rect1.height + ", "\r
1295 // + _rect1.width + "-->"\r
1296 // + ((int) _rect1.x + (int) _rect1.width));\r
1297 // Advance rectangle to next start position and Fill\r
1298 // with space until next event\r
1299 _rect1.x += _rect1.width;\r
1300 x0 = x1;\r
a5823d5f 1301 xNext = rect.x + (double) ((nextEventTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1302 }\r
1303 // Fill space till next event\r
1304 fillSpace(rect, gc, selected, x0, xNext, xEnd);\r
1305\r
1306 lastEvent = currEvent;\r
1307 currEvent = nextEvent;\r
1308 currEventTime = nextEventTime;\r
1309 // Move x0 to the beginning of next event\r
a5823d5f 1310 x0 = rect.x + (double) ((nextEventTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1311 // Trace.debug("rect.x: " + rect.x + " + " +\r
1312 // "(nextEvenTime: "\r
1313 // + nextEventTime + "- time0: " + time0 + ") * K: "\r
1314 // + K + " = " + x0);\r
1315 }\r
1316 }\r
1317\r
1318 // fill space after last event\r
1319 int xEnd = rect.x + rect.width;\r
1320 if (x0 < xEnd) {\r
1321 // Trace.debug("Space after last event, x0: " + x0 + ", xEnd: "\r
1322 // + xEnd);\r
1323 _rect1.x = (int) (x0 >= rect.x ? x0 : rect.x);\r
1324 _rect1.width = xEnd - _rect1.x;\r
1325 gc.setBackground(_colors\r
1326 .getBkColor(selected, _isInFocus, false));\r
1327 gc.fillRectangle(_rect1);\r
1328 // draw middle line\r
1329 gc.setForeground(_colors.getColor(utilImpl\r
1330 .getEventColorVal(lastEvent)));\r
1331 int midy = _rect1.y + _rect1.height / 2;\r
1332 int lw = gc.getLineWidth();\r
1333 gc.setLineWidth(2);\r
1334 gc.drawLine(_rect1.x, midy, _rect1.x + _rect1.width, midy);\r
1335 gc.setLineWidth(lw);\r
1336 }\r
1337\r
1338 // draw focus area\r
1339 Utils.init(_rect1, rect);\r
1340 gc.setForeground(_colors.getBkColor(selected, _isInFocus, false));\r
1341 int y = _rect1.y;\r
1342 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1343 y++;\r
1344 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1345 y++;\r
1346 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1347 y = _rect1.y + _rect1.height - 1;\r
1348 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1349 y--;\r
1350 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1351 y--;\r
1352 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1353 }\r
1354\r
1355 // draw selected time\r
a5823d5f 1356 int x = rect.x + (int) ((selectedTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1357 if (x >= rect.x && x < rect.x + rect.width) {\r
1358 gc.setForeground(_colors.getColor(TraceColorScheme.SELECTED_TIME));\r
1359 if (group)\r
1360 gc.drawLine(x, rect.y + rect.height - 1, x, rect.y\r
1361 + rect.height);\r
1362 else\r
1363 gc.drawLine(x, rect.y, x, rect.y + rect.height);\r
1364 }\r
1365 }\r
1366\r
1367 /**\r
1368 * Represent the series of events with specified durations\r
1369 * \r
1370 * @param item\r
1371 * @param rect\r
1372 * - The container rectangle to be colored to different states\r
1373 * @param time0\r
1374 * - Base time of all events - start of visible window\r
1375 * @param time1\r
1376 * - End time of visible events - end time of visible window\r
1377 * @param endTime\r
1378 * - End time of all events - may not be visible in selected\r
1379 * visible window\r
1380 * @param selectedTime\r
1381 * @param gc\r
1382 */\r
1383 void drawItemDataDurations(Item item, Rectangle rect, long time0,\r
1384 long time1, long endTime, long selectedTime, GC gc) {\r
1385 if (rect.isEmpty())\r
1386 return;\r
1387 if (time1 <= time0) {\r
1388 gc.setBackground(_colors.getBkColor(false, false, false));\r
1389 gc.fillRectangle(rect);\r
1390 return;\r
1391 }\r
1392\r
1393 // Initialize _rect1 to same values as enclosing rectangle rect\r
1394 Utils.init(_rect1, rect);\r
1395 boolean selected = item._selected;\r
1396 // K pixels per second\r
8b9fa226
ASL
1397 double pixelsPerNanoSec = (rect.width <= RIGHT_MARGIN) ? 0\r
1398 : (double) (rect.width - RIGHT_MARGIN) / (time1 - time0);\r
b0d3496e
ASL
1399 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "\r
1400 // + time0 + " time1:" + time1 + " endTime: " + endTime);\r
1401\r
1402 boolean group = item instanceof GroupItem;\r
1403\r
1404 if (group) {\r
1405 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));\r
1406 // gc.fillRectangle(rect);\r
1407 } else if (item instanceof TraceItem) {\r
1408 ITmfTimeAnalysisEntry trace = ((TraceItem) item)._trace;\r
1409\r
1410 double x0 = rect.x;\r
1411 List<TimeEvent> list = trace.getTraceEvents();\r
1412 // Iterator it = list.iterator();\r
1413 int count = list.size();\r
a5823d5f 1414 // ITimeEvent lastEvent = null;\r
b0d3496e
ASL
1415 // if (Trace.isDEBUG()) {\r
1416 // Trace.debug("\n\t\t\tTrace: " + trace.getName()\r
1417 // + utilImpl.getTraceClassName(trace));\r
1418 // }\r
1419 // Trace.debug("count is: " + count);\r
a5823d5f
ASL
1420 // Drawing rectangle is smaller than reserved space\r
1421 _rect1.y += 3;\r
1422 _rect1.height -= 6;\r
1423\r
1424 // Clean up to empty line to draw on top\r
1425 int xEnd = rect.x + rect.width;\r
1426 fillSpace(rect, gc, selected, _rect1.x, xEnd, xEnd);\r
b0d3496e
ASL
1427 if (count > 0) {\r
1428 ITimeEvent currEvent = list.get(0);\r
1429 ITimeEvent nextEvent = null;\r
1430 long currEventTime = currEvent.getTime();\r
1431 long currEventDuration = currEvent.getDuration();\r
1432 // initial value\r
1433 long nextEventTime = currEventTime;\r
1434 // x0 - Points to the beginning of the event being drawn\r
a5823d5f 1435 double step = (double) ((currEventTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1436 x0 = rect.x + step;\r
1437 // xEnd - Points to the end of the events rectangle\r
1438 double x1 = -1;\r
1439 int idx = 1;\r
1440 double xNext = 0;\r
1441\r
1442 // draw event states\r
a5823d5f 1443 while (/* x0 <= xEnd &&*/ null != currEvent) {\r
b0d3496e
ASL
1444 boolean stopped = false;// currEvent instanceof\r
1445 // refresh current event duration as the loop moves\r
1446 currEventDuration = currEvent.getDuration();\r
1447 // TsfTmTraceDeadEvent;\r
1448 if (idx < count) {\r
1449 nextEvent = list.get(idx);\r
1450 nextEventTime = nextEvent.getTime();\r
1451 idx++;\r
1452 } else if (stopped) {\r
1453 nextEvent = null;\r
1454 nextEventTime = time1;\r
1455 } else {\r
1456 nextEvent = null;\r
1457 nextEventTime = endTime;\r
1458 // Trace\r
1459 // .debug("nexEventTime is endTime: "\r
1460 // + nextEventTime);\r
1461 }\r
1462\r
1463 // Calculate position to next event\r
a5823d5f 1464 xNext = rect.x + (double) ((nextEventTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1465\r
1466 // Calculate end position of current event\r
1467 if (currEventDuration < 0) {\r
a5823d5f
ASL
1468 x1 = rect.x + (double) ((nextEventTime - time0) * pixelsPerNanoSec);\r
1469 } else if (currEventDuration == 0) {\r
1470 x1 = x0;\r
b0d3496e 1471 } else {\r
a5823d5f 1472 x1 = x0 + (double) ((currEventDuration) * pixelsPerNanoSec);\r
b0d3496e
ASL
1473 }\r
1474\r
1475 // If event end position x1 further away than start position\r
1476 // of\r
1477 // next event, cut width till next event\r
1478 // Trace.debug("Next Event Pos: " + xNext\r
1479 // + " End Of Current at: " + x1 + " Event Duration: "\r
1480 // + currEventDuration);\r
a5823d5f
ASL
1481 if (currEventDuration != 0) {\r
1482 x1 = x1 > xNext ? xNext : x1;\r
1483 }\r
b0d3496e
ASL
1484 // if event end boundary is within time range\r
1485 if (x1 >= rect.x && x0 <= xEnd) {\r
a5823d5f
ASL
1486 if (currEventDuration != 0) {\r
1487 x0 = (double) (x0 >= rect.x ? x0 : rect.x);\r
8b9fa226 1488 _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - x0);\r
a5823d5f 1489 } else {\r
8b9fa226 1490 _rect1.width = 2; // make punctual events 2 pixels wide\r
a5823d5f 1491 }\r
b0d3496e
ASL
1492 _rect1.x = (int) x0;\r
1493 boolean timeSelected = currEventTime <= selectedTime\r
1494 && selectedTime < nextEventTime;\r
1495 utilImpl.drawState(_colors, currEvent, _rect1, gc,\r
1496 selected, false, timeSelected);\r
1497 // Trace.debug("Drawing rectangle: " + _rect1.x + ","\r
1498 // + _rect1.y + "," + _rect1.height + ", "\r
1499 // + _rect1.width + "-->"\r
1500 // + ((int) _rect1.x + (int) _rect1.width));\r
1501 // Advance rectangle to next start position and Fill\r
1502 // with space until next event\r
1503 _rect1.x += _rect1.width;\r
1504 x0 = _rect1.x;\r
1505 }\r
1506\r
1507 // Fill space till next event\r
a5823d5f 1508 // fillSpace(rect, gc, selected, x0, xNext, xEnd);\r
b0d3496e 1509\r
a5823d5f 1510 // lastEvent = currEvent;\r
b0d3496e
ASL
1511 currEvent = nextEvent;\r
1512 currEventTime = nextEventTime;\r
1513 // Move x0 to the beginning of next event\r
a5823d5f 1514 x0 = rect.x + (double) ((nextEventTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1515 // Trace.debug("rect.x: " + rect.x + " + " +\r
1516 // "(nextEvenTime: "\r
1517 // + nextEventTime + "- time0: " + time0 + ") * K: "\r
1518 // + K + " = " + x0);\r
1519 }\r
1520 }\r
1521\r
1522 // draw focus area\r
1523 Utils.init(_rect1, rect);\r
1524 gc.setForeground(_colors.getBkColor(selected, _isInFocus, false));\r
1525 int y = _rect1.y;\r
1526 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1527 y++;\r
1528 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1529 y++;\r
1530 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1531 y = _rect1.y + _rect1.height - 1;\r
1532 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1533 y--;\r
1534 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1535 y--;\r
1536 gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
1537 }\r
1538\r
1539 // draw selected time\r
a5823d5f 1540 int x = rect.x + (int) ((double) (selectedTime - time0) * pixelsPerNanoSec);\r
b0d3496e
ASL
1541 if (x >= rect.x && x < rect.x + rect.width) {\r
1542 gc.setForeground(_colors.getColor(TraceColorScheme.SELECTED_TIME));\r
1543 if (group)\r
1544 gc.drawLine(x, rect.y + rect.height - 1, x, rect.y\r
1545 + rect.height);\r
1546 else\r
1547 gc.drawLine(x, rect.y, x, rect.y + rect.height);\r
1548 }\r
1549 }\r
1550\r
1551 private void fillSpace(Rectangle rect, GC gc, boolean selected, double x0,\r
1552 double x1, double xEnd) {\r
1553 // fill space before first event\r
1554 if (x0 >= rect.x && x0 < xEnd) {\r
1555 // _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - x0);\r
1556 // Trace.debug("Drawing Space: " + _rect1.x + "," + _rect1.y + ","\r
1557 // + _rect1.height + ", " + _rect1.width + "--> "\r
1558 // + ((int) _rect1.x + (int) _rect1.width));\r
1559\r
1560 // if (_rect1.width < 0) {\r
1561 // Trace.debug("Incorrect width:" + _rect1.width);\r
1562 // }\r
1563 gc.setBackground(_colors.getBkColor(selected, _isInFocus, false));\r
1564 gc.fillRectangle(_rect1);\r
1565 // draw middle line\r
1566 gc.setForeground(_colors.getColor(TraceColorScheme.MID_LINE));\r
1567 int midy = _rect1.y + _rect1.height / 2;\r
1568 gc.drawLine(_rect1.x, midy, _rect1.x + _rect1.width, midy);\r
1569 } else {\r
1570 // Trace.debug("No space added since, x0 is out of range " + x0\r
1571 // + " rect.x: " + rect.x + " xEnd: " + xEnd);\r
1572 }\r
1573 }\r
1574\r
1575 public void keyTraversed(TraverseEvent e) {\r
1576 if ((e.detail == SWT.TRAVERSE_TAB_NEXT)\r
1577 || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS))\r
1578 e.doit = true;\r
1579 }\r
1580\r
1581 public void keyPressed(KeyEvent e) {\r
1582 int idx = -1;\r
1583 if (SWT.HOME == e.keyCode) {\r
1584 idx = getTopIndex();\r
1585 } else if (SWT.END == e.keyCode) {\r
1586 idx = getBottomIndex();\r
1587 } else if (SWT.ARROW_DOWN == e.keyCode) {\r
1588 idx = getSelectedIndex();\r
1589 if (idx < 0)\r
1590 idx = 0;\r
1591 else if (idx < _data._items.length - 1)\r
1592 idx++;\r
1593 } else if (SWT.ARROW_UP == e.keyCode) {\r
1594 idx = getSelectedIndex();\r
1595 if (idx < 0)\r
1596 idx = 0;\r
1597 else if (idx > 0)\r
1598 idx--;\r
1599 } else if (SWT.ARROW_LEFT == e.keyCode) {\r
1600 selectPrevEvent();\r
1601 } else if (SWT.ARROW_RIGHT == e.keyCode) {\r
1602 selectNextEvent();\r
1603 } else if (SWT.PAGE_DOWN == e.keyCode) {\r
1604 int page = countPerPage();\r
1605 idx = getSelectedIndex();\r
1606 if (idx < 0)\r
1607 idx = 0;\r
1608 idx += page;\r
1609 if (idx >= _data._items.length)\r
1610 idx = _data._items.length - 1;\r
1611 } else if (SWT.PAGE_UP == e.keyCode) {\r
1612 int page = countPerPage();\r
1613 idx = getSelectedIndex();\r
1614 if (idx < 0)\r
1615 idx = 0;\r
1616 idx -= page;\r
1617 if (idx < 0)\r
1618 idx = 0;\r
1619 } else if (SWT.CR == e.keyCode) {\r
1620 idx = getSelectedIndex();\r
1621 if (idx >= 0) {\r
1622 if (_data._items[idx] instanceof TraceItem)\r
1623 fireDefaultSelection();\r
1624 else if (_data._items[idx] instanceof GroupItem)\r
1625 toggle(idx);\r
1626 }\r
1627 idx = -1;\r
1628 }\r
1629 if (idx >= 0) {\r
1630 selectItem(idx, false);\r
1631 fireSelectionChanged();\r
1632 }\r
1633 }\r
1634\r
1635 public void keyReleased(KeyEvent e) {\r
1636 }\r
1637\r
1638 public void focusGained(FocusEvent e) {\r
1639 _isInFocus = true;\r
1640 redraw();\r
a5823d5f 1641 getDisplay().addFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
b0d3496e
ASL
1642 }\r
1643\r
1644 public void focusLost(FocusEvent e) {\r
1645 _isInFocus = false;\r
1646 if (0 != _dragState) {\r
1647 setCapture(false);\r
1648 _dragState = 0;\r
1649 }\r
1650 redraw();\r
a5823d5f 1651 getDisplay().removeFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
b0d3496e
ASL
1652 }\r
1653\r
1654 public boolean isInFocus() {\r
1655 return _isInFocus;\r
1656 }\r
1657\r
1658 public void mouseMove(MouseEvent e) {\r
1659 if (null == _timeProvider)\r
1660 return;\r
1661 Point size = getCtrlSize();\r
1662 if (1 == _dragState) {\r
1663 int nameWidth = _timeProvider.getNameSpace();\r
1664 int x = e.x - nameWidth;\r
1665 if (x > 0 && size.x > nameWidth && _dragX != x) {\r
1666 _dragX = x;\r
8b9fa226
ASL
1667 double pixelsPerNanoSec = (size.x - nameWidth <= RIGHT_MARGIN) ? 0\r
1668 : (double) (size.x - nameWidth - RIGHT_MARGIN) / (_time1bak - _time0bak);\r
a5823d5f 1669 long timeDelta = (long) ((pixelsPerNanoSec == 0) ? 0 : ((_dragX - _dragX0) / pixelsPerNanoSec));\r
b0d3496e
ASL
1670 long time1 = _time1bak - timeDelta;\r
1671 long maxTime = _timeProvider.getMaxTime();\r
1672 if (time1 > maxTime)\r
1673 time1 = maxTime;\r
1674 long time0 = time1 - (_time1bak - _time0bak);\r
1675 if (time0 < _timeProvider.getMinTime()) {\r
1676 time0 = _timeProvider.getMinTime();\r
1677 time1 = time0 + (_time1bak - _time0bak);\r
1678 }\r
1679 _timeProvider.setStartFinishTime(time0, time1);\r
1680 }\r
1681 } else if (3 == _dragState) {\r
1682 _dragX = e.x;\r
1683 _timeProvider.setNameSpace(_hitIdx + _dragX - _dragX0);\r
1684 } else if (0 == _dragState) {\r
1685 boolean mouseHover = hitSplitTest(e.x, e.y) > 0;\r
1686 if (_mouseHover != mouseHover)\r
1687 redraw();\r
1688 _mouseHover = mouseHover;\r
a5823d5f
ASL
1689 // Make sure any time changes are notified to the application e.g.\r
1690 // getting back from the horizontal scroll bar or zoomed using the\r
1691 // mouse wheel\r
8b9fa226 1692 _timeProvider.notifyStartFinishTime();\r
b0d3496e
ASL
1693 }\r
1694 updateCursor(e.x, e.y);\r
1695 }\r
1696\r
1697 public void mouseDoubleClick(MouseEvent e) {\r
1698 if (null == _timeProvider)\r
1699 return;\r
1700 if (1 == e.button) {\r
1701 int idx = hitSplitTest(e.x, e.y);\r
1702 if (idx >= 0) {\r
1703 _timeProvider.setNameSpace(_idealNameWidth + 3 * MARGIN\r
1704 + SMALL_ICON_SIZE);\r
1705 return;\r
1706 }\r
1707 idx = hitTest(e.x, e.y);\r
1708 if (idx >= 0) {\r
1709 selectItem(idx, false);\r
1710 if (_data._items[idx] instanceof TraceItem) {\r
1711 fireDefaultSelection();\r
1712 }\r
1713 }\r
1714 }\r
1715 }\r
1716\r
41dc35d0
FC
1717 /**\r
1718 * <p>\r
1719 * If the x, y position is over the vertical split line (name to time\r
1720 * ranges), then change the cursor to a drag cursor to indicate the user the\r
1721 * possibility of resizing\r
1722 * </p>\r
1723 * \r
1724 * @param x\r
1725 * @param y\r
1726 */\r
b0d3496e 1727 void updateCursor(int x, int y) {\r
41dc35d0
FC
1728 // if Wait cursor not active, check for the need to change to a drag\r
1729 // cursor\r
1730 if (_isWaitCursor == false) {\r
1731 int idx = hitSplitTest(x, y);\r
1732 // No dragcursor is name space is fixed to zero\r
1733 if (idx > 0 && !_isDragCursor3 && _timeProvider.getNameSpace() > 0) {\r
1734 setCursor(_dragCursor3);\r
1735 _isDragCursor3 = true;\r
1736 } else if (idx <= 0 && _isDragCursor3) {\r
1737 setCursor(null);\r
1738 _isDragCursor3 = false;\r
1739 }\r
1740 }\r
1741 }\r
1742\r
1743 /**\r
1744 * Provide the possibilty to control the wait cursor externally e.g. data\r
1745 * requests in progress\r
1746 * \r
1747 * @param waitInd\r
1748 */\r
1749 public void waitCursor(boolean waitInd) {\r
1750 // Update cursor as indicated\r
1751 if (waitInd) {\r
1752 setCursor(_WaitCursor);\r
1753 _isWaitCursor = true;\r
1754 } else {\r
b0d3496e 1755 setCursor(null);\r
41dc35d0 1756 _isWaitCursor = false;\r
b0d3496e 1757 }\r
41dc35d0
FC
1758\r
1759 // Get ready for next mouse move\r
1760 _isDragCursor3 = false;\r
b0d3496e
ASL
1761 }\r
1762\r
1763 public void mouseDown(MouseEvent e) {\r
1764 if (null == _timeProvider)\r
1765 return;\r
1766 int idx;\r
1767 if (1 == e.button) {\r
1768 int namewidth = _timeProvider.getNameSpace();\r
1769 if (namewidth != 0) {\r
1770 idx = hitSplitTest(e.x, e.y);\r
1771 if (idx > 0) {\r
1772 _dragState = 3;\r
1773 _dragX = _dragX0 = e.x;\r
1774 _hitIdx = _timeProvider.getNameSpace();\r
1775 ;\r
1776 _time0bak = _timeProvider.getTime0();\r
1777 _time1bak = _timeProvider.getTime1();\r
1778 redraw();\r
1779 return;\r
1780 }\r
1781 }\r
1782\r
1783 idx = hitTest(e.x, e.y);\r
1784 if (idx >= 0) {\r
1785 if (_data._items[idx] instanceof TraceItem) {\r
1786 long hitTime = hitTimeTest(e.x, e.y);\r
1787 if (hitTime >= 0) {\r
1788 _timeProvider.setSelectedTimeInt(hitTime, false);\r
1789 setCapture(true);\r
1790 _dragState = 1;\r
1791 _dragX = _dragX0 = e.x - _timeProvider.getNameSpace();\r
1792 _time0bak = _timeProvider.getTime0();\r
1793 _time1bak = _timeProvider.getTime1();\r
1794 }\r
1795 } else if (_data._items[idx] instanceof GroupItem) {\r
1796 _hitIdx = idx;\r
1797 _dragState = 2;\r
1798 }\r
1799 selectItem(idx, false);\r
1800 fireSelectionChanged();\r
a5823d5f
ASL
1801 } else {\r
1802 selectItem(idx, false); // clear selection\r
b0d3496e
ASL
1803 }\r
1804 }\r
1805 }\r
1806\r
1807 public void mouseUp(MouseEvent e) {\r
1808 if (0 != _dragState) {\r
1809 setCapture(false);\r
8b9fa226
ASL
1810 if (1 == _dragState) {\r
1811 // Notify time provider to check the need for listener notification\r
1812 _timeProvider.notifyStartFinishTime();\r
1813 } else if (2 == _dragState) {\r
b0d3496e
ASL
1814 if (hitTest(e.x, e.y) == _hitIdx)\r
1815 toggle(_hitIdx);\r
1816 } else if (3 == _dragState) {\r
1817 redraw();\r
1818 }\r
1819 _dragState = 0;\r
1820 }\r
1821 }\r
1822\r
1823 public void controlMoved(ControlEvent e) {\r
1824 }\r
1825\r
1826 public void controlResized(ControlEvent e) {\r
1827 adjustScrolls();\r
1828 }\r
1829\r
1830 public void widgetDefaultSelected(SelectionEvent e) {\r
1831 }\r
1832\r
1833 public void widgetSelected(SelectionEvent e) {\r
1834 if (e.widget == getVerticalBar()) {\r
1835 _topItem = getVerticalBar().getSelection();\r
1836 if (_topItem < 0)\r
1837 _topItem = 0;\r
1838 redraw();\r
1839 } else if (e.widget == getHorizontalBar() && null != _timeProvider) {\r
a5823d5f 1840 int start = getHorizontalBar().getSelection();\r
b0d3496e
ASL
1841 long time0 = _timeProvider.getTime0();\r
1842 long time1 = _timeProvider.getTime1();\r
1843 long timeMin = _timeProvider.getMinTime();\r
1844 long timeMax = _timeProvider.getMaxTime();\r
1845 long delta = timeMax - timeMin;\r
1846\r
1847 long range = time1 - time0;\r
1848 // _timeRangeFixed = true;\r
a5823d5f 1849 time0 = timeMin + (long) (delta * ((double) start / H_SCROLLBAR_MAX));\r
b0d3496e 1850 time1 = time0 + range;\r
a5823d5f
ASL
1851\r
1852 // TODO: Follow-up with Bug 310310\r
1853 // In Linux SWT.DRAG is the only value received\r
1854 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310310\r
1855 if (e.detail == SWT.DRAG) {\r
1856 _timeProvider.setStartFinishTime(time0, time1);\r
1857 } else {\r
1858 _timeProvider.setStartFinishTimeNotify(time0, time1);\r
1859 }\r
b0d3496e
ASL
1860 }\r
1861 }\r
1862\r
1863 public void mouseEnter(MouseEvent e) {\r
1864 }\r
1865\r
1866 public void mouseExit(MouseEvent e) {\r
1867 if (_mouseHover) {\r
1868 _mouseHover = false;\r
1869 redraw();\r
1870 }\r
1871 }\r
1872\r
1873 public void mouseHover(MouseEvent e) {\r
1874 }\r
1875\r
1876 public void mouseScrolled(MouseEvent e) {\r
a5823d5f
ASL
1877 if (!_isInFocus)\r
1878 return;\r
b0d3496e 1879 if (e.count > 0) {\r
a5823d5f 1880 zoom(true);\r
b0d3496e 1881 } else if (e.count < 0) {\r
a5823d5f 1882 zoom(false);\r
b0d3496e
ASL
1883 }\r
1884 }\r
1885\r
1886 public boolean isVisibleVerticalScroll() {\r
1887 return _visibleVerticalScroll;\r
1888 }\r
1889\r
1890 public void setVisibleVerticalScroll(boolean visibleVerticalScroll) {\r
1891 ScrollBar scrollVer = getVerticalBar();\r
1892 if (scrollVer != null) {\r
1893 scrollVer.setVisible(visibleVerticalScroll);\r
1894 }\r
1895 this._visibleVerticalScroll = visibleVerticalScroll;\r
1896 }\r
1897\r
4e3aa37d 1898 @Override\r
b0d3496e
ASL
1899 public int getBorderWidth() {\r
1900 return _borderWidth;\r
1901 }\r
1902\r
1903 public void setBorderWidth(int borderWidth) {\r
1904 this._borderWidth = borderWidth;\r
1905 }\r
1906\r
1907 public int getHeaderHeight() {\r
1908 return _headerHeight;\r
1909 }\r
1910\r
1911 public void setHeaderHeight(int headerHeight) {\r
1912 this._headerHeight = headerHeight;\r
1913 }\r
1914\r
1915 public int getItemHeight() {\r
1916 return _itemHeight;\r
1917 }\r
1918\r
1919 public void setItemHeight(int rowHeight) {\r
1920 this._itemHeight = rowHeight;\r
1921 }\r
1922\r
1923 public Vector<ITmfTimeAnalysisEntry> getFilteredOut() {\r
1924 return _data.getFilteredOut();\r
1925 }\r
1926\r
1927// @Override\r
1928 public void addSelectionChangedListener(ISelectionChangedListener listener) {\r
1929 if (listener != null) {\r
1930 if (!_selectionChangedListeners.contains(listener)) {\r
1931 _selectionChangedListeners.add(listener);\r
1932 }\r
1933 }\r
1934 }\r
1935\r
1936// @Override\r
1937 public void removeSelectionChangedListener(\r
1938 ISelectionChangedListener listener) {\r
1939 if (listener != null) {\r
1940 _selectionChangedListeners.remove(listener);\r
1941 }\r
1942 }\r
1943\r
1944// @Override\r
1945 public void setSelection(ISelection selection) {\r
1946 if (selection instanceof PlainSelection) {\r
1947 PlainSelection sel = (PlainSelection) selection;\r
1948 Object ob = sel.getFirstElement();\r
1949 if (ob instanceof ITmfTimeAnalysisEntry) {\r
1950 ITmfTimeAnalysisEntry trace = (ITmfTimeAnalysisEntry) ob;\r
1951 selectItem(trace, false);\r
1952 }\r
1953 }\r
1954\r
1955 }\r
1956}\r
1957\r
1958class Item {\r
1959 public boolean _expanded;\r
1960 public boolean _selected;\r
1961 public boolean _hasChildren;\r
1962 public String _name;\r
1963\r
1964 Item(String name) {\r
1965 _name = name;\r
1966 }\r
1967\r
4e3aa37d 1968 @Override\r
b0d3496e
ASL
1969 public String toString() {\r
1970 return _name;\r
1971 }\r
1972}\r
1973\r
1974class TraceItem extends Item {\r
1975 public ITmfTimeAnalysisEntry _trace;\r
1976\r
1977 TraceItem(ITmfTimeAnalysisEntry trace, String name) {\r
1978 super(name);\r
1979 _trace = trace;\r
1980 }\r
1981}\r
1982\r
1983class GroupItem extends Item {\r
1984 public List<ITmfTimeAnalysisEntry> _traces;\r
1985\r
1986 GroupItem(String name) {\r
1987 super(name);\r
1988 _traces = new ArrayList<ITmfTimeAnalysisEntry>();\r
1989 _hasChildren = true;\r
1990 }\r
1991\r
1992 void add(ITmfTimeAnalysisEntry trace) {\r
1993 _traces.add(trace);\r
1994 }\r
1995}\r
1996\r
1997class ItemData {\r
1998 public Object[] _items = new Object[0];\r
1999 private Object _traces[] = new Object[0];\r
2000 private boolean traceFilter[] = new boolean[0];\r
2001 private Map<String, GroupItem> _groupTable = new HashMap<String, GroupItem>();\r
2002 private boolean _flatList = false;\r
2003 private TmfTimeAnalysisProvider utilsImp;\r
2004 private Vector<ITmfTimeAnalysisEntry> filteredOut = new Vector<ITmfTimeAnalysisEntry>();\r
2005\r
2006 public ItemData(TmfTimeAnalysisProvider utils) {\r
2007 this.utilsImp = utils;\r
2008 }\r
2009\r
2010 protected void groupTraces(boolean on) {\r
2011 if (_flatList == on) {\r
2012 _flatList = !on;\r
2013 updateItems();\r
2014 }\r
2015 }\r
2016\r
2017 void clearGroups() {\r
2018 Iterator<GroupItem> it = _groupTable.values().iterator();\r
2019 while (it.hasNext()) {\r
2020 GroupItem group = it.next();\r
2021 group._traces.clear();\r
2022 }\r
2023 }\r
2024\r
2025 void deleteEmptyGroups() {\r
2026 Iterator<GroupItem> it = _groupTable.values().iterator();\r
2027 while (it.hasNext()) {\r
2028 GroupItem group = it.next();\r
2029 if (group._traces.size() == 0)\r
2030 it.remove();\r
2031 }\r
2032 }\r
2033\r
2034 TraceItem findTraceItem(ITmfTimeAnalysisEntry trace) {\r
2035 if (trace == null)\r
2036 return null;\r
2037\r
2038 int traceId = trace.getId();\r
2039 TraceItem traceItem = null;\r
2040\r
2041 for (int i = 0; i < _items.length; i++) {\r
2042 Object item = _items[i];\r
2043 if (item instanceof TraceItem) {\r
2044 TraceItem ti = (TraceItem) item;\r
2045 if (ti._trace.getId() == traceId) {\r
2046 traceItem = ti;\r
2047 break;\r
2048 }\r
2049 }\r
2050 }\r
2051\r
2052 return traceItem;\r
2053 }\r
2054\r
2055 Integer findTraceItemIndex(ITmfTimeAnalysisEntry trace) {\r
2056 if (trace == null)\r
2057 return null;\r
2058\r
2059 int traceId = trace.getId();\r
2060\r
2061 Integer idx = null;\r
2062 for (int i = 0; i < _items.length; i++) {\r
2063 idx = i;\r
2064 Object item = _items[i];\r
2065 if (item instanceof TraceItem) {\r
2066 TraceItem ti = (TraceItem) item;\r
2067 if (ti._trace.getId() == traceId) {\r
2068 break;\r
2069 }\r
2070 }\r
2071 }\r
2072\r
2073 return idx;\r
2074 }\r
2075\r
2076 public void updateItems() {\r
2077 List<Item> itemList = new ArrayList<Item>();\r
2078 String name = "";\r
2079\r
2080 Iterator<GroupItem> it = _groupTable.values().iterator();\r
2081 while (it.hasNext()) {\r
2082 GroupItem group = it.next();\r
2083 if (!_flatList)\r
2084 itemList.add(group);\r
2085\r
2086 if (_flatList || group._expanded) {\r
2087 Iterator<ITmfTimeAnalysisEntry> it2 = group._traces.iterator();\r
2088 while (it2.hasNext()) {\r
2089 ITmfTimeAnalysisEntry trace = it2.next();\r
2090 TraceItem traceItem = findTraceItem(trace);\r
2091 name = utilsImp.composeTraceName(trace, false);\r
2092 traceItem = new TraceItem(trace, name);\r
2093 itemList.add(traceItem);\r
2094 }\r
2095 }\r
2096 }\r
2097 _items = itemList.toArray();\r
2098 }\r
2099\r
2100 public int expandItem(int idx, boolean expand) {\r
2101 if (idx < 0 || idx >= _items.length)\r
2102 return 0;\r
2103 int ret = 0;\r
2104 Item item = (Item) _items[idx];\r
2105 if (item._hasChildren && !item._expanded) {\r
2106 item._expanded = expand;\r
2107 ret = _items.length;\r
2108 updateItems();\r
2109 ret = _items.length - ret;\r
2110 }\r
2111 return ret;\r
2112 }\r
2113\r
2114 public void refreshData(Object traces[]) {\r
2115 if (traces == null || traces.length == 0) {\r
2116 traceFilter = null;\r
2117 } else if (traceFilter == null || traces.length != traceFilter.length) {\r
2118 traceFilter = new boolean[traces.length];\r
2119 java.util.Arrays.fill(traceFilter, true);\r
2120 }\r
2121\r
2122 _traces = traces;\r
2123 refreshData();\r
2124 }\r
2125\r
2126 /**\r
2127 * Allows to update the GUI from a stream of events handling addition one by\r
2128 * one over known TmfTaTrace parents.\r
2129 * \r
2130 * @param parent\r
2131 * @param childItem\r
2132 */\r
2133 public void refreshPartial(ITmfTimeAnalysisEntry parent, TimeEvent childItem) {\r
2134 // Find the Trace item within the current list\r
2135 TraceItem item = findTraceItem(parent);\r
2136\r
bbeafe9d
FC
2137// This method is not used (yet) so this code can be commented out for now\r
2138// FIXME: Arrays.copyOf is a Java6 feature\r
2139// if (item == null) {\r
2140// // If the parent item is not found, make room for it in the current\r
2141// // array\r
2142// int length = 1;\r
2143// Object[] traces;\r
2144// if (_traces != null) {\r
2145// length = _traces.length + 1;\r
2146// traces = Arrays.copyOf(_traces, length);\r
2147// } else {\r
2148// traces = new Object[length];\r
2149// }\r
2150//\r
2151// // Add the new parent element to the end of the array.\r
2152// traces[length - 1] = parent;\r
2153//\r
2154// // update the filter array to accomodate a postion to the new\r
2155// // element\r
2156// traceFilter = new boolean[traces.length];\r
2157// java.util.Arrays.fill(traceFilter, true);\r
2158//\r
2159// // rebuild internal data\r
2160// _traces = traces;\r
2161// refreshData();\r
2162//\r
2163// // item must be there\r
2164// item = findTraceItem(parent);\r
2165// }\r
b0d3496e
ASL
2166\r
2167 ITmfTimeAnalysisEntry localTraceItem = item._trace;\r
2168 // Local trace found\r
2169 Vector<TimeEvent> children = localTraceItem.getTraceEvents();\r
2170 TimeEvent lastChildIn = children.lastElement();\r
2171 long lastChildSTime = lastChildIn.getTime();\r
2172 long newChildSTime = childItem.getTime();\r
2173 if (newChildSTime < lastChildSTime) {\r
2174 // The children are expected to arrive sorted by time\r
2175 // since the new time is earlier than the last child\r
2176 // The infomation is being refreshed from start, remove all\r
2177 // children and start over\r
2178 children.clear();\r
2179 }\r
2180 // Add the new item\r
2181 children.add(childItem);\r
2182\r
2183 }\r
2184\r
2185 public void refreshData() {\r
2186 clearGroups();\r
2187 filteredOut.clear();\r
2188 String undef = Messages._UNDEFINED_GROUP;\r
2189 List<GroupItem> groupList = new ArrayList<GroupItem>();\r
2190 for (int i = 0; i < _traces.length; i++) {\r
2191 ITmfTimeAnalysisEntry trace = (ITmfTimeAnalysisEntry) _traces[i];\r
2192 if (!traceFilter[i]) {\r
2193 filteredOut.add(trace);\r
2194 continue;\r
2195 }\r
2196\r
2197 String groupName = trace.getGroupName();\r
2198 if (null == groupName)\r
2199 groupName = undef;\r
2200\r
2201 GroupItem group = _groupTable.get(groupName);\r
2202 if (null == group) {\r
2203 group = new GroupItem(NLS.bind(Messages._TRACE_GROUP_LABEL,\r
2204 groupName));\r
2205 group._expanded = !groupName.equalsIgnoreCase("system")\r
2206 && !groupName.equalsIgnoreCase(undef);\r
2207 _groupTable.put(groupName, group);\r
2208 groupList.add(group);\r
2209 }\r
2210 group.add(trace);\r
2211 }\r
2212\r
2213 deleteEmptyGroups();\r
2214 updateItems();\r
2215 }\r
2216\r
2217 public Object[] getTraces() {\r
2218 return _traces;\r
2219 }\r
2220\r
2221 public boolean[] getTraceFilter() {\r
2222 return traceFilter;\r
2223 }\r
2224\r
2225 public Vector<ITmfTimeAnalysisEntry> getFilteredOut() {\r
2226 return filteredOut;\r
2227 }\r
2228}\r
This page took 0.144725 seconds and 5 git commands to generate.