Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 4adc38ab280e386a90bcfe822fa43480c58ddbbf (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
/*****************************************************************************
 * Copyright (c) 2010 CEA
 *
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Atos Origin - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrus.uml.diagram.sequence.edit.policies;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.util.EList;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.BorderItemSelectionEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.DurationConstraintEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.util.OccurrenceSpecificationMoveHelper;
import org.eclipse.uml2.uml.DurationConstraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ExecutionOccurrenceSpecification;
import org.eclipse.uml2.uml.ExecutionSpecification;

/**
 * Edit policy to restrict border item movement. This edit policy moves the related events when a Time/Duration Observation/Constraint is moved.
 */
public class TimeRelatedSelectionEditPolicy extends BorderItemSelectionEditPolicy {

	@Override
	protected Command getMoveCommand(ChangeBoundsRequest request) {
		updateRequest(request);
		// Prepare request
		if (getHost() instanceof IBorderItemEditPart) {
			OccurrenceSpecificationMoveHelper.prepareTimeRelatedElementMoveRequest(request, (IBorderItemEditPart) getHost());
		}
		// In fact, BorderItem can not be moved out of parent bounds, so the moveDelta if not correctly when move out parent.
		Command command = super.getMoveCommand(request);
		if (command != null) {
			if (invalidMoveDurationConstraint(request.getMoveDelta())) {
				return UnexecutableCommand.INSTANCE;
			}
			command = OccurrenceSpecificationMoveHelper.completeMoveTimeRelatedElementCommand(command, request, getHost(), getHostFigure());
		}
		return command;
	}

	/**
	 * Bug description:
	 * When we move down the Duration Constraint which attached to a Execution Specification, the Execution Specification can be moved out it's Parent
	 * Execution Specification. This would not happen when move Execution Specification directly.
	 *
	 * At present, we just avoid this kind of moving.
	 */
	private boolean invalidMoveDurationConstraint(Point moveDelta) {
		if (!(getHost() instanceof DurationConstraintEditPart) || moveDelta == null || moveDelta.y == 0) {
			return false;
		}
		DurationConstraintEditPart editPart = (DurationConstraintEditPart) getHost();
		DurationConstraint durationConstraint = (DurationConstraint) editPart.resolveSemanticElement();
		EList<Element> constrainedElements = durationConstraint.getConstrainedElements();
		List<ExecutionSpecification> executions = new ArrayList<>();
		for (Element element : constrainedElements) {
			if (!(element instanceof ExecutionOccurrenceSpecification)) {
				continue;
			}
			ExecutionSpecification execution = ((ExecutionOccurrenceSpecification) element).getExecution();
			if (execution != null && !executions.contains(execution)) {
				executions.add(execution);
			}
		}
		if (executions.isEmpty()) {
			return false;
		}
		// LifelineEditPart lifelineEditPart = (LifelineEditPart)getHost().getParent();
		// for(ExecutionSpecification executionSpecification : executions) {
		// Collection<Setting> settings = CacheAdapter.getInstance().getNonNavigableInverseReferences(executionSpecification);
		// for(Setting ref : settings) {
		// if(NotationPackage.eINSTANCE.getView_Element().equals(ref.getEStructuralFeature())) {
		// View view = (View)ref.getEObject();
		// EditPart part = DiagramEditPartsUtil.getEditPartFromView(view, getHost());
		// if(!(part instanceof ShapeNodeEditPart)) {
		// continue;
		// }
		// Rectangle childBounds = ((ShapeNodeEditPart)part).getFigure().getBounds().getCopy();
		// List<ShapeNodeEditPart> toCheckExecutionSpecificationList = new ArrayList<ShapeNodeEditPart>(lifelineEditPart.getChildShapeNodeEditPart());
		// toCheckExecutionSpecificationList.remove(part);
		// ShapeNodeEditPart parent = LifelineXYLayoutEditPolicy.getParent(lifelineEditPart, childBounds, toCheckExecutionSpecificationList);
		// if(parent != null) {
		// Rectangle parentBounds = parent.getFigure().getBounds().getCopy();
		// if(childBounds.y + moveDelta.y >= parentBounds.bottom() - 1) {
		// return true;
		// }
		// }
		// }
		// }
		// }
		return true;
	}

	/**
	 * By default, the IBorderItemEditPart can not be moved out of the parent.
	 *
	 * @param request
	 */
	private void updateRequest(ChangeBoundsRequest request) {
		IBorderItemEditPart borderItemEP = (IBorderItemEditPart) getHost();
		IBorderItemLocator borderItemLocator = borderItemEP.getBorderItemLocator();
		if (borderItemLocator != null) {
			Rectangle initialFeedbackBounds = getInitialFeedbackBounds();
			PrecisionRectangle rect = new PrecisionRectangle(initialFeedbackBounds.getCopy());
			getHostFigure().translateToAbsolute(rect);
			rect.translate(request.getMoveDelta());
			rect.resize(request.getSizeDelta());
			getHostFigure().translateToRelative(rect);
			Rectangle realLocation = borderItemLocator.getValidLocation(rect.getCopy(), borderItemEP.getFigure());
			Point parentOrigin = borderItemEP.getFigure().getParent().getBounds().getTopLeft();
			Dimension d = realLocation.getTopLeft().getDifference(parentOrigin);
			Point newLocation = new Point(d.width, d.height);
			if (getHost().getModel() instanceof Node && ((Node) getHost().getModel()).getLayoutConstraint() instanceof Bounds) {
				Bounds bounds = (Bounds) ((Node) getHost().getModel()).getLayoutConstraint();
				Point moveDelta = request.getMoveDelta();
				moveDelta.x = newLocation.x - bounds.getX();
				moveDelta.y = newLocation.y - bounds.getY();
			}
		}
	}

	@Override
	protected void showChangeBoundsFeedback(ChangeBoundsRequest request) {
		if (getHost() instanceof IBorderItemEditPart) {
			OccurrenceSpecificationMoveHelper.prepareTimeRelatedElementMoveRequest(request, (IBorderItemEditPart) getHost());
		}
		super.showChangeBoundsFeedback(request);
	}
}

Back to the top