From 8ea3ec2e74deb6ac0918489a29d66682da96cca4 Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Tue, 23 Aug 2011 14:08:54 +0000
Subject: [PATCH] refactored GEF editor base

---
 .../editor/gef/GraphicalViewerEditorBase.java | 31 ++++++
 .../base/ui/editpart/DiagramEditPartBase.java | 75 +++++++++++++-
 .../base/ui/editpart/ElementEditPartBase.java | 14 +++
 .../editpart/FreeConnectorEditPartBase.java   |  8 ++
 .../LayoutedConnectionEditPartBase.java       | 97 ++++++++++++++++++-
 .../editpart/StickyConnectorEditPartBase.java |  7 ++
 6 files changed, 227 insertions(+), 5 deletions(-)

diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/GraphicalViewerEditorBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/GraphicalViewerEditorBase.java
index 14c6a0cd5..fd6658b3f 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/GraphicalViewerEditorBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/GraphicalViewerEditorBase.java
@@ -22,18 +22,24 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.conqat.ide.commons.gef.editpart.EditPartUtils;
+import org.eclipse.draw2d.geometry.Dimension;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.gef.EditDomain;
+import org.eclipse.gef.EditPart;
 import org.eclipse.gef.EditPartFactory;
 import org.eclipse.gef.EditPartViewer;
 import org.eclipse.gef.GraphicalViewer;
 import org.eclipse.gef.MouseWheelHandler;
 import org.eclipse.gef.MouseWheelZoomHandler;
+import org.eclipse.gef.Request;
 import org.eclipse.gef.RootEditPart;
+import org.eclipse.gef.SnapToGeometry;
+import org.eclipse.gef.SnapToGrid;
 import org.eclipse.gef.commands.CommandStack;
 import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
 import org.eclipse.gef.editparts.ScalableRootEditPart;
 import org.eclipse.gef.editparts.ZoomManager;
+import org.eclipse.gef.editpolicies.AbstractEditPolicy;
 import org.eclipse.gef.ui.actions.ActionRegistry;
 import org.eclipse.gef.ui.actions.DeleteAction;
 import org.eclipse.gef.ui.actions.PrintAction;
@@ -66,6 +72,7 @@ import org.fortiss.tooling.base.ui.action.PasteModelElementAction;
 import org.fortiss.tooling.base.ui.dnd.DropTargetListener;
 import org.fortiss.tooling.base.ui.editpart.ExtendedLayerRootEditPart;
 import org.fortiss.tooling.base.ui.editpart.figure.EVisualStyle;
+import org.fortiss.tooling.base.ui.layout.constants.DefaultLayoutConstants;
 import org.fortiss.tooling.kernel.ui.service.IEditPartFactoryService;
 
 /**
@@ -145,6 +152,30 @@ public class GraphicalViewerEditorBase<T extends EObject> extends EditorBase<T>
 
 		// drag and drop
 		viewer.addDropTargetListener(new DropTargetListener(viewer));
+
+		viewer.getControl().setBackground(parent.getBackground());
+		viewer.setProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED, true);
+		viewer.setProperty(SnapToGrid.PROPERTY_GRID_ORIGIN,
+				DefaultLayoutConstants.DEFAULT_GRID_ORIGIN);
+
+		Dimension gridSpacing = new Dimension(
+				DefaultLayoutConstants.DEFAULT_GRID_SIZE,
+				DefaultLayoutConstants.DEFAULT_GRID_SIZE);
+		viewer.setProperty(SnapToGrid.PROPERTY_GRID_SPACING, gridSpacing);
+		viewer.setProperty(SnapToGrid.PROPERTY_GRID_ENABLED, true);
+		viewer.setProperty(SnapToGrid.PROPERTY_GRID_VISIBLE, true);
+
+		// this is needed by direct connection feature. the root edit part
+		// becomes transparent when GEF selects a tool on button down event.
+		// we have to reloacte the call to the underlying root's content
+		((ScalableRootEditPart) viewer.getRootEditPart()).installEditPolicy(
+				"Test", new AbstractEditPolicy() {
+					@Override
+					public EditPart getTargetEditPart(Request request) {
+						return getHost().getRoot().getContents()
+								.getTargetEditPart(request);
+					}
+				});
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/DiagramEditPartBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/DiagramEditPartBase.java
index a538603f1..9319a5000 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/DiagramEditPartBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/DiagramEditPartBase.java
@@ -22,17 +22,27 @@ import java.util.List;
 
 import org.eclipse.draw2d.BendpointConnectionRouter;
 import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.ConnectionAnchor;
 import org.eclipse.draw2d.ConnectionLayer;
 import org.eclipse.draw2d.ConnectionRouter;
 import org.eclipse.draw2d.FreeformLayer;
 import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.XYAnchor;
 import org.eclipse.draw2d.XYLayout;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.ConnectionEditPart;
+import org.eclipse.gef.DragTracker;
 import org.eclipse.gef.EditPolicy;
 import org.eclipse.gef.LayerConstants;
+import org.eclipse.gef.NodeEditPart;
+import org.eclipse.gef.Request;
 import org.eclipse.gef.SnapToHelper;
 import org.eclipse.gef.editpolicies.RootComponentEditPolicy;
 import org.eclipse.gef.editpolicies.SnapFeedbackPolicy;
+import org.eclipse.gef.requests.CreateConnectionRequest;
+import org.eclipse.gef.requests.SelectionRequest;
+import org.eclipse.gef.tools.ConnectionDragCreationTool;
+import org.eclipse.gef.tools.MarqueeDragTracker;
 import org.eclipse.swt.SWT;
 import org.fortiss.tooling.base.ui.editpart.policy.ConnectionGraphicalNodeEditPolicy;
 import org.fortiss.tooling.base.ui.editpart.policy.DiagramLayoutEditPolicy;
@@ -50,7 +60,7 @@ import org.fortiss.tooling.base.ui.layout.util.SnapToGridUtils;
  * @ConQAT.Rating YELLOW Hash: 76BF89DC0EFA9511DDF95CA4EC32C074
  */
 public abstract class DiagramEditPartBase<T extends EObject> extends
-		GraphicalEditPartBase<T> {
+		GraphicalEditPartBase<T> implements NodeEditPart {
 
 	/** Stores the connection router. */
 	private final ConnectionRouter connectionRouter;
@@ -102,6 +112,33 @@ public abstract class DiagramEditPartBase<T extends EObject> extends
 		return true;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 * <p>
+	 * This enables the creation of connections using ALT or CTRL key.
+	 */
+	@Override
+	public DragTracker getDragTracker(Request request) {
+		if (supportsDrag() && request instanceof SelectionRequest) {
+			SelectionRequest sr = (SelectionRequest) request;
+			if (sr.getLastButtonPressed() == 1
+					&& (sr.isAltKeyPressed() || sr.isControlKeyPressed())) {
+				return new ConnectionDragCreationTool();
+			} else if (sr.getLastButtonPressed() == 1) {
+				return new MarqueeDragTracker();
+			}
+		}
+		return super.getDragTracker(request);
+	}
+
+	/**
+	 * Supports drags (e.g. used in direct connections). The default is
+	 * <code>true</code>.
+	 */
+	protected boolean supportsDrag() {
+		return true;
+	}
+
 	/** {@inheritDoc} */
 	@SuppressWarnings("rawtypes")
 	@Override
@@ -135,4 +172,40 @@ public abstract class DiagramEditPartBase<T extends EObject> extends
 			cLayer.setConnectionRouter(connectionRouter);
 		}
 	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ConnectionAnchor getSourceConnectionAnchor(
+			ConnectionEditPart connection) {
+		// not needed
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ConnectionAnchor getSourceConnectionAnchor(Request request) {
+		if (request instanceof CreateConnectionRequest) {
+			return new XYAnchor(
+					((CreateConnectionRequest) request).getLocation());
+		}
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ConnectionAnchor getTargetConnectionAnchor(
+			ConnectionEditPart connection) {
+		// not needed
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ConnectionAnchor getTargetConnectionAnchor(Request request) {
+		if (request instanceof CreateConnectionRequest) {
+			return new XYAnchor(
+					((CreateConnectionRequest) request).getLocation());
+		}
+		return null;
+	}
 }
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/ElementEditPartBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/ElementEditPartBase.java
index d6d6c2b50..de0ff1916 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/ElementEditPartBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/ElementEditPartBase.java
@@ -20,9 +20,12 @@ package org.fortiss.tooling.base.ui.editpart;
 import java.util.List;
 
 import org.conqat.lib.commons.string.StringUtils;
+import org.eclipse.draw2d.ChopboxAnchor;
+import org.eclipse.draw2d.ConnectionAnchor;
 import org.eclipse.draw2d.Label;
 import org.eclipse.draw2d.PositionConstants;
 import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
 import org.eclipse.gef.EditPolicy;
 import org.eclipse.gef.Request;
 import org.eclipse.gef.RequestConstants;
@@ -111,6 +114,7 @@ public abstract class ElementEditPartBase<T extends ILayoutedModelElement & INam
 	}
 
 	/** {@inheritDoc} */
+	@SuppressWarnings("unchecked")
 	@Override
 	protected void refreshVisuals() {
 		super.refreshVisuals();
@@ -128,6 +132,16 @@ public abstract class ElementEditPartBase<T extends ILayoutedModelElement & INam
 		labelBounds.width -= 4 * DefaultLayoutConstants.DEFAULT_SHAPE_INSETS;
 		labelBounds.height = textBounds.height;
 		labelFigure.setBounds(labelBounds);
+
+		for (EditPart child : (List<EditPart>) getChildren()) {
+			child.refresh();
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected ConnectionAnchor defaultConnectionAnchor() {
+		return new ChopboxAnchor(getFigure());
 	}
 
 	/**
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/FreeConnectorEditPartBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/FreeConnectorEditPartBase.java
index aa67cfbb7..835e545a4 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/FreeConnectorEditPartBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/FreeConnectorEditPartBase.java
@@ -17,6 +17,7 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.base.ui.editpart;
 
+import org.fortiss.tooling.base.model.base.ExitConnectorBase;
 import org.fortiss.tooling.base.model.element.IConnector;
 import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
 import org.fortiss.tooling.kernel.model.INamedCommentedElement;
@@ -38,4 +39,11 @@ public abstract class FreeConnectorEditPartBase<T extends ILayoutedModelElement
 	protected FreeConnectorEditPartBase(T modelElement) {
 		super(modelElement);
 	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected boolean isTarget() {
+		// logic is reversed for free ports.
+		return modelElement instanceof ExitConnectorBase;
+	}
 }
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LayoutedConnectionEditPartBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LayoutedConnectionEditPartBase.java
index 18f115000..bb2640703 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LayoutedConnectionEditPartBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LayoutedConnectionEditPartBase.java
@@ -17,12 +17,28 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.base.ui.editpart;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.AbsoluteBendpoint;
+import org.eclipse.draw2d.BendpointConnectionRouter;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.MidpointLocator;
+import org.eclipse.draw2d.PolygonDecoration;
+import org.eclipse.draw2d.PolylineConnection;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.ecore.util.EContentAdapter;
-import org.fortiss.tooling.base.model.element.IConnection;
-import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
+import org.fortiss.tooling.base.model.base.ConnectionSegmentBase;
 import org.fortiss.tooling.base.model.layout.LayoutPackage;
+import org.fortiss.tooling.base.model.layout.Point;
+import org.fortiss.tooling.base.model.layout.Points;
+import org.fortiss.tooling.base.ui.editpart.policy.RemoveEditPolicy;
+import org.fortiss.tooling.base.ui.layout.constants.DefaultLayoutConstants;
+import org.fortiss.tooling.base.ui.layout.util.LayoutDataUtils;
 
 /**
  * The base class for all layouted connection edit parts. This makes sure the
@@ -36,12 +52,17 @@ import org.fortiss.tooling.base.model.layout.LayoutPackage;
  * @version $Rev$
  * @ConQAT.Rating YELLOW Hash: 4528B935FD404A834CBD215E46A1BFC1
  */
-public abstract class LayoutedConnectionEditPartBase<T extends ILayoutedModelElement & IConnection>
+public abstract class LayoutedConnectionEditPartBase<T extends ConnectionSegmentBase>
 		extends ConnectionEditPartBase<T> {
 
-	// TODO (FH): check for collision with full refresh adapter of super class !
+	/** The connection drawn. */
+	protected PolylineConnection connection;
+
+	/** The label drawn next to the connection. */
+	protected final Label relationshipLabel = new Label(modelElement.getName());
 
 	/** The adapter used for dealing with changes of the */
+	// TODO (FH): check for collision with full refresh adapter of super class !
 	protected final Adapter layoutChanged = new EContentAdapter() {
 
 		@Override
@@ -64,6 +85,68 @@ public abstract class LayoutedConnectionEditPartBase<T extends ILayoutedModelEle
 		super(modelElement);
 	}
 
+	/** {@inheritDoc} */
+	@Override
+	protected void createEditPolicies() {
+		installEditPolicy(EditPolicy.COMPONENT_ROLE, new RemoveEditPolicy());
+		installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
+				createBendPointPolicy());
+		installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,
+				new ConnectionEndpointEditPolicy());
+	}
+
+	/** Updates the bend points, based on the model. */
+	protected void refreshBendpoints() {
+		Points pts = LayoutDataUtils.getConnectionPoints(modelElement);
+
+		List<AbsoluteBendpoint> figureConstraint = new ArrayList<AbsoluteBendpoint>();
+		int size = 0;
+		if (pts != null) {
+			size = pts.getPointsLength();
+			for (int i = 0; i < size; i++) {
+				Point pt = pts.getPoints(i);
+				org.eclipse.draw2d.geometry.Point p = new org.eclipse.draw2d.geometry.Point(
+						pt.getX(), pt.getY());
+
+				figureConstraint.add(new AbsoluteBendpoint(p));
+			}
+		}
+
+		// Update connection label
+		if (connection.getChildren().contains(relationshipLabel)) {
+			connection.remove(relationshipLabel);
+		}
+		relationshipLabel.setText(modelElement.getName());
+		MidpointLocator mpl = new MidpointLocator(connection, size / 2) {
+			@Override
+			protected org.eclipse.draw2d.geometry.Point getReferencePoint() {
+				org.eclipse.draw2d.geometry.Point p = super.getReferencePoint();
+				p.y += DefaultLayoutConstants.DEFAULT_GRID_SIZE;
+				return p;
+			}
+		};
+		connection.add(relationshipLabel, mpl);
+
+		getConnectionFigure().setRoutingConstraint(figureConstraint);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected PolylineConnection createFigure() {
+		connection = new PolylineConnection();
+
+		// arrow at target end point
+		connection.setTargetDecoration(new PolygonDecoration());
+		connection.setLineStyle(Graphics.LINE_SOLID);
+
+		BendpointConnectionRouter connectionRouter = new BendpointConnectionRouter();
+		connection.setConnectionRouter(connectionRouter);
+		return connection;
+	}
+
+	/** Create connection specific bend point policy. */
+	protected abstract EditPolicy createBendPointPolicy();
+
 	/** {@inheritDoc} */
 	@Override
 	public void activate() {
@@ -77,4 +160,10 @@ public abstract class LayoutedConnectionEditPartBase<T extends ILayoutedModelEle
 		modelElement.eAdapters().remove(layoutChanged);
 		super.deactivate();
 	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected void refreshVisuals() {
+		refreshBendpoints();
+	}
 }
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/StickyConnectorEditPartBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/StickyConnectorEditPartBase.java
index 6d9dc13cb..da9a3d732 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/StickyConnectorEditPartBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/StickyConnectorEditPartBase.java
@@ -18,6 +18,7 @@ $Id$
 package org.fortiss.tooling.base.ui.editpart;
 
 import org.eclipse.draw2d.geometry.Rectangle;
+import org.fortiss.tooling.base.model.base.EntryConnectorBase;
 import org.fortiss.tooling.base.model.element.IConnector;
 import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
 import org.fortiss.tooling.base.ui.layout.constants.DefaultLayoutConstants;
@@ -54,4 +55,10 @@ public abstract class StickyConnectorEditPartBase<T extends ILayoutedModelElemen
 				DefaultLayoutConstants.DEFAULT_CONNECTOR_SIZE,
 				DefaultLayoutConstants.DEFAULT_CONNECTOR_SIZE);
 	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected boolean isTarget() {
+		return modelElement instanceof EntryConnectorBase;
+	}
 }
-- 
GitLab