Bug 442157 LinkLF routing: provide basic super class for connection
edit-parts, allow switching LinkLF mode on and off (for safety)
Change-Id: I53fc060f70a53aa2c934e9ab0087893adf26bb43
diff --git a/plugins/org.eclipse.gmf.tooling.runtime/META-INF/MANIFEST.MF b/plugins/org.eclipse.gmf.tooling.runtime/META-INF/MANIFEST.MF
index fec0679..b78213a 100644
--- a/plugins/org.eclipse.gmf.tooling.runtime/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.gmf.tooling.runtime/META-INF/MANIFEST.MF
@@ -36,6 +36,7 @@
org.eclipse.gmf.tooling.runtime.edit.policies.labels,
org.eclipse.gmf.tooling.runtime.edit.policies.reparent,
org.eclipse.gmf.tooling.runtime.linklf,
+ org.eclipse.gmf.tooling.runtime.linklf.editparts,
org.eclipse.gmf.tooling.runtime.linklf.labels,
org.eclipse.gmf.tooling.runtime.linklf.policies,
org.eclipse.gmf.tooling.runtime.linklf.router,
diff --git a/plugins/org.eclipse.gmf.tooling.runtime/src/org/eclipse/gmf/tooling/runtime/linklf/editparts/LinkLFConnectionNodeEditPart.java b/plugins/org.eclipse.gmf.tooling.runtime/src/org/eclipse/gmf/tooling/runtime/linklf/editparts/LinkLFConnectionNodeEditPart.java
new file mode 100644
index 0000000..79764d5
--- /dev/null
+++ b/plugins/org.eclipse.gmf.tooling.runtime/src/org/eclipse/gmf/tooling/runtime/linklf/editparts/LinkLFConnectionNodeEditPart.java
@@ -0,0 +1,131 @@
+/*****************************************************************************
+ * Copyright (c) 2014-15 CEA LIST, Montages AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Michael Golubev (Montages) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.gmf.tooling.runtime.linklf.editparts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.Bendpoint;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionNodeEditPart;
+import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.ForestRouter;
+import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.OrthogonalRouter;
+import org.eclipse.gmf.runtime.gef.ui.internal.editpolicies.LineMode;
+import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint;
+import org.eclipse.gmf.tooling.runtime.linklf.AbsoluteBendpointsConvention;
+import org.eclipse.gmf.tooling.runtime.linklf.policies.LinksLFConnectionBendpointEditPolicy;
+import org.eclipse.gmf.tooling.runtime.linklf.policies.LinksLFConnectionEndPointEditPolicy;
+
+/**
+ * This is a base class for LinkLF connection edit parts which allows to switch
+ * LinkLF mode on / off. When the LinkLF is switched off, the link should behave
+ * exactly like default GMF Runtime {@link ConnectionNodeEditPart}.
+ * <p/>
+ *
+ * @since 3.3
+ */
+public abstract class LinkLFConnectionNodeEditPart extends
+ OverridableConnectionNodeEditPart {
+
+ private boolean myLinkLFEnabled;
+ private EditPolicy myOriginalEndPointsEditPolicy;
+
+ public LinkLFConnectionNodeEditPart(View view) {
+ super(view);
+ }
+
+ public void setLinkLFEnabled(boolean enabled) {
+ if (enabled != myLinkLFEnabled) {
+ myLinkLFEnabled = enabled;
+ refreshRouterChange();
+ refreshEndPointsEditPolicy();
+ }
+ }
+
+ /**
+ * Called when LinkLF-mode for the link is changed. It is expected to happen
+ * at max once in the link lifetime.
+ */
+ protected void refreshEndPointsEditPolicy() {
+ if (myOriginalEndPointsEditPolicy == null) {
+ myOriginalEndPointsEditPolicy = getEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE);
+ }
+
+ EditPolicy endPoints = myLinkLFEnabled ? createEndPointsEditPolicy()
+ : myOriginalEndPointsEditPolicy;
+ installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, endPoints);
+ }
+
+ /**
+ * Allows subclasses to redefine an edit policy for
+ * {@link EditPolicy#CONNECTION_ENDPOINTS_ROLE} role.
+ */
+ protected EditPolicy createEndPointsEditPolicy() {
+ // return new DebugShowConnectionEndPointsAndAnchorsEditPolicy();
+ return new LinksLFConnectionEndPointEditPolicy();
+ }
+
+ @Override
+ protected void refreshBendpoints() {
+ if (!myLinkLFEnabled) {
+ super.refreshBendpoints();
+ return;
+ }
+
+ RelativeBendpoints bendpoints = (RelativeBendpoints) getEdge()
+ .getBendpoints();
+ List<?> modelConstraint = bendpoints.getPoints();
+ List<Bendpoint> figureConstraint = new ArrayList<Bendpoint>();
+ for (int i = 0; i < modelConstraint.size(); i++) {
+ RelativeBendpoint wbp = (RelativeBendpoint) modelConstraint.get(i);
+ float weight;
+ if (modelConstraint.size() == 1) {
+ weight = 0.5f;
+ } else {
+ weight = i / ((float) modelConstraint.size() - 1);
+ }
+ Bendpoint bp = AbsoluteBendpointsConvention.getInstance()
+ .d2dBendpoint(wbp, getConnectionFigure(), weight);
+ figureConstraint.add(bp);
+ }
+ getConnectionFigure().setRoutingConstraint(figureConstraint);
+ }
+
+ /**
+ * When in the LinkLF mode, installs LinkLF-versions of the corresponding
+ * {@link EditPolicy#CONNECTION_BENDPOINTS_ROLE} edit policy.
+ */
+ protected final void installBendpointEditPolicy() {
+ if (!myLinkLFEnabled) {
+ super.installBendpointEditPolicy();
+ return;
+ }
+
+ if (getConnectionFigure().getConnectionRouter() instanceof ForestRouter) {
+ installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
+ new LinksLFConnectionBendpointEditPolicy(
+ LineMode.ORTHOGONAL_CONSTRAINED));
+ } else if (getConnectionFigure().getConnectionRouter() instanceof OrthogonalRouter) {
+ installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
+ new LinksLFConnectionBendpointEditPolicy(
+ LineMode.ORTHOGONAL_FREE));
+ } else {
+ installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
+ new LinksLFConnectionBendpointEditPolicy(LineMode.OBLIQUE));
+ }
+ refreshConnectionCursor();
+ }
+
+}
diff --git a/plugins/org.eclipse.gmf.tooling.runtime/src/org/eclipse/gmf/tooling/runtime/linklf/editparts/OverridableConnectionNodeEditPart.java b/plugins/org.eclipse.gmf.tooling.runtime/src/org/eclipse/gmf/tooling/runtime/linklf/editparts/OverridableConnectionNodeEditPart.java
new file mode 100644
index 0000000..f45c8a3
--- /dev/null
+++ b/plugins/org.eclipse.gmf.tooling.runtime/src/org/eclipse/gmf/tooling/runtime/linklf/editparts/OverridableConnectionNodeEditPart.java
@@ -0,0 +1,125 @@
+package org.eclipse.gmf.tooling.runtime.linklf.editparts;
+
+import org.eclipse.draw2d.Connection;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionNodeEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ConnectionBendpointEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.ConnectionLineSegEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.TreeConnectionBendpointEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.util.EditPartUtil;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx;
+import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.ForestRouter;
+import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.OrthogonalRouter;
+import org.eclipse.gmf.runtime.gef.ui.internal.l10n.Cursors;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.RoutingStyle;
+import org.eclipse.gmf.runtime.notation.View;
+
+/**
+ * This class is a workaround for a bunch of private methods dealing with the
+ * default edit policies for the {@link ConnectionNodeEditPart}
+ * <p/>
+ * This class is expected to become obsolete and removed in the Mars+1 release,
+ * once the corresponding methods made protected in the super-class
+ * <p/>
+ * [GMFR make protected]
+ *
+ * @see OverridableConnectionNodeEditPart#installBendpointEditPolicy()
+ * @since 3.3
+ */
+public abstract class OverridableConnectionNodeEditPart extends ConnectionNodeEditPart {
+
+ public OverridableConnectionNodeEditPart(View view) {
+ super(view);
+ }
+
+ /**
+ * This method is private in {@link ConnectionEditPart} while being called
+ * from the methods which have to be overridden in the LinkLF framework.
+ * <p/>
+ * This class does NOT change the logic from the super class, it only allows
+ * to override it in subclasses
+ */
+ protected void installBendpointEditPolicy() {
+ if (getConnectionFigure().getConnectionRouter() instanceof ForestRouter) {
+ installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
+ new TreeConnectionBendpointEditPolicy());
+ } else if (getConnectionFigure().getConnectionRouter() instanceof OrthogonalRouter) {
+ installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
+ new ConnectionLineSegEditPolicy());
+ } else {
+ installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
+ new ConnectionBendpointEditPolicy());
+ }
+ refreshConnectionCursor();
+ }
+
+ /**
+ * This method is part of the private
+ * {@link ConnectionEditPart#installBendpointEditPolicy}, extracted to
+ * simplify the overriding code in the sub-classes.
+ *
+ * @see OverridableConnectionNodeEditPart#installBendpointEditPolicy()
+ */
+ protected void refreshConnectionCursor() {
+ EditPartUtil.synchronizeRunnableToMainThread(this, new Runnable() {
+
+ public void run() {
+ if (getConnectionFigure().getConnectionRouter() instanceof ForestRouter) {
+ getConnectionFigure().setCursor(Cursors.CURSOR_SEG_MOVE);
+ } else if (getConnectionFigure().getConnectionRouter() instanceof OrthogonalRouter) {
+ getConnectionFigure().setCursor(Cursors.CURSOR_SEG_MOVE);
+ } else {
+ getConnectionFigure().setCursor(Cursors.CURSOR_SEG_ADD);
+ }
+ };
+ });
+ }
+
+ /**
+ * This method is copy-pasted from In contrast to super-class, this code
+ * calls the local version of {@link #installBendpointEditPolicy()} which
+ * can be overridden in sub-class
+ */
+ @Override
+ protected void refreshRouterChange() {
+ refreshBendpoints();
+ installBendpointEditPolicy();
+ }
+
+ /**
+ * This method is copy-pasted from the
+ * {@link ConnectionEditPart#refreshRoutingStyles}.
+ * <p/>
+ * In contrast to super-class, this code calls the local version of
+ * {@link #installBendpointEditPolicy()} which can be overridden in
+ * sub-class.
+ */
+ @Override
+ protected void refreshRoutingStyles() {
+ Connection connection = getConnectionFigure();
+ if (!(connection instanceof PolylineConnectionEx)) {
+ return;
+ }
+
+ PolylineConnectionEx poly = (PolylineConnectionEx) connection;
+
+ RoutingStyle style = (RoutingStyle) ((View) getModel())
+ .getStyle(NotationPackage.Literals.ROUTING_STYLE);
+ if (style != null) {
+
+ boolean closestDistance = style.isClosestDistance();
+ boolean avoidObstruction = style.isAvoidObstructions();
+
+ poly.setRoutingStyles(closestDistance, avoidObstruction);
+
+ if (avoidObstruction) {
+ installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, null);
+ } else {
+ installBendpointEditPolicy();
+ }
+ }
+ }
+
+}