X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fhandler%2FConnectionCommandHandler.java;h=ad3d510def3568d9103af86e8446933cc13606d1;hb=1ecae6e1ad40507badb8807fb14bb67b4adf199c;hp=129cdf16d431055d1189eea6d907b2063c7300e4;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/handler/ConnectionCommandHandler.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/handler/ConnectionCommandHandler.java
index 129cdf16d..ad3d510de 100644
--- a/bundles/org.simantics.diagram/src/org/simantics/diagram/handler/ConnectionCommandHandler.java
+++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/handler/ConnectionCommandHandler.java
@@ -1,311 +1,311 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2010 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.handler;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Line2D;
-import java.awt.geom.Point2D;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.simantics.Simantics;
-import org.simantics.db.Resource;
-import org.simantics.db.WriteGraph;
-import org.simantics.db.common.request.WriteRequest;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.diagram.content.ConnectionUtil;
-import org.simantics.diagram.content.EdgeResource;
-import org.simantics.diagram.stubs.DiagramResource;
-import org.simantics.diagram.synchronization.graph.RemoveBranchpoint;
-import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
-import org.simantics.g2d.connection.ConnectionEntity;
-import org.simantics.g2d.diagram.DiagramHints;
-import org.simantics.g2d.diagram.IDiagram;
-import org.simantics.g2d.diagram.handler.PickRequest;
-import org.simantics.g2d.diagram.handler.Topology;
-import org.simantics.g2d.diagram.handler.Topology.Connection;
-import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
-import org.simantics.g2d.diagram.participant.Selection;
-import org.simantics.g2d.element.ElementHints;
-import org.simantics.g2d.element.ElementUtils;
-import org.simantics.g2d.element.IElement;
-import org.simantics.g2d.elementclass.BranchPoint;
-import org.simantics.g2d.elementclass.BranchPoint.Direction;
-import org.simantics.g2d.participant.MouseUtil;
-import org.simantics.g2d.participant.MouseUtil.MouseInfo;
-import org.simantics.g2d.participant.WorkbenchStatusLine;
-import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
-import org.simantics.scenegraph.g2d.events.command.CommandEvent;
-import org.simantics.scenegraph.g2d.events.command.Commands;
-import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;
-import org.simantics.ui.SimanticsUI;
-import org.simantics.utils.ui.ErrorLogger;
-
-/**
- * A participant for handling:
- *
- * - DELETE for deleting route points from DIA.Connection type connections
- *
- SPLIT_CONNECTION for creating new route points into DIA.Connection type connections
- *
- ROTATE_ELEMENT_CW & ROTATE_ELEMENT_CCW for rotating route points orientations.
- *
- *
- * NOTE: this participant does nothing useful with DIA.RouteGraphConnection type connections.
- *
- * @author Tuukka Lehtonen
- *
- * TODO: start using {@link WorkbenchStatusLine}
- */
-public class ConnectionCommandHandler extends AbstractDiagramParticipant {
-
- @Dependency MouseUtil mouseUtil;
- @Dependency Selection selection;
- //@Dependency WorkbenchStatusLine statusLine;
-
- @EventHandler(priority = 100)
- public boolean handleCommand(CommandEvent event) {
- if (Commands.DELETE.equals(event.command)) {
- try {
- return joinConnection();
- } catch (DatabaseException e) {
- ErrorLogger.defaultLogError(e);
- return false;
- }
- } else if (Commands.SPLIT_CONNECTION.equals(event.command) && routePointsEnabled()) {
- return splitConnection();
- } else if (Commands.ROTATE_ELEMENT_CW.equals(event.command) || Commands.ROTATE_ELEMENT_CCW.equals(event.command)) {
- boolean clockWise = Commands.ROTATE_ELEMENT_CW.equals(event.command);
- try {
- return rotateBranchPoint(clockWise);
- } catch (DatabaseException e) {
- ErrorLogger.defaultLogError(e);
- return false;
- }
- }
- return false;
- }
-
- private boolean routePointsEnabled() {
- return Boolean.TRUE.equals(diagram.getHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS));
- }
-
- boolean joinConnection() throws DatabaseException {
-
- final Set routePoints = getBranchPoints(2);
-
- if (routePoints.isEmpty())
- return false;
-
- selection.clear(0);
-
- Simantics.getSession().sync(new WriteRequest() {
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- for (IElement routePoint : routePoints) {
- Object node = ElementUtils.getObject(routePoint);
- if (node instanceof Resource) {
- new RemoveBranchpoint(routePoint).perform(graph);
- }
- }
- }
- });
- setDirty();
-
- //statusLine.message("Deleted " + routePoints.size() + " route points");
- return true;
- }
-
- private boolean rotateBranchPoint(final boolean clockWise) throws DatabaseException {
- final Set routePoints = getBranchPoints(Integer.MAX_VALUE);
- if (routePoints.isEmpty())
- return false;
-
- // Rotate branch points.
- try {
- SimanticsUI.getSession().syncRequest(new WriteRequest() {
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- DiagramResource DIA = DiagramResource.getInstance(graph);
- for (IElement bp : routePoints) {
- Resource bpr = (Resource) ElementUtils.getObject(bp);
- boolean vertical = graph.hasStatement(bpr, DIA.Vertical, bpr);
- boolean horizontal = graph.hasStatement(bpr, DIA.Horizontal, bpr);
- Direction dir = Direction.toDirection(horizontal, vertical);
- Direction newDir = clockWise ? dir.cycleNext() : dir.cyclePrevious();
- switch (newDir) {
- case Any:
- graph.deny(bpr, DIA.Vertical);
- graph.deny(bpr, DIA.Horizontal);
- break;
- case Horizontal:
- graph.deny(bpr, DIA.Vertical);
- graph.claim(bpr, DIA.Horizontal, bpr);
- break;
- case Vertical:
- graph.deny(bpr, DIA.Horizontal);
- graph.claim(bpr, DIA.Vertical, bpr);
- break;
- }
- }
- }
- });
- } catch (DatabaseException e) {
- ErrorLogger.defaultLogError(e);
- }
-
- return true;
- }
-
- boolean splitConnection() {
-
- final IElement edge = getSingleConnectionSegment();
- if (edge == null)
- return false;
- final IDiagram diagram = ElementUtils.peekDiagram(edge);
- if (diagram == null)
- return false;
-
- MouseInfo mi = mouseUtil.getMouseInfo(0);
- final Point2D mousePos = mi.canvasPosition;
-
- ISnapAdvisor snap = getHint(DiagramHints.SNAP_ADVISOR);
- if (snap != null)
- snap.snap(mousePos);
-
- final AffineTransform splitPos = AffineTransform.getTranslateInstance(mousePos.getX(), mousePos.getY());
-
- try {
- SimanticsUI.getSession().syncRequest(new WriteRequest() {
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- DiagramResource DIA = DiagramResource.getInstance(graph);
-
- // Split the edge with a new branch point
- ConnectionUtil cu = new ConnectionUtil(graph);
- EdgeResource segment = (EdgeResource) ElementUtils.getObject(edge);
- Resource bp = cu.split(segment, splitPos);
-
- Line2D nearestLine = ConnectionUtil.resolveNearestEdgeLineSegment(mousePos, edge);
- if (nearestLine != null) {
- double angle = Math.atan2(
- Math.abs(nearestLine.getY2() - nearestLine.getY1()),
- Math.abs(nearestLine.getX2() - nearestLine.getX1())
- );
-
- if (angle >= 0 && angle < Math.PI / 4) {
- graph.claim(bp, DIA.Horizontal, bp);
- } else if (angle > Math.PI / 4 && angle <= Math.PI / 2) {
- graph.claim(bp, DIA.Vertical, bp);
- }
- }
- }
- });
-
- selection.clear(0);
-
- } catch (DatabaseException e) {
- ErrorLogger.defaultLogError(e);
- }
-
- return false;
- }
-
- /**
- * @return all route points in the current diagram selection if and only if
- * only route points are selected. If anything else is selected,
- * even branch points, an empty set will be returned.
- */
- Set getBranchPoints(int maxDegree) throws DatabaseException {
-
- Set ss = selection.getSelection(0);
- if (ss.isEmpty())
- return Collections.emptySet();
-
- final Set result = new HashSet();
- Collection connections = new ArrayList();
- for (IElement e : ss) {
- if (!e.getElementClass().containsClass(BranchPoint.class))
- return Collections.emptySet();
- ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);
- if (ce == null)
- return Collections.emptySet();
- IDiagram diagram = ElementUtils.peekDiagram(e);
- if (diagram == null)
- return Collections.emptySet();
- for (Topology topology : diagram.getDiagramClass().getItemsByClass(Topology.class)) {
- connections.clear();
- topology.getConnections(e, ElementUtils.getSingleTerminal(e), connections);
- int degree = connections.size();
- if (degree < 2 || degree > maxDegree)
- return Collections.emptySet();
- result.add(e);
- }
- }
-
- return result;
- }
-
- /**
- * @return if a single edge is selected, return the edge. If a single
- * connection is selected and it contains only one edge segment,
- * return it. Otherwise return null
.
- */
- IElement getSingleConnectionSegment() {
- Set s = selection.getSelection(0);
- if (s.size() != 1)
- return null;
- IElement e = s.iterator().next();
- if (PickRequest.PickFilter.FILTER_CONNECTIONS.accept(e)) {
- // Does this connection have only one edge and no branch points?
- ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);
- Collection coll = ce.getBranchPoints(null);
- if (!coll.isEmpty())
- return null;
- ce.getSegments(coll);
- if (coll.size() != 1)
- return null;
- // Return the only edge element of the whole connection.
- return coll.iterator().next();
- }
- if (PickRequest.PickFilter.FILTER_CONNECTION_EDGES.accept(e))
- return e;
- return null;
- }
-
- /**
- * @return the selected top-level connection element if and only if the
- * selection contains the connection or parts of the same connection
- * (edge segments or branch/route points) and nothing else.
- */
- IElement getSingleConnection() {
-
- Set ss = selection.getSelection(0);
- if (ss.isEmpty())
- return null;
-
- IElement result = null;
-
- for (IElement e : ss) {
- ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);
- if (ce == null)
- continue;
- if (result != null && !ce.getConnection().equals(result))
- return null;
- result = ce.getConnection();
- }
-
- return result;
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.handler;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.simantics.Simantics;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.diagram.content.ConnectionUtil;
+import org.simantics.diagram.content.EdgeResource;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.synchronization.graph.RemoveBranchpoint;
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
+import org.simantics.g2d.connection.ConnectionEntity;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.PickRequest;
+import org.simantics.g2d.diagram.handler.Topology;
+import org.simantics.g2d.diagram.handler.Topology.Connection;
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
+import org.simantics.g2d.diagram.participant.Selection;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.elementclass.BranchPoint;
+import org.simantics.g2d.elementclass.BranchPoint.Direction;
+import org.simantics.g2d.participant.MouseUtil;
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;
+import org.simantics.g2d.participant.WorkbenchStatusLine;
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;
+import org.simantics.scenegraph.g2d.events.command.Commands;
+import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;
+import org.simantics.ui.SimanticsUI;
+import org.simantics.utils.ui.ErrorLogger;
+
+/**
+ * A participant for handling:
+ *
+ * - DELETE for deleting route points from DIA.Connection type connections
+ *
- SPLIT_CONNECTION for creating new route points into DIA.Connection type connections
+ *
- ROTATE_ELEMENT_CW & ROTATE_ELEMENT_CCW for rotating route points orientations.
+ *
+ *
+ * NOTE: this participant does nothing useful with DIA.RouteGraphConnection type connections.
+ *
+ * @author Tuukka Lehtonen
+ *
+ * TODO: start using {@link WorkbenchStatusLine}
+ */
+public class ConnectionCommandHandler extends AbstractDiagramParticipant {
+
+ @Dependency MouseUtil mouseUtil;
+ @Dependency Selection selection;
+ //@Dependency WorkbenchStatusLine statusLine;
+
+ @EventHandler(priority = 100)
+ public boolean handleCommand(CommandEvent event) {
+ if (Commands.DELETE.equals(event.command)) {
+ try {
+ return joinConnection();
+ } catch (DatabaseException e) {
+ ErrorLogger.defaultLogError(e);
+ return false;
+ }
+ } else if (Commands.SPLIT_CONNECTION.equals(event.command) && routePointsEnabled()) {
+ return splitConnection();
+ } else if (Commands.ROTATE_ELEMENT_CW.equals(event.command) || Commands.ROTATE_ELEMENT_CCW.equals(event.command)) {
+ boolean clockWise = Commands.ROTATE_ELEMENT_CW.equals(event.command);
+ try {
+ return rotateBranchPoint(clockWise);
+ } catch (DatabaseException e) {
+ ErrorLogger.defaultLogError(e);
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private boolean routePointsEnabled() {
+ return Boolean.TRUE.equals(diagram.getHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS));
+ }
+
+ boolean joinConnection() throws DatabaseException {
+
+ final Set routePoints = getBranchPoints(2);
+
+ if (routePoints.isEmpty())
+ return false;
+
+ selection.clear(0);
+
+ Simantics.getSession().sync(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ for (IElement routePoint : routePoints) {
+ Object node = ElementUtils.getObject(routePoint);
+ if (node instanceof Resource) {
+ new RemoveBranchpoint(routePoint).perform(graph);
+ }
+ }
+ }
+ });
+ setDirty();
+
+ //statusLine.message("Deleted " + routePoints.size() + " route points");
+ return true;
+ }
+
+ private boolean rotateBranchPoint(final boolean clockWise) throws DatabaseException {
+ final Set routePoints = getBranchPoints(Integer.MAX_VALUE);
+ if (routePoints.isEmpty())
+ return false;
+
+ // Rotate branch points.
+ try {
+ Simantics.getSession().syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ for (IElement bp : routePoints) {
+ Resource bpr = (Resource) ElementUtils.getObject(bp);
+ boolean vertical = graph.hasStatement(bpr, DIA.Vertical, bpr);
+ boolean horizontal = graph.hasStatement(bpr, DIA.Horizontal, bpr);
+ Direction dir = Direction.toDirection(horizontal, vertical);
+ Direction newDir = clockWise ? dir.cycleNext() : dir.cyclePrevious();
+ switch (newDir) {
+ case Any:
+ graph.deny(bpr, DIA.Vertical);
+ graph.deny(bpr, DIA.Horizontal);
+ break;
+ case Horizontal:
+ graph.deny(bpr, DIA.Vertical);
+ graph.claim(bpr, DIA.Horizontal, bpr);
+ break;
+ case Vertical:
+ graph.deny(bpr, DIA.Horizontal);
+ graph.claim(bpr, DIA.Vertical, bpr);
+ break;
+ }
+ }
+ }
+ });
+ } catch (DatabaseException e) {
+ ErrorLogger.defaultLogError(e);
+ }
+
+ return true;
+ }
+
+ boolean splitConnection() {
+
+ final IElement edge = getSingleConnectionSegment();
+ if (edge == null)
+ return false;
+ final IDiagram diagram = ElementUtils.peekDiagram(edge);
+ if (diagram == null)
+ return false;
+
+ MouseInfo mi = mouseUtil.getMouseInfo(0);
+ final Point2D mousePos = mi.canvasPosition;
+
+ ISnapAdvisor snap = getHint(DiagramHints.SNAP_ADVISOR);
+ if (snap != null)
+ snap.snap(mousePos);
+
+ final AffineTransform splitPos = AffineTransform.getTranslateInstance(mousePos.getX(), mousePos.getY());
+
+ try {
+ Simantics.getSession().syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+
+ // Split the edge with a new branch point
+ ConnectionUtil cu = new ConnectionUtil(graph);
+ EdgeResource segment = (EdgeResource) ElementUtils.getObject(edge);
+ Resource bp = cu.split(segment, splitPos);
+
+ Line2D nearestLine = ConnectionUtil.resolveNearestEdgeLineSegment(mousePos, edge);
+ if (nearestLine != null) {
+ double angle = Math.atan2(
+ Math.abs(nearestLine.getY2() - nearestLine.getY1()),
+ Math.abs(nearestLine.getX2() - nearestLine.getX1())
+ );
+
+ if (angle >= 0 && angle < Math.PI / 4) {
+ graph.claim(bp, DIA.Horizontal, bp);
+ } else if (angle > Math.PI / 4 && angle <= Math.PI / 2) {
+ graph.claim(bp, DIA.Vertical, bp);
+ }
+ }
+ }
+ });
+
+ selection.clear(0);
+
+ } catch (DatabaseException e) {
+ ErrorLogger.defaultLogError(e);
+ }
+
+ return false;
+ }
+
+ /**
+ * @return all route points in the current diagram selection if and only if
+ * only route points are selected. If anything else is selected,
+ * even branch points, an empty set will be returned.
+ */
+ Set getBranchPoints(int maxDegree) throws DatabaseException {
+
+ Set ss = selection.getSelection(0);
+ if (ss.isEmpty())
+ return Collections.emptySet();
+
+ final Set result = new HashSet();
+ Collection connections = new ArrayList();
+ for (IElement e : ss) {
+ if (!e.getElementClass().containsClass(BranchPoint.class))
+ return Collections.emptySet();
+ ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);
+ if (ce == null)
+ return Collections.emptySet();
+ IDiagram diagram = ElementUtils.peekDiagram(e);
+ if (diagram == null)
+ return Collections.emptySet();
+ for (Topology topology : diagram.getDiagramClass().getItemsByClass(Topology.class)) {
+ connections.clear();
+ topology.getConnections(e, ElementUtils.getSingleTerminal(e), connections);
+ int degree = connections.size();
+ if (degree < 2 || degree > maxDegree)
+ return Collections.emptySet();
+ result.add(e);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @return if a single edge is selected, return the edge. If a single
+ * connection is selected and it contains only one edge segment,
+ * return it. Otherwise return null
.
+ */
+ IElement getSingleConnectionSegment() {
+ Set s = selection.getSelection(0);
+ if (s.size() != 1)
+ return null;
+ IElement e = s.iterator().next();
+ if (PickRequest.PickFilter.FILTER_CONNECTIONS.accept(e)) {
+ // Does this connection have only one edge and no branch points?
+ ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);
+ Collection coll = ce.getBranchPoints(null);
+ if (!coll.isEmpty())
+ return null;
+ ce.getSegments(coll);
+ if (coll.size() != 1)
+ return null;
+ // Return the only edge element of the whole connection.
+ return coll.iterator().next();
+ }
+ if (PickRequest.PickFilter.FILTER_CONNECTION_EDGES.accept(e))
+ return e;
+ return null;
+ }
+
+ /**
+ * @return the selected top-level connection element if and only if the
+ * selection contains the connection or parts of the same connection
+ * (edge segments or branch/route points) and nothing else.
+ */
+ IElement getSingleConnection() {
+
+ Set ss = selection.getSelection(0);
+ if (ss.isEmpty())
+ return null;
+
+ IElement result = null;
+
+ for (IElement e : ss) {
+ ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);
+ if (ce == null)
+ continue;
+ if (result != null && !ce.getConnection().equals(result))
+ return null;
+ result = ce.getConnection();
+ }
+
+ return result;
+ }
+
+}