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