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