Commit | Line | Data |
---|---|---|
73005152 BH |
1 | /********************************************************************** |
2 | * Copyright (c) 2005, 2008, 2011 IBM Corporation and others. | |
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 | * $Id: TimeCompressionBar.java,v 1.3 2008/01/24 02:29:01 apnan Exp $ | |
8 | * | |
9 | * Contributors: | |
10 | * IBM - Initial API and implementation | |
11 | * Bernd Hufmann - Updated for TMF | |
12 | * | |
13 | **********************************************************************/ | |
14 | package org.eclipse.linuxtools.tmf.ui.views.uml2sd; | |
15 | ||
16 | import java.util.ArrayList; | |
17 | import java.util.Arrays; | |
18 | import java.util.List; | |
19 | ||
6c13869b | 20 | import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp; |
73005152 BH |
21 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage; |
22 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessageReturn; | |
23 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BaseMessage; | |
24 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ExecutionOccurrence; | |
25 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame; | |
26 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; | |
27 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ITimeRange; | |
28 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; | |
29 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Metrics; | |
30 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SDTimeEvent; | |
31 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; | |
32 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; | |
33 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; | |
34 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; | |
35 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.TimeEventComparator; | |
36 | import org.eclipse.swt.SWT; | |
37 | import org.eclipse.swt.accessibility.ACC; | |
38 | import org.eclipse.swt.accessibility.Accessible; | |
39 | import org.eclipse.swt.accessibility.AccessibleAdapter; | |
40 | import org.eclipse.swt.accessibility.AccessibleControlAdapter; | |
41 | import org.eclipse.swt.accessibility.AccessibleControlEvent; | |
42 | import org.eclipse.swt.accessibility.AccessibleEvent; | |
43 | import org.eclipse.swt.events.DisposeEvent; | |
44 | import org.eclipse.swt.events.DisposeListener; | |
45 | import org.eclipse.swt.events.FocusEvent; | |
46 | import org.eclipse.swt.events.FocusListener; | |
47 | import org.eclipse.swt.events.KeyEvent; | |
48 | import org.eclipse.swt.events.MouseEvent; | |
49 | import org.eclipse.swt.events.TraverseEvent; | |
50 | import org.eclipse.swt.events.TraverseListener; | |
51 | import org.eclipse.swt.graphics.Color; | |
52 | import org.eclipse.swt.graphics.GC; | |
53 | import org.eclipse.swt.graphics.Image; | |
54 | import org.eclipse.swt.widgets.Composite; | |
55 | import org.eclipse.swt.widgets.Control; | |
56 | import org.eclipse.swt.widgets.Display; | |
57 | ||
58 | /** | |
59 | * @author sveyrier | |
60 | * | |
61 | */ | |
62 | public class TimeCompressionBar extends ScrollView implements DisposeListener { | |
63 | ||
64 | /** | |
65 | * The listener list | |
66 | */ | |
67 | protected ArrayList<ITimeCompressionListener> listenerList = null; | |
68 | ||
69 | protected Frame frame = null; | |
70 | protected List<SDTimeEvent> nodeList = null; | |
71 | protected TmfTimestamp min = new TmfTimestamp(); | |
72 | protected TmfTimestamp max = new TmfTimestamp(); | |
73 | protected float zoomValue = 1; | |
74 | protected DrawableToolTip tooltip = null; | |
75 | ||
76 | protected ColorImpl[] col; | |
77 | ||
78 | protected Accessible accessible = null; | |
79 | ||
80 | protected int focusedWidget = -1; | |
81 | ||
82 | protected SDView view = null; | |
83 | ||
84 | protected Lifeline ll = null; | |
85 | protected int ls = 0; | |
86 | protected int ln = 0; | |
87 | protected IColor lc = null; | |
88 | ||
89 | protected int nextNodeY = 0; | |
90 | protected int prevNodeY = 0; | |
91 | ||
92 | public TimeCompressionBar(Composite parent, int s) { | |
93 | super(parent, s | SWT.NO_BACKGROUND, false); | |
94 | setVScrollBarMode(ScrollView.ALWAYS_OFF); | |
95 | setHScrollBarMode(ScrollView.ALWAYS_OFF); | |
96 | listenerList = new ArrayList<ITimeCompressionListener>(); | |
97 | col = new ColorImpl[10]; | |
98 | col[0] = new ColorImpl(Display.getDefault(), 255, 229, 229); | |
99 | col[1] = new ColorImpl(Display.getDefault(), 255, 204, 204); | |
100 | col[2] = new ColorImpl(Display.getDefault(), 255, 178, 178); | |
101 | col[3] = new ColorImpl(Display.getDefault(), 255, 153, 153); | |
102 | col[4] = new ColorImpl(Display.getDefault(), 255, 127, 127); | |
103 | col[5] = new ColorImpl(Display.getDefault(), 255, 102, 102); | |
104 | col[6] = new ColorImpl(Display.getDefault(), 255, 76, 76); | |
105 | col[7] = new ColorImpl(Display.getDefault(), 255, 51, 51); | |
106 | col[8] = new ColorImpl(Display.getDefault(), 255, 25, 25); | |
107 | col[9] = new ColorImpl(Display.getDefault(), 255, 0, 0); | |
108 | super.addDisposeListener(this); | |
109 | ||
110 | accessible = getViewControl().getAccessible(); | |
111 | ||
112 | accessible.addAccessibleListener(new AccessibleAdapter() { | |
113 | @Override | |
114 | public void getName(AccessibleEvent e) { | |
115 | if (e.childID == ACC.CHILDID_SELF) { | |
116 | // e.result = "Sequence Diagram"; | |
117 | } | |
118 | // Case toolTip | |
119 | else if (e.childID == 0) { | |
120 | if (tooltip != null) | |
121 | e.result = tooltip.getAccessibleText(); | |
122 | } else if (e.childID == 1) { | |
123 | createFakeTooltip(); | |
124 | e.result = tooltip.getAccessibleText(); | |
125 | } | |
126 | } | |
127 | }); | |
128 | ||
129 | accessible.addAccessibleControlListener(new AccessibleControlAdapter() { | |
130 | @Override | |
131 | public void getFocus(AccessibleControlEvent e) { | |
132 | if (focusedWidget == -1) | |
133 | e.childID = ACC.CHILDID_SELF; | |
134 | else | |
135 | e.childID = focusedWidget; | |
136 | } | |
137 | ||
138 | @Override | |
139 | public void getRole(AccessibleControlEvent e) { | |
140 | switch (e.childID) { | |
141 | case ACC.CHILDID_SELF: | |
142 | e.detail = ACC.ROLE_CLIENT_AREA; | |
143 | break; | |
144 | case 0: | |
145 | e.detail = ACC.ROLE_TOOLTIP; | |
146 | break; | |
147 | case 1: | |
148 | e.detail = ACC.ROLE_LABEL; | |
149 | break; | |
150 | } | |
151 | } | |
152 | ||
153 | @Override | |
154 | public void getState(AccessibleControlEvent e) { | |
155 | e.detail = ACC.STATE_FOCUSABLE; | |
156 | if (e.childID == ACC.CHILDID_SELF) { | |
157 | e.detail |= ACC.STATE_FOCUSED; | |
158 | } else { | |
159 | e.detail |= ACC.STATE_SELECTABLE; | |
160 | if (e.childID == focusedWidget) | |
161 | e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED; | |
162 | } | |
163 | } | |
164 | }); | |
165 | ||
166 | getViewControl().addTraverseListener(new TraverseListener() { | |
167 | ||
168 | @Override | |
169 | public void keyTraversed(TraverseEvent e) { | |
170 | if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) | |
171 | e.doit = true; | |
172 | ||
173 | } | |
174 | ||
175 | }); | |
176 | ||
177 | addTraverseListener(new TraverseListener() { | |
178 | ||
179 | @Override | |
180 | public void keyTraversed(TraverseEvent e) { | |
181 | if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) | |
182 | e.doit = true; | |
183 | ||
184 | } | |
185 | ||
186 | }); | |
187 | ||
188 | getViewControl().addFocusListener(new FocusListener() { | |
189 | ||
190 | @Override | |
191 | public void focusGained(FocusEvent e) { | |
192 | ||
193 | redraw(); | |
194 | } | |
195 | ||
196 | @Override | |
197 | public void focusLost(FocusEvent e) { | |
198 | redraw(); | |
199 | } | |
200 | }); | |
201 | } | |
202 | ||
203 | void setFocus(int newFocusShape) { | |
204 | focusedWidget = newFocusShape; | |
205 | if (focusedWidget == -1) { | |
206 | getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF); | |
207 | } else { | |
208 | getViewControl().getAccessible().setFocus(focusedWidget); | |
209 | } | |
210 | } | |
211 | ||
212 | public void setFrame(Frame theFrame) { | |
213 | frame = theFrame; | |
214 | min = frame.getMinTime(); | |
215 | max = frame.getMaxTime(); | |
216 | } | |
217 | ||
218 | @Override | |
219 | protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { | |
220 | if (frame == null) | |
221 | return; | |
222 | nodeList = new ArrayList<SDTimeEvent>(); | |
223 | int messageArraysStep = 1; | |
224 | ||
225 | if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * zoomValue < Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1) | |
226 | messageArraysStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1 / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * zoomValue)); | |
227 | ||
228 | int firstVisible = frame.getFirstVisibleSyncMessage(); | |
229 | if (firstVisible > 0) | |
230 | firstVisible = firstVisible - 1; | |
231 | for (int i = firstVisible; i < frame.syncMessageCount(); i = i + messageArraysStep) { | |
232 | SyncMessage m = frame.getSyncMessage(i); | |
233 | if (m.hasTimeInfo()) { | |
234 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), (ITimeRange) m); | |
235 | nodeList.add(t); | |
236 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
237 | break; | |
238 | } | |
239 | } | |
240 | ||
241 | firstVisible = frame.getFirstVisibleSyncMessageReturn(); | |
242 | if (firstVisible > 0) | |
243 | firstVisible = firstVisible - 1; | |
244 | for (int i = firstVisible; i < frame.syncMessageReturnCount(); i = i + messageArraysStep) { | |
245 | SyncMessage m = frame.getSyncMessageReturn(i); | |
246 | if (m.hasTimeInfo()) { | |
247 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), (ITimeRange) m); | |
248 | nodeList.add(t); | |
249 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
250 | break; | |
251 | } | |
252 | } | |
253 | ||
254 | firstVisible = frame.getFirstVisibleAsyncMessage(); | |
255 | if (firstVisible > 0) | |
256 | firstVisible = firstVisible - 1; | |
257 | for (int i = firstVisible; i < frame.asyncMessageCount(); i = i + messageArraysStep) { | |
258 | AsyncMessage m = frame.getAsyncMessage(i); | |
259 | if (m.hasTimeInfo()) { | |
260 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), (ITimeRange) m); | |
261 | nodeList.add(t); | |
262 | t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), (ITimeRange) m); | |
263 | nodeList.add(t); | |
264 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
265 | break; | |
266 | } | |
267 | } | |
268 | ||
269 | firstVisible = frame.getFirstVisibleAsyncMessageReturn(); | |
270 | if (firstVisible > 0) | |
271 | firstVisible = firstVisible - 1; | |
272 | for (int i = firstVisible; i < frame.asyncMessageReturnCount(); i = i + messageArraysStep) { | |
273 | AsyncMessageReturn m = frame.getAsyncMessageReturn(i); | |
274 | if (m.hasTimeInfo()) { | |
275 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), (ITimeRange) m); | |
276 | nodeList.add(t); | |
277 | t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), (ITimeRange) m); | |
278 | nodeList.add(t); | |
279 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
280 | break; | |
281 | } | |
282 | } | |
283 | ||
284 | /* | |
285 | * for (int i=0; i<frame.lifeLinesCount();i++) { | |
286 | * Lifeline lifeline = frame.getLifeline(i); | |
287 | * if (lifeline.getExecutions()!=null) | |
288 | * for (int j=lifeline.getExecOccurrenceDrawIndex(); j<lifeline.getExecutions().size(); j++) { | |
289 | * ExecutionOccurrence exec = (ExecutionOccurrence)lifeline.getExecutions().get(j); | |
290 | * if (exec.hasTimeInfo()) { | |
291 | * TimeEvent t = new TimeEvent(exec.getFirstTime(), exec.getStartOccurrence(),(ITimeRange)exec); | |
292 | * nodeList.add(t); | |
293 | * t = new TimeEvent(exec.getLastTime(),exec.getEndOccurrence(),(ITimeRange)exec); nodeList.add(t); | |
294 | * } | |
295 | * if (exec.getY()*zoomValue>getContentsY()+getVisibleHeight()) break; | |
296 | * } | |
297 | * float g= lifeline.getX()*zoomValue; | |
298 | * int h=frame.getContentX(); int r=frame.getVisibleWidth(); | |
299 | * } | |
300 | */ | |
301 | List<SDTimeEvent> executionOccurrencesWithTime = frame.getExecutionOccurrencesWithTime(); | |
302 | if (executionOccurrencesWithTime != null) { | |
303 | nodeList.addAll(executionOccurrencesWithTime); | |
304 | } | |
305 | ||
306 | SDTimeEvent[] temp = nodeList.toArray(new SDTimeEvent[0]); | |
307 | Arrays.sort(temp, new TimeEventComparator()); | |
308 | nodeList = Arrays.asList(temp); | |
309 | ||
310 | Image dbuffer = null; | |
311 | GC gcim = null; | |
312 | try { | |
313 | dbuffer = new Image(getDisplay(), getClientArea().width, getClientArea().height); | |
314 | } catch (Exception e) { | |
315 | System.out.println(e.toString()); | |
316 | } | |
317 | gcim = new GC(dbuffer); | |
318 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
319 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
320 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
321 | ||
322 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
323 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
324 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
325 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
326 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
327 | continue; | |
328 | } | |
329 | } | |
330 | ||
331 | min = frame.getMinTime(); | |
332 | max = frame.getMaxTime(); | |
333 | TmfTimestamp minMaxdelta = max.getDelta(min); | |
334 | double gr = (minMaxdelta.getValue()) / (double) 10; | |
335 | ||
336 | TmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(min); | |
337 | long absDelta = Math.abs(delta.getValue()); | |
338 | ||
339 | ColorImpl color; | |
340 | if (gr != 0) { | |
341 | int colIndex = Math.round((float) (absDelta / gr)); | |
342 | if (colIndex < col.length && colIndex > 0) | |
343 | color = col[colIndex - 1]; | |
344 | else if (colIndex <= 0) | |
345 | color = col[0]; | |
346 | else | |
347 | color = col[col.length - 1]; | |
348 | } else | |
349 | color = col[0]; | |
350 | ||
351 | if (color.getColor() instanceof Color) | |
352 | gcim.setBackground((Color) color.getColor()); | |
353 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
354 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
355 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
356 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
357 | if (as.getEndTime() == m1.getTime()) | |
358 | y1 += as.getHeight(); | |
359 | } | |
360 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
361 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
362 | if (as.getEndTime() == m2.getTime()) | |
363 | y2 += as.getHeight(); | |
364 | } | |
365 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
366 | ||
367 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
368 | if (m1.getEvent() == eo.getEndOccurrence()) | |
369 | y1 += eo.getHeight(); | |
370 | ||
371 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
372 | ||
373 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
374 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
375 | y2 += eo2.getHeight(); | |
376 | ||
377 | } | |
378 | } | |
379 | gcim.fillRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * zoomValue)), 10, Math.round((y2 - y1) * zoomValue) + 1); | |
380 | if (messageArraysStep == 1) { | |
381 | Color backupColor = gcim.getForeground(); | |
382 | gcim.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); | |
383 | gcim.drawRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * zoomValue)), 9, Math.round((y2 - y1) * zoomValue)); | |
384 | gcim.setForeground(backupColor); | |
385 | } | |
386 | } | |
387 | if (getViewControl().isFocusControl() || isFocusControl()) { | |
388 | gcim.drawFocus(contentsToViewX(0), contentsToViewY(Math.round(prevNodeY * zoomValue)), contentsToViewX(10), Math.round((nextNodeY - prevNodeY) * zoomValue)); | |
389 | } | |
390 | try { | |
391 | gc.drawImage(dbuffer, 0, 0, getClientArea().width, getClientArea().height, 0, 0, getClientArea().width, getClientArea().height); | |
392 | } catch (Exception e) { | |
393 | System.out.println(e.getMessage()); | |
394 | } | |
395 | gcim.dispose(); | |
396 | if (dbuffer != null) { | |
397 | dbuffer.dispose(); | |
398 | } | |
399 | gc.dispose(); | |
400 | } | |
401 | ||
402 | protected boolean checkFocusOnChilds(Control childs) { | |
403 | if (childs instanceof Composite) { | |
404 | Control[] child = ((Composite) childs).getChildren(); | |
405 | for (int i = 0; i < child.length; i++) { | |
406 | if (child[i].isFocusControl()) { | |
407 | return true; | |
408 | } else | |
409 | checkFocusOnChilds(child[i]); | |
410 | } | |
411 | } | |
412 | return false; | |
413 | } | |
414 | ||
415 | @Override | |
416 | public boolean isFocusControl() { | |
417 | Control[] child = getChildren(); | |
418 | for (int i = 0; i < child.length; i++) { | |
419 | if (child[i].isFocusControl()) { | |
420 | return true; | |
421 | } else | |
422 | checkFocusOnChilds(child[i]); | |
423 | } | |
424 | return false; | |
425 | } | |
426 | ||
427 | @Override | |
428 | protected void contentsMouseMoveEvent(MouseEvent event) { | |
429 | if (tooltip != null) | |
430 | tooltip.hideToolTip(); | |
431 | super.contentsMouseMoveEvent(event); | |
432 | if (!isFocusControl() || getViewControl().isFocusControl()) { | |
433 | Control[] child = getParent().getChildren(); | |
434 | for (int i = 0; i < child.length; i++) { | |
435 | if (child[i].isFocusControl()) { | |
436 | // getViewControl().setFocus(); | |
437 | break; | |
438 | } | |
439 | } | |
440 | } | |
441 | setFocus(-1); | |
442 | } | |
443 | ||
444 | @Override | |
445 | protected void contentsMouseHover(MouseEvent e) { | |
446 | if (tooltip == null) { | |
447 | tooltip = new DrawableToolTip(this); | |
448 | } | |
449 | if (frame != null) { | |
450 | setFocus(0); | |
451 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
452 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
453 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
454 | ||
455 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
456 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
457 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
458 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
459 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
460 | continue; | |
461 | } | |
462 | } | |
463 | ||
464 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
465 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
466 | ||
467 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
468 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
469 | if (as.getEndTime() == m1.getTime()) | |
470 | y1 += as.getHeight(); | |
471 | } | |
472 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
473 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
474 | if (as.getEndTime() == m2.getTime()) | |
475 | y2 += as.getHeight(); | |
476 | } | |
477 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
478 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
479 | if (m1.getEvent() == eo.getEndOccurrence()) | |
480 | y1 += eo.getHeight(); | |
481 | ||
482 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
483 | ||
484 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
485 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
486 | y2 += eo2.getHeight(); | |
487 | ||
488 | } | |
489 | } | |
490 | int m1Y = Math.round(y1 * zoomValue); | |
491 | int m2Y = Math.round(y2 * zoomValue); | |
492 | if ((m1Y < e.y) && (m2Y >= e.y)) { | |
493 | TmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); | |
494 | tooltip.showToolTip(delta, min, max); | |
495 | } | |
496 | } | |
497 | } | |
498 | setFocus(0); | |
499 | } | |
500 | ||
501 | @Override | |
502 | protected void contentsMouseExit(MouseEvent e) { | |
503 | if (tooltip != null) | |
504 | tooltip.hideToolTip(); | |
505 | } | |
506 | ||
507 | @Override | |
508 | protected void contentsMouseUpEvent(MouseEvent event) { | |
509 | selectTimeDelta(event.y, 0); | |
510 | setFocus(); | |
511 | super.contentsMouseUpEvent(event); | |
512 | } | |
513 | ||
514 | /** | |
515 | * Force the time compression bar to highlight the event occurrences between the two given messages. The event | |
516 | * occurrences are highlighted on the first message's end lifeline | |
517 | * | |
518 | * @param mes1 the first message | |
519 | * @param mes2 | |
520 | */ | |
521 | public void highlightRegion(BaseMessage mes1, BaseMessage mes2) { | |
522 | if (frame == null) | |
523 | return; | |
524 | if (!(mes1 instanceof ITimeRange)) | |
525 | return; | |
526 | if (!(mes2 instanceof ITimeRange)) | |
527 | return; | |
528 | ITimeRange t1 = (ITimeRange) mes1; | |
529 | ITimeRange t2 = (ITimeRange) mes2; | |
530 | ||
531 | TmfTimestamp time1 = t1.getStartTime(); | |
532 | TmfTimestamp time2 = t2.getStartTime(); | |
533 | int event1 = mes1.getEventOccurrence(); | |
534 | int event2 = mes2.getEventOccurrence(); | |
535 | ||
536 | if (mes1 instanceof AsyncMessage) { | |
537 | AsyncMessage as = (AsyncMessage) mes2; | |
538 | time1 = as.getEndTime(); | |
539 | event1 = as.getEndOccurrence(); | |
540 | } | |
541 | if (mes2 instanceof AsyncMessage) { | |
542 | AsyncMessage as = (AsyncMessage) mes2; | |
543 | if (as.getEndOccurrence() > as.getStartOccurrence()) { | |
544 | time1 = as.getEndTime(); | |
545 | event1 = as.getEndOccurrence(); | |
546 | } else { | |
547 | time1 = as.getStartTime(); | |
548 | event1 = as.getStartOccurrence(); | |
549 | } | |
550 | } | |
551 | ||
552 | if (event1 > event2) { | |
553 | BaseMessage tempMes = mes2; | |
554 | mes2 = mes1; | |
555 | mes1 = tempMes; | |
556 | ||
557 | t1 = (ITimeRange) mes1; | |
558 | t2 = (ITimeRange) mes2; | |
559 | ||
560 | time1 = t1.getStartTime(); | |
561 | time2 = t2.getStartTime(); | |
562 | event1 = mes1.getEventOccurrence(); | |
563 | event2 = mes2.getEventOccurrence(); | |
564 | ||
565 | if (mes1 instanceof AsyncMessage) { | |
566 | AsyncMessage as = (AsyncMessage) mes2; | |
567 | time1 = as.getEndTime(); | |
568 | event1 = as.getEndOccurrence(); | |
569 | } | |
570 | if (mes2 instanceof AsyncMessage) { | |
571 | AsyncMessage as = (AsyncMessage) mes2; | |
572 | if (as.getEndOccurrence() > as.getStartOccurrence()) { | |
573 | time1 = as.getEndTime(); | |
574 | event1 = as.getEndOccurrence(); | |
575 | } else { | |
576 | time1 = as.getStartTime(); | |
577 | event1 = as.getStartOccurrence(); | |
578 | } | |
579 | } | |
580 | } | |
581 | ||
582 | TmfTimestamp minMaxdelta = max.getDelta(min); | |
583 | double gr = (minMaxdelta.getValue()) / (double) 10; | |
584 | ||
585 | TmfTimestamp delta = time2.getDelta(time1).getDelta(min); | |
586 | long absDelta = Math.abs(delta.getValue()); | |
587 | ||
588 | int colIndex = 0; | |
589 | if (gr != 0) { | |
590 | colIndex = Math.round((float) (absDelta / gr)); | |
591 | if (colIndex >= col.length) | |
592 | colIndex = col.length - 1; | |
593 | else if (colIndex < 0) | |
594 | colIndex = 0; | |
595 | } else | |
596 | colIndex = 0; | |
597 | for (int j = 0; j < listenerList.size(); j++) { | |
598 | ITimeCompressionListener list = (ITimeCompressionListener) listenerList.get(j); | |
599 | if (mes1.getEndLifeline() != null) { | |
600 | list.deltaSelected(mes1.getEndLifeline(), event1, event2 - event1, col[colIndex]); | |
601 | } else if (mes2.getStartLifeline() != null) { | |
602 | list.deltaSelected(mes2.getStartLifeline(), event1, event2 - event1, col[colIndex]); | |
603 | } else | |
604 | list.deltaSelected(mes1.getStartLifeline(), event1, event2 - event1, col[colIndex]); | |
605 | } | |
606 | } | |
607 | ||
608 | /** | |
609 | * Force the time compression bar to highlight the event occurrences between the two given messages. The event | |
610 | * occurrences are highlighted on the first message's end lifeline | |
611 | * | |
612 | * @param mes1 the first message | |
613 | * @param mes2 | |
614 | */ | |
615 | public void highlightRegionSync(final BaseMessage mes1, final BaseMessage mes2) { | |
616 | getDisplay().syncExec(new Runnable() { | |
617 | @Override | |
618 | public void run() { | |
619 | highlightRegion(mes1, mes2); | |
620 | } | |
621 | }); | |
622 | } | |
623 | ||
624 | @Override | |
625 | public void scrollBy(int x, int y) { | |
626 | } | |
627 | ||
628 | public void setZoom(float value) { | |
629 | zoomValue = value; | |
630 | redraw(); | |
631 | } | |
632 | ||
633 | public void addTimeCompressionListener(ITimeCompressionListener listener) { | |
634 | if (!listenerList.contains(listener)) | |
635 | listenerList.add(listener); | |
636 | } | |
637 | ||
638 | public void removeSelectionChangedListener(ITimeCompressionListener listener) { | |
639 | listenerList.remove(listener); | |
640 | } | |
641 | ||
642 | @Override | |
643 | public void widgetDisposed(DisposeEvent e) { | |
644 | if (tooltip != null) | |
645 | tooltip.dispose(); | |
646 | super.removeDisposeListener(this); | |
647 | for (int i = 0; i < col.length; i++) | |
648 | col[i].dispose(); | |
649 | } | |
650 | ||
651 | @Override | |
652 | protected void keyPressedEvent(KeyEvent _e) { | |
653 | if (tooltip != null) | |
654 | tooltip.hideToolTip(); | |
655 | if (!isFocusControl() || getViewControl().isFocusControl()) { | |
656 | Control[] child = getParent().getChildren(); | |
657 | for (int i = 0; i < child.length; i++) { | |
658 | if (child[i].isFocusControl()) { | |
659 | // getViewControl().setFocus(); | |
660 | break; | |
661 | } | |
662 | } | |
663 | } | |
664 | setFocus(-1); | |
665 | ||
666 | boolean top = false; | |
667 | if (nextNodeY == 0) | |
668 | top = true; | |
669 | if ((frame != null) && (nextNodeY == 0)) { | |
670 | for (int i = 0; i < nodeList.size() - 1 && i < 1; i++) { | |
671 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
672 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
673 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
674 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
675 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
676 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
677 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
678 | continue; | |
679 | } | |
680 | } | |
681 | ||
682 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
683 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
684 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
685 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
686 | if (as.getEndTime() == m1.getTime()) | |
687 | y1 += as.getHeight(); | |
688 | } | |
689 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
690 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
691 | if (as.getEndTime() == m2.getTime()) | |
692 | y2 += as.getHeight(); | |
693 | } | |
694 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
695 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
696 | if (m1.getEvent() == eo.getEndOccurrence()) | |
697 | y1 += eo.getHeight(); | |
698 | ||
699 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
700 | ||
701 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
702 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
703 | y2 += eo2.getHeight(); | |
704 | ||
705 | } | |
706 | } | |
707 | prevNodeY = Math.round(y1 * zoomValue); | |
708 | nextNodeY = Math.round(y2 * zoomValue); | |
709 | } | |
710 | } | |
711 | ||
712 | if (ll != null) | |
713 | for (int j = 0; j < listenerList.size(); j++) { | |
714 | ITimeCompressionListener list = (ITimeCompressionListener) listenerList.get(j); | |
715 | list.deltaSelected(ll, ls, ln, lc); | |
716 | } | |
717 | ||
718 | if (_e.keyCode == SWT.ARROW_DOWN) { | |
719 | if (!top) | |
720 | selectTimeDelta(nextNodeY + 1, 1); | |
721 | else | |
722 | selectTimeDelta(prevNodeY + 1, 1); | |
723 | setFocus(1); | |
724 | } else if (_e.keyCode == SWT.ARROW_UP) { | |
725 | selectTimeDelta(prevNodeY - 1, 2); | |
726 | setFocus(1); | |
727 | } else if (_e.keyCode == SWT.ARROW_RIGHT) { | |
728 | selectTimeDelta(prevNodeY, 1); | |
729 | setFocus(1); | |
730 | } | |
731 | super.keyPressedEvent(_e); | |
732 | } | |
733 | ||
734 | @Override | |
735 | protected void keyReleasedEvent(KeyEvent _e) { | |
736 | super.keyReleasedEvent(_e); | |
737 | } | |
738 | ||
739 | /** | |
740 | * 0 no direction, 1 = down, 2 = up | |
741 | * | |
742 | * @param dy | |
743 | * @param direction | |
744 | */ | |
745 | protected void selectTimeDelta(int dy, int direction) { | |
746 | SDTimeEvent lastM1 = null; | |
747 | SDTimeEvent lastM2 = null; | |
748 | int lastY1 = 0; | |
749 | int lastY2 = 0; | |
750 | boolean done = false; | |
751 | if (frame != null) { | |
752 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
753 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
754 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
755 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
756 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
757 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
758 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
759 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
760 | continue; | |
761 | } | |
762 | } | |
763 | ||
764 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
765 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
766 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
767 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
768 | if (as.getEndTime() == m1.getTime()) | |
769 | y1 += as.getHeight(); | |
770 | } | |
771 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
772 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
773 | if (as.getEndTime() == m2.getTime()) | |
774 | y2 += as.getHeight(); | |
775 | } | |
776 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
777 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
778 | if (m1.getEvent() == eo.getEndOccurrence()) | |
779 | y1 += eo.getHeight(); | |
780 | ||
781 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
782 | ||
783 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
784 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
785 | y2 += eo2.getHeight(); | |
786 | ||
787 | } | |
788 | } | |
789 | int m1Y = Math.round(y1 * zoomValue); | |
790 | int m2Y = Math.round(y2 * zoomValue); | |
791 | ||
792 | if ((m1Y < dy) && (m2Y > dy) || (!done && m2Y > dy && direction == 1 && lastM1 != null) || (!done && m1Y > dy && direction == 2 && lastM1 != null)) { | |
793 | if (m1Y > dy && direction == 2) { | |
794 | m1 = lastM1; | |
795 | m2 = lastM2; | |
796 | m1Y = lastY1; | |
797 | m2Y = lastY2; | |
798 | } | |
799 | done = true; | |
800 | prevNodeY = m1Y; | |
801 | nextNodeY = m2Y; | |
802 | TmfTimestamp minMaxdelta = max.getDelta(min); | |
803 | double gr = (minMaxdelta.getValue()) / (double) 10; | |
804 | ||
805 | TmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(min); | |
806 | long absDelta = Math.abs(delta.getValue()); | |
807 | ||
808 | int colIndex = 0; | |
809 | if (gr != 0) { | |
810 | colIndex = Math.round((float) (absDelta / gr)); | |
811 | if (colIndex >= col.length) | |
812 | colIndex = col.length - 1; | |
813 | else if (colIndex < 0) | |
814 | colIndex = 0; | |
815 | } else | |
816 | colIndex = 0; | |
817 | if (m1.getGraphNode() instanceof BaseMessage) { | |
818 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
819 | if (mes1.getEndLifeline() != null) { | |
820 | ll = mes1.getEndLifeline(); | |
821 | ls = m1.getEvent(); | |
822 | ln = m2.getEvent() - m1.getEvent(); | |
823 | lc = col[colIndex]; | |
824 | } else if (m2.getGraphNode() instanceof BaseMessage && ((BaseMessage) m2.getGraphNode()).getStartLifeline() != null) { | |
825 | ll = ((BaseMessage) m2.getGraphNode()).getStartLifeline(); | |
826 | ls = m1.getEvent(); | |
827 | ln = m2.getEvent() - m1.getEvent(); | |
828 | lc = col[colIndex]; | |
829 | } else { | |
830 | ll = mes1.getStartLifeline(); | |
831 | ls = m1.getEvent(); | |
832 | ln = m2.getEvent() - m1.getEvent(); | |
833 | lc = col[colIndex]; | |
834 | } | |
835 | } else if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
836 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
837 | ExecutionOccurrence eo = (ExecutionOccurrence) m2.getGraphNode(); | |
838 | ll = eo.getLifeline(); | |
839 | ls = m1.getEvent(); | |
840 | ln = m2.getEvent() - m1.getEvent(); | |
841 | lc = col[colIndex]; | |
842 | } else { | |
843 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
844 | ll = eo.getLifeline(); | |
845 | ls = m1.getEvent(); | |
846 | ln = m2.getEvent() - m1.getEvent(); | |
847 | lc = col[colIndex]; | |
848 | } | |
849 | } | |
850 | for (int j = 0; j < listenerList.size(); j++) { | |
851 | ITimeCompressionListener list = (ITimeCompressionListener) listenerList.get(j); | |
852 | list.deltaSelected(ll, ls, ln, lc); | |
853 | } | |
854 | break; | |
855 | } else { | |
856 | lastM1 = m1; | |
857 | lastM2 = m2; | |
858 | lastY1 = m1Y; | |
859 | lastY2 = m2Y; | |
860 | } | |
861 | } | |
862 | } | |
863 | } | |
864 | ||
865 | protected void createFakeTooltip() { | |
866 | if (tooltip == null) { | |
867 | tooltip = new DrawableToolTip(this); | |
868 | } | |
869 | if (frame != null) { | |
870 | setFocus(0); | |
871 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
872 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
873 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
874 | ||
875 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
876 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
877 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
878 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
879 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
880 | continue; | |
881 | } | |
882 | } | |
883 | ||
884 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
885 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
886 | ||
887 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
888 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
889 | if (as.getEndTime() == m1.getTime()) | |
890 | y1 += as.getHeight(); | |
891 | } | |
892 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
893 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
894 | if (as.getEndTime() == m2.getTime()) | |
895 | y2 += as.getHeight(); | |
896 | } | |
897 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
898 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
899 | if (m1.getEvent() == eo.getEndOccurrence()) | |
900 | y1 += eo.getHeight(); | |
901 | ||
902 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
903 | ||
904 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
905 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
906 | y2 += eo2.getHeight(); | |
907 | ||
908 | } | |
909 | } | |
910 | int m1Y = Math.round(y1 * zoomValue); | |
911 | int m2Y = Math.round(y2 * zoomValue); | |
912 | if ((m1Y < prevNodeY + 1) && (m2Y >= prevNodeY + 1)) { | |
913 | TmfTimestamp delta = m2.getTime().getDelta(m1.getTime()); | |
914 | tooltip.showToolTip(delta, min, max); | |
915 | tooltip.hideToolTip(); | |
916 | } | |
917 | } | |
918 | } | |
919 | } | |
920 | } |