/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.workflow.editor.commands; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.draw2d.FigureCanvas; import org.eclipse.draw2d.geometry.Point; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.RequestConstants; import org.eclipse.gef.commands.Command; import org.eclipse.gef.editparts.ScalableFreeformRootEditPart; import org.eclipse.gef.editpolicies.BendpointEditPolicy; import org.eclipse.gef.handles.BendpointCreationHandle; import org.eclipse.gef.handles.BendpointMoveHandle; import org.eclipse.gef.requests.BendpointRequest; import de.rcenvironment.core.component.workflow.model.api.Connection; import de.rcenvironment.core.component.workflow.model.api.WorkflowDescription; import de.rcenvironment.core.gui.workflow.parts.ConnectionWrapper; import de.rcenvironment.core.gui.workflow.parts.CustomConnectionBendpointTracker; /** * Policy to allow for adding bendpoints in connections. * * @author Oliver Seebach * */ public class ConnectionBendpointEditPolicy extends BendpointEditPolicy { private static final Log LOGGER = LogFactory.getLog(ConnectionBendpointEditPolicy.class); @Override protected List createSelectionHandles() { List listOfHandles = super.createSelectionHandles(); // Custom bendpoint tracker required to enable snap to grid for bendpoints for (Object selectionHandle : listOfHandles) { if (selectionHandle instanceof BendpointCreationHandle){ BendpointCreationHandle bendpointCreationHandle = (BendpointCreationHandle) selectionHandle; int index = bendpointCreationHandle.getIndex(); CustomConnectionBendpointTracker tracker = new CustomConnectionBendpointTracker((ConnectionEditPart) getHost(), index); tracker.setType(RequestConstants.REQ_CREATE_BENDPOINT); bendpointCreationHandle.setDragTracker(tracker); } else if (selectionHandle instanceof BendpointMoveHandle){ BendpointMoveHandle bendpointMoveHandle = (BendpointMoveHandle) selectionHandle; int index = bendpointMoveHandle.getIndex(); CustomConnectionBendpointTracker tracker = new CustomConnectionBendpointTracker((ConnectionEditPart) getHost(), index); tracker.setType(RequestConstants.REQ_MOVE_BENDPOINT); bendpointMoveHandle.setDragTracker(tracker); } } return listOfHandles; } @Override protected Command getCreateBendpointCommand(BendpointRequest request) { EditPart parent = request.getSource().getParent(); if (parent == null) { return null; } Object model = ((ScalableFreeformRootEditPart) parent).getContents().getModel(); if (model instanceof WorkflowDescription) { List<Connection> connections = getMatchingConnectionModelsForConnectionWrapper((ConnectionWrapper) request.getSource().getModel()); List<Connection> connectionsInverse = getMatchingInverseConnectionModelsForConnectionWrapper((ConnectionWrapper) request.getSource().getModel()); BendpointCreateCommand command = new BendpointCreateCommand(); Point translatedPoint = getTranslatedPointByViewersOffset(request); command.setConnectionsInModel(connections); command.setConnectionsInModelInverse(connectionsInverse); command.setReferencedwrapper((ConnectionWrapper) request.getSource().getModel()); command.setWorkflowDescription((WorkflowDescription) model); command.setNewLocation(translatedPoint); command.setIndex(request.getIndex()); return command; } else { return null; } } @Override protected Command getDeleteBendpointCommand(BendpointRequest request) { EditPart parent = request.getSource().getParent(); if (parent == null) { return null; } Object model = ((ScalableFreeformRootEditPart) parent).getContents().getModel(); if (model instanceof WorkflowDescription) { List<Connection> connections = getMatchingConnectionModelsForConnectionWrapper((ConnectionWrapper) request.getSource().getModel()); List<Connection> connectionsInverse = getMatchingInverseConnectionModelsForConnectionWrapper((ConnectionWrapper) request.getSource().getModel()); BendpointDeleteCommand command = new BendpointDeleteCommand(); command.setConnectionsInModel(connections); command.setConnectionsInModelInverse(connectionsInverse); command.setReferencedwrapper((ConnectionWrapper) request.getSource().getModel()); command.setWorkflowDescription((WorkflowDescription) model); command.setIndex(request.getIndex()); return command; } else { return null; } } @Override protected Command getMoveBendpointCommand(BendpointRequest request) { EditPart parent = request.getSource().getParent(); if (parent == null) { return null; } Object model = ((ScalableFreeformRootEditPart) parent).getContents().getModel(); if (model instanceof WorkflowDescription) { List<Connection> connections = getMatchingConnectionModelsForConnectionWrapper((ConnectionWrapper) request.getSource().getModel()); List<Connection> connectionsInverse = getMatchingInverseConnectionModelsForConnectionWrapper((ConnectionWrapper) request.getSource().getModel()); BendpointMoveCommand command = new BendpointMoveCommand(); Point translatedPoint = getTranslatedPointByViewersOffset(request); command.setConnectionsInModel(connections); command.setConnectionsInModelInverse(connectionsInverse); command.setReferencedwrapper((ConnectionWrapper) request.getSource().getModel()); command.setWorkflowDescription((WorkflowDescription) model); command.setNewLocation(translatedPoint); command.setIndex(request.getIndex()); return command; } else { return null; } } // Returns the connection within a connection wrapper that lead from connection wrappers source to target private List<Connection> getMatchingConnectionModelsForConnectionWrapper(ConnectionWrapper connectionWrapper) { List<Connection> connections = new ArrayList<>(); Object parent = getHost().getParent().getViewer().getContents().getModel(); WorkflowDescription description = null; if (parent instanceof WorkflowDescription) { description = (WorkflowDescription) parent; for (Connection connectionInModel : description.getConnections()) { if (connectionWrapper.getSource().getIdentifier().equals(connectionInModel.getSourceNode().getIdentifier()) && connectionWrapper.getTarget().getIdentifier().equals(connectionInModel.getTargetNode().getIdentifier())) { connections.add(connectionInModel); } } } else { LOGGER.debug("Model's type is not WorkflowDescription, but " + parent.getClass()); } return connections; } // Returns the connection within a connection wrapper that lead from connection wrappers target to source (thus called inverse) private List<Connection> getMatchingInverseConnectionModelsForConnectionWrapper(ConnectionWrapper connectionWrapper) { List<Connection> connections = new ArrayList<>(); Object parent = getHost().getParent().getViewer().getContents().getModel(); WorkflowDescription description = null; if (parent instanceof WorkflowDescription) { description = (WorkflowDescription) parent; for (Connection connectionInModel : description.getConnections()) { if (connectionWrapper.getSource().getIdentifier().equals(connectionInModel.getTargetNode().getIdentifier()) && connectionWrapper.getTarget().getIdentifier().equals(connectionInModel.getSourceNode().getIdentifier())) { connections.add(connectionInModel); } } } else { LOGGER.debug("Model's type is not WorkflowDescription, but " + parent.getClass()); } return connections; } // Return the location for a request translated by the offset of the viewer caused by scrollbars private Point getTranslatedPointByViewersOffset(BendpointRequest request) { Point offsetPoint = ((FigureCanvas) ((ScalableFreeformRootEditPart) request.getSource().getParent()) .getContents().getViewer().getControl()).getViewport().getViewLocation(); double zoomLevel = ((ScalableFreeformRootEditPart) request.getSource().getParent()).getZoomManager().getZoom(); int coordinateWithOffsetAndZoomX = (int) ((request.getLocation().x + offsetPoint.x) / zoomLevel); int coordinateWithOffsetAndZoomY = (int) ((request.getLocation().y + offsetPoint.y) / zoomLevel); return new Point(coordinateWithOffsetAndZoomX, coordinateWithOffsetAndZoomY); } }