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