tmf: API clean-up of sequence diagram framework
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / SDWidget.java
CommitLineData
73005152 1/**********************************************************************
c8422608 2 * Copyright (c) 2005, 2013 IBM Corporation, Ericsson
73005152
BH
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
013a5f1c
AM
7 *
8 * Contributors:
c8422608
AM
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
73005152 11 **********************************************************************/
c8422608 12
73005152
BH
13package org.eclipse.linuxtools.tmf.ui.views.uml2sd;
14
15import java.text.MessageFormat;
16import java.util.ArrayList;
17import java.util.List;
18import java.util.Timer;
19import java.util.TimerTask;
20
21import org.eclipse.jface.contexts.IContextIds;
22import org.eclipse.jface.util.IPropertyChangeListener;
23import org.eclipse.jface.util.PropertyChangeEvent;
24import org.eclipse.jface.viewers.ISelectionProvider;
25import org.eclipse.jface.viewers.StructuredSelection;
8fd82db5 26import org.eclipse.linuxtools.internal.tmf.ui.Activator;
d34665f9 27import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
3bd46eef 28import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
73005152
BH
29import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BaseMessage;
30import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BasicExecutionOccurrence;
31import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame;
32import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode;
33import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ITimeRange;
34import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline;
35import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Metrics;
df0b8ff4
BH
36import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.SDPrintDialog;
37import org.eclipse.linuxtools.tmf.ui.views.uml2sd.dialogs.SDPrintDialogUI;
73005152 38import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor;
73005152
BH
39import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDCollapseProvider;
40import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.LoadersManager;
df0b8ff4 41import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences;
73005152 42import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref;
92330441 43import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.Messages;
73005152
BH
44import org.eclipse.swt.SWT;
45import org.eclipse.swt.accessibility.ACC;
46import org.eclipse.swt.accessibility.Accessible;
47import org.eclipse.swt.accessibility.AccessibleAdapter;
48import org.eclipse.swt.accessibility.AccessibleControlAdapter;
49import org.eclipse.swt.accessibility.AccessibleControlEvent;
50import org.eclipse.swt.accessibility.AccessibleEvent;
51import org.eclipse.swt.events.DisposeEvent;
52import org.eclipse.swt.events.DisposeListener;
53import org.eclipse.swt.events.FocusEvent;
54import org.eclipse.swt.events.FocusListener;
55import org.eclipse.swt.events.KeyEvent;
56import org.eclipse.swt.events.MouseEvent;
57import org.eclipse.swt.events.SelectionEvent;
58import org.eclipse.swt.events.SelectionListener;
59import org.eclipse.swt.events.TraverseEvent;
60import org.eclipse.swt.events.TraverseListener;
61import org.eclipse.swt.graphics.GC;
62import org.eclipse.swt.graphics.Image;
63import org.eclipse.swt.graphics.ImageData;
64import org.eclipse.swt.graphics.Rectangle;
65import org.eclipse.swt.printing.Printer;
66import org.eclipse.swt.printing.PrinterData;
67import org.eclipse.swt.widgets.Canvas;
68import org.eclipse.swt.widgets.Caret;
69import org.eclipse.swt.widgets.Composite;
70import org.eclipse.swt.widgets.Control;
71import org.eclipse.swt.widgets.Display;
72import org.eclipse.swt.widgets.Event;
73import org.eclipse.swt.widgets.Listener;
74import org.eclipse.swt.widgets.MenuItem;
75import org.eclipse.ui.contexts.IContextService;
76import org.eclipse.ui.part.ViewPart;
77
78/**
df0b8ff4
BH
79 * <p>
80 * This class implements sequence diagram widget used in the sequence diagram view.
81 * </p>
013a5f1c
AM
82 *
83 * @version 1.0
73005152 84 * @author sveyrier
73005152 85 */
a55887ca
AM
86public class SDWidget extends ScrollView implements SelectionListener,
87 IPropertyChangeListener, DisposeListener, ITimeCompressionListener {
73005152 88
df0b8ff4
BH
89 // ------------------------------------------------------------------------
90 // Attributes
91 // ------------------------------------------------------------------------
92
93 /**
94 * The frame to display in the sequence diagram widget.
95 */
cab6c8ff 96 private Frame fFrame;
df0b8ff4
BH
97 /**
98 * The overview image to display.
99 */
cab6c8ff 100 private Image fOverView = null;
df0b8ff4 101 /**
013a5f1c 102 * The zoom in menu item.
df0b8ff4 103 */
cab6c8ff 104 private MenuItem fZoomIn = null;
df0b8ff4 105 /**
013a5f1c 106 * The zoom out menu item.
df0b8ff4 107 */
cab6c8ff 108 private MenuItem fZoomOut = null;
df0b8ff4 109 /**
013a5f1c 110 * The sequence diagram selection provider.
df0b8ff4 111 */
cab6c8ff 112 private SDWidgetSelectionProvider fSelProvider = null;
df0b8ff4 113 /**
013a5f1c 114 * The current zoom value.
df0b8ff4 115 */
cab6c8ff 116 private float fZoomValue = 1;
df0b8ff4 117 /**
013a5f1c 118 * The current zoomInMode (true for zoom in).
df0b8ff4 119 */
cab6c8ff 120 private boolean fZoomInMode = false;
df0b8ff4 121 /**
013a5f1c 122 * The current zoomOutMode (true for zoom out).
df0b8ff4 123 */
cab6c8ff 124 private boolean fZoomOutMode = false;
df0b8ff4 125 /**
013a5f1c 126 * The current list of selected graph nodes.
df0b8ff4 127 */
cab6c8ff 128 private List<GraphNode> fSelectedNodeList = null;
df0b8ff4 129 /**
013a5f1c 130 * Flag whether ctrl button is selected or not.
df0b8ff4 131 */
cab6c8ff 132 private boolean fCtrlSelection = false;
df0b8ff4 133 /**
013a5f1c 134 * A reference to the view site.
df0b8ff4 135 */
cab6c8ff 136 private ViewPart fSite = null;
df0b8ff4 137 /**
013a5f1c 138 * The current graph node (the last selected one).
df0b8ff4 139 */
cab6c8ff 140 private GraphNode fCurrentGraphNode = null;
df0b8ff4 141 /**
013a5f1c 142 * The first graph node in list (multiple selection).
df0b8ff4 143 */
cab6c8ff 144 private GraphNode fListStart = null;
df0b8ff4 145 /**
013a5f1c 146 * The previous graph node (multiple selection).
df0b8ff4 147 */
cab6c8ff 148 private List<GraphNode> fPrevList = null;
df0b8ff4 149 /**
013a5f1c 150 * The time compression bar.
df0b8ff4 151 */
cab6c8ff 152 private TimeCompressionBar fTimeBar = null;
df0b8ff4 153 /**
013a5f1c 154 * The current diagram tool tip.
df0b8ff4 155 */
cab6c8ff 156 private DiagramToolTip fToolTip = null;
df0b8ff4
BH
157 /**
158 * The accessible object reference of view control.
159 */
cab6c8ff 160 private Accessible fAccessible = null;
df0b8ff4
BH
161 /**
162 * The current node for the tooltip to display.
163 */
cab6c8ff 164 private GraphNode fToolTipNode;
df0b8ff4
BH
165 /**
166 * The life line to drag and drop.
167 */
cab6c8ff 168 private Lifeline fDragAndDrop = null;
df0b8ff4 169 /**
013a5f1c 170 * The number of focused widgets.
df0b8ff4 171 */
cab6c8ff 172 private int fFocusedWidget = -1;
df0b8ff4
BH
173 /**
174 * The printer zoom.
175 */
cab6c8ff 176 private float fPrinterZoom = 0;
df0b8ff4
BH
177 /**
178 * Y coordinate for printer.
179 */
cab6c8ff 180 private int fPrinterY = 0;
df0b8ff4
BH
181 /**
182 * X coordinate for printer.
183 */
cab6c8ff 184 private int fPrinterX = 0;
df0b8ff4 185 /**
013a5f1c 186 * Flag whether drag and drop is enabled or not.
df0b8ff4 187 */
cab6c8ff 188 private boolean fIsDragAndDrop = false;
df0b8ff4
BH
189 /**
190 * The x coordinate for drag.
191 */
cab6c8ff 192 private int fDragX = 0;
df0b8ff4
BH
193 /**
194 * The y coordinate for drag.
195 */
cab6c8ff 196 private int fDragY = 0;
df0b8ff4
BH
197 /**
198 * The reorder mode.
199 */
cab6c8ff 200 private boolean fReorderMode = false;
df0b8ff4
BH
201 /**
202 * The collapse caret image.
203 */
cab6c8ff 204 private Image fCollapaseCaretImg = null;
df0b8ff4
BH
205 /**
206 * The arrow up caret image.
207 */
cab6c8ff 208 private Image fArrowUpCaretImg = null;
df0b8ff4
BH
209 /**
210 * The current caret image.
211 */
cab6c8ff 212 private Image fCurrentCaretImage = null;
df0b8ff4
BH
213 /**
214 * A sequence diagramm collapse provider (for collapsing graph nodes)
215 */
cab6c8ff 216 private ISDCollapseProvider fCollapseProvider = null;
df0b8ff4
BH
217 /**
218 * The insertion caret.
219 */
cab6c8ff 220 private Caret fInsertionCartet = null;
df0b8ff4
BH
221 /**
222 * The reorder list when in reorder mode.
223 */
cab6c8ff 224 private List<Lifeline[]> fReorderList = null;
df0b8ff4
BH
225 /**
226 * Flag to specify whether in printing mode or not.
227 */
cab6c8ff 228 private boolean fIsPrinting = false;
df0b8ff4
BH
229 /**
230 * A printer reference.
231 */
cab6c8ff 232 private Printer fPrinter = null;
df0b8ff4 233 /**
013a5f1c 234 * Flag whether shift was selected or not.
df0b8ff4 235 */
cab6c8ff 236 private boolean fShiftSelection = false;
df0b8ff4 237 /**
013a5f1c 238 * The scroll tooltip.
df0b8ff4 239 */
cab6c8ff 240 private DiagramToolTip fScrollToolTip = null;
013a5f1c
AM
241 /**
242 * Timer for auto_scroll feature
df0b8ff4 243 */
cab6c8ff 244 private AutoScroll fLocalAutoScroll = null;
df0b8ff4 245 /**
013a5f1c 246 * TimerTask for auto_scroll feature !=null when auto scroll is running
df0b8ff4 247 */
cab6c8ff 248 private Timer fLocalAutoScrollTimer = null;
73005152 249
df0b8ff4
BH
250 // ------------------------------------------------------------------------
251 // Constructor
252 // ------------------------------------------------------------------------
253 /**
254 * Constructor for SDWidget.
255 * @param c The parent composite
256 * @param s The style
257 */
73005152
BH
258 public SDWidget(Composite c, int s) {
259 super(c, s | SWT.NO_BACKGROUND, true);
260 setOverviewEnabled(true);
eb63f5ff
BH
261 fSelectedNodeList = new ArrayList<GraphNode>();
262 fSelProvider = new SDWidgetSelectionProvider();
73005152 263 SDViewPref.getInstance().addPropertyChangeListener(this);
eb63f5ff 264 fToolTip = new DiagramToolTip(getViewControl());
73005152
BH
265 super.addDisposeListener(this);
266
eb63f5ff 267 fScrollToolTip = new DiagramToolTip(c);
73005152
BH
268 getVerticalBar().addListener(SWT.MouseUp, new Listener() {
269
270 @Override
271 public void handleEvent(Event event) {
eb63f5ff 272 fScrollToolTip.hideToolTip();
73005152
BH
273 }
274
275 });
eb63f5ff 276 fAccessible = getViewControl().getAccessible();
73005152 277
eb63f5ff 278 fAccessible.addAccessibleListener(new AccessibleAdapter() {
73005152
BH
279 @Override
280 public void getName(AccessibleEvent e) {
73005152 281 // Case toolTip
df0b8ff4 282 if (e.childID == 0) {
eb63f5ff
BH
283 if (fToolTipNode != null) {
284 if (fToolTipNode instanceof Lifeline) {
285 Lifeline lifeline = (Lifeline) fToolTipNode;
73005152
BH
286 e.result = lifeline.getToolTipText();
287 } else {
eb63f5ff 288 e.result = fToolTipNode.getName() + getPostfixForTooltip(true);
73005152
BH
289 }
290 }
291 } else {
292 if (getFocusNode() != null) {
293 if (getFocusNode() instanceof Lifeline) {
92330441 294 e.result = MessageFormat.format(Messages.SequenceDiagram_LifelineNode, new Object[] { String.valueOf(getFocusNode().getName()) });
73005152
BH
295 }
296 if (getFocusNode() instanceof BaseMessage) {
297 BaseMessage mes = (BaseMessage) getFocusNode();
298 if ((mes.getStartLifeline() != null) && (mes.getEndLifeline() != null)) {
299 e.result = MessageFormat.format(
92330441 300 Messages.SequenceDiagram_MessageNode,
73005152
BH
301 new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getStartLifeline().getName()), Integer.valueOf(mes.getStartOccurrence()), String.valueOf(mes.getEndLifeline().getName()),
302 Integer.valueOf(mes.getEndOccurrence()) });
303 } else if ((mes.getStartLifeline() == null) && (mes.getEndLifeline() != null)) {
92330441 304 e.result = MessageFormat.format(Messages.SequenceDiagram_FoundMessageNode, new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getEndLifeline().getName()), Integer.valueOf(mes.getEndOccurrence()) });
73005152 305 } else if ((mes.getStartLifeline() != null) && (mes.getEndLifeline() == null)) {
92330441 306 e.result = MessageFormat.format(Messages.SequenceDiagram_LostMessageNode, new Object[] { String.valueOf(mes.getName()), String.valueOf(mes.getStartLifeline().getName()), Integer.valueOf(mes.getStartOccurrence()) });
73005152
BH
307 }
308 } else if (getFocusNode() instanceof BasicExecutionOccurrence) {
309 BasicExecutionOccurrence exec = (BasicExecutionOccurrence) getFocusNode();
92330441 310 e.result = MessageFormat.format(Messages.SequenceDiagram_ExecutionOccurrenceWithParams,
73005152
BH
311 new Object[] { String.valueOf(exec.getName()), String.valueOf(exec.getLifeline().getName()), Integer.valueOf(exec.getStartOccurrence()), Integer.valueOf(exec.getEndOccurrence()) });
312 }
313
314 }
73005152
BH
315 }
316 }
317 });
318
eb63f5ff 319 fAccessible.addAccessibleControlListener(new AccessibleControlAdapter() {
73005152
BH
320 @Override
321 public void getFocus(AccessibleControlEvent e) {
eb63f5ff 322 if (fFocusedWidget == -1) {
73005152 323 e.childID = ACC.CHILDID_SELF;
df0b8ff4 324 } else {
eb63f5ff 325 e.childID = fFocusedWidget;
df0b8ff4 326 }
73005152
BH
327 }
328
329 @Override
330 public void getRole(AccessibleControlEvent e) {
331 switch (e.childID) {
332 case ACC.CHILDID_SELF:
333 e.detail = ACC.ROLE_CLIENT_AREA;
334 break;
335 case 0:
336 e.detail = ACC.ROLE_TOOLTIP;
337 break;
338 case 1:
339 e.detail = ACC.ROLE_LABEL;
340 break;
eb63f5ff
BH
341 default:
342 break;
73005152
BH
343 }
344 }
345
346 @Override
347 public void getState(AccessibleControlEvent e) {
348 e.detail = ACC.STATE_FOCUSABLE;
349 if (e.childID == ACC.CHILDID_SELF) {
350 e.detail |= ACC.STATE_FOCUSED;
351 } else {
352 e.detail |= ACC.STATE_SELECTABLE;
013a5f1c 353 if (e.childID == fFocusedWidget) {
73005152 354 e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED;
013a5f1c 355 }
73005152
BH
356 }
357 }
358 });
359
eb63f5ff
BH
360 fInsertionCartet = new Caret((Canvas) getViewControl(), SWT.NONE);
361 fInsertionCartet.setVisible(false);
73005152 362
8fd82db5
FC
363 fCollapaseCaretImg = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_COLLAPSE_OBJ);
364 fArrowUpCaretImg = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_ARROW_UP_OBJ);
73005152 365
eb63f5ff 366 fReorderList = new ArrayList<Lifeline[]>();
3145ec83 367 getViewControl().addTraverseListener(new LocalTraverseListener());
73005152 368
3145ec83 369 addTraverseListener(new LocalTraverseListener());
73005152
BH
370
371 getViewControl().addFocusListener(new FocusListener() {
372
373 @Override
374 public void focusGained(FocusEvent e) {
73005152 375 SDViewPref.getInstance().setNoFocusSelection(false);
eb63f5ff
BH
376 fCtrlSelection = false;
377 fShiftSelection = false;
73005152
BH
378 redraw();
379 }
380
381 @Override
382 public void focusLost(FocusEvent e) {
383 SDViewPref.getInstance().setNoFocusSelection(true);
384 redraw();
385 }
386 });
387 }
013a5f1c 388
df0b8ff4
BH
389 // ------------------------------------------------------------------------
390 // Operations
391 // ------------------------------------------------------------------------
11252342 392
df0b8ff4
BH
393 /**
394 * Sets the time compression bar.
013a5f1c 395 *
df0b8ff4
BH
396 * @param bar The time compression bar to set
397 */
73005152
BH
398 public void setTimeBar(TimeCompressionBar bar) {
399 if (bar != null) {
eb63f5ff
BH
400 fTimeBar = bar;
401 fTimeBar.addTimeCompressionListener(this);
73005152
BH
402 }
403 }
013a5f1c 404
73005152
BH
405 /**
406 * Resize the contents to insure the frame fit into the view
013a5f1c 407 *
73005152
BH
408 * @param frame the frame which will be drawn in the view
409 */
410 public void resizeContents(Frame frame) {
eb63f5ff
BH
411 int width = Math.round((frame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue);
412 int height = Math.round((frame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue);
73005152
BH
413 resizeContents(width, height);
414 }
415
73005152
BH
416 /**
417 * The frame to render (the sequence diagram)
013a5f1c 418 *
73005152 419 * @param theFrame the frame to display
df0b8ff4 420 * @param resetPosition boolean
73005152
BH
421 */
422 public void setFrame(Frame theFrame, boolean resetPosition) {
eb63f5ff
BH
423 fReorderList.clear();
424 fSelectedNodeList.clear();
425 fSelProvider.setSelection(new StructuredSelection());
426 fFrame = theFrame;
73005152
BH
427 if (resetPosition) {
428 setContentsPos(0, 0);
eb63f5ff 429 resizeContents(fFrame);
73005152
BH
430 redraw();
431 }
432 // prepare the old overview to be reused
eb63f5ff
BH
433 if (fOverView != null) {
434 fOverView.dispose();
df0b8ff4 435 }
eb63f5ff
BH
436 fOverView = null;
437 resizeContents(fFrame);
73005152
BH
438 }
439
440 /**
441 * Returns the current Frame (the sequence diagram container)
013a5f1c
AM
442 *
443 * @return the frame
73005152
BH
444 */
445 public Frame getFrame() {
eb63f5ff 446 return fFrame;
73005152
BH
447 }
448
449 /**
450 * Returns the selection provider for the current sequence diagram
013a5f1c
AM
451 *
452 * @return the selection provider
73005152
BH
453 */
454 public ISelectionProvider getSelectionProvider() {
eb63f5ff 455 return fSelProvider;
73005152 456 }
013a5f1c 457
df0b8ff4
BH
458 /**
459 * Returns a list of selected graph nodes.
013a5f1c 460 *
df0b8ff4
BH
461 * @return a list of selected graph nodes.
462 */
463 public List<GraphNode> getSelection() {
eb63f5ff 464 return fSelectedNodeList;
73005152
BH
465 }
466
df0b8ff4
BH
467 /**
468 * Adds a graph node to the selected nodes list.
013a5f1c 469 *
df0b8ff4
BH
470 * @param node A graph node
471 */
472 public void addSelection(GraphNode node) {
473 if (node == null) {
474 return;
475 }
eb63f5ff 476 fSelectedNodeList.add(node);
df0b8ff4 477 node.setSelected(true);
eb63f5ff
BH
478 fCurrentGraphNode = node;
479 StructuredSelection selection = new StructuredSelection(fSelectedNodeList);
480 fSelProvider.setSelection(selection);
df0b8ff4
BH
481 }
482
483 /**
484 * Adds a list of node to the selected nodes list.
013a5f1c 485 *
df0b8ff4
BH
486 * @param list of graph nodes
487 */
488 public void addSelection(List<GraphNode> list) {
df0b8ff4 489 for (int i = 0; i < list.size(); i++) {
eb63f5ff
BH
490 if (!fSelectedNodeList.contains(list.get(i))) {
491 fSelectedNodeList.add(list.get(i));
abbdd66a 492 list.get(i).setSelected(true);
df0b8ff4
BH
493 }
494 }
eb63f5ff
BH
495 StructuredSelection selection = new StructuredSelection(fSelectedNodeList);
496 fSelProvider.setSelection(selection);
df0b8ff4
BH
497 }
498
499 /**
500 * Removes a node from the selected nodes list.
013a5f1c 501 *
df0b8ff4
BH
502 * @param node to remove
503 */
504 public void removeSelection(GraphNode node) {
eb63f5ff 505 fSelectedNodeList.remove(node);
df0b8ff4
BH
506 node.setSelected(false);
507 node.setFocused(false);
eb63f5ff
BH
508 StructuredSelection selection = new StructuredSelection(fSelectedNodeList);
509 fSelProvider.setSelection(selection);
df0b8ff4
BH
510 }
511
512 /**
513 * Removes a list of graph nodes from the selected nodes list.
013a5f1c 514 *
df0b8ff4
BH
515 * @param list of nodes to remove.
516 */
517 public void removeSelection(List<GraphNode> list) {
eb63f5ff 518 fSelectedNodeList.removeAll(list);
df0b8ff4 519 for (int i = 0; i < list.size(); i++) {
abbdd66a
AM
520 list.get(i).setSelected(false);
521 list.get(i).setFocused(false);
df0b8ff4 522 }
eb63f5ff
BH
523 StructuredSelection selection = new StructuredSelection(fSelectedNodeList);
524 fSelProvider.setSelection(selection);
df0b8ff4
BH
525 }
526
527 /**
528 * Clear the list of GraphNodes which must be drawn selected.
529 */
530 public void clearSelection() {
eb63f5ff 531 for (int i = 0; i < fSelectedNodeList.size(); i++) {
abbdd66a
AM
532 fSelectedNodeList.get(i).setSelected(false);
533 fSelectedNodeList.get(i).setFocused(false);
df0b8ff4 534 }
eb63f5ff
BH
535 fCurrentGraphNode = null;
536 fSelectedNodeList.clear();
537 fSelProvider.setSelection(new StructuredSelection());
df0b8ff4
BH
538 }
539
540 /**
541 * Sets view part.
013a5f1c 542 *
df0b8ff4
BH
543 * @param viewSite The view part to set
544 */
545 public void setSite(ViewPart viewSite) {
eb63f5ff
BH
546 fSite = viewSite;
547 fSite.getSite().setSelectionProvider(fSelProvider);
548 IContextService service = (IContextService) fSite.getSite().getWorkbenchWindow().getService(IContextService.class);
df0b8ff4
BH
549 service.activateContext("org.eclipse.linuxtools.tmf.ui.view.uml2sd.context"); //$NON-NLS-1$
550 service.activateContext(IContextIds.CONTEXT_ID_WINDOW);
551 }
552
553 /**
554 * Returns the GraphNode overView the mouse if any
013a5f1c
AM
555 *
556 * @return the current graph node
df0b8ff4
BH
557 * */
558 public GraphNode getMouseOverNode() {
eb63f5ff 559 return fCurrentGraphNode;
df0b8ff4 560 }
013a5f1c 561
df0b8ff4
BH
562 /**
563 * Sets the zoom in mode.
013a5f1c 564 *
a55887ca
AM
565 * @param value
566 * The mode value to set.
df0b8ff4
BH
567 */
568 public void setZoomInMode(boolean value) {
569 if (value) {
570 setZoomOutMode(false);
571 }
eb63f5ff 572 fZoomInMode = value;
df0b8ff4
BH
573 }
574
575 /**
576 * Sets the zoom out mode.
013a5f1c 577 *
a55887ca 578 * @param value
cab6c8ff 579 * The mode value to set.
df0b8ff4
BH
580 */
581 public void setZoomOutMode(boolean value) {
582 if (value) {
583 setZoomInMode(false);
584 }
eb63f5ff 585 fZoomOutMode = value;
df0b8ff4
BH
586 }
587
cab6c8ff
BH
588 /**
589 * Sets the current zoom value.
590 *
591 * @param zoomValue
592 * The current zoom value
593 * @since 2.0
594 */
595 public void setZoomValue(float zoomValue) {
596 fZoomValue = zoomValue;
597 }
598
df0b8ff4
BH
599 /**
600 * Moves the Sequence diagram to ensure the given node is visible and draw it selected
013a5f1c 601 *
df0b8ff4
BH
602 * @param node the GraphNode to move to
603 */
604 public void moveTo(GraphNode node) {
605 if (node == null) {
606 return;
607 }
608 clearSelection();
609 addSelection(node);
610 ensureVisible(node);
611 }
612
613 /**
614 * Moves the Sequence diagram to ensure the given node is visible
013a5f1c 615 *
df0b8ff4
BH
616 * @param node the GraphNode to move to
617 */
618 public void ensureVisible(GraphNode node) {
619 if (node == null) {
620 return;
621 }
eb63f5ff
BH
622 int x = Math.round(node.getX() * fZoomValue);
623 int y = Math.round(node.getY() * fZoomValue);
624 int width = Math.round(node.getWidth() * fZoomValue);
625 int height = Math.round(node.getHeight() * fZoomValue);
626 if ((node instanceof BaseMessage) && (height == 0)) {
627 int header = Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN * 2 + Metrics.getLifelineHeaderFontHeigth();
628 height = -Math.round((Metrics.getMessagesSpacing() + header) * fZoomValue);
629 y = y + Math.round(Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT * fZoomValue);
df0b8ff4
BH
630 }
631 if (node instanceof BasicExecutionOccurrence) {
632 width = 1;
633 height = 1;
634 }
635 if (node instanceof Lifeline) {
636 y = getContentsY();
637 height = getVisibleHeight();
638 }
639 ensureVisible(x, y, width, height, SWT.CENTER, true);
640 redraw();
641 }
642
643 /**
644 * Returns the current zoom factor.
645 * @return the current zoom factor.
646 */
647 public float getZoomFactor() {
eb63f5ff 648 return fZoomValue;
df0b8ff4
BH
649 }
650
651 /**
652 * Returns teh printer reference.
013a5f1c 653 *
df0b8ff4
BH
654 * @return the printer reference
655 */
656 public Printer getPrinter() {
eb63f5ff 657 return fPrinter;
df0b8ff4
BH
658 }
659
660 /**
661 * Returns whether the widget is used for printing or not.
013a5f1c 662 *
df0b8ff4
BH
663 * @return whether the widget is used for printing or not
664 */
665 public boolean isPrinting() {
eb63f5ff 666 return fIsPrinting;
df0b8ff4
BH
667 }
668
cab6c8ff
BH
669 /**
670 * Returns the current graph node.
671 *
672 * @return the current graph node
673 * @since 2.0
674 */
675 public GraphNode getCurrentGraphNode() {
676 return fCurrentGraphNode;
677 }
678
679 /**
680 * Returns the current zoom value.
681 *
682 * @return the current zoom value
683 * @since 2.0
684 */
685 public float getZoomValue() {
686 return fZoomValue;
687 }
688
689 /**
690 * Gets the zoom in mode.
691 *
692 * @return the mode value to set.
693 * @since 2.0
694 */
695 public boolean getZoomInMode() {
696 return fZoomInMode;
697 }
698
699
700 /**
701 * Gets the zoom out mode.
702 *
703 * @return the mode value to set.
704 * @since 2.0
705 */
706 public boolean getZoomOutMode() {
707 return fZoomOutMode;
708 }
709
710 /**
711 * Returns if ctrl selection
712 * @return true if ctrl selection else false
713 * @since 2.0
714 */
715 public boolean isCtrlSelection() {
716 return fCtrlSelection;
717 }
718
719 /**
720 * Returns if shift selection
721 * @return true if shift Selection else false
722 * @since 2.0
723 */
724 public boolean isShiftSelection() {
725 return fCtrlSelection;
726 }
727
df0b8ff4
BH
728 /**
729 * Gets the overview image.
013a5f1c 730 *
df0b8ff4
BH
731 * @param rect Rectangle to include overview.
732 * @return the overview image
733 */
734 public Image getOverview(Rectangle rect) {
eb63f5ff
BH
735 float oldzoom = fZoomValue;
736 if ((fOverView != null) && ((rect.width != fOverView.getBounds().width) || (rect.height != fOverView.getBounds().height))) {
737 fOverView.dispose();
738 fOverView = null;
df0b8ff4 739 }
eb63f5ff 740 if (fOverView == null) {
df0b8ff4
BH
741 int backX = getContentsX();
742 int backY = getContentsY();
743 setContentsPos(0, 0);
eb63f5ff
BH
744 fOverView = new Image(getDisplay(), rect.width, rect.height);
745 GC gcim = new GC(fOverView);
df0b8ff4 746 NGC context = new NGC(this, gcim);
abbdd66a 747 context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME));
eb63f5ff 748 fFrame.draw(context);
df0b8ff4
BH
749 setContentsPos(backX, backY);
750 gcim.dispose();
751 context.dispose();
752 }
eb63f5ff
BH
753 fZoomValue = oldzoom;
754 return fOverView;
df0b8ff4 755 }
013a5f1c 756
df0b8ff4
BH
757 /**
758 * Resets the zoom factor.
759 */
760 public void resetZoomFactor() {
eb63f5ff
BH
761 int currentX = Math.round(getContentsX() / fZoomValue);
762 int currentY = Math.round(getContentsY() / fZoomValue);
763 fZoomValue = 1;
764 if (fTimeBar != null && !fTimeBar.isDisposed()) {
765 fTimeBar.setZoom(fZoomValue);
df0b8ff4
BH
766 }
767 redraw();
768 update();
769 setContentsPos(currentX, currentY);
770 }
771
772 /**
773 * Enable or disable the lifeline reodering using Drag and Drop
013a5f1c 774 *
df0b8ff4
BH
775 * @param mode - true to enable false otherwise
776 */
777 public void setReorderMode(boolean mode) {
eb63f5ff 778 fReorderMode = mode;
df0b8ff4
BH
779 }
780
781 /**
782 * Return the lifelines reorder sequence (using Drag and Drop) if the the reorder mode is turn on. Each ArryList
783 * element is of type Lifeline[2] with Lifeline[0] inserted before Lifeline[1] in the diagram
013a5f1c
AM
784 *
785 * @return - the re-odered sequence
df0b8ff4 786 */
3145ec83 787 public List<Lifeline[]> getLifelineReoderList() {
eb63f5ff 788 return fReorderList;
df0b8ff4
BH
789 }
790
791 /**
792 * Sets the focus on given graph node (current node).
013a5f1c 793 *
a55887ca
AM
794 * @param node
795 * The graph node to focus on.
df0b8ff4
BH
796 */
797 public void setFocus(GraphNode node) {
798 if (node == null) {
799 return;
800 }
eb63f5ff
BH
801 if (fCurrentGraphNode != null) {
802 fCurrentGraphNode.setFocused(false);
df0b8ff4 803 }
eb63f5ff 804 fCurrentGraphNode = node;
df0b8ff4
BH
805 node.setFocused(true);
806 ensureVisible(node);
807 setFocus(0);
808 }
809
810 /**
811 * Returns the graph node focused on.
013a5f1c 812 *
df0b8ff4
BH
813 * @return the current graph node
814 */
815 public GraphNode getFocusNode() {
eb63f5ff 816 return fCurrentGraphNode;
df0b8ff4
BH
817 }
818
819 /**
820 * Method to traverse right.
821 */
822 public void traverseRight() {
823 Object selectedNode = getFocusNode();
824 if (selectedNode == null) {
825 traverseLeft();
826 }
827 GraphNode node = null;
eb63f5ff
BH
828 if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getEndLifeline() != null)) {
829 node = fFrame.getCalledMessage((BaseMessage) selectedNode);
df0b8ff4
BH
830 }
831 if (selectedNode instanceof BasicExecutionOccurrence) {
832 selectedNode = ((BasicExecutionOccurrence) selectedNode).getLifeline();
833 }
834 if ((node == null) && (selectedNode instanceof Lifeline)) {
eb63f5ff
BH
835 for (int i = 0; i < fFrame.lifeLinesCount(); i++) {
836 if ((selectedNode == fFrame.getLifeline(i)) && (i < fFrame.lifeLinesCount() - 1)) {
837 node = fFrame.getLifeline(i + 1);
df0b8ff4
BH
838 break;
839 }
840 }
841 }
842 if (node != null) {
843 setFocus(node);
844 redraw();
845 }
846 }
847
848 /**
849 * Method to traverse left.
850 */
851 public void traverseLeft() {
852 Object selectedNode = getFocusNode();
853 GraphNode node = null;
eb63f5ff
BH
854 if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getStartLifeline() != null)) {
855 node = fFrame.getCallerMessage((BaseMessage) selectedNode);
df0b8ff4
BH
856 }
857 if (selectedNode instanceof BasicExecutionOccurrence) {
858 selectedNode = ((BasicExecutionOccurrence) selectedNode).getLifeline();
859 }
860 if (node == null) {
eb63f5ff
BH
861 if ((selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getEndLifeline() != null)) {
862 selectedNode = ((BaseMessage) selectedNode).getEndLifeline();
df0b8ff4 863 }
eb63f5ff
BH
864 for (int i = 0; i < fFrame.lifeLinesCount(); i++) {
865 if ((selectedNode == fFrame.getLifeline(i)) && (i > 0)) {
866 node = fFrame.getLifeline(i - 1);
df0b8ff4
BH
867 break;
868 }
869 }
eb63f5ff
BH
870 if ((fFrame.lifeLinesCount() > 0) && (node == null)) {
871 node = fFrame.getLifeline(0);
df0b8ff4
BH
872 }
873 }
874 if (node != null) {
875 setFocus(node);
876 redraw();
877 }
878 }
879
880 /**
881 * Method to traverse up.
882 */
883 public void traverseUp() {
884 Object selectedNode = getFocusNode();
885 if (selectedNode == null) {
886 traverseLeft();
887 }
888 GraphNode node = null;
889 if (selectedNode instanceof BaseMessage) {
eb63f5ff 890 node = fFrame.getPrevLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), (BaseMessage) selectedNode);
df0b8ff4 891 } else if (selectedNode instanceof Lifeline) {
eb63f5ff 892 node = fFrame.getPrevLifelineMessage((Lifeline) selectedNode, null);
df0b8ff4
BH
893 if (!(node instanceof Lifeline)) {
894 node = null;
895 }
896 } else if (selectedNode instanceof BasicExecutionOccurrence) {
eb63f5ff 897 node = fFrame.getPrevExecOccurrence((BasicExecutionOccurrence) selectedNode);
df0b8ff4
BH
898 if (node == null) {
899 node = ((BasicExecutionOccurrence) selectedNode).getLifeline();
900 }
901 }
eb63f5ff
BH
902 if ((node == null) && (selectedNode instanceof BaseMessage) && (((BaseMessage) selectedNode).getStartLifeline() != null)) {
903 node = ((BaseMessage) selectedNode).getStartLifeline();
df0b8ff4
BH
904 }
905
906 if (node != null) {
907 setFocus(node);
908 redraw();
909 }
910 }
911
912 /**
913 * Method to traverse down.
914 */
915 public void traverseDown() {
916 Object selectedNode = getFocusNode();
917 if (selectedNode == null) {
918 traverseLeft();
919 }
920 GraphNode node;
921 if (selectedNode instanceof BaseMessage) {
eb63f5ff 922 node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), (BaseMessage) selectedNode);
df0b8ff4 923 } else if (selectedNode instanceof Lifeline) {
eb63f5ff 924 node = fFrame.getFirstExecution((Lifeline) selectedNode);
df0b8ff4 925 } else if (selectedNode instanceof BasicExecutionOccurrence) {
eb63f5ff 926 node = fFrame.getNextExecOccurrence((BasicExecutionOccurrence) selectedNode);
df0b8ff4
BH
927 } else {
928 return;
929 }
930
931 if (node != null) {
932 setFocus(node);
933 redraw();
934 }
935 }
936
937 /**
938 * Method to traverse home.
939 */
940 public void traverseHome() {
941 Object selectedNode = getFocusNode();
942 if (selectedNode == null) {
943 traverseLeft();
944 }
945 GraphNode node = null;
013a5f1c 946
df0b8ff4
BH
947 if (selectedNode instanceof BaseMessage) {
948 if (((BaseMessage) selectedNode).getStartLifeline() != null) {
eb63f5ff 949 node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), null);
df0b8ff4 950 } else {
eb63f5ff 951 node = fFrame.getNextLifelineMessage(((BaseMessage) selectedNode).getEndLifeline(), null);
df0b8ff4
BH
952 }
953 } else if (selectedNode instanceof Lifeline) {
eb63f5ff 954 node = fFrame.getNextLifelineMessage((Lifeline) selectedNode, null);
df0b8ff4 955 } else if (selectedNode instanceof BasicExecutionOccurrence) {
eb63f5ff 956 node = fFrame.getFirstExecution(((BasicExecutionOccurrence) selectedNode).getLifeline());
df0b8ff4 957 } else {
eb63f5ff
BH
958 if (fFrame.lifeLinesCount() > 0) {
959 Lifeline lifeline = fFrame.getLifeline(0);
960 node = fFrame.getNextLifelineMessage(lifeline, null);
df0b8ff4
BH
961 }
962 }
963
964 if (node != null) {
965 setFocus(node);
966 redraw();
967 }
968 }
969
970 /**
971 * Method to traverse to the end.
972 */
973 public void traverseEnd() {
974 Object selectedNode = getFocusNode();
975 if (selectedNode == null) {
976 traverseLeft();
977 }
978 GraphNode node;
979 if (selectedNode instanceof BaseMessage) {
eb63f5ff 980 node = fFrame.getPrevLifelineMessage(((BaseMessage) selectedNode).getStartLifeline(), null);
df0b8ff4 981 } else if (selectedNode instanceof Lifeline) {
eb63f5ff 982 node = fFrame.getPrevLifelineMessage((Lifeline) selectedNode, null);
df0b8ff4 983 } else if (selectedNode instanceof BasicExecutionOccurrence) {
eb63f5ff 984 node = fFrame.getLastExecOccurrence(((BasicExecutionOccurrence) selectedNode).getLifeline());
df0b8ff4 985 } else {
eb63f5ff
BH
986 if (fFrame.lifeLinesCount() > 0) {
987 Lifeline lifeline = fFrame.getLifeline(0);
988 node = fFrame.getPrevLifelineMessage(lifeline, null);
df0b8ff4
BH
989 } else {
990 return;
991 }
992 }
993
994 if (node != null) {
995 setFocus(node);
996 redraw();
997 }
998 }
999
1000 /**
1001 * Method to print UI.
013a5f1c 1002 *
df0b8ff4
BH
1003 * @param sdPrintDialog the sequence diagram printer dialog.
1004 */
1005 public void printUI(SDPrintDialogUI sdPrintDialog) {
1006 PrinterData data = sdPrintDialog.getPrinterData();
1007
eb63f5ff 1008 if ((data == null) || (fFrame == null)) {
df0b8ff4
BH
1009 return;
1010 }
013a5f1c 1011
eb63f5ff 1012 fPrinter = new Printer(data);
013a5f1c 1013
92330441 1014 String jobName = MessageFormat.format(Messages.SequenceDiagram_plus, new Object[] { String.valueOf(fSite.getContentDescription()), String.valueOf(fFrame.getName()) });
eb63f5ff 1015 fPrinter.startJob(jobName);
013a5f1c 1016
eb63f5ff 1017 GC gc = new GC(fPrinter);
df0b8ff4 1018
eb63f5ff 1019 float lastZoom = fZoomValue;
df0b8ff4
BH
1020
1021 Rectangle area = getClientArea();
1022 GC gcim = null;
1023
1024 gcim = gc;
1025 NGC context = new NGC(this, gcim);
1026
1027 // Set the metrics to use for lifeline text and message text
1028 // using the Graphical Context
abbdd66a
AM
1029 Metrics.setLifelineFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)));
1030 Metrics.setLifelineFontWidth(context.getFontWidth(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)));
df0b8ff4 1031 Metrics.setLifelineWidth(SDViewPref.getInstance().getLifelineWidth());
3145ec83
BH
1032 Metrics.setFrameFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_FRAME_NAME)));
1033 Metrics.setLifelineHeaderFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE_HEADER)));
df0b8ff4 1034
abbdd66a
AM
1035 int syncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS));
1036 int syncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS_RET));
1037 int asyncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS));
1038 int asyncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS_RET));
df0b8ff4
BH
1039
1040 int messageFontHeight = 0;
1041 if (syncMessFontH > syncMessRetFontH) {
1042 messageFontHeight = syncMessFontH;
1043 } else {
1044 messageFontHeight = syncMessRetFontH;
1045 }
1046 if (messageFontHeight < asyncMessFontH) {
1047 messageFontHeight = asyncMessFontH;
1048 }
1049 if (messageFontHeight < asyncMessRetFontH) {
1050 messageFontHeight = asyncMessRetFontH;
1051 }
1052 Metrics.setMessageFontHeight(messageFontHeight);
abbdd66a 1053 context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE));
df0b8ff4 1054
eb63f5ff
BH
1055 int width = Math.round((fFrame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue);
1056 int height = Math.round((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue);
df0b8ff4
BH
1057 if (width < area.width) {
1058 width = area.width;
1059 }
1060 if (height < area.height) {
1061 height = area.height;
1062 }
1063 resizeContents(width, height);
1064
3145ec83 1065 context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME));
df0b8ff4 1066 context.fillRectangle(0, 0, getContentsWidth(), Metrics.FRAME_V_MARGIN);
eb63f5ff
BH
1067 context.fillRectangle(0, 0, fFrame.getX(), getContentsHeight());
1068 context.fillRectangle(fFrame.getX() + fFrame.getWidth() + 1, 0, getContentsWidth() - (fFrame.getX() + fFrame.getWidth() + 1), getContentsHeight());
1069 context.fillRectangle(0, fFrame.getY() + fFrame.getHeight() + 1, getContentsWidth(), getContentsHeight() - (fFrame.getY() + fFrame.getHeight() + 1));
df0b8ff4
BH
1070 gcim.setLineWidth(1);
1071
eb63f5ff
BH
1072 fPrinter.startPage();
1073 fZoomValue = lastZoom;
df0b8ff4
BH
1074
1075 int restoreX = getContentsX();
1076 int restoreY = getContentsY();
1077
eb63f5ff
BH
1078 float zh = sdPrintDialog.getStepY() * sdPrintDialog.getZoomFactor();
1079 float zw = sdPrintDialog.getStepX() * sdPrintDialog.getZoomFactor();
df0b8ff4 1080
eb63f5ff
BH
1081 float zoomValueH = fPrinter.getClientArea().height / zh;
1082 float zoomValueW = fPrinter.getClientArea().width / zw;
df0b8ff4 1083 if (zoomValueH > zoomValueW) {
eb63f5ff 1084 fPrinterZoom = zoomValueH;
df0b8ff4 1085 } else {
eb63f5ff 1086 fPrinterZoom = zoomValueW;
df0b8ff4
BH
1087 }
1088
1089 if (sdPrintDialog.printSelection()) {
1090 int[] pagesList = sdPrintDialog.getPageList();
1091
1092 for (int pageIndex = 0; pageIndex < pagesList.length; pageIndex++) {
1093 printPage(pagesList[pageIndex], sdPrintDialog, context);
1094 }
1095 } else if (sdPrintDialog.printAll()) {
1096 for (int pageIndex = 1; pageIndex <= sdPrintDialog.maxNumOfPages(); pageIndex++) {
1097 printPage(pageIndex, sdPrintDialog, context);
1098 }
1099 } else if (sdPrintDialog.printCurrent()) {
1100 printPage(getContentsX(), getContentsY(), sdPrintDialog, context, 1);
1101 } else if (sdPrintDialog.printRange()) {
1102 for (int pageIndex = sdPrintDialog.getFrom(); pageIndex <= sdPrintDialog.maxNumOfPages() && pageIndex <= sdPrintDialog.getTo(); pageIndex++) {
1103 printPage(pageIndex, sdPrintDialog, context);
1104 }
1105 }
1106
eb63f5ff
BH
1107 fPrinter.endJob();
1108 fIsPrinting = false;
df0b8ff4
BH
1109
1110 gc.dispose();
1111 context.dispose();
1112
eb63f5ff
BH
1113 fZoomValue = lastZoom;
1114 fPrinter.dispose();
df0b8ff4
BH
1115 setContentsPos(restoreX, restoreY);
1116 }
1117
1118 /**
1119 * Method to print.
1120 */
1121 public void print() {
1122 SDPrintDialog sdPrinter = new SDPrintDialog(this.getShell(), this);
1123 try {
1124 if (sdPrinter.open() != 0) {
1125 return;
1126 }
1127 } catch (Exception e) {
8fd82db5 1128 Activator.getDefault().logError("Error creating image", e); //$NON-NLS-1$
df0b8ff4
BH
1129 return;
1130 }
1131 printUI(sdPrinter.getDialogUI());
1132 }
1133
1134 /**
1135 * Method to print a page.
013a5f1c 1136 *
df0b8ff4
BH
1137 * @param pageNum The page number
1138 * @param pd The sequence diagram print dialog
1139 * @param context The graphical context
1140 */
1141 public void printPage(int pageNum, SDPrintDialogUI pd, NGC context) {
1142 int j = pageNum / pd.getNbRow();
1143 int i = pageNum % pd.getNbRow();
1144 if (i != 0) {
1145 j++;
1146 } else {
1147 i = pd.getNbRow();
1148 }
1149
1150 i--;
1151 j--;
1152
1153 i = (int) (i * pd.getStepX());
1154 j = (int) (j * pd.getStepY());
1155
1156 printPage(i, j, pd, context, pageNum);
1157
eb63f5ff 1158 fPrinter.endPage();
df0b8ff4
BH
1159 }
1160
1161 /**
1162 * Method to print page ranges.
013a5f1c 1163 *
a55887ca
AM
1164 * @param i
1165 * The start page
1166 * @param j
1167 * The end page
1168 * @param pd
1169 * The sequence diagram print dialog
1170 * @param context
1171 * The graphical context
1172 * @param pageNum
1173 * The current page
df0b8ff4
BH
1174 */
1175 public void printPage(int i, int j, SDPrintDialogUI pd, NGC context, int pageNum) {
eb63f5ff
BH
1176 fIsPrinting = false;
1177 int pageNumFontZoom = fPrinter.getClientArea().height / getVisibleHeight();
1178 fPrinterX = i;
1179 fPrinterY = j;
df0b8ff4
BH
1180 setContentsPos(i, j);
1181 update();
eb63f5ff
BH
1182 fIsPrinting = true;
1183 float lastZoom = fZoomValue;
1184 fZoomValue = fPrinterZoom * lastZoom;
df0b8ff4 1185
eb63f5ff 1186 fFrame.draw(context);
df0b8ff4 1187
eb63f5ff 1188 fZoomValue = pageNumFontZoom;
abbdd66a 1189 context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE));
df0b8ff4
BH
1190 String currentPageNum = String.valueOf(pageNum);
1191 int ii = context.textExtent(currentPageNum);
1192 int jj = context.getCurrentFontHeight();
eb63f5ff
BH
1193 fZoomValue = fPrinterZoom * lastZoom;
1194 context.drawText(currentPageNum, Math.round(fPrinterX + getVisibleWidth() / fPrinterZoom - ii / fPrinterZoom), Math.round(fPrinterY + getVisibleHeight() / fPrinterZoom - jj / fPrinterZoom), false);
1195 fIsPrinting = false;
1196 fZoomValue = lastZoom;
df0b8ff4 1197 }
013a5f1c 1198
df0b8ff4
BH
1199 /**
1200 * Sets the collapse provider.
013a5f1c 1201 *
df0b8ff4
BH
1202 * @param provider The collapse provider to set
1203 */
1204 protected void setCollapseProvider(ISDCollapseProvider provider) {
eb63f5ff 1205 fCollapseProvider = provider;
df0b8ff4
BH
1206 }
1207
013a5f1c 1208
df0b8ff4
BH
1209 /**
1210 * Checks for focus of children.
013a5f1c 1211 *
df0b8ff4
BH
1212 * @param children Control to check
1213 * @return true if child is on focus else false
1214 */
1215 protected boolean checkFocusOnChilds(Control children) {
1216 if (children instanceof Composite) {
1217 Control[] child = ((Composite) children).getChildren();
1218 for (int i = 0; i < child.length; i++) {
1219 if (child[i].isFocusControl()) {
1220 return true;
73005152 1221 }
abbdd66a 1222 checkFocusOnChilds(child[i]);
df0b8ff4 1223 }
73005152 1224 }
df0b8ff4 1225 return false;
73005152
BH
1226 }
1227
df0b8ff4
BH
1228 /**
1229 * A post action for a tooltip (before displaying).
013a5f1c 1230 *
df0b8ff4
BH
1231 * @param accessible true if accessible else false
1232 * @return the tooltip text.
1233 */
73005152 1234 protected String getPostfixForTooltip(boolean accessible) {
3145ec83 1235 StringBuffer postfix = new StringBuffer();
73005152
BH
1236 // Determine if the tooltip must show the time difference between the current mouse position and
1237 // the last selected graphNode
013a5f1c
AM
1238 if ((fCurrentGraphNode != null) &&
1239 (fCurrentGraphNode instanceof ITimeRange) &&
1240 (fToolTipNode instanceof ITimeRange) &&
1241 (fCurrentGraphNode != fToolTipNode) &&
1242 ((ITimeRange) fToolTipNode).hasTimeInfo() &&
eb63f5ff 1243 ((ITimeRange) fCurrentGraphNode).hasTimeInfo()) {
3145ec83
BH
1244 postfix.append(" -> "); //$NON-NLS-1$
1245 postfix.append(fCurrentGraphNode.getName());
1246 postfix.append("\n"); //$NON-NLS-1$
92330441 1247 postfix.append(Messages.SequenceDiagram_Delta);
3145ec83 1248 postfix.append(" "); //$NON-NLS-1$
013a5f1c 1249
73005152 1250 //double delta = ((ITimeRange)toolTipNode).getLastTime()-((ITimeRange)currentGraphNode).getLastTime();
eb63f5ff
BH
1251 ITmfTimestamp firstTime = ((ITimeRange) fCurrentGraphNode).getEndTime();
1252 ITmfTimestamp lastTime = ((ITimeRange) fToolTipNode).getEndTime();
a9ee1687 1253 ITmfTimestamp delta = lastTime.getDelta(firstTime);
3145ec83
BH
1254 postfix.append(delta.toString());
1255
73005152 1256 } else {
eb63f5ff 1257 if ((fToolTipNode instanceof ITimeRange) && ((ITimeRange) fToolTipNode).hasTimeInfo()) {
3145ec83 1258 postfix.append("\n"); //$NON-NLS-1$
eb63f5ff 1259 ITmfTimestamp firstTime = ((ITimeRange) fToolTipNode).getStartTime();
013a5f1c
AM
1260 ITmfTimestamp lastTime = ((ITimeRange) fToolTipNode).getEndTime();
1261
73005152
BH
1262 if (firstTime != null) {
1263 if (lastTime != null && firstTime.compareTo(lastTime, true) != 0) {
3145ec83
BH
1264 postfix.append("start: "); //$NON-NLS-1$
1265 postfix.append(firstTime.toString());
1266 postfix.append("\n"); //$NON-NLS-1$
013a5f1c 1267 postfix.append("end: "); //$NON-NLS-1$
3145ec83
BH
1268 postfix.append(lastTime.toString());
1269 postfix.append("\n"); //$NON-NLS-1$
df0b8ff4 1270 } else {
3145ec83 1271 postfix.append(firstTime.toString());
df0b8ff4
BH
1272 }
1273 }
1274 else if (lastTime != null) {
3145ec83 1275 postfix.append(lastTime.toString());
73005152 1276 }
73005152
BH
1277 }
1278 }
3145ec83 1279 return postfix.toString();
df0b8ff4 1280 }
73005152 1281
df0b8ff4
BH
1282 /**
1283 * Sets a new focused widget.
013a5f1c 1284 *
df0b8ff4
BH
1285 * @param newFocusShape A new focus shape.
1286 */
1287 protected void setFocus(int newFocusShape) {
eb63f5ff
BH
1288 fFocusedWidget = newFocusShape;
1289 if (fFocusedWidget == -1) {
df0b8ff4
BH
1290 getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF);
1291 } else {
eb63f5ff 1292 getViewControl().getAccessible().setFocus(fFocusedWidget);
df0b8ff4 1293 }
73005152
BH
1294 }
1295
1296 /**
1297 * Highlight the given GraphNode<br>
1298 * The GraphNode is then displayed using the system default selection color
013a5f1c 1299 *
73005152
BH
1300 * @param node the GraphNode to highlight
1301 */
1302 protected void performSelection(GraphNode node) {
eb63f5ff 1303 if ((fCtrlSelection) || (fShiftSelection)) {
73005152 1304 if (node != null) {
eb63f5ff 1305 if (fSelectedNodeList.contains(node)) {
73005152
BH
1306 removeSelection(node);
1307 } else {
1308 addSelection(node);
1309 }
df0b8ff4 1310 } else {
73005152 1311 return;
df0b8ff4 1312 }
73005152
BH
1313 } else {
1314 clearSelection();
1315 if (node != null) {
1316 addSelection(node);
1317 }
1318 }
1319 }
1320
73005152 1321 /**
df0b8ff4 1322 * Returns a draw buffer image.
013a5f1c
AM
1323 *
1324 * @return a Image containing the draw buffer.
73005152 1325 */
df0b8ff4 1326 protected Image getDrawBuffer() {
73005152
BH
1327
1328 update();
1329 Rectangle area = getClientArea();
1330 Image dbuffer = null;
1331 GC gcim = null;
1332
1333 try {
73005152
BH
1334 dbuffer = new Image(getDisplay(), area.width, area.height);
1335 } catch (Exception e) {
8fd82db5 1336 Activator.getDefault().logError("Error creating image", e); //$NON-NLS-1$
73005152 1337 }
df0b8ff4 1338
73005152
BH
1339 gcim = new GC(dbuffer);
1340
1341 NGC context = new NGC(this, gcim);
1342
1343 // Set the metrics to use for lifeline text and message text
1344 // using the Graphical Context
abbdd66a
AM
1345 Metrics.setLifelineFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)));
1346 Metrics.setLifelineFontWidth(context.getFontWidth(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE)));
73005152 1347 Metrics.setLifelineWidth(SDViewPref.getInstance().getLifelineWidth());
3145ec83
BH
1348 Metrics.setFrameFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_FRAME_NAME)));
1349 Metrics.setLifelineHeaderFontHeight(context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE_HEADER)));
73005152 1350
abbdd66a
AM
1351 int syncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS));
1352 int syncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_SYNC_MESS_RET));
1353 int asyncMessFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS));
1354 int asyncMessRetFontH = context.getFontHeight(SDViewPref.getInstance().getFont(ISDPreferences.PREF_ASYNC_MESS_RET));
73005152
BH
1355
1356 int messageFontHeight = 0;
df0b8ff4 1357 if (syncMessFontH > syncMessRetFontH) {
73005152 1358 messageFontHeight = syncMessFontH;
df0b8ff4 1359 } else {
73005152 1360 messageFontHeight = syncMessRetFontH;
df0b8ff4
BH
1361 }
1362 if (messageFontHeight < asyncMessFontH) {
73005152 1363 messageFontHeight = asyncMessFontH;
df0b8ff4
BH
1364 }
1365 if (messageFontHeight < asyncMessRetFontH) {
73005152 1366 messageFontHeight = asyncMessRetFontH;
df0b8ff4 1367 }
73005152 1368 Metrics.setMessageFontHeight(messageFontHeight);
abbdd66a 1369 context.setFont(SDViewPref.getInstance().getFont(ISDPreferences.PREF_LIFELINE));
73005152 1370
eb63f5ff
BH
1371 int width = (int) ((fFrame.getWidth() + 2 * Metrics.FRAME_H_MARGIN) * fZoomValue);
1372 int height = (int) ((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue);
df0b8ff4 1373
73005152
BH
1374 resizeContents(width, height);
1375
3145ec83 1376 context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME));
73005152 1377 context.fillRectangle(0, 0, getContentsWidth(), Metrics.FRAME_V_MARGIN);
eb63f5ff
BH
1378 context.fillRectangle(0, 0, fFrame.getX(), getContentsHeight());
1379 context.fillRectangle(fFrame.getX() + fFrame.getWidth() + 1, 0, getContentsWidth() - (fFrame.getX() + fFrame.getWidth() + 1), getContentsHeight());
1380 context.fillRectangle(0, fFrame.getY() + fFrame.getHeight() + 1, getContentsWidth(), getContentsHeight() - (fFrame.getY() + fFrame.getHeight() + 1));
73005152
BH
1381 gcim.setLineWidth(1);
1382
eb63f5ff
BH
1383 fFrame.draw(context);
1384 if (fDragAndDrop != null) {
abbdd66a 1385 Lifeline node = fDragAndDrop;
eb63f5ff
BH
1386 boolean isSelected = fDragAndDrop.isSelected();
1387 boolean hasFocus = fDragAndDrop.hasFocus();
73005152
BH
1388 node.setSelected(false);
1389 node.setFocused(false);
eb63f5ff 1390 node.draw(context, fDragX, fDragY);
73005152
BH
1391 node.setSelected(isSelected);
1392 node.setFocused(hasFocus);
1393 }
1394 gcim.dispose();
1395 context.dispose();
1396 return dbuffer;
1397 }
013a5f1c 1398
73005152 1399 @Override
df0b8ff4
BH
1400 protected void keyPressedEvent(KeyEvent event) {
1401 if (!(isFocusControl() || getViewControl().isFocusControl())) {
1402 Control[] child = getParent().getChildren();
1403 for (int i = 0; i < child.length; i++) {
eb63f5ff
BH
1404 if ((child[i].isFocusControl())&& (!(child[i] instanceof ScrollView))) {
1405 getViewControl().setFocus();
1406 break;
df0b8ff4
BH
1407 }
1408 }
73005152 1409 }
df0b8ff4 1410 setFocus(-1);
73005152 1411
df0b8ff4 1412 if (event.keyCode == SWT.CTRL) {
eb63f5ff 1413 fCtrlSelection = true;
df0b8ff4
BH
1414 }
1415 if (event.keyCode == SWT.SHIFT) {
eb63f5ff
BH
1416 fShiftSelection = true;
1417 fPrevList = new ArrayList<GraphNode>();
1418 fPrevList.addAll(getSelection());
df0b8ff4 1419 }
73005152 1420
df0b8ff4
BH
1421 GraphNode prevNode = getFocusNode();
1422
1423 if (event.keyCode == SWT.ARROW_RIGHT) {
1424 traverseRight();
73005152 1425 }
df0b8ff4
BH
1426
1427 if (event.keyCode == SWT.ARROW_LEFT) {
1428 traverseLeft();
73005152 1429 }
df0b8ff4
BH
1430
1431 if (event.keyCode == SWT.ARROW_DOWN) {
1432 traverseDown();
73005152 1433 }
73005152 1434
df0b8ff4
BH
1435 if (event.keyCode == SWT.ARROW_UP) {
1436 traverseUp();
1437 }
73005152 1438
df0b8ff4
BH
1439 if (event.keyCode == SWT.HOME) {
1440 traverseHome();
1441 }
73005152 1442
df0b8ff4
BH
1443 if (event.keyCode == SWT.END) {
1444 traverseEnd();
73005152 1445 }
73005152 1446
eb63f5ff
BH
1447 if ((!fShiftSelection) && (!fCtrlSelection)) {
1448 fListStart = fCurrentGraphNode;
df0b8ff4 1449 }
73005152 1450
df0b8ff4 1451 if (event.character == ' ') {
eb63f5ff 1452 performSelection(fCurrentGraphNode);
013a5f1c 1453 if (!fShiftSelection) {
eb63f5ff 1454 fListStart = fCurrentGraphNode;
013a5f1c 1455 }
df0b8ff4 1456 }
73005152 1457
eb63f5ff 1458 if ((fShiftSelection) && (prevNode != getFocusNode())) {
df0b8ff4 1459 clearSelection();
eb63f5ff
BH
1460 addSelection(fPrevList);
1461 addSelection(fFrame.getNodeList(fListStart, getFocusNode()));
df0b8ff4
BH
1462 if (getFocusNode() instanceof Lifeline) {
1463 ensureVisible(getFocusNode().getX(), getFocusNode().getY(), getFocusNode().getWidth(), getFocusNode().getHeight(), SWT.CENTER | SWT.VERTICAL, true);
013a5f1c 1464 } else {
df0b8ff4
BH
1465 ensureVisible(getFocusNode());
1466 }
eb63f5ff 1467 } else if ((!fCtrlSelection) && (!fShiftSelection)) {
73005152 1468
df0b8ff4
BH
1469 clearSelection();
1470 if (getFocusNode() != null) {
1471 addSelection(getFocusNode());
1472
1473 if (getFocusNode() instanceof Lifeline) {
1474 ensureVisible(getFocusNode().getX(), getFocusNode().getY(), getFocusNode().getWidth(), getFocusNode().getHeight(), SWT.CENTER | SWT.VERTICAL, true);
1475 } else {
1476 ensureVisible(getFocusNode());
1477 }
73005152
BH
1478 }
1479 }
df0b8ff4 1480
eb63f5ff
BH
1481 if (fCurrentGraphNode != null) {
1482 fCurrentGraphNode.setFocused(true);
73005152 1483 }
73005152 1484 redraw();
73005152 1485
eb63f5ff
BH
1486 if ((event.character == ' ') && ((fZoomInMode) || (fZoomOutMode))) {
1487 int cx = Math.round((getContentsX() + getVisibleWidth() / 2) / fZoomValue);
1488 int cy = Math.round((getContentsY() + getVisibleHeight() / 2) / fZoomValue);
1489 if (fZoomInMode) {
1490 if (fZoomValue < 64) {
1491 fZoomValue = fZoomValue * (float) 1.25;
df0b8ff4
BH
1492 }
1493 } else {
eb63f5ff 1494 fZoomValue = fZoomValue / (float) 1.25;
df0b8ff4 1495 }
eb63f5ff
BH
1496 int x = Math.round(cx * fZoomValue - getVisibleWidth() / (float) 2);
1497 int y = Math.round(cy * fZoomValue - getVisibleHeight() / (float) 2);
df0b8ff4 1498 setContentsPos(x, y);
eb63f5ff
BH
1499 if (fTimeBar != null) {
1500 fTimeBar.setZoom(fZoomValue);
df0b8ff4
BH
1501 }
1502 // redraw also resize the scrollView content
1503 redraw();
1504 }
73005152
BH
1505 }
1506
73005152 1507 @Override
df0b8ff4
BH
1508 protected void keyReleasedEvent(KeyEvent event) {
1509 setFocus(-1);
013a5f1c 1510 if (event.keyCode == SWT.CTRL) {
eb63f5ff 1511 fCtrlSelection = false;
013a5f1c
AM
1512 }
1513 if (event.keyCode == SWT.SHIFT) {
eb63f5ff 1514 fShiftSelection = false;
013a5f1c 1515 }
df0b8ff4
BH
1516 super.keyReleasedEvent(event);
1517 setFocus(1);
73005152
BH
1518 }
1519
1520 @Override
df0b8ff4
BH
1521 public boolean isFocusControl() {
1522 Control[] child = getChildren();
1523 for (int i = 0; i < child.length; i++) {
1524 if (child[i].isFocusControl()) {
1525 return true;
df0b8ff4 1526 }
abbdd66a 1527 checkFocusOnChilds(child[i]);
73005152 1528 }
df0b8ff4 1529 return false;
73005152
BH
1530 }
1531
df0b8ff4
BH
1532 @Override
1533 public boolean setContentsPos(int x, int y) {
eb63f5ff
BH
1534 int localX = x;
1535 int localY = y;
013a5f1c 1536
eb63f5ff
BH
1537 if (localX < 0) {
1538 localX = 0;
73005152 1539 }
eb63f5ff
BH
1540 if (localY < 0) {
1541 localY = 0;
73005152 1542 }
eb63f5ff 1543 if (fFrame == null) {
df0b8ff4 1544 return false;
73005152 1545 }
eb63f5ff
BH
1546 if (localX + getVisibleWidth() > getContentsWidth()) {
1547 localX = getContentsWidth() - getVisibleWidth();
73005152 1548 }
eb63f5ff
BH
1549 if (localY + getVisibleHeight() > getContentsHeight()) {
1550 localY = getContentsHeight() - getVisibleHeight();
df0b8ff4 1551 }
eb63f5ff
BH
1552 int x1 = Math.round(localX / fZoomValue);
1553 int y2 = Math.round(localY / fZoomValue);
1554 int width = Math.round(getVisibleWidth() / fZoomValue);
1555 int height = Math.round(getVisibleHeight() / fZoomValue);
1556 fFrame.updateIndex(x1, y2, width, height);
73005152 1557
eb63f5ff
BH
1558 if (fInsertionCartet != null && fInsertionCartet.isVisible()) {
1559 fInsertionCartet.setVisible(false);
df0b8ff4 1560 }
73005152 1561
eb63f5ff 1562 return super.setContentsPos(localX, localY);
73005152
BH
1563 }
1564
1565 @Override
df0b8ff4
BH
1566 protected void contentsMouseHover(MouseEvent event) {
1567 GraphNode graphNode = null;
eb63f5ff
BH
1568 if (fFrame != null) {
1569 int x = Math.round(event.x / fZoomValue);
1570 int y = Math.round(event.y / fZoomValue);
1571 graphNode = fFrame.getNodeAt(x, y);
df0b8ff4 1572 if ((graphNode != null) && (SDViewPref.getInstance().tooltipEnabled())) {
eb63f5ff 1573 fToolTipNode = graphNode;
df0b8ff4
BH
1574 String postfix = getPostfixForTooltip(true);
1575 if (graphNode instanceof Lifeline) {
1576 Lifeline lifeline = (Lifeline) graphNode;
eb63f5ff 1577 fToolTip.showToolTip(lifeline.getToolTipText() + postfix);
df0b8ff4
BH
1578 setFocus(0);
1579 } else {
eb63f5ff 1580 fToolTip.showToolTip(graphNode.getName() + postfix);
df0b8ff4
BH
1581 setFocus(0);
1582 }
1583 } else {
eb63f5ff 1584 fToolTip.hideToolTip();
df0b8ff4 1585 }
73005152 1586 }
73005152
BH
1587 }
1588
df0b8ff4
BH
1589 @Override
1590 protected void contentsMouseMoveEvent(MouseEvent e) {
eb63f5ff
BH
1591 fScrollToolTip.hideToolTip();
1592 fToolTip.hideToolTip();
df0b8ff4
BH
1593 if (!(isFocusControl() || getViewControl().isFocusControl())) {
1594 Control[] child = getParent().getChildren();
1595 for (int i = 0; i < child.length; i++) {
eb63f5ff
BH
1596 if ((child[i].isFocusControl()) && (!(child[i] instanceof ScrollView))) {
1597 getViewControl().setFocus();
1598 break;
df0b8ff4
BH
1599 }
1600 }
1601 }
1602 setFocus(-1);
73005152 1603
eb63f5ff
BH
1604 if (((e.stateMask & SWT.BUTTON_MASK) != 0) && ((fDragAndDrop != null) || fIsDragAndDrop) && (fReorderMode || fCollapseProvider != null)) {
1605 fIsDragAndDrop = false;
1606 if (fCurrentGraphNode instanceof Lifeline) {
1607 fDragAndDrop = (Lifeline) fCurrentGraphNode;
df0b8ff4 1608 }
eb63f5ff 1609 if (fDragAndDrop != null) {
df0b8ff4
BH
1610 int dx = 0;
1611 int dy = 0;
1612 if (e.x > getContentsX() + getVisibleWidth()) {
1613 dx = e.x - (getContentsX() + getVisibleWidth());
1614 } else if (e.x < getContentsX()) {
1615 dx = -getContentsX() + e.x;
1616 }
1617 if (e.y > getContentsY() + getVisibleHeight()) {
1618 dy = e.y - (getContentsY() + getVisibleHeight());
1619 } else if (e.y < getContentsY()) {
1620 dy = -getContentsY() + e.y;
1621 }
eb63f5ff
BH
1622 fDragX = e.x;
1623 fDragY = e.y;
df0b8ff4 1624 if (dx != 0 || dy != 0) {
eb63f5ff
BH
1625 if (fLocalAutoScroll == null) {
1626 if (fLocalAutoScrollTimer == null) {
1627 fLocalAutoScrollTimer = new Timer(true);
df0b8ff4 1628 }
eb63f5ff
BH
1629 fLocalAutoScroll = new AutoScroll(this, dx, dy);
1630 fLocalAutoScrollTimer.schedule(fLocalAutoScroll, 0, 75);
df0b8ff4 1631 } else {
eb63f5ff
BH
1632 fLocalAutoScroll.fDeltaX = dx;
1633 fLocalAutoScroll.fDeltaY = dy;
df0b8ff4 1634 }
eb63f5ff
BH
1635 } else if (fLocalAutoScroll != null) {
1636 fLocalAutoScroll.cancel();
1637 fLocalAutoScroll = null;
df0b8ff4 1638 }
eb63f5ff
BH
1639 fDragX = Math.round(e.x / fZoomValue);
1640 fDragY = Math.round(e.y / fZoomValue);
df0b8ff4 1641 redraw();
eb63f5ff
BH
1642 Lifeline node = fFrame.getCloserLifeline(fDragX);
1643 if ((node != null) && (node != fDragAndDrop)) {
df0b8ff4
BH
1644 int y = 0;
1645 int y1 = 0;
1646 int height = Metrics.getLifelineHeaderFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN;
1647 int hMargin = Metrics.LIFELINE_VT_MAGIN / 4;
1648 int x = node.getX();
1649 int width = node.getWidth();
eb63f5ff
BH
1650 if (fFrame.getVisibleAreaY() < node.getY() + node.getHeight() - height - hMargin) {
1651 y = contentsToViewY(Math.round((node.getY() + node.getHeight()) * fZoomValue));
df0b8ff4 1652 } else {
eb63f5ff 1653 y = Math.round(height * fZoomValue);
df0b8ff4 1654 }
73005152 1655
eb63f5ff
BH
1656 if (fFrame.getVisibleAreaY() < contentsToViewY(node.getY() - hMargin)) {
1657 y1 = contentsToViewY(Math.round((node.getY() - hMargin) * fZoomValue));
df0b8ff4 1658 } else {
eb63f5ff 1659 y1 = Math.round(height * fZoomValue);
df0b8ff4
BH
1660 }
1661
eb63f5ff 1662 int rx = Math.round(x * fZoomValue);
df0b8ff4 1663
eb63f5ff
BH
1664 fInsertionCartet.setVisible(true);
1665 if ((fInsertionCartet.getImage() != null) && (!fInsertionCartet.getImage().isDisposed())) {
1666 fInsertionCartet.getImage().dispose();
df0b8ff4 1667 }
eb63f5ff
BH
1668 if (rx <= e.x && Math.round(rx + (width * fZoomValue)) >= e.x) {
1669 if (fCollapseProvider != null) {
1670 ImageData data = fCollapaseCaretImg.getImageData();
1671 data = data.scaledTo(Math.round(fCollapaseCaretImg.getBounds().width * fZoomValue), Math.round(fCollapaseCaretImg.getBounds().height * fZoomValue));
1672 fCurrentCaretImage = new Image(Display.getCurrent(), data);
1673 fInsertionCartet.setImage(fCurrentCaretImage);
1674 fInsertionCartet.setLocation(contentsToViewX(rx + Math.round((width / (float) 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2, y);
df0b8ff4 1675 }
eb63f5ff 1676 } else if (fReorderMode) {
df0b8ff4 1677 if (rx > e.x) {
eb63f5ff 1678 if (node.getIndex() > 1 && fFrame.getLifeline(node.getIndex() - 2) == fDragAndDrop) {
df0b8ff4
BH
1679 return;
1680 }
eb63f5ff
BH
1681 ImageData data = fArrowUpCaretImg.getImageData();
1682 data = data.scaledTo(Math.round(fArrowUpCaretImg.getBounds().width * fZoomValue), Math.round(fArrowUpCaretImg.getBounds().height * fZoomValue));
1683 fCurrentCaretImage = new Image(Display.getCurrent(), data);
1684 fInsertionCartet.setImage(fCurrentCaretImage);
1685 fInsertionCartet.setLocation(contentsToViewX(Math.round((x - Metrics.LIFELINE_SPACING / 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2, y1);
df0b8ff4 1686 } else {
eb63f5ff 1687 if (node.getIndex() < fFrame.lifeLinesCount() && fFrame.getLifeline(node.getIndex()) == fDragAndDrop) {
df0b8ff4
BH
1688 return;
1689 }
eb63f5ff
BH
1690 ImageData data = fArrowUpCaretImg.getImageData();
1691 data = data.scaledTo(Math.round(fArrowUpCaretImg.getBounds().width * fZoomValue), Math.round(fArrowUpCaretImg.getBounds().height * fZoomValue));
1692 fCurrentCaretImage = new Image(Display.getCurrent(), data);
1693 fInsertionCartet.setImage(fCurrentCaretImage);
1694 fInsertionCartet.setLocation(contentsToViewX(Math.round((x + width + Metrics.LIFELINE_SPACING / 2) * fZoomValue)) - fCurrentCaretImage.getBounds().width / 2 + 1, y1);
df0b8ff4
BH
1695 }
1696 }
1697 } else {
eb63f5ff 1698 fInsertionCartet.setVisible(false);
73005152
BH
1699 }
1700 }
df0b8ff4
BH
1701 } else {
1702 super.contentsMouseMoveEvent(e);
73005152
BH
1703 }
1704 }
1705
df0b8ff4
BH
1706 @Override
1707 protected void contentsMouseUpEvent(MouseEvent event) {
1708 // Just in case the diagram highlight a time compression region
1709 // this region need to be released when clicking everywhere
eb63f5ff
BH
1710 fInsertionCartet.setVisible(false);
1711 if (fDragAndDrop != null) {
1712 if ((fOverView != null) && (!fOverView.isDisposed())) {
1713 fOverView.dispose();
73005152 1714 }
eb63f5ff
BH
1715 fOverView = null;
1716 Lifeline node = fFrame.getCloserLifeline(fDragX);
df0b8ff4 1717 if (node != null) {
eb63f5ff
BH
1718 int rx = Math.round(node.getX() * fZoomValue);
1719 if (rx <= event.x && Math.round(rx + (node.getWidth() * fZoomValue)) >= event.x) {
1720 if ((fCollapseProvider != null) && (fDragAndDrop != node)) {
abbdd66a 1721 fCollapseProvider.collapseTwoLifelines(fDragAndDrop, node);
df0b8ff4
BH
1722 }
1723 } else if (rx < event.x) {
abbdd66a 1724 fFrame.insertLifelineAfter(fDragAndDrop, node);
eb63f5ff 1725 if (node.getIndex() < fFrame.lifeLinesCount()) {
abbdd66a 1726 Lifeline temp[] = { fDragAndDrop, fFrame.getLifeline(node.getIndex()) };
eb63f5ff 1727 fReorderList.add(temp);
df0b8ff4 1728 } else {
abbdd66a 1729 Lifeline temp[] = { fDragAndDrop, null };
eb63f5ff 1730 fReorderList.add(temp);
df0b8ff4
BH
1731 }
1732 } else {
abbdd66a
AM
1733 fFrame.insertLifelineBefore(fDragAndDrop, node);
1734 Lifeline temp[] = { fDragAndDrop, node };
eb63f5ff 1735 fReorderList.add(temp);
73005152
BH
1736 }
1737 }
73005152 1738 }
eb63f5ff 1739 fDragAndDrop = null;
df0b8ff4 1740 redraw();
eb63f5ff 1741 if (fFrame == null) {
73005152 1742 return;
73005152 1743 }
eb63f5ff 1744 fFrame.resetTimeCompression();
73005152 1745
df0b8ff4 1746 // reset auto scroll if it's engaged
eb63f5ff
BH
1747 if (fLocalAutoScroll != null) {
1748 fLocalAutoScroll.cancel();
1749 fLocalAutoScroll = null;
73005152 1750 }
df0b8ff4 1751 super.contentsMouseUpEvent(event);
73005152
BH
1752 }
1753
df0b8ff4
BH
1754 @Override
1755 protected void contentsMouseDownEvent(MouseEvent event) {
eb63f5ff
BH
1756 if (fCurrentGraphNode != null) {
1757 fCurrentGraphNode.setFocused(false);
73005152 1758 }
73005152 1759
df0b8ff4
BH
1760 // Just in case the diagram highlight a time compression region
1761 // this region need to be released when clicking everywhere
eb63f5ff 1762 if (fFrame == null) {
73005152
BH
1763 return;
1764 }
eb63f5ff
BH
1765
1766 fFrame.resetTimeCompression();
73005152 1767
df0b8ff4 1768 if ((event.stateMask & SWT.CTRL) != 0) {
eb63f5ff 1769 fCtrlSelection = true;
df0b8ff4 1770 } else {
eb63f5ff 1771 fCtrlSelection = false;
df0b8ff4 1772 }
73005152 1773
eb63f5ff
BH
1774 if (((fZoomInMode) || (fZoomOutMode)) && (event.button == 1)) {
1775 int cx = Math.round(event.x / fZoomValue);
1776 int cy = Math.round(event.y / fZoomValue);
1777 if (fZoomInMode) {
1778 if (fZoomValue < 64) {
1779 fZoomValue = fZoomValue * (float) 1.25;
df0b8ff4
BH
1780 }
1781 } else {
eb63f5ff 1782 fZoomValue = fZoomValue / (float) 1.25;
73005152 1783 }
eb63f5ff
BH
1784 int x = Math.round(cx * fZoomValue - getVisibleWidth() / (float) 2);
1785 int y = Math.round(cy * fZoomValue - getVisibleHeight() / (float) 2);
df0b8ff4 1786 setContentsPos(x, y);
eb63f5ff
BH
1787 if (fTimeBar != null) {
1788 fTimeBar.setZoom(fZoomValue);
73005152 1789 }
df0b8ff4
BH
1790 // redraw also resize the scrollView content
1791 redraw();
cab6c8ff 1792 } else {
df0b8ff4 1793 GraphNode node = null;
eb63f5ff
BH
1794 int x = Math.round(event.x / fZoomValue);
1795 int y = Math.round(event.y / fZoomValue);
1796 node = fFrame.getNodeAt(x, y);
1797
1798 if ((event.button == 1) || ((node != null) && !node.isSelected())) {
1799 if (!fShiftSelection) {
1800 fListStart = node;
1801 }
1802 if (fShiftSelection) {
1803 clearSelection();
1804 addSelection(fFrame.getNodeList(fListStart, node));
1805 } else {
1806 performSelection(node);
1807 }
1808 fCurrentGraphNode = node;
1809 if (node != null) {
1810 node.setFocused(true);
df0b8ff4 1811 }
73005152 1812 }
eb63f5ff 1813 redraw();
73005152 1814 }
eb63f5ff 1815 if (fDragAndDrop == null) {
df0b8ff4
BH
1816 super.contentsMouseDownEvent(event);
1817 }
eb63f5ff 1818 fIsDragAndDrop = (event.button == 1);
73005152 1819
df0b8ff4 1820 }
013a5f1c
AM
1821
1822 /**
1823 * TimerTask for auto scroll feature.
df0b8ff4
BH
1824 */
1825 protected static class AutoScroll extends TimerTask {
1826 /**
1827 * Field delta x.
1828 */
eb63f5ff 1829 public int fDeltaX;
df0b8ff4
BH
1830 /**
1831 * Field delta y.
1832 */
eb63f5ff 1833 public int fDeltaY;
df0b8ff4
BH
1834 /**
1835 * Field sequence diagram reference.
1836 */
eb63f5ff 1837 public SDWidget fSdWidget;
73005152 1838
df0b8ff4
BH
1839 /**
1840 * Constructor for AutoScroll.
013a5f1c 1841 * @param sv sequence diagram widget reference
eb63f5ff
BH
1842 * @param dx delta x
1843 * @param dy delta y
df0b8ff4 1844 */
eb63f5ff
BH
1845 public AutoScroll(SDWidget sv, int dx, int dy) {
1846 fSdWidget = sv;
1847 fDeltaX = dx;
1848 fDeltaY = dy;
df0b8ff4 1849 }
73005152 1850
df0b8ff4
BH
1851 @Override
1852 public void run() {
1853 Display.getDefault().asyncExec(new Runnable() {
1854 @Override
1855 public void run() {
013a5f1c 1856 if (fSdWidget.isDisposed()) {
df0b8ff4 1857 return;
013a5f1c 1858 }
eb63f5ff
BH
1859 fSdWidget.fDragX += fDeltaX;
1860 fSdWidget.fDragY += fDeltaY;
1861 fSdWidget.scrollBy(fDeltaX, fDeltaY);
df0b8ff4
BH
1862 }
1863 });
1864 }
73005152
BH
1865 }
1866
df0b8ff4
BH
1867 @Override
1868 protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) {
eb63f5ff 1869 if (fFrame == null) {
df0b8ff4
BH
1870 gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
1871 gc.fillRectangle(0, 0, getVisibleWidth(), getVisibleHeight());
1872 gc.dispose();
1873 return;
df0b8ff4 1874 }
abbdd66a 1875 SDViewPref.getInstance();
df0b8ff4
BH
1876
1877 Rectangle area = getClientArea();
1878 Image dbuffer = getDrawBuffer();
eb63f5ff 1879 int height = Math.round((fFrame.getHeight() + 2 * Metrics.FRAME_V_MARGIN) * fZoomValue);
df0b8ff4 1880
73005152 1881 try {
df0b8ff4 1882 gc.drawImage(dbuffer, 0, 0, area.width, area.height, 0, 0, area.width, area.height);
73005152 1883 } catch (Exception e) {
8fd82db5 1884 Activator.getDefault().logError("Error drawin content", e); //$NON-NLS-1$
df0b8ff4
BH
1885 }
1886 dbuffer.dispose();
eb63f5ff
BH
1887 setHScrollBarIncrement(Math.round(SDViewPref.getInstance().getLifelineWidth() / (float) 2 * fZoomValue));
1888 setVScrollBarIncrement(Math.round(Metrics.getMessagesSpacing() * fZoomValue));
1889 if ((fTimeBar != null) && (fFrame.hasTimeInfo())) {
1890 fTimeBar.resizeContents(9, height + getHorizontalBarHeight());
1891 fTimeBar.setContentsPos(getContentsX(), getContentsY());
1892 fTimeBar.redraw();
1893 fTimeBar.update();
73005152 1894 }
df0b8ff4
BH
1895 float xRatio = getContentsWidth() / (float) getVisibleWidth();
1896 float yRatio = getContentsHeight() / (float) getVisibleHeight();
1897 if (yRatio > xRatio) {
1898 setOverviewSize((int) (getVisibleHeight() * 0.75));
1899 } else {
1900 setOverviewSize((int) (getVisibleWidth() * 0.75));
1901 }
1902 }
73005152 1903
df0b8ff4
BH
1904 @Override
1905 public void widgetDefaultSelected(SelectionEvent event) {
73005152
BH
1906 }
1907
df0b8ff4
BH
1908 @Override
1909 public void widgetSelected(SelectionEvent event) {
eb63f5ff
BH
1910 if (event.widget == fZoomIn) {
1911 fZoomValue = fZoomValue * 2;
1912 } else if (event.widget == fZoomOut) {
1913 fZoomValue = fZoomValue / 2;
df0b8ff4
BH
1914 }
1915 redraw();
1916 }
73005152 1917
11252342
AM
1918 /**
1919 * Called when property changed occurs in the preference page. "PREFOK" is
1920 * fired when the user press the ok or apply button
df0b8ff4
BH
1921 */
1922 @Override
1923 public void propertyChange(PropertyChangeEvent e) {
eb63f5ff
BH
1924 if (fFrame != null && !isDisposed()) {
1925 fFrame.resetTimeCompression();
df0b8ff4
BH
1926 }
1927 if (e.getProperty().equals("PREFOK")) //$NON-NLS-1$
1928 {
1929 // Prepare the overview to be reused for the new
1930 // settings (especially the colors)
013a5f1c 1931 if (fOverView != null) {
eb63f5ff 1932 fOverView.dispose();
013a5f1c 1933 }
eb63f5ff 1934 fOverView = null;
df0b8ff4
BH
1935 redraw();
1936 }
1937 }
73005152 1938
df0b8ff4
BH
1939 @Override
1940 public void widgetDisposed(DisposeEvent e) {
eb63f5ff
BH
1941 if (fOverView != null) {
1942 fOverView.dispose();
df0b8ff4
BH
1943 }
1944 super.removeDisposeListener(this);
eb63f5ff
BH
1945 if ((fCurrentCaretImage != null) && (!fCurrentCaretImage.isDisposed())) {
1946 fCurrentCaretImage.dispose();
df0b8ff4 1947 }
eb63f5ff
BH
1948 if ((fArrowUpCaretImg != null) && (!fArrowUpCaretImg.isDisposed())) {
1949 fArrowUpCaretImg.dispose();
df0b8ff4 1950 }
eb63f5ff
BH
1951 if ((fCollapaseCaretImg != null) && (!fCollapaseCaretImg.isDisposed())) {
1952 fCollapaseCaretImg.dispose();
df0b8ff4
BH
1953 }
1954 SDViewPref.getInstance().removePropertyChangeListener(this);
1955 LoadersManager lm = LoadersManager.getInstance();
eb63f5ff
BH
1956 if (fSite instanceof SDView) {
1957 ((SDView) fSite).resetProviders();
df0b8ff4 1958 if (lm != null) {
eb63f5ff 1959 lm.resetLoader(((SDView) fSite).getViewSite().getId());
df0b8ff4
BH
1960 }
1961 }
1962 }
73005152 1963
df0b8ff4
BH
1964 @Override
1965 protected void drawOverview(GC gc, Rectangle r) {
eb63f5ff 1966 float oldzoom = fZoomValue;
df0b8ff4 1967 if (getContentsWidth() > getContentsHeight()) {
eb63f5ff 1968 fZoomValue = (float) r.width / (float) getContentsWidth() * oldzoom;
df0b8ff4 1969 } else {
eb63f5ff 1970 fZoomValue = (float) r.height / (float) getContentsHeight() * oldzoom;
df0b8ff4 1971 }
eb63f5ff
BH
1972 if ((fOverView != null) && ((r.width != fOverView.getBounds().width) || (r.height != fOverView.getBounds().height))) {
1973 fOverView.dispose();
1974 fOverView = null;
df0b8ff4 1975 }
eb63f5ff 1976 if (fOverView == null) {
df0b8ff4
BH
1977 int backX = getContentsX();
1978 int backY = getContentsY();
1979 setContentsPos(0, 0);
eb63f5ff
BH
1980 fOverView = new Image(getDisplay(), r.width, r.height);
1981 GC gcim = new GC(fOverView);
df0b8ff4 1982 NGC context = new NGC(this, gcim);
abbdd66a 1983 context.setBackground(SDViewPref.getInstance().getBackGroundColor(ISDPreferences.PREF_FRAME));
eb63f5ff 1984 fFrame.draw(context);
df0b8ff4
BH
1985 setContentsPos(backX, backY);
1986 gcim.dispose();
1987 context.dispose();
1988 }
eb63f5ff
BH
1989 if ((fOverView != null) && (r.width == fOverView.getBounds().width) && (r.height == fOverView.getBounds().height)) {
1990 gc.drawImage(fOverView, 0, 0, r.width, r.height, 0, 0, r.width, r.height);
df0b8ff4 1991 }
73005152 1992
eb63f5ff 1993 fZoomValue = oldzoom;
df0b8ff4
BH
1994
1995 super.drawOverview(gc, r);
73005152
BH
1996 }
1997
df0b8ff4
BH
1998 @Override
1999 public void deltaSelected(Lifeline lifeline, int startEvent, int nbEvent, IColor color) {
eb63f5ff 2000 fFrame.highlightTimeCompression(lifeline, startEvent, nbEvent, color);
df0b8ff4
BH
2001 ensureVisible(lifeline);
2002 int y1 = lifeline.getY() + lifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEvent;
2003 int y2 = lifeline.getY() + lifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * (startEvent + nbEvent);
2004 ensureVisible(lifeline.getX(), y1 - (Metrics.getLifelineHeaderFontHeigth() + +2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN), lifeline.getWidth(), y2 - y1 + 3, SWT.CENTER | SWT.VERTICAL, true);
2005 redraw();
73005152 2006 update();
73005152
BH
2007 }
2008
2009 @Override
2010 public int getVisibleWidth() {
eb63f5ff
BH
2011 if (fIsPrinting) {
2012 return fPrinter.getClientArea().width;
df0b8ff4 2013 }
73005152
BH
2014 return super.getVisibleWidth();
2015 }
2016
2017 @Override
2018 public int getVisibleHeight() {
eb63f5ff
BH
2019 if (fIsPrinting) {
2020 return fPrinter.getClientArea().height;
df0b8ff4 2021 }
73005152
BH
2022 return super.getVisibleHeight();
2023 }
2024
2025 @Override
eb63f5ff
BH
2026 public int contentsToViewX(int x) {
2027 if (fIsPrinting) {
2028 int v = Math.round(fPrinterX * fPrinterZoom);
2029 return x - v;
73005152 2030 }
eb63f5ff 2031 return x - getContentsX();
73005152
BH
2032 }
2033
2034 @Override
eb63f5ff
BH
2035 public int contentsToViewY(int y) {
2036 if (fIsPrinting) {
2037 int v = Math.round(fPrinterY * fPrinterZoom);
2038 return y - v;
73005152 2039 }
eb63f5ff 2040 return y - getContentsY();
73005152
BH
2041 }
2042
2043 @Override
2044 public int getContentsX() {
eb63f5ff
BH
2045 if (fIsPrinting) {
2046 return Math.round(fPrinterX * fPrinterZoom);
df0b8ff4 2047 }
73005152 2048 return super.getContentsX();
73005152
BH
2049 }
2050
2051 @Override
2052 public int getContentsY() {
eb63f5ff
BH
2053 if (fIsPrinting) {
2054 return Math.round(fPrinterY * fPrinterZoom);
df0b8ff4 2055 }
73005152
BH
2056 return super.getContentsY();
2057 }
013a5f1c 2058
3145ec83
BH
2059 /**
2060 * Traverse Listener implementation.
2061 */
2062 protected static class LocalTraverseListener implements TraverseListener {
3145ec83
BH
2063 @Override
2064 public void keyTraversed(TraverseEvent e) {
2065 if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) {
2066 e.doit = true;
2067 }
2068 }
2069 }
2070
73005152 2071}
This page took 0.146372 seconds and 5 git commands to generate.