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