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