Skip to main content
summaryrefslogtreecommitdiffstats
blob: f52c251d9f0cf5a60d4f1aa0e6e2de3747a3733b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
package org.eclipse.papyrus.uml.diagram.sequence.util;

import java.util.List;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.common.core.command.ICompositeCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.SetBoundsCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.Shape;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CombinedFragmentCombinedFragmentCompartmentEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.CombinedFragmentEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.InteractionInteractionCompartmentEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.InteractionOperandEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.part.UMLVisualIDRegistry;
import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes;
import org.eclipse.uml2.uml.CombinedFragment;
import org.eclipse.uml2.uml.InteractionOperand;

public class OperandBoundsComputeHelper {

	/**
	 * Default height of Interaction Operand
	 */
	public static final int DEFAULT_INTERACTION_OPERAND_HEIGHT = 61;
	
	public static final int MIN_INTERACTION_OPERAND_HEIGHT = 10; 
	/**
	 * Default width of Interaction Operand
	 */
	public static final int DEFAULT_INTERACTION_OPERAND_WIDTH = 210;
	/**
	 * Border width of CombinedFragmentFigure
	 */
	public static final int COMBINED_FRAGMENT_FIGURE_BORDER = 1;
	
	/**
	 * Find first Interaction Operand EditpPart of CombinedFragmentCombinedFragmentCompartmentEditPart
	 * @param compartEP
	 * @return InteractionOperandEditPart
	 */
	public static InteractionOperandEditPart findFirstIOEP(
			CombinedFragmentCombinedFragmentCompartmentEditPart compartEP) {
		InteractionOperandEditPart firstIOEP = null;
		List children = compartEP.getChildren();
		for (int i = 0; i < children.size(); i++) {
			if (children.get(i) instanceof InteractionOperandEditPart) {
				firstIOEP = (InteractionOperandEditPart) children.get(i);
				break;
			}
		}
		return firstIOEP;
	}
	
	/**
	 * Find Last Interaction Operand EditpPart of CombinedFragmentCombinedFragmentCompartmentEditPart
	 * @param compartEP
	 * @return InteractionOperandEditPart
	 */
	public static InteractionOperandEditPart findLastIOEP(
			CombinedFragmentCombinedFragmentCompartmentEditPart compartEP) {
		InteractionOperandEditPart lastIOEP = null;
		List children = compartEP.getChildren();
		for (int i = children.size() - 1; i >= 0; i--) {
			if (children.get(i) instanceof InteractionOperandEditPart) {
				lastIOEP = (InteractionOperandEditPart) children.get(i);
				break;
			}
		}
		return lastIOEP;
	}
	
	/**
	 * Find Previous Interaction Operand EditpPart of current given InteractionOperandEditPart
	 * @param compartEP
	 * @param currentIOEP
	 * @return InteractionOperandEditPart
	 */
	public static InteractionOperandEditPart findPreviousIOEP(
			CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
			InteractionOperandEditPart currentIOEP) {
		InteractionOperandEditPart previousIOEP = null;
		List children = compartEP.getChildren();
		for (int i = 0; i < children.size() - 1; i++) {
			if (children.get(i) instanceof InteractionOperandEditPart) {
				if (children.get(i) == currentIOEP) {
					break;
				} else {
					previousIOEP = (InteractionOperandEditPart) children.get(i);
				}
			}
		}
		return previousIOEP;
	}
	
	/**
	 * Find Latter Interaction Operand EditpPart of current given InteractionOperandEditPart
	 * @param compartEP
	 * @param currentIOEP
	 * @return InteractionOperandEditPart
	 */
	public static InteractionOperandEditPart findLatterIOEP(
			CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
			InteractionOperandEditPart currentIOEP) {
		InteractionOperandEditPart latterIOEP = null;
		List children = compartEP.getChildren();
		for (int i = children.size() - 1; i > 0; i--) {
			if (children.get(i) instanceof InteractionOperandEditPart) {
				if (children.get(i) == currentIOEP) {
					break;
				} else {
					latterIOEP = (InteractionOperandEditPart) children.get(i);
				}
			}
		}
		return latterIOEP;
	}

	/**
	 * Update EditPart bounds using new rect
	 * @param parent
	 * @param rect
	 */
	public static void updateEditPartBounds(GraphicalEditPart editpart,
			final Rectangle rect) {
		if (editpart.getModel() instanceof Node) {
			Node node = (Node) editpart.getModel();
			if (node.getLayoutConstraint() instanceof Bounds) {
				Bounds bounds = (Bounds) node.getLayoutConstraint();
				updateBounds(bounds, rect, editpart.getEditingDomain());
			}
		}
	}
	
	/**
	 * Update EditPart bounds using new rect
	 * @param parent
	 * @param rect
	 */
	public static ICommand createUpdateEditPartBoundsCommand(
			final GraphicalEditPart editpart, final Rectangle rect) {
		ICommand cmd = new AbstractTransactionalCommand(
				editpart.getEditingDomain(),
				"Update Operand Bounds", null) {
			@Override
			protected CommandResult doExecuteWithResult(
					IProgressMonitor monitor, IAdaptable info)
					throws ExecutionException {
				if (editpart.getModel() instanceof Node) {
					Node node = (Node) editpart.getModel();
					if (node.getLayoutConstraint() instanceof Bounds) {
						Bounds bounds = (Bounds) node.getLayoutConstraint();
						fillBounds(bounds, rect);
					}
				}
				return CommandResult.newOKCommandResult();
			}
		};
		return cmd;
	}
	
	/**
	 * Create command for updating Interaction Operand EditpPart bounds after the CombinedFragment to be created. 
	 * @param editPart
	 * @param request
	 * @return ICommand
	 */
	public static ICommand createUpdateCFAndIOBoundsForCFCreationCommand(final EditPart editPart, final CreateViewRequest request) {
		if (!(editPart instanceof GraphicalEditPart)) {
			return null;
		}
		GraphicalEditPart graphicalEditPart= (GraphicalEditPart)editPart;
		ICommand cmd = new AbstractTransactionalCommand(graphicalEditPart.getEditingDomain(),"Create update operand bounds command",null) {
			@Override
			protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
					IAdaptable info) throws ExecutionException {
				OperandBoundsComputeHelper.updateCFAndIOBoundsForCFCreation(
						(GraphicalEditPart) editPart, request);
				return CommandResult.newOKCommandResult();
			}
		};
		return cmd;
	}
	
	/**
	 * Update Interaction Operand EditpPart bounds after the CombinedFragment to be created. 
	 * @param parent
	 * @param request
	 * @param selectionRect
	 */
	private static void updateCFAndIOBoundsForCFCreation(GraphicalEditPart parent, CreateViewRequest request) {
		Object subEditPart = null;
		if (parent instanceof InteractionInteractionCompartmentEditPart) {
			InteractionInteractionCompartmentEditPart interactionInteractionCompartmentEditPart = (InteractionInteractionCompartmentEditPart) parent;
			subEditPart = interactionInteractionCompartmentEditPart
					.getChildren().get(
							interactionInteractionCompartmentEditPart
									.getChildren().size() - 1);
			
		}else if (parent instanceof InteractionOperandEditPart) {
			InteractionOperandEditPart interactionOperandEditPart = (InteractionOperandEditPart) parent;
			subEditPart = interactionOperandEditPart
					.getChildren().get(
							interactionOperandEditPart
									.getChildren().size() - 1);
		}
		if (subEditPart != null
				&& subEditPart instanceof CombinedFragmentEditPart) {
			CombinedFragmentEditPart combinedFragmentEditPart = (CombinedFragmentEditPart) subEditPart;
			// set bounds for CombinedFragmentEditPart
			Rectangle cfEPAbsoluteRect = null;
			int labelContainerHeight = computeCombinedFragementHeaderHeight(combinedFragmentEditPart);
			Shape cfEPShape = (Shape) combinedFragmentEditPart.getModel();
			if (cfEPShape.getLayoutConstraint() instanceof Bounds) {
				if(request.getSize() == null){
					Dimension cfEPDefaultSize = new Dimension();
					cfEPDefaultSize.setWidth(DEFAULT_INTERACTION_OPERAND_WIDTH+COMBINED_FRAGMENT_FIGURE_BORDER*2);
					cfEPDefaultSize.setHeight(DEFAULT_INTERACTION_OPERAND_HEIGHT+labelContainerHeight+COMBINED_FRAGMENT_FIGURE_BORDER*2);
					cfEPAbsoluteRect = new Rectangle(request.getLocation(),cfEPDefaultSize);
				}else{
					cfEPAbsoluteRect = new Rectangle(request.getLocation(),request.getSize());
				}
				Rectangle cfEPRelativeRect = cfEPAbsoluteRect.getCopy();
				combinedFragmentEditPart.getFigure().translateToRelative(cfEPRelativeRect);
				Bounds cfEPBounds = (Bounds) cfEPShape.getLayoutConstraint();
				fillBounds(cfEPBounds,cfEPRelativeRect);
			}
			
			// set bounds for new added Operand
			InteractionOperandEditPart lastOperand = OperandBoundsComputeHelper
					.findLastIOEP((CombinedFragmentCombinedFragmentCompartmentEditPart) combinedFragmentEditPart.getChildBySemanticHint(UMLVisualIDRegistry
							.getType(CombinedFragmentCombinedFragmentCompartmentEditPart.VISUAL_ID)));
			Shape shape = (Shape) lastOperand.getModel();
			if (shape.getLayoutConstraint() instanceof Bounds) {
				Bounds bounds = (Bounds) shape.getLayoutConstraint();
				Rectangle rect = new Rectangle(bounds.getX(), bounds.getY(),
						cfEPAbsoluteRect.width()-COMBINED_FRAGMENT_FIGURE_BORDER*2, cfEPAbsoluteRect.height()
								- labelContainerHeight-COMBINED_FRAGMENT_FIGURE_BORDER*2);
				fillBounds(bounds,rect);
			}
		}
	}

	/**
	 * Create command for updating Interaction Operand EditpPart bounds after CombinedFragment to be resized. 
	 * @param compoundCmd
	 * @param request
	 * @param combinedFragmentEditPart
	 * @return Command
	 */
	public static Command createUpdateIOBoundsForCFResizeCommand(
			CompoundCommand compoundCmd, final ChangeBoundsRequest request,
			CombinedFragmentEditPart combinedFragmentEditPart) {
		if (combinedFragmentEditPart.getChildren().size() > 0
				&& combinedFragmentEditPart.getChildren().get(0) instanceof CombinedFragmentCombinedFragmentCompartmentEditPart) {
			CombinedFragmentCombinedFragmentCompartmentEditPart compartment = (CombinedFragmentCombinedFragmentCompartmentEditPart) combinedFragmentEditPart
					.getChildren().get(0);
			CombinedFragment cf = (CombinedFragment) ((CombinedFragmentEditPart) combinedFragmentEditPart)
					.resolveSemanticElement();
			InteractionOperandEditPart targetIOEP = null;
			if ((request.getResizeDirection() & PositionConstants.NORTH) != 0) {
				targetIOEP = findFirstIOEP(compartment);
			} else if ((request.getResizeDirection() & PositionConstants.SOUTH) != 0) {
				targetIOEP = findLastIOEP(compartment);
			}
			updateIOBoundsForCFResize(
					request,
					compoundCmd,
					compartment.getChildren(),
					cf,
					targetIOEP != null ? (InteractionOperand) targetIOEP
							.resolveSemanticElement() : null,
					request.getSizeDelta(), request.getResizeDirection());
		}
		return compoundCmd;
	}

	/**
	 * Update Interaction Operand EditpPart bounds after CombinedFragment to be resized. 
	 * @param request
	 * @param compoundCmd
	 * @param combinedFragmentChildrenEditParts
	 * @param cf
	 * @param targetOperand
	 * @param sizeDelta
	 * @param direction
	 */
	private static void updateIOBoundsForCFResize(final ChangeBoundsRequest request,
			CompoundCommand compoundCmd,
			List<EditPart> combinedFragmentChildrenEditParts,
			CombinedFragment cf, InteractionOperand targetOperand,
			final Dimension sizeDelta, int direction) {
		InteractionOperandEditPart targetOperandEditPart = findTargetOperandEditPart(
				cf, targetOperand, combinedFragmentChildrenEditParts);
		for (EditPart ep : combinedFragmentChildrenEditParts) {
			if (ep instanceof InteractionOperandEditPart) {
				InteractionOperandEditPart ioEP = (InteractionOperandEditPart) ep;
				Object ioEPModel = ioEP.getModel();
				if (ioEPModel instanceof Shape) {
					Shape ioEPShape = (Shape) ioEPModel;
					if (ioEPShape.getLayoutConstraint() instanceof Bounds) {
						final Bounds ioEPOriginalBounds = (Bounds) ioEPShape
								.getLayoutConstraint();
						ICommand cmd = new UpdateIOBoundsForCFResizeCommand(
								ioEP.getEditingDomain(),
								"Update operand bounds interaction command",
								ioEPOriginalBounds, request, sizeDelta,
								ioEP == targetOperandEditPart, direction);
						compoundCmd.add(new ICommandProxy(cmd));
					}
				}
			}
		}

	}
	
	/**
	 * Update bounds using new rect
	 * @param bounds
	 * @param rect
	 * @param transactionalEditingDomain
	 */
	public static void updateBounds(final Bounds bounds, final Rectangle rect,
			TransactionalEditingDomain transactionalEditingDomain) {
		if (bounds != null) {
			final Rectangle originalBounds = new Rectangle();
			originalBounds.setX(bounds.getX());
			originalBounds.setY(bounds.getY());
			originalBounds.setWidth(bounds.getWidth());
			originalBounds.setHeight(bounds.getHeight());
			AbstractCommand cmd = new AbstractCommand() {
				public boolean canExecute() {
					return true;
				}

				public void execute() {
					exec(rect);
				}

				public void redo() {
					execute();
				}
				
				public void undo(){
					exec(originalBounds);
				}
				
				public void exec(Rectangle rect){
					fillBounds(bounds,rect);
				}

				public boolean canUndo() {
					return true;
				}
			};
			CommandHelper.executeCommandWithoutHistory(
					transactionalEditingDomain, cmd,true);
		}
	}

	/**
	 * Get InteractionOperandEditPart from its model object InteractionOperand.
	 * @param cf
	 * @param targetOperand
	 * @param combinedFragmentChildrenEditParts
	 * @return InteractionOperandEditPart
	 */
	public static InteractionOperandEditPart findTargetOperandEditPart(CombinedFragment cf,
			InteractionOperand targetOperand,
			List<EditPart> combinedFragmentChildrenEditParts) {
		if(targetOperand == null)
			return null;
		for(EditPart ep : combinedFragmentChildrenEditParts) {
			if(ep instanceof InteractionOperandEditPart) {
				InteractionOperandEditPart ioEP = (InteractionOperandEditPart)ep;
				InteractionOperand io = (InteractionOperand)ioEP.resolveSemanticElement();
				if(cf.getOperands().contains(io)) {
					if(targetOperand.equals(io)) {
						return ioEP;
					}
				}
			}
		}
		return null;
	}
	
	/**
	 * Get graphical edit part bounds
	 * @param editPart
	 * @return
	 */
	public static Bounds getEditPartBounds(GraphicalEditPart editPart){
		if (editPart.getModel() instanceof Node) {
			Node node = (Node) editPart.getModel();
			if (node.getLayoutConstraint() instanceof Bounds) {
				Bounds bounds = (Bounds) node.getLayoutConstraint();
				return bounds;
			}
		}
		return null;
	}
	
	/**
	 * Fill data from Bounds to Rectangle
	 * @param source
	 * @return Rectangle
	 */
	public static Rectangle fillRectangle(Bounds source) {
		if (source == null) {
			return null;
		}
		Rectangle target = new Rectangle();
		target.setX(source.getX());
		target.setY(source.getY());
		target.setWidth(source.getWidth());
		target.setHeight(source.getHeight());
		return target;
	}
	
	/**
	 * Fill data from Rectangle to Bounds
	 * @param bounds
	 * @param source
	 * @return Bounds
	 */
	public static Bounds fillBounds(Bounds bounds,Rectangle source) {
		if (bounds == null || source == null) {
			return null;
		}
		bounds.setX(source.x());
		bounds.setY(source.y());
		bounds.setWidth(source.width());
		bounds.setHeight(source.height());
		return bounds;
	}
	
	/**
	 * Get interaction operand bounds
	 * @param operandEP
	 * @return Bounds
	 */
	public static Bounds getInteractionOperandEPBounds(GraphicalEditPart operandEP){
		Object lastChildModel = operandEP.getModel();
		if (lastChildModel instanceof Shape) {
			Shape lastOperandShape = (Shape) lastChildModel;
			if (lastOperandShape.getLayoutConstraint() instanceof Bounds) {
				return (Bounds)lastOperandShape.getLayoutConstraint();
			}
		}
		return null;
	}
	
	/**
	 * Create interaction operand resize command
	 * @param currentIOEP
	 * @param heightDelta
	 * @param compartEP
	 * @param direction
	 * @return
	 */
	public static Command createIOEPResizeCommand(
			InteractionOperandEditPart currentIOEP, int heightDelta,
			CombinedFragmentCombinedFragmentCompartmentEditPart compartEP,
			int direction) {
		Bounds currentIOEPBounds = OperandBoundsComputeHelper
				.getEditPartBounds(currentIOEP);
		if (currentIOEPBounds == null) {
			return null;
		}
		InteractionOperandEditPart targetIOEP = null;
		if ((direction & PositionConstants.NORTH) != 0) {
			targetIOEP = OperandBoundsComputeHelper.findPreviousIOEP(compartEP,
					currentIOEP);
		} else if ((direction & PositionConstants.SOUTH) != 0) {
			targetIOEP = OperandBoundsComputeHelper.findLatterIOEP(compartEP,
					currentIOEP);
		}
		
		CompositeCommand compositeCommand = new CompositeCommand(
				"Resize Operand");
		// if last operand
		if(targetIOEP == null){
			if (heightDelta < 0) {
				if (currentIOEPBounds.getHeight() - Math.abs(heightDelta) < OperandBoundsComputeHelper.MIN_INTERACTION_OPERAND_HEIGHT) {
					return null;
				}
			}
			Rectangle currentIOEPRect = OperandBoundsComputeHelper
					.fillRectangle(currentIOEPBounds);
			currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
			ICommand currentIOEPCommand = OperandBoundsComputeHelper
					.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);
			compositeCommand.add(currentIOEPCommand);
			// auto update CombinedFragmentEditPart bounds after resize the last operand
			if(compartEP.getParent() instanceof CombinedFragmentEditPart){
				CombinedFragmentEditPart parent = (CombinedFragmentEditPart) compartEP.getParent();
				if (parent.getModel() instanceof Node) {
					Node node = (Node) parent.getModel();
					if (node.getLayoutConstraint() instanceof Bounds) {
						Bounds containerBounds = (Bounds) node
								.getLayoutConstraint();
						Dimension preferredSize = parent.getFigure().getPreferredSize();
						int width = containerBounds.getWidth()!=-1? containerBounds.getWidth() :  preferredSize.width();
						int height = containerBounds.getHeight()!=-1? containerBounds.getHeight() :  preferredSize.height();
						height = height + heightDelta;
						Rectangle containerRect = new Rectangle(containerBounds.getX(),containerBounds.getY(),width,height);
						compositeCommand.add(OperandBoundsComputeHelper.createUpdateEditPartBoundsCommand(parent, containerRect));
					}
				}
			}
		}else{
			Bounds targetIOEPBounds = OperandBoundsComputeHelper
					.getEditPartBounds(targetIOEP);
			if (targetIOEPBounds == null) {
				return null;
			}
			if (heightDelta > 0) {
				if (targetIOEPBounds.getHeight() - heightDelta < OperandBoundsComputeHelper.MIN_INTERACTION_OPERAND_HEIGHT) {
					return null;
				}
			} else {
				if (currentIOEPBounds.getHeight() - Math.abs(heightDelta) < OperandBoundsComputeHelper.MIN_INTERACTION_OPERAND_HEIGHT) {
					return null;
				}
			}
			Rectangle targetIOEPRect = OperandBoundsComputeHelper
					.fillRectangle(targetIOEPBounds);
			Rectangle currentIOEPRect = OperandBoundsComputeHelper
					.fillRectangle(currentIOEPBounds);
			targetIOEPRect.setHeight(targetIOEPBounds.getHeight() - heightDelta);
			currentIOEPRect.setHeight(currentIOEPBounds.getHeight() + heightDelta);
			if ((direction & PositionConstants.NORTH) != 0) {
				currentIOEPRect.setY(currentIOEPRect.y() - heightDelta);
			}else if ((direction & PositionConstants.SOUTH) != 0) {
				targetIOEPRect.setY(targetIOEPRect.y() + heightDelta);
			}

			ICommand previousIOEPCommand = OperandBoundsComputeHelper
					.createUpdateEditPartBoundsCommand(targetIOEP, targetIOEPRect);
			ICommand currentIOEPCommand = OperandBoundsComputeHelper
					.createUpdateEditPartBoundsCommand(currentIOEP, currentIOEPRect);

			compositeCommand.add(previousIOEPCommand);
			compositeCommand.add(currentIOEPCommand);
		}

		return new ICommandProxy(compositeCommand);
	}
	
	/**
	 * Compute CombinedFragement's header height
	 * @param combinedFragmentEditPart 
	 * @return int
	 */
	public static int computeCombinedFragementHeaderHeight(
			CombinedFragmentEditPart combinedFragmentEditPart) {
		int headerHeight = 0;
		IFigure labelContainer = combinedFragmentEditPart.getPrimaryShape().getHeaderLabel().getParent();
		if(labelContainer!=null){
			headerHeight = labelContainer.getPreferredSize().height();
		}
		return headerHeight;
	}
	
	/**
	 * Check if operation resizing on CombinedFragment is allowed
	 * @param request
	 * @param child
	 * @return boolean
	 */
	public static boolean checkRedistrictOnCFResize(ChangeBoundsRequest request,
			EditPart child) {
		if(child instanceof CombinedFragmentEditPart){
			if ((request.getResizeDirection() & PositionConstants.NORTH_SOUTH) != 0) {
				CombinedFragmentEditPart combinedFragmentEditPart = (CombinedFragmentEditPart)child;
				if (combinedFragmentEditPart.getChildren().size() > 0
						&& combinedFragmentEditPart.getChildren()
								.get(0) instanceof CombinedFragmentCombinedFragmentCompartmentEditPart) {
					CombinedFragmentCombinedFragmentCompartmentEditPart compartment = (CombinedFragmentCombinedFragmentCompartmentEditPart) combinedFragmentEditPart
							.getChildren().get(0);
					List<EditPart> combinedFragmentChildrenEditParts = compartment
							.getChildren();
					CombinedFragment cf = (CombinedFragment) ((CombinedFragmentEditPart) combinedFragmentEditPart)
							.resolveSemanticElement();
					InteractionOperand targetOperand = null;
					if ((request.getResizeDirection() & PositionConstants.NORTH) != 0) {
						targetOperand = cf.getOperands().get(0);
					} else if ((request.getResizeDirection() & PositionConstants.SOUTH) != 0) {
						targetOperand = cf.getOperands().get(
								cf.getOperands().size() - 1);
					}
					InteractionOperandEditPart targetOperandEditPart = OperandBoundsComputeHelper.findTargetOperandEditPart(
							cf, targetOperand, combinedFragmentChildrenEditParts);
					int heightDelta = request.getSizeDelta().height();
					if(targetOperandEditPart!=null && heightDelta<0){
						int height = targetOperandEditPart.getFigure().getBounds().height();
						if(height-Math.abs(heightDelta) < OperandBoundsComputeHelper.MIN_INTERACTION_OPERAND_HEIGHT){
							return false;
						}
					}
				}
			}
		}
		return true;
	}
	
	/**
	 * Add command for updating adjacent interaction operand bounds after deleting a interaction operand
	 * @param editPart
	 * @param cmd
	 */
	public static void addUpdateBoundsCommandForOperandDelelete(EditPart editPart,ICompositeCommand cmd) {
		if(editPart instanceof InteractionOperandEditPart){
			if(editPart.getParent() instanceof CombinedFragmentCombinedFragmentCompartmentEditPart){
				CombinedFragmentCombinedFragmentCompartmentEditPart compartment = (CombinedFragmentCombinedFragmentCompartmentEditPart)editPart.getParent();
					if(compartment.getParent() instanceof CombinedFragmentEditPart){
						List<EditPart> combinedFragmentChildrenEditParts = compartment
								.getChildren();
						InteractionOperandEditPart previousIOEP = null;
						InteractionOperandEditPart latterIOEP = null;
						boolean isFirstOperand = false;
						
						InteractionOperandEditPart currentioEP = (InteractionOperandEditPart)editPart;
						final Rectangle currentioEPBounds = currentioEP.getFigure().getBounds();
						
						for(int i = 0;i<combinedFragmentChildrenEditParts.size();i++) {
							EditPart ep = combinedFragmentChildrenEditParts.get(i);
							if(ep instanceof InteractionOperandEditPart) {
								InteractionOperandEditPart ioEP = (InteractionOperandEditPart)ep;
								if(currentioEP == ioEP){
									if(previousIOEP!=null){
										Object previousIOEPModel = previousIOEP.getModel();
										if (previousIOEPModel instanceof Shape) {
											Shape previousIOEPShape = (Shape) previousIOEPModel;
											if (previousIOEPShape.getLayoutConstraint() instanceof Bounds) {
												final Bounds previousIOEPOriginalBounds = (Bounds) previousIOEPShape.getLayoutConstraint();
												ICommand command = new AbstractTransactionalCommand(previousIOEP.getEditingDomain(),"Merge operand bounds command",null){
													@Override
													protected CommandResult doExecuteWithResult(
															IProgressMonitor monitor,
															IAdaptable info)
															throws ExecutionException {
														previousIOEPOriginalBounds.setHeight(previousIOEPOriginalBounds.getHeight() + currentioEPBounds.height());
														return CommandResult.newOKCommandResult();
													}
												};
												cmd.add(command);
											}
										}
										break;
									}else{
										isFirstOperand = true; 
										continue;
									}
								}else{
									previousIOEP = ioEP;
								}
								if(isFirstOperand){
									latterIOEP = ioEP;
									break;
								}
							}
						}
						if(isFirstOperand && latterIOEP!=null){
							Object latterIOEPModel = latterIOEP.getModel();
							if (latterIOEPModel instanceof Shape) {
								Shape latterIOEPShape = (Shape) latterIOEPModel;
								if (latterIOEPShape.getLayoutConstraint() instanceof Bounds) {
									final Bounds latterIOEPOriginalBounds = (Bounds) latterIOEPShape.getLayoutConstraint();
									ICommand command = new AbstractTransactionalCommand(previousIOEP.getEditingDomain(),"Merge operand bounds command",null){
										@Override
										protected CommandResult doExecuteWithResult(
												IProgressMonitor monitor,
												IAdaptable info)
												throws ExecutionException {
											latterIOEPOriginalBounds.setY(0);
											latterIOEPOriginalBounds.setHeight(latterIOEPOriginalBounds.getHeight() + currentioEPBounds.height());
											return CommandResult.newOKCommandResult();
										}
									};
									cmd.add(command);
								}
							}
						}
					}
			}
		}
		
	}
	
	/**
	 * Add update InteractionOperand bounds command after IO is created 
	 * @param compartment
	 * @param request
	 * @param command
	 */
	public static void addUpdateBoundsForIOCreationCommand(
			CombinedFragmentCombinedFragmentCompartmentEditPart compartment, ViewDescriptor viewDescriptor,
			CompositeCommand command) {
		List children = compartment.getChildren();
		if (children != null && children.size() > 0) {
			InteractionOperandEditPart lastOperandEP = OperandBoundsComputeHelper.findLastIOEP(compartment);
			// update bounds
			if (lastOperandEP != null) {
				Bounds lastOperandBounds = OperandBoundsComputeHelper.getInteractionOperandEPBounds(lastOperandEP);
				if (lastOperandBounds!= null) {
					Rectangle rect = new Rectangle(
							lastOperandBounds.getX(),
							lastOperandBounds.getY()+lastOperandBounds.getHeight(), lastOperandBounds.getWidth(), OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT);
					// auto update CombinedFragmentEditPart bounds after added new operand
					if(compartment.getParent() instanceof CombinedFragmentEditPart){
						CombinedFragmentEditPart parent = (CombinedFragmentEditPart) compartment
								.getParent();
						if (parent.getModel() instanceof Node) {
							Node node = (Node) parent.getModel();
							if (node.getLayoutConstraint() instanceof Bounds) {
								Bounds containerBounds = (Bounds) node.getLayoutConstraint();
								Dimension preferredSize = parent.getFigure().getPreferredSize();
								int width = containerBounds.getWidth()!=-1? containerBounds.getWidth() :  preferredSize.width();
								int height = containerBounds.getHeight()!=-1? containerBounds.getHeight() :  preferredSize.height();
								height = height + OperandBoundsComputeHelper.DEFAULT_INTERACTION_OPERAND_HEIGHT;
								View shapeView = (View) parent.getModel();
								ICommand setParentBoundsCmd = new SetBoundsCommand(compartment.getEditingDomain(),
							            DiagramUIMessages.SetLocationCommand_Label_Resize,
							            new EObjectAdapter(shapeView), new Rectangle(containerBounds.getX(),containerBounds.getY(),width,height));
								command.add(setParentBoundsCmd);
							}
						}
					}
					command.add(new SetBoundsCommand(compartment.getEditingDomain(), DiagramUIMessages.SetLocationCommand_Label_Resize, viewDescriptor, rect));
				}
			}
		}else{ // first add operand
			if(compartment.getParent() instanceof CombinedFragmentEditPart){
				CombinedFragmentEditPart parent = (CombinedFragmentEditPart) compartment
						.getParent();
				if (parent.getModel() instanceof Node) {
					Node node = (Node) parent.getModel();
					if (node.getLayoutConstraint() instanceof Bounds) {
						Bounds containerBounds = (Bounds) node.getLayoutConstraint();
						Dimension preferredSize = parent.getFigure().getPreferredSize();
						int width = containerBounds.getWidth()!=-1? containerBounds.getWidth() :  preferredSize.width();
						int height = containerBounds.getHeight()!=-1? containerBounds.getHeight() :  preferredSize.height();
						height = height - computeCombinedFragementHeaderHeight(parent);
						command.add(new SetBoundsCommand(compartment.getEditingDomain(), DiagramUIMessages.SetLocationCommand_Label_Resize, viewDescriptor, new Rectangle(0,0,width-COMBINED_FRAGMENT_FIGURE_BORDER*2,height-COMBINED_FRAGMENT_FIGURE_BORDER*2)));
					}
				}
			}
		}
	}
	
	/**
	 * Check if it is a combined fragment.
	 * 
	 * @param hint
	 *        the semantic hint
	 * @return
	 */
	public static boolean isDerivedCombinedFragment(String hint) {
		if(((IHintedType)UMLElementTypes.CombinedFragment_3004).getSemanticHint().equals(hint)) {
			return true;
		}
		if(((IHintedType)UMLElementTypes.ConsiderIgnoreFragment_3007).getSemanticHint().equals(hint)) {
			return true;
		}
		return false;
	}
	
	/**
	 * Command class for updating Interaction Operand EditpPart bounds after CombinedFragment to be resized. 
	 *
	 */
	private static final class UpdateIOBoundsForCFResizeCommand extends
			AbstractTransactionalCommand {
		private final Bounds ioEPOriginalBounds;
		private final ChangeBoundsRequest request;
		private final Dimension sizeDelta;
		private boolean updateHeight = false;
		private int direction;

		private UpdateIOBoundsForCFResizeCommand(TransactionalEditingDomain domain,
				String label, Bounds ioEPOriginalBounds,
				ChangeBoundsRequest request, Dimension sizeDelta,
				boolean updateHeight, int direction) {
			super(domain, label, null);
			this.ioEPOriginalBounds = ioEPOriginalBounds;
			this.request = request;
			this.sizeDelta = sizeDelta;
			this.updateHeight = updateHeight;
			this.direction = direction;
		}

		@Override
		protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
				IAdaptable info) throws ExecutionException {
			if (updateHeight) {
				ioEPOriginalBounds.setHeight(ioEPOriginalBounds.getHeight()
						+ sizeDelta.height());
			} else if ((direction & PositionConstants.NORTH) != 0) {
				ioEPOriginalBounds.setY(ioEPOriginalBounds.getY()
						+ sizeDelta.height());
			}
			if ((request.getResizeDirection() & PositionConstants.EAST_WEST) != 0) {
				ioEPOriginalBounds.setWidth(ioEPOriginalBounds.getWidth()
						+ sizeDelta.width());
			}

			return CommandResult.newOKCommandResult();
		}

	}

}

Back to the top