Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorskovalsky2015-02-23 15:23:54 +0000
committervincent lorenzo2015-03-19 12:36:42 +0000
commit24d189725f3dee2e5903b052f10eaaa584ba1e59 (patch)
treecd518620afdd871409bc0c5a34cf42ca69910706 /plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common
parenta14a62398864446a1c08d60e77300909880bae6c (diff)
downloadorg.eclipse.papyrus-24d189725f3dee2e5903b052f10eaaa584ba1e59.tar.gz
org.eclipse.papyrus-24d189725f3dee2e5903b052f10eaaa584ba1e59.tar.xz
org.eclipse.papyrus-24d189725f3dee2e5903b052f10eaaa584ba1e59.zip
Bug 459839 - [All Diagrams] unexpected behavior moving multiple linked
elements Change-Id: I6a1074f93b61fbc2d9872d6f16fdc017b1367837 Signed-off-by: skovalsky <kovalsky@montages.com>
Diffstat (limited to 'plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common')
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/PapyrusResizableShapeEditPolicy.java135
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/XYLayoutWithConstrainedResizedEditPolicy.java44
2 files changed, 172 insertions, 7 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/PapyrusResizableShapeEditPolicy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/PapyrusResizableShapeEditPolicy.java
index 7b78ab6377b..86ddc758eb6 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/PapyrusResizableShapeEditPolicy.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/PapyrusResizableShapeEditPolicy.java
@@ -13,6 +13,14 @@
*****************************************************************************/
package org.eclipse.papyrus.infra.gmfdiag.common.editpolicies;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.ChangeBoundsRequest;
@@ -28,6 +36,56 @@ import org.eclipse.papyrus.infra.gmfdiag.common.snap.ResizeTrackerWithPreference
public class PapyrusResizableShapeEditPolicy extends ResizableShapeEditPolicy {
/**
+ * The same {@link ChangeBoundsRequest} is sent to all moved edit parts,
+ * so we can cache the info about them in request potentially improving o(N^2) performance.
+ */
+ private static final String PARAM_CACHED_EDIT_PARTS_SET = PapyrusResizableShapeEditPolicy.class.getName() + ":CachedMovedEPs";
+
+ /**
+ * Tries to find the cached instance of {@link CachedEditPartsSet} in the request extended data map.
+ * If not found, initializes the new instance and caches it in request for other edit-policy instances.
+ *
+ * @param req
+ * @return never returns <code>null</code>
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected static CachedEditPartsSet getMovedEditPartsSet(ChangeBoundsRequest req) {
+ Map extData = req.getExtendedData();
+ CachedEditPartsSet set = (CachedEditPartsSet) extData.get(PARAM_CACHED_EDIT_PARTS_SET);
+ if (set == null) {
+ set = new CachedEditPartsSet(req.getEditParts());
+ extData.put(PARAM_CACHED_EDIT_PARTS_SET, set);
+ }
+ return set;
+ }
+
+ /**
+ * This implementation overrides {@link org.eclipse.gef.editpolicies.NonResizableEditPolicy#getMoveCommand} and keeps all parent's logic.
+ * Multi-selection request identified by the presence of {@link PapyrusResizableShapeEditPolicy#PARAM_CACHED_EDIT_PARTS_SET} key
+ * for request extended data
+ * see {@link org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.XYLayoutWithConstrainedResizedEditPolicy#getConnectionsToElementsNotBeingMoved}
+ *
+ * @param request
+ * the change bounds request
+ * @return the command contribution to the request
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Command getMoveCommand(ChangeBoundsRequest request) {
+ ChangeBoundsRequest req = new ChangeBoundsRequest(REQ_MOVE_CHILDREN);
+ req.setEditParts(getHost());
+ req.setMoveDelta(request.getMoveDelta());
+ req.setSizeDelta(request.getSizeDelta());
+ req.setLocation(request.getLocation());
+ Map<Object, Object> extendedData = new HashMap<Object, Object>();
+ extendedData.putAll(request.getExtendedData());
+ CachedEditPartsSet set = new CachedEditPartsSet(request.getEditParts());
+ extendedData.put(PARAM_CACHED_EDIT_PARTS_SET, set);
+ req.setExtendedData(extendedData);
+ return getHost().getParent().getCommand(req);
+ }
+
+ /**
* See Bug 424943 ResizableEditPolicy#getResizeCommand duplicates request ignoring some request values
* TODO : remove this override when the bug will be fixed
*
@@ -75,4 +133,81 @@ public class PapyrusResizableShapeEditPolicy extends ResizableShapeEditPolicy {
return new ResizeTrackerWithPreferences((GraphicalEditPart) getHost(), direction);
}
+ protected static enum MovedNodeKind {
+ DIRECTLY, INDIRECTLY, NO
+ }
+
+ protected static class CachedEditPartsSet {
+
+ private final Set<EditPart> myDirectlyMoved;
+
+ private final Set<EditPart> myKnownIndirectlyYes;
+
+ private final Set<EditPart> myKnownIndirectlyNo;
+
+ public CachedEditPartsSet(List<EditPart> directlyMoved) {
+ myDirectlyMoved = new HashSet<EditPart>(directlyMoved);
+ myKnownIndirectlyNo = new HashSet<EditPart>(directlyMoved.size() * 5 + 1);
+ myKnownIndirectlyYes = new HashSet<EditPart>(directlyMoved.size() * 5 + 1);
+ }
+
+ public boolean isMovedEditPart(EditPart ep) {
+ return isMoved(ep) != MovedNodeKind.NO;
+ }
+
+ public MovedNodeKind isMoved(EditPart ep) {
+ List<EditPart> chainUp = new LinkedList<EditPart>();
+ EditPart cur = ep;
+ MovedNodeKind kind = null;
+ while (cur != null) {
+ kind = getKnownKind(cur);
+ if (kind != null) {
+ break;
+ }
+ chainUp.add(cur);
+ cur = cur.getParent();
+ }
+ if (cur == null || kind == null) {
+ kind = MovedNodeKind.NO;
+ } else if (kind == MovedNodeKind.DIRECTLY && cur != ep) {
+ kind = MovedNodeKind.INDIRECTLY;
+ }
+
+ Set<EditPart> forKind;
+ switch (kind) {
+ case DIRECTLY:
+ forKind = myDirectlyMoved;
+ break;
+ case INDIRECTLY:
+ forKind = myKnownIndirectlyYes;
+ break;
+ case NO:
+ forKind = myKnownIndirectlyNo;
+ break;
+ default:
+ throw new IllegalArgumentException("Wow: " + kind);
+ }
+
+ if (kind != MovedNodeKind.DIRECTLY) {
+ forKind.addAll(chainUp);
+ }
+
+ return kind;
+ }
+
+ private MovedNodeKind getKnownKind(EditPart ep) {
+ if (myDirectlyMoved.contains(ep)) {
+ return MovedNodeKind.DIRECTLY;
+ }
+ if (myKnownIndirectlyYes.contains(ep)) {
+ return MovedNodeKind.INDIRECTLY;
+ }
+ if (myKnownIndirectlyNo.contains(ep)) {
+ return MovedNodeKind.NO;
+ }
+ return null;
+ }
+
+ }
+
}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/XYLayoutWithConstrainedResizedEditPolicy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/XYLayoutWithConstrainedResizedEditPolicy.java
index dd9c392c172..ea0dcb65f4d 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/XYLayoutWithConstrainedResizedEditPolicy.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/XYLayoutWithConstrainedResizedEditPolicy.java
@@ -13,6 +13,7 @@
*****************************************************************************/
package org.eclipse.papyrus.infra.gmfdiag.common.editpolicies;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -31,6 +32,7 @@ import org.eclipse.gef.NodeEditPart;
import org.eclipse.gef.SnapToHelper;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
+import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
@@ -207,22 +209,50 @@ public class XYLayoutWithConstrainedResizedEditPolicy extends XYLayoutEditPolicy
protected Command createChangeConstraintCommand(ChangeBoundsRequest request, EditPart child, Object constraint) {
final Command cmd = super.createChangeConstraintCommand(request, child, constraint);
if (org.eclipse.gef.RequestConstants.REQ_MOVE_CHILDREN.equals(request.getType()) && child instanceof INodeEditPart) {
- List<?> sources = ((INodeEditPart) child).getSourceConnections();
- List<?> targets = ((INodeEditPart) child).getTargetConnections();
- Set<Object> connections = new HashSet<Object>();
- connections.addAll(sources);
- connections.addAll(targets);
- if (!connections.isEmpty()) {
+ Set<Object> notBeingMovedConnections = getConnectionsToElementsNotBeingMoved(request, child);
+ if (!notBeingMovedConnections.isEmpty()) {
final CompoundCommand cc = new CompoundCommand();
cc.add(cmd);
// see bug 430702: [Diagram] Moving source of a link moves the target too.
- cc.add(new ICommandProxy(new FixEdgeAnchorsDeferredCommand(getEditingDomain(), (IGraphicalEditPart) getHost(), connections)));
+ cc.add(new ICommandProxy(new FixEdgeAnchorsDeferredCommand(getEditingDomain(), (IGraphicalEditPart) getHost(), notBeingMovedConnections)));
return cc;
}
}
return cmd;
}
+ /*
+ * {@link FixEdgeAnchorsDeferredCommand} should not be applied to the multiple selection move request
+ * see Bug 459839 - [All Diagrams] unexpected behavior moving multiple linked elements
+ */
+ private Set<Object> getConnectionsToElementsNotBeingMoved(ChangeBoundsRequest request, EditPart child) {
+ List<?> sources = ((INodeEditPart) child).getSourceConnections();
+ List<?> targets = ((INodeEditPart) child).getTargetConnections();
+ Set<Object> connections = new HashSet<Object>();
+ connections.addAll(sources);
+ connections.addAll(targets);
+ if (connections.isEmpty()) {
+ return Collections.emptySet();
+ }
+ PapyrusResizableShapeEditPolicy.CachedEditPartsSet movedEditPartsSet = PapyrusResizableShapeEditPolicy.getMovedEditPartsSet(request);
+ final Set<Object> result = new HashSet<Object>();
+ final Iterator<?> connectionsIter = connections.iterator();
+ while (connectionsIter.hasNext()) {
+ final Object nextConnection = connectionsIter.next();
+ if (false == nextConnection instanceof AbstractConnectionEditPart) {
+ continue;
+ }
+ AbstractConnectionEditPart nextTypedConnection = (AbstractConnectionEditPart) nextConnection;
+ EditPart sourceEnd = nextTypedConnection.getSource();
+ EditPart targetEnd = nextTypedConnection.getTarget();
+ if (movedEditPartsSet.isMovedEditPart(sourceEnd) && movedEditPartsSet.isMovedEditPart(targetEnd)) {
+ continue;
+ }
+ result.add(nextConnection);
+ }
+ return result;
+ }
+
protected final TransactionalEditingDomain getEditingDomain() {
TransactionalEditingDomain domain = null;

Back to the top