-/*******************************************************************************\r
- * Copyright (c) 2011 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.diagram.profile;\r
-\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Stroke;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Line2D;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.common.utils.OrderedSetUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.diagram.content.ConnectionUtil;\r
-import org.simantics.diagram.flag.FlagUtil;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
-import org.simantics.g2d.connection.handler.ConnectionHandler;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.DataElementMap;\r
-import org.simantics.g2d.diagram.handler.PickRequest.PickFilter;\r
-import org.simantics.g2d.diagram.handler.Relationship;\r
-import org.simantics.g2d.diagram.handler.Topology.Connection;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.BendsHandler;\r
-import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
-import org.simantics.g2d.utils.GeometryUtils;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.scenegraph.INode;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.scenegraph.g2d.nodes.RelationshipNode2;\r
-import org.simantics.scenegraph.profile.DataNodeMap;\r
-import org.simantics.scenegraph.profile.EvaluationContext;\r
-import org.simantics.scenegraph.profile.common.ProfileVariables;\r
-import org.simantics.utils.datastructures.Pair;\r
-import org.simantics.utils.datastructures.map.Tuple;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class ShowRelatedElements extends StyleBase<Object> {\r
-\r
- protected Collection<Connection> terminalConnections = new ArrayList<Connection>(4);\r
-\r
- protected final BasicStroke highlightStroke = new BasicStroke(1.0f,\r
- BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f,\r
- new float[] { 4.0f, 6.0f }, 0);\r
-\r
- protected Line2D line = new Line2D.Double();\r
-\r
- /**\r
- * One possible result of\r
- * {@link ShowRelatedElements#calculateStyle(ReadGraph, Resource, Resource, Variable)}\r
- */\r
- public static class Relation extends Tuple {\r
- public Relation(String relation,\r
- Resource element, AffineTransform elementTransform,\r
- Resource otherElement, AffineTransform otherElementTransform)\r
- {\r
- super(relation, element, elementTransform, otherElement, otherElementTransform);\r
- }\r
- public String getRelation() {\r
- return (String) getField(0);\r
- }\r
- public Resource getElement() {\r
- return (Resource) getField(1);\r
- }\r
- public AffineTransform getTransform() {\r
- return (AffineTransform) getField(2);\r
- }\r
- public Resource getOtherElement() {\r
- return (Resource) getField(3);\r
- }\r
- public AffineTransform getOtherTransform() {\r
- return (AffineTransform) getField(4);\r
- }\r
- }\r
-\r
- /**\r
- * Calculates a result that is contains the styled element, its parent and\r
- * transforms of both. This takes care of the style updating the visuals\r
- * properly every time the related components move.\r
- */\r
- @Override\r
- public Object calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration)\r
- throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
- if (graph.isInstanceOf(element, DIA.Monitor)) {\r
- return calculateFromComponent(graph, runtimeDiagram, element, DIA.HasMonitorComponent);\r
- }\r
- if (graph.isInstanceOf(element, DIA.Flag)) {\r
- return calculateFromFlag(graph, element);\r
- }\r
-\r
- // Just return anything, no relationship to visualize.\r
- return Boolean.TRUE;\r
- }\r
-\r
- protected Object calculateFromFlag(ReadGraph graph, Resource flag) throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
- Resource relatedFlag = FlagUtil.getPossibleCounterpart(graph, flag);\r
- if (relatedFlag != null) {\r
- Collection<Resource> flagDiagrams = OrderedSetUtils.getOwnerLists(graph, flag, DIA.Diagram);\r
- Collection<Resource> relatedDiagrams = OrderedSetUtils.getOwnerLists(graph, relatedFlag, DIA.Diagram);\r
- if (!Collections.disjoint(flagDiagrams, relatedDiagrams)) {\r
- AffineTransform flagAt = DiagramGraphUtil.getTransform(graph, flag);\r
- AffineTransform relatedFlagAt = DiagramGraphUtil.getTransform(graph, relatedFlag);\r
- return new Relation(Relationship.RELATED_TO.toString(), flag, flagAt, relatedFlag, relatedFlagAt);\r
- }\r
- }\r
-\r
- return Boolean.TRUE;\r
- }\r
-\r
- protected Object calculateFromComponent(ReadGraph graph, Resource runtime, Resource element, Resource elementToComponentRelation) throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
- ModelingResources MOD = ModelingResources.getInstance(graph);\r
-\r
- Resource parentComponent = graph.getPossibleObject(element, elementToComponentRelation);\r
- if (parentComponent != null) {\r
- Resource parentElement = graph.getPossibleObject(parentComponent, MOD.ComponentToElement);\r
- if (parentElement != null) {\r
- AffineTransform at = DiagramGraphUtil.getTransform(graph, element);\r
- if (graph.isInstanceOf(parentElement, DIA.Connection))\r
- return new Relation(Relationship.CHILD_OF.toString(), element, at, parentElement,\r
- getConnectionOutputNodePosition(graph, runtime, parentElement));\r
-\r
- AffineTransform parentAt = DiagramGraphUtil.getTransform(graph, parentElement);\r
- return new Relation(Relationship.CHILD_OF.toString(), element, at, parentElement, parentAt);\r
- }\r
- }\r
-\r
- return Boolean.TRUE;\r
- }\r
-\r
- protected AffineTransform getConnectionOutputNodePosition(ReadGraph graph, Resource runtime, Resource connection) throws DatabaseException {\r
- Statement toTail = ConnectionUtil.getConnectionTailNodeStatement(graph, connection);\r
- if (toTail == null)\r
- return null;\r
-\r
- AffineTransform at = DiagramGraphUtil.getDynamicAffineTransform(graph, runtime, toTail.getObject());\r
-\r
- Resource connectionPoint = graph.getPossibleInverse(toTail.getPredicate());\r
- if (connectionPoint == null)\r
- return at;\r
-\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
- for (Resource terminal : graph.getObjects(connectionPoint, DIA.HasConnectionPoint_Inverse)) {\r
- AffineTransform terminalAt = DiagramGraphUtil.getDynamicAffineTransform(graph, runtime, terminal);\r
- at.concatenate(terminalAt);\r
- }\r
-\r
- return at;\r
- }\r
-\r
- @Override\r
- public void applyStyleForItem(EvaluationContext evaluationContext, DataNodeMap map, Object item, Object value) {\r
- INode node = map.getNode(item);\r
- if (node == null) {\r
- evaluationContext.update();\r
- return;\r
- }\r
-\r
- if (!(value instanceof Relation)) {\r
- cleanupStyleForNode(node);\r
- return;\r
- }\r
-\r
- IDiagram diagram = evaluationContext.getConstant(ProfileKeys.DIAGRAM);\r
-\r
- Relation r = (Relation) value;\r
-\r
- DataElementMap emap = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
- IElement element = emap.getElement(diagram, item);\r
- IElement otherElement = emap.getElement(diagram, r.getOtherElement());\r
- if (otherElement != null)\r
- addCorrespondence(r, (G2DParentNode) node, r.getRelation(), element, otherElement, highlightStroke, Color.GRAY);\r
- }\r
-\r
- protected void addCorrespondence(Relation r, G2DParentNode p, String id, IElement from, IElement to, Stroke lineStroke, Color lineColor) {\r
- Pair<Point2D, Rectangle2D> p1 = toPoint(r.getTransform(), from);\r
- Pair<Point2D, Rectangle2D> p2 = toPoint(r.getOtherTransform(), to);\r
- if (p1 != null && p2 != null)\r
- addCorrespondence(p, id, p1, p2, lineStroke, lineColor);\r
- }\r
-\r
- /**\r
- * @param parentTransform\r
- * @param e \r
- * @return origin and bounding box of the specified element in canvas\r
- * coordinate system\r
- */\r
- protected Pair<Point2D, Rectangle2D> toPoint(AffineTransform parentTransform, IElement e) {\r
- if (PickFilter.FILTER_CONNECTIONS.accept(e)) {\r
- // For connections select the first found output terminal position as\r
- // the correspondence visualization point.\r
-\r
- ConnectionHandler ch = e.getElementClass().getSingleItem(ConnectionHandler.class);\r
- terminalConnections.clear();\r
- ch.getTerminalConnections(e, terminalConnections);\r
- for (Connection c : terminalConnections) {\r
- if (c.end != EdgeEnd.Begin)\r
- continue;\r
-\r
- BendsHandler bh = c.edge.getElementClass().getAtMostOneItemOfClass(BendsHandler.class);\r
- if (bh != null) {\r
- List<Point2D> points = new ArrayList<Point2D>();\r
- GeometryUtils.getPoints(bh.getPath(c.edge), points);\r
- if (!points.isEmpty())\r
- return Pair.make(points.get(0), null);\r
- } else {\r
- AffineTransform at = parentTransform;\r
- Point2D point = new Point2D.Double(at.getTranslateX(), at.getTranslateY());\r
- return Pair.make(point, null);\r
- }\r
- }\r
-\r
- // Fall back to the default logic if connection output terminal\r
- // search fails.\r
- }\r
-\r
- // Using element origin prevents the relationship rubber band target\r
- // from changing every time the content of the node changes, e.g. the\r
- // text of a monitor.\r
- AffineTransform at = ElementUtils.getTransform(e);\r
- Point2D p = new Point2D.Double(at.getTranslateX(), at.getTranslateY());\r
- Rectangle2D r = ElementUtils.getElementBoundsOnDiagram(e).getBounds2D();\r
- return Pair.make(p, r);\r
- }\r
-\r
- protected void addCorrespondence(G2DParentNode p, String id,\r
- Pair<Point2D, Rectangle2D> p1,\r
- Pair<Point2D, Rectangle2D> p2,\r
- Stroke lineStroke, Color lineColor)\r
- {\r
- RelationshipNode2 node = p.getOrCreateNode(id, RelationshipNode2.class);\r
- node.setZIndex(-10);\r
-\r
- if (p1.second != null) {\r
- line.setLine(p1.first, p2.first);\r
- if (LineUtilities.clipLine(line, p1.second))\r
- p1.first.setLocation(line.getX2(), line.getY2());\r
- }\r
- if (p2.second != null) {\r
- line.setLine(p1.first, p2.first);\r
- if (LineUtilities.clipLine(line, p2.second))\r
- p2.first.setLocation(line.getX1(), line.getY1());\r
- }\r
-\r
- node.init(lineStroke, lineColor, p1.first, p2.first);\r
- }\r
-\r
- @Override\r
- protected void cleanupStyleForNode(INode node) {\r
- ProfileVariables.denyChild(node, "", Relationship.CHILD_OF.toString()); \r
- //ProfileVariables.denyChild(node, "", Relationship.PARENT_OF.toString()); \r
- ProfileVariables.denyChild(node, "", Relationship.RELATED_TO.toString()); \r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return "show related elements";\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2011 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * 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:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.profile;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.common.utils.OrderedSetUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.diagram.content.ConnectionUtil;
+import org.simantics.diagram.flag.FlagUtil;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
+import org.simantics.g2d.connection.handler.ConnectionHandler;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.DataElementMap;
+import org.simantics.g2d.diagram.handler.PickRequest.PickFilter;
+import org.simantics.g2d.diagram.handler.Relationship;
+import org.simantics.g2d.diagram.handler.Topology.Connection;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.BendsHandler;
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;
+import org.simantics.g2d.utils.GeometryUtils;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.nodes.RelationshipNode2;
+import org.simantics.scenegraph.profile.DataNodeMap;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.datastructures.map.Tuple;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class ShowRelatedElements extends StyleBase<Object> {
+
+ protected Collection<Connection> terminalConnections = new ArrayList<Connection>(4);
+
+ protected final BasicStroke highlightStroke = new BasicStroke(1.0f,
+ BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f,
+ new float[] { 4.0f, 6.0f }, 0);
+
+ protected Line2D line = new Line2D.Double();
+
+ /**
+ * One possible result of
+ * {@link ShowRelatedElements#calculateStyle(ReadGraph, Resource, Resource, Variable)}
+ */
+ public static class Relation extends Tuple {
+ public Relation(String relation,
+ Resource element, AffineTransform elementTransform,
+ Resource otherElement, AffineTransform otherElementTransform)
+ {
+ super(relation, element, elementTransform, otherElement, otherElementTransform);
+ }
+ public String getRelation() {
+ return (String) getField(0);
+ }
+ public Resource getElement() {
+ return (Resource) getField(1);
+ }
+ public AffineTransform getTransform() {
+ return (AffineTransform) getField(2);
+ }
+ public Resource getOtherElement() {
+ return (Resource) getField(3);
+ }
+ public AffineTransform getOtherTransform() {
+ return (AffineTransform) getField(4);
+ }
+ }
+
+ /**
+ * Calculates a result that is contains the styled element, its parent and
+ * transforms of both. This takes care of the style updating the visuals
+ * properly every time the related components move.
+ */
+ @Override
+ public Object calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration)
+ throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+
+ if (graph.isInstanceOf(element, DIA.Monitor)) {
+ return calculateFromComponent(graph, runtimeDiagram, element, DIA.HasMonitorComponent);
+ }
+ if (graph.isInstanceOf(element, DIA.Flag)) {
+ return calculateFromFlag(graph, element);
+ }
+
+ // Just return anything, no relationship to visualize.
+ return Boolean.TRUE;
+ }
+
+ protected Object calculateFromFlag(ReadGraph graph, Resource flag) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+
+ Resource relatedFlag = FlagUtil.getPossibleCounterpart(graph, flag);
+ if (relatedFlag != null) {
+ Collection<Resource> flagDiagrams = OrderedSetUtils.getOwnerLists(graph, flag, DIA.Diagram);
+ Collection<Resource> relatedDiagrams = OrderedSetUtils.getOwnerLists(graph, relatedFlag, DIA.Diagram);
+ if (!Collections.disjoint(flagDiagrams, relatedDiagrams)) {
+ AffineTransform flagAt = DiagramGraphUtil.getTransform(graph, flag);
+ AffineTransform relatedFlagAt = DiagramGraphUtil.getTransform(graph, relatedFlag);
+ return new Relation(Relationship.RELATED_TO.toString(), flag, flagAt, relatedFlag, relatedFlagAt);
+ }
+ }
+
+ return Boolean.TRUE;
+ }
+
+ protected Object calculateFromComponent(ReadGraph graph, Resource runtime, Resource element, Resource elementToComponentRelation) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+
+ Resource parentComponent = graph.getPossibleObject(element, elementToComponentRelation);
+ if (parentComponent != null) {
+ Resource parentElement = graph.getPossibleObject(parentComponent, MOD.ComponentToElement);
+ if (parentElement != null) {
+ AffineTransform at = DiagramGraphUtil.getTransform(graph, element);
+ if (graph.isInstanceOf(parentElement, DIA.Connection))
+ return new Relation(Relationship.CHILD_OF.toString(), element, at, parentElement,
+ getConnectionOutputNodePosition(graph, runtime, parentElement));
+
+ AffineTransform parentAt = DiagramGraphUtil.getTransform(graph, parentElement);
+ return new Relation(Relationship.CHILD_OF.toString(), element, at, parentElement, parentAt);
+ }
+ }
+
+ return Boolean.TRUE;
+ }
+
+ protected AffineTransform getConnectionOutputNodePosition(ReadGraph graph, Resource runtime, Resource connection) throws DatabaseException {
+ Statement toTail = ConnectionUtil.getConnectionTailNodeStatement(graph, connection);
+ if (toTail == null)
+ return null;
+
+ AffineTransform at = DiagramGraphUtil.getDynamicAffineTransform(graph, runtime, toTail.getObject());
+
+ Resource connectionPoint = graph.getPossibleInverse(toTail.getPredicate());
+ if (connectionPoint == null)
+ return at;
+
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ for (Resource terminal : graph.getObjects(connectionPoint, DIA.HasConnectionPoint_Inverse)) {
+ AffineTransform terminalAt = DiagramGraphUtil.getDynamicAffineTransform(graph, runtime, terminal);
+ at.concatenate(terminalAt);
+ }
+
+ return at;
+ }
+
+ @Override
+ public void applyStyleForItem(EvaluationContext evaluationContext, DataNodeMap map, Object item, Object value) {
+ INode node = map.getNode(item);
+ if (node == null) {
+ evaluationContext.update();
+ return;
+ }
+
+ if (!(value instanceof Relation)) {
+ cleanupStyleForNode(node);
+ return;
+ }
+
+ IDiagram diagram = evaluationContext.getConstant(ProfileKeys.DIAGRAM);
+
+ Relation r = (Relation) value;
+
+ DataElementMap emap = diagram.getDiagramClass().getSingleItem(DataElementMap.class);
+ IElement element = emap.getElement(diagram, item);
+ IElement otherElement = emap.getElement(diagram, r.getOtherElement());
+ if (otherElement != null)
+ addCorrespondence(r, (G2DParentNode) node, r.getRelation(), element, otherElement, highlightStroke, Color.GRAY);
+ }
+
+ protected void addCorrespondence(Relation r, G2DParentNode p, String id, IElement from, IElement to, Stroke lineStroke, Color lineColor) {
+ Pair<Point2D, Rectangle2D> p1 = toPoint(r.getTransform(), from);
+ Pair<Point2D, Rectangle2D> p2 = toPoint(r.getOtherTransform(), to);
+ if (p1 != null && p2 != null)
+ addCorrespondence(p, id, p1, p2, lineStroke, lineColor);
+ }
+
+ /**
+ * @param parentTransform
+ * @param e
+ * @return origin and bounding box of the specified element in canvas
+ * coordinate system
+ */
+ protected Pair<Point2D, Rectangle2D> toPoint(AffineTransform parentTransform, IElement e) {
+ if (PickFilter.FILTER_CONNECTIONS.accept(e)) {
+ // For connections select the first found output terminal position as
+ // the correspondence visualization point.
+
+ ConnectionHandler ch = e.getElementClass().getSingleItem(ConnectionHandler.class);
+ terminalConnections.clear();
+ ch.getTerminalConnections(e, terminalConnections);
+ for (Connection c : terminalConnections) {
+ if (c.end != EdgeEnd.Begin)
+ continue;
+
+ BendsHandler bh = c.edge.getElementClass().getAtMostOneItemOfClass(BendsHandler.class);
+ if (bh != null) {
+ List<Point2D> points = new ArrayList<Point2D>();
+ GeometryUtils.getPoints(bh.getPath(c.edge), points);
+ if (!points.isEmpty())
+ return Pair.make(points.get(0), null);
+ } else {
+ AffineTransform at = parentTransform;
+ Point2D point = new Point2D.Double(at.getTranslateX(), at.getTranslateY());
+ return Pair.make(point, null);
+ }
+ }
+
+ // Fall back to the default logic if connection output terminal
+ // search fails.
+ }
+
+ // Using element origin prevents the relationship rubber band target
+ // from changing every time the content of the node changes, e.g. the
+ // text of a monitor.
+ AffineTransform at = ElementUtils.getTransform(e);
+ Point2D p = new Point2D.Double(at.getTranslateX(), at.getTranslateY());
+ Rectangle2D r = ElementUtils.getElementBoundsOnDiagram(e).getBounds2D();
+ return Pair.make(p, r);
+ }
+
+ protected void addCorrespondence(G2DParentNode p, String id,
+ Pair<Point2D, Rectangle2D> p1,
+ Pair<Point2D, Rectangle2D> p2,
+ Stroke lineStroke, Color lineColor)
+ {
+ RelationshipNode2 node = p.getOrCreateNode(id, RelationshipNode2.class);
+ node.setZIndex(-10);
+
+ if (p1.second != null) {
+ line.setLine(p1.first, p2.first);
+ if (LineUtilities.clipLine(line, p1.second))
+ p1.first.setLocation(line.getX2(), line.getY2());
+ }
+ if (p2.second != null) {
+ line.setLine(p1.first, p2.first);
+ if (LineUtilities.clipLine(line, p2.second))
+ p2.first.setLocation(line.getX1(), line.getY1());
+ }
+
+ node.init(lineStroke, lineColor, p1.first, p2.first);
+ }
+
+ @Override
+ protected void cleanupStyleForNode(INode node) {
+ ProfileVariables.denyChild(node, "", Relationship.CHILD_OF.toString());
+ //ProfileVariables.denyChild(node, "", Relationship.PARENT_OF.toString());
+ ProfileVariables.denyChild(node, "", Relationship.RELATED_TO.toString());
+ }
+
+ @Override
+ public String toString() {
+ return "show related elements";
+ }
+
+}