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