1 /**********************************************************************
2 * Copyright (c) 2005, 2008 IBM Corporation and others.
3 * Copyright (c) 2011, 2012 Ericsson.
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
11 * IBM - Initial API and implementation
12 * Bernd Hufmann - Updated for TMF
14 **********************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
;
17 import java
.util
.ArrayList
;
18 import java
.util
.Arrays
;
19 import java
.util
.List
;
21 import org
.eclipse
.core
.runtime
.IStatus
;
22 import org
.eclipse
.core
.runtime
.Status
;
23 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.TmfUiPlugin
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
26 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessage
;
27 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessageReturn
;
28 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.BaseMessage
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ExecutionOccurrence
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Frame
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.GraphNode
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ITimeRange
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Lifeline
;
34 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Metrics
;
35 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SDTimeEvent
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SyncMessage
;
37 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IColor
;
38 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.impl
.ColorImpl
;
39 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.SDViewPref
;
40 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.util
.TimeEventComparator
;
41 import org
.eclipse
.swt
.SWT
;
42 import org
.eclipse
.swt
.accessibility
.ACC
;
43 import org
.eclipse
.swt
.accessibility
.Accessible
;
44 import org
.eclipse
.swt
.accessibility
.AccessibleAdapter
;
45 import org
.eclipse
.swt
.accessibility
.AccessibleControlAdapter
;
46 import org
.eclipse
.swt
.accessibility
.AccessibleControlEvent
;
47 import org
.eclipse
.swt
.accessibility
.AccessibleEvent
;
48 import org
.eclipse
.swt
.events
.DisposeEvent
;
49 import org
.eclipse
.swt
.events
.DisposeListener
;
50 import org
.eclipse
.swt
.events
.FocusEvent
;
51 import org
.eclipse
.swt
.events
.FocusListener
;
52 import org
.eclipse
.swt
.events
.KeyEvent
;
53 import org
.eclipse
.swt
.events
.MouseEvent
;
54 import org
.eclipse
.swt
.events
.TraverseEvent
;
55 import org
.eclipse
.swt
.events
.TraverseListener
;
56 import org
.eclipse
.swt
.graphics
.Color
;
57 import org
.eclipse
.swt
.graphics
.GC
;
58 import org
.eclipse
.swt
.graphics
.Image
;
59 import org
.eclipse
.swt
.widgets
.Composite
;
60 import org
.eclipse
.swt
.widgets
.Control
;
61 import org
.eclipse
.swt
.widgets
.Display
;
65 * The time compression bar implementation.
72 public class TimeCompressionBar
extends ScrollView
implements DisposeListener
{
74 // ------------------------------------------------------------------------
76 // ------------------------------------------------------------------------
81 protected List
<ITimeCompressionListener
> fListenerList
= null;
83 * The current frame displayed.
85 protected Frame fFrame
= null;
87 * List of time events.
89 protected List
<SDTimeEvent
> fNodeList
= null;
91 * The minimum time delta.
93 protected ITmfTimestamp fMinTime
= new TmfTimestamp();
95 * The maximum time delta.
97 protected ITmfTimestamp fMaxTime
= new TmfTimestamp();
99 * The current zoom value.
101 protected float fZoomValue
= 1;
103 * The tooltip to display.
105 protected DrawableToolTip fTooltip
= null;
107 * Array of colors for displaying wight of time deltas.
109 protected ColorImpl
[] fColors
;
111 * The accessible object reference.
113 protected Accessible fAccessible
= null;
115 * The focused widget reference.
117 protected int fFocusedWidget
= -1;
119 * The sequence diagram view reference.
121 protected SDView view
= null;
123 * The current lifeline.
125 protected Lifeline fLifeline
= null;
127 * The current start event value.
129 protected int fLifelineStart
= 0;
131 * The current number of events.
133 protected int fLifelineNumEvents
= 0;
135 * The Current color of range to display.
137 protected IColor fLifelineColor
= null;
139 * The next graph node y coordinate.
141 protected int fNextNodeY
= 0;
143 * The previous graph node y coordinate.
145 protected int fPrevNodeY
= 0;
147 // ------------------------------------------------------------------------
149 // ------------------------------------------------------------------------
151 * Standard constructor
153 * @param parent The parent composite
154 * @param s The style bits
156 public TimeCompressionBar(Composite parent
, int s
) {
157 super(parent
, s
| SWT
.NO_BACKGROUND
, false);
158 setVScrollBarMode(ScrollView
.ALWAYS_OFF
);
159 setHScrollBarMode(ScrollView
.ALWAYS_OFF
);
160 fListenerList
= new ArrayList
<ITimeCompressionListener
>();
161 fColors
= new ColorImpl
[10];
162 fColors
[0] = new ColorImpl(Display
.getDefault(), 255, 229, 229);
163 fColors
[1] = new ColorImpl(Display
.getDefault(), 255, 204, 204);
164 fColors
[2] = new ColorImpl(Display
.getDefault(), 255, 178, 178);
165 fColors
[3] = new ColorImpl(Display
.getDefault(), 255, 153, 153);
166 fColors
[4] = new ColorImpl(Display
.getDefault(), 255, 127, 127);
167 fColors
[5] = new ColorImpl(Display
.getDefault(), 255, 102, 102);
168 fColors
[6] = new ColorImpl(Display
.getDefault(), 255, 76, 76);
169 fColors
[7] = new ColorImpl(Display
.getDefault(), 255, 51, 51);
170 fColors
[8] = new ColorImpl(Display
.getDefault(), 255, 25, 25);
171 fColors
[9] = new ColorImpl(Display
.getDefault(), 255, 0, 0);
172 super.addDisposeListener(this);
174 fAccessible
= getViewControl().getAccessible();
176 fAccessible
.addAccessibleListener(new AccessibleAdapter() {
178 public void getName(AccessibleEvent e
) {
180 if (e
.childID
== 0) {
181 if (fTooltip
!= null) {
182 e
.result
= fTooltip
.getAccessibleText();
184 } else if (e
.childID
== 1) {
186 e
.result
= fTooltip
.getAccessibleText();
191 fAccessible
.addAccessibleControlListener(new AccessibleControlAdapter() {
194 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getFocus(org.eclipse.swt.accessibility.AccessibleControlEvent)
197 public void getFocus(AccessibleControlEvent e
) {
198 if (fFocusedWidget
== -1) {
199 e
.childID
= ACC
.CHILDID_SELF
;
202 e
.childID
= fFocusedWidget
;
208 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getRole(org.eclipse.swt.accessibility.AccessibleControlEvent)
211 public void getRole(AccessibleControlEvent e
) {
213 case ACC
.CHILDID_SELF
:
214 e
.detail
= ACC
.ROLE_CLIENT_AREA
;
217 e
.detail
= ACC
.ROLE_TOOLTIP
;
220 e
.detail
= ACC
.ROLE_LABEL
;
229 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getState(org.eclipse.swt.accessibility.AccessibleControlEvent)
232 public void getState(AccessibleControlEvent e
) {
233 e
.detail
= ACC
.STATE_FOCUSABLE
;
234 if (e
.childID
== ACC
.CHILDID_SELF
) {
235 e
.detail
|= ACC
.STATE_FOCUSED
;
237 e
.detail
|= ACC
.STATE_SELECTABLE
;
238 if (e
.childID
== fFocusedWidget
) {
239 e
.detail
|= ACC
.STATE_FOCUSED
| ACC
.STATE_SELECTED
| ACC
.STATE_CHECKED
;
245 getViewControl().addTraverseListener(new LocalTraverseListener());
247 addTraverseListener(new LocalTraverseListener());
249 getViewControl().addFocusListener(new FocusListener() {
253 * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
256 public void focusGained(FocusEvent e
) {
262 * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
265 public void focusLost(FocusEvent e
) {
271 // ------------------------------------------------------------------------
273 // ------------------------------------------------------------------------
276 * Sets the focus widget
278 * @param newFocusShape widget reference to set
280 void setFocus(int newFocusShape
) {
281 fFocusedWidget
= newFocusShape
;
282 if (fFocusedWidget
== -1) {
283 getViewControl().getAccessible().setFocus(ACC
.CHILDID_SELF
);
285 getViewControl().getAccessible().setFocus(fFocusedWidget
);
290 * Sets the current frame.
292 * @param theFrame The frame to set
294 public void setFrame(Frame theFrame
) {
296 fMinTime
= fFrame
.getMinTime();
297 fMaxTime
= fFrame
.getMaxTime();
302 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#drawContents(org.eclipse.swt.graphics.GC, int, int, int, int)
305 protected void drawContents(GC gc
, int clipx
, int clipy
, int clipw
, int cliph
) {
306 if (fFrame
== null) {
309 fNodeList
= new ArrayList
<SDTimeEvent
>();
310 int messageArraysStep
= 1;
312 if ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
< Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1) {
313 messageArraysStep
= Math
.round(Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1 / ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
));
316 int firstVisible
= fFrame
.getFirstVisibleSyncMessage();
317 if (firstVisible
> 0) {
318 firstVisible
= firstVisible
- 1;
320 for (int i
= firstVisible
; i
< fFrame
.syncMessageCount(); i
= i
+ messageArraysStep
) {
321 SyncMessage m
= fFrame
.getSyncMessage(i
);
322 if (m
.hasTimeInfo()) {
323 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), (ITimeRange
) m
);
325 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
331 firstVisible
= fFrame
.getFirstVisibleSyncMessageReturn();
332 if (firstVisible
> 0) {
333 firstVisible
= firstVisible
- 1;
335 for (int i
= firstVisible
; i
< fFrame
.syncMessageReturnCount(); i
= i
+ messageArraysStep
) {
336 SyncMessage m
= fFrame
.getSyncMessageReturn(i
);
337 if (m
.hasTimeInfo()) {
338 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), (ITimeRange
) m
);
340 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
346 firstVisible
= fFrame
.getFirstVisibleAsyncMessage();
347 if (firstVisible
> 0) {
348 firstVisible
= firstVisible
- 1;
350 for (int i
= firstVisible
; i
< fFrame
.asyncMessageCount(); i
= i
+ messageArraysStep
) {
351 AsyncMessage m
= fFrame
.getAsyncMessage(i
);
352 if (m
.hasTimeInfo()) {
353 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), (ITimeRange
) m
);
355 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), (ITimeRange
) m
);
357 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
363 firstVisible
= fFrame
.getFirstVisibleAsyncMessageReturn();
364 if (firstVisible
> 0) {
365 firstVisible
= firstVisible
- 1;
367 for (int i
= firstVisible
; i
< fFrame
.asyncMessageReturnCount(); i
= i
+ messageArraysStep
) {
368 AsyncMessageReturn m
= fFrame
.getAsyncMessageReturn(i
);
369 if (m
.hasTimeInfo()) {
370 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), (ITimeRange
) m
);
372 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), (ITimeRange
) m
);
374 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
380 List
<SDTimeEvent
> executionOccurrencesWithTime
= fFrame
.getExecutionOccurrencesWithTime();
381 if (executionOccurrencesWithTime
!= null) {
382 fNodeList
.addAll(executionOccurrencesWithTime
);
385 SDTimeEvent
[] temp
= fNodeList
.toArray(new SDTimeEvent
[fNodeList
.size()]);
386 Arrays
.sort(temp
, new TimeEventComparator());
387 fNodeList
= Arrays
.asList(temp
);
389 Image dbuffer
= null;
392 dbuffer
= new Image(getDisplay(), getClientArea().width
, getClientArea().height
);
393 } catch (Exception e
) {
394 TmfUiPlugin
.getDefault().getLog().log(new Status(IStatus
.ERROR
,TmfUiPlugin
.PLUGIN_ID
, "Error creating image", e
)); //$NON-NLS-1$
396 gcim
= new GC(dbuffer
);
397 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
398 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
399 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
401 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
402 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
403 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
404 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
409 fMinTime
= fFrame
.getMinTime();
410 fMaxTime
= fFrame
.getMaxTime();
411 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
412 double gr
= (minMaxdelta
.getValue()) / (double) 10;
414 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
415 long absDelta
= Math
.abs(delta
.getValue());
419 int colIndex
= Math
.round((float) (absDelta
/ gr
));
420 if (colIndex
< fColors
.length
&& colIndex
> 0) {
421 color
= fColors
[colIndex
- 1];
422 } else if (colIndex
<= 0) {
425 color
= fColors
[fColors
.length
- 1];
431 if (color
.getColor() instanceof Color
) {
432 gcim
.setBackground((Color
) color
.getColor());
434 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
435 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
436 if (m1
.getGraphNode() instanceof AsyncMessage
) {
437 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
438 if (as
.getEndTime() == m1
.getTime()) {
439 y1
+= as
.getHeight();
442 if (m2
.getGraphNode() instanceof AsyncMessage
) {
443 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
444 if (as
.getEndTime() == m2
.getTime()) {
445 y2
+= as
.getHeight();
448 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
450 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
451 if (m1
.getEvent() == eo
.getEndOccurrence()) {
452 y1
+= eo
.getHeight();
455 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
457 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
458 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
459 y2
+= eo2
.getHeight();
464 gcim
.fillRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 10, Math
.round((y2
- y1
) * fZoomValue
) + 1);
465 if (messageArraysStep
== 1) {
466 Color backupColor
= gcim
.getForeground();
467 gcim
.setForeground(Display
.getDefault().getSystemColor(SWT
.COLOR_WHITE
));
468 gcim
.drawRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 9, Math
.round((y2
- y1
) * fZoomValue
));
469 gcim
.setForeground(backupColor
);
472 if (getViewControl().isFocusControl() || isFocusControl()) {
473 gcim
.drawFocus(contentsToViewX(0), contentsToViewY(Math
.round(fPrevNodeY
* fZoomValue
)), contentsToViewX(10), Math
.round((fNextNodeY
- fPrevNodeY
) * fZoomValue
));
476 gc
.drawImage(dbuffer
, 0, 0, getClientArea().width
, getClientArea().height
, 0, 0, getClientArea().width
, getClientArea().height
);
477 } catch (Exception e
) {
478 TmfUiPlugin
.getDefault().getLog().log(new Status(IStatus
.ERROR
,TmfUiPlugin
.PLUGIN_ID
, "Error drawing image", e
)); //$NON-NLS-1$
481 if (dbuffer
!= null) {
488 * Checks for focus of children.
490 * @param children Control to check
491 * @return true if child is on focus else false
493 protected boolean checkFocusOnChilds(Control childs
) {
494 if (childs
instanceof Composite
) {
495 Control
[] child
= ((Composite
) childs
).getChildren();
496 for (int i
= 0; i
< child
.length
; i
++) {
497 if (child
[i
].isFocusControl()) {
500 checkFocusOnChilds(child
[i
]);
509 * @see org.eclipse.swt.widgets.Control#isFocusControl()
512 public boolean isFocusControl() {
513 Control
[] child
= getChildren();
514 for (int i
= 0; i
< child
.length
; i
++) {
515 if (child
[i
].isFocusControl()) {
518 checkFocusOnChilds(child
[i
]);
526 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseMoveEvent(org.eclipse.swt.events.MouseEvent)
529 protected void contentsMouseMoveEvent(MouseEvent event
) {
530 if (fTooltip
!= null) {
531 fTooltip
.hideToolTip();
533 super.contentsMouseMoveEvent(event
);
534 if (!isFocusControl() || getViewControl().isFocusControl()) {
535 Control
[] child
= getParent().getChildren();
536 for (int i
= 0; i
< child
.length
; i
++) {
537 if (child
[i
].isFocusControl()) {
547 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseHover(org.eclipse.swt.events.MouseEvent)
550 protected void contentsMouseHover(MouseEvent e
) {
551 if (fTooltip
== null) {
552 fTooltip
= new DrawableToolTip(this);
554 if (fFrame
!= null) {
556 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
557 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
558 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
560 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
561 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
562 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
563 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
568 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
569 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
571 if (m1
.getGraphNode() instanceof AsyncMessage
) {
572 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
573 if (as
.getEndTime() == m1
.getTime()) {
574 y1
+= as
.getHeight();
577 if (m2
.getGraphNode() instanceof AsyncMessage
) {
578 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
579 if (as
.getEndTime() == m2
.getTime()) {
580 y2
+= as
.getHeight();
583 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
584 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
585 if (m1
.getEvent() == eo
.getEndOccurrence()) {
586 y1
+= eo
.getHeight();
589 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
591 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
592 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
593 y2
+= eo2
.getHeight();
597 int m1Y
= Math
.round(y1
* fZoomValue
);
598 int m2Y
= Math
.round(y2
* fZoomValue
);
599 if ((m1Y
< e
.y
) && (m2Y
>= e
.y
)) {
600 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
601 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
610 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseExit(org.eclipse.swt.events.MouseEvent)
613 protected void contentsMouseExit(MouseEvent e
) {
614 if (fTooltip
!= null)
615 fTooltip
.hideToolTip();
620 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseUpEvent(org.eclipse.swt.events.MouseEvent)
623 protected void contentsMouseUpEvent(MouseEvent event
) {
624 selectTimeDelta(event
.y
, 0);
626 super.contentsMouseUpEvent(event
);
630 * Force the time compression bar to highlight the event occurrences between the two given messages. The event
631 * occurrences are highlighted on the first message's end lifeline
633 * @param mes1 the first message
634 * @param localMes2 the second message
636 public void highlightRegion(BaseMessage mes1
, BaseMessage mes2
) {
637 BaseMessage localMes1
= mes1
;
638 BaseMessage localMes2
= mes2
;
640 if (fFrame
== null) {
643 if (!(localMes1
instanceof ITimeRange
)) {
646 if (!(localMes2
instanceof ITimeRange
)) {
649 ITimeRange t1
= (ITimeRange
) localMes1
;
650 ITimeRange t2
= (ITimeRange
) localMes2
;
652 ITmfTimestamp time1
= t1
.getStartTime();
653 ITmfTimestamp time2
= t2
.getStartTime();
654 int event1
= localMes1
.getEventOccurrence();
655 int event2
= localMes2
.getEventOccurrence();
657 if (localMes1
instanceof AsyncMessage
) {
658 AsyncMessage as
= (AsyncMessage
) localMes1
;
659 time1
= as
.getEndTime();
660 event1
= as
.getEndOccurrence();
662 if (localMes2
instanceof AsyncMessage
) {
663 AsyncMessage as
= (AsyncMessage
) localMes2
;
664 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
665 time1
= as
.getEndTime();
666 event1
= as
.getEndOccurrence();
668 time1
= as
.getStartTime();
669 event1
= as
.getStartOccurrence();
673 if (event1
> event2
) {
674 BaseMessage tempMes
= localMes2
;
675 localMes2
= localMes1
;
678 t1
= (ITimeRange
) localMes1
;
679 t2
= (ITimeRange
) localMes2
;
681 time1
= t1
.getStartTime();
682 time2
= t2
.getStartTime();
683 event1
= localMes1
.getEventOccurrence();
684 event2
= localMes2
.getEventOccurrence();
686 if (localMes1
instanceof AsyncMessage
) {
687 AsyncMessage as
= (AsyncMessage
) localMes1
;
688 time1
= as
.getEndTime();
689 event1
= as
.getEndOccurrence();
691 if (localMes2
instanceof AsyncMessage
) {
692 AsyncMessage as
= (AsyncMessage
) localMes2
;
693 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
694 time1
= as
.getEndTime();
695 event1
= as
.getEndOccurrence();
697 time1
= as
.getStartTime();
698 event1
= as
.getStartOccurrence();
703 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
704 double gr
= (minMaxdelta
.getValue()) / (double) 10;
706 ITmfTimestamp delta
= time2
.getDelta(time1
).getDelta(fMinTime
);
707 long absDelta
= Math
.abs(delta
.getValue());
711 colIndex
= Math
.round((float) (absDelta
/ gr
));
712 if (colIndex
>= fColors
.length
) {
713 colIndex
= fColors
.length
- 1;
714 } else if (colIndex
< 0) {
720 for (int j
= 0; j
< fListenerList
.size(); j
++) {
721 ITimeCompressionListener list
= (ITimeCompressionListener
) fListenerList
.get(j
);
722 if (localMes1
.getEndLifeline() != null) {
723 list
.deltaSelected(localMes1
.getEndLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
724 } else if (localMes2
.getStartLifeline() != null) {
725 list
.deltaSelected(localMes2
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
727 list
.deltaSelected(localMes1
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
733 * Force the time compression bar to highlight the event occurrences between the two given messages. The event
734 * occurrences are highlighted on the first message's end lifeline
736 * @param mes1 the first message
737 * @param mes2 the second message
739 public void highlightRegionSync(final BaseMessage mes1
, final BaseMessage mes2
) {
740 getDisplay().syncExec(new Runnable() {
743 highlightRegion(mes1
, mes2
);
750 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#scrollBy(int, int)
753 public void scrollBy(int x
, int y
) {
757 * Sets the zoom value.
759 * @param value The zoom value to set.
761 public void setZoom(float value
) {
767 * Adds a listener to the time compression listener list to be notified about selected deltas.
769 * @param listener The listener to add
771 public void addTimeCompressionListener(ITimeCompressionListener listener
) {
772 if (!fListenerList
.contains(listener
)) {
773 fListenerList
.add(listener
);
778 * Removes a time compression listener.
780 * @param listener The listener to remove.
782 public void removeSelectionChangedListener(ITimeCompressionListener listener
) {
783 fListenerList
.remove(listener
);
788 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
791 public void widgetDisposed(DisposeEvent e
) {
792 if (fTooltip
!= null) {
795 super.removeDisposeListener(this);
796 for (int i
= 0; i
< fColors
.length
; i
++) {
797 fColors
[i
].dispose();
803 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#keyPressedEvent(org.eclipse.swt.events.KeyEvent)
806 protected void keyPressedEvent(KeyEvent event
) {
807 if (fTooltip
!= null) {
808 fTooltip
.hideToolTip();
810 if (!isFocusControl() || getViewControl().isFocusControl()) {
811 Control
[] child
= getParent().getChildren();
812 for (int i
= 0; i
< child
.length
; i
++) {
813 if (child
[i
].isFocusControl()) {
814 // getViewControl().setFocus();
822 if (fNextNodeY
== 0) {
825 if ((fFrame
!= null) && (fNextNodeY
== 0)) {
826 for (int i
= 0; i
< fNodeList
.size() - 1 && i
< 1; i
++) {
827 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
828 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
829 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
830 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
831 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
832 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
837 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
838 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
839 if (m1
.getGraphNode() instanceof AsyncMessage
) {
840 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
841 if (as
.getEndTime() == m1
.getTime()) {
842 y1
+= as
.getHeight();
845 if (m2
.getGraphNode() instanceof AsyncMessage
) {
846 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
847 if (as
.getEndTime() == m2
.getTime()) {
848 y2
+= as
.getHeight();
851 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
852 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
853 if (m1
.getEvent() == eo
.getEndOccurrence()) {
854 y1
+= eo
.getHeight();
857 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
859 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
860 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
861 y2
+= eo2
.getHeight();
865 fPrevNodeY
= Math
.round(y1
* fZoomValue
);
866 fNextNodeY
= Math
.round(y2
* fZoomValue
);
870 if (fLifeline
!= null) {
871 for (int j
= 0; j
< fListenerList
.size(); j
++) {
872 ITimeCompressionListener list
= (ITimeCompressionListener
) fListenerList
.get(j
);
873 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
877 if (event
.keyCode
== SWT
.ARROW_DOWN
) {
879 selectTimeDelta(fNextNodeY
+ 1, 1);
881 selectTimeDelta(fPrevNodeY
+ 1, 1);
884 } else if (event
.keyCode
== SWT
.ARROW_UP
) {
885 selectTimeDelta(fPrevNodeY
- 1, 2);
887 } else if (event
.keyCode
== SWT
.ARROW_RIGHT
) {
888 selectTimeDelta(fPrevNodeY
, 1);
891 super.keyPressedEvent(event
);
895 * Selects the time delta for given delta y coordinate and direction.
897 * @param dy The delta in y coordinate.
898 * @param direction 0 no direction, 1 = down, 2 = up
900 protected void selectTimeDelta(int dy
, int direction
) {
901 SDTimeEvent lastM1
= null;
902 SDTimeEvent lastM2
= null;
905 boolean done
= false;
906 if (fFrame
!= null) {
907 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
908 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
909 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
910 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
911 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
912 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
913 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
918 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
919 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
920 if (m1
.getGraphNode() instanceof AsyncMessage
) {
921 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
922 if (as
.getEndTime() == m1
.getTime()) {
923 y1
+= as
.getHeight();
926 if (m2
.getGraphNode() instanceof AsyncMessage
) {
927 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
928 if (as
.getEndTime() == m2
.getTime()) {
929 y2
+= as
.getHeight();
932 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
933 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
934 if (m1
.getEvent() == eo
.getEndOccurrence()) {
935 y1
+= eo
.getHeight();
938 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
939 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
940 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
941 y2
+= eo2
.getHeight();
945 int m1Y
= Math
.round(y1
* fZoomValue
);
946 int m2Y
= Math
.round(y2
* fZoomValue
);
948 if ((m1Y
< dy
) && (m2Y
> dy
) || (!done
&& m2Y
> dy
&& direction
== 1 && lastM1
!= null) || (!done
&& m1Y
> dy
&& direction
== 2 && lastM1
!= null)) {
949 if (m1Y
> dy
&& direction
== 2) {
958 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
959 double gr
= (minMaxdelta
.getValue()) / (double) 10;
961 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
962 long absDelta
= Math
.abs(delta
.getValue());
966 colIndex
= Math
.round((float) (absDelta
/ gr
));
967 if (colIndex
>= fColors
.length
) {
968 colIndex
= fColors
.length
- 1;
969 } else if (colIndex
< 0) {
975 if (m1
.getGraphNode() instanceof BaseMessage
) {
976 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
977 if (mes1
.getEndLifeline() != null) {
978 fLifeline
= mes1
.getEndLifeline();
979 fLifelineStart
= m1
.getEvent();
980 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
981 fLifelineColor
= fColors
[colIndex
];
982 } else if (m2
.getGraphNode() instanceof BaseMessage
&& ((BaseMessage
) m2
.getGraphNode()).getStartLifeline() != null) {
983 fLifeline
= ((BaseMessage
) m2
.getGraphNode()).getStartLifeline();
984 fLifelineStart
= m1
.getEvent();
985 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
986 fLifelineColor
= fColors
[colIndex
];
988 fLifeline
= mes1
.getStartLifeline();
989 fLifelineStart
= m1
.getEvent();
990 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
991 fLifelineColor
= fColors
[colIndex
];
993 } else if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
994 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
995 ExecutionOccurrence eo
= (ExecutionOccurrence
) m2
.getGraphNode();
996 fLifeline
= eo
.getLifeline();
997 fLifelineStart
= m1
.getEvent();
998 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
999 fLifelineColor
= fColors
[colIndex
];
1001 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1002 fLifeline
= eo
.getLifeline();
1003 fLifelineStart
= m1
.getEvent();
1004 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
1005 fLifelineColor
= fColors
[colIndex
];
1008 for (int j
= 0; j
< fListenerList
.size(); j
++) {
1009 ITimeCompressionListener list
= (ITimeCompressionListener
) fListenerList
.get(j
);
1010 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
1024 * Creates a fake tool tip.
1026 protected void createFakeTooltip() {
1027 if (fTooltip
== null) {
1028 fTooltip
= new DrawableToolTip(this);
1031 if (fFrame
!= null) {
1033 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
1034 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
1035 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
1037 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
1038 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
1039 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
1040 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
1045 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
1046 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
1048 if (m1
.getGraphNode() instanceof AsyncMessage
) {
1049 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
1050 if (as
.getEndTime() == m1
.getTime()) {
1051 y1
+= as
.getHeight();
1054 if (m2
.getGraphNode() instanceof AsyncMessage
) {
1055 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
1056 if (as
.getEndTime() == m2
.getTime()) {
1057 y2
+= as
.getHeight();
1060 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
1061 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1062 if (m1
.getEvent() == eo
.getEndOccurrence()) {
1063 y1
+= eo
.getHeight();
1066 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
1068 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
1069 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
1070 y2
+= eo2
.getHeight();
1074 int m1Y
= Math
.round(y1
* fZoomValue
);
1075 int m2Y
= Math
.round(y2
* fZoomValue
);
1076 if ((m1Y
< fPrevNodeY
+ 1) && (m2Y
>= fPrevNodeY
+ 1)) {
1077 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
1078 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
1079 fTooltip
.hideToolTip();
1086 * Traverse Listener implementation.
1088 protected static class LocalTraverseListener
implements TraverseListener
{
1092 * @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
1095 public void keyTraversed(TraverseEvent e
) {
1096 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
) || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
)) {