code: /*--------------------------------------------------------------*
    Copyright (C) 2006-2015 OpenSim Ltd.
  
    This file is distributed WITHOUT ANY WARRANTY. See the file
    'License' for details on this and other legal matters.
  *--------------------------------------------------------------*/
  
  package org.omnetpp.ned.editor.graph.parts.policies;
  
  import org.eclipse.draw2d.Connection;
  import org.eclipse.draw2d.IFigure;
  import org.eclipse.gef.LayerConstants;
  import org.eclipse.gef.Request;
  import org.eclipse.gef.commands.Command;
  import org.eclipse.gef.commands.UnexecutableCommand;
  import org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy;
  import org.eclipse.gef.requests.CreateConnectionRequest;
  import org.eclipse.gef.requests.ReconnectRequest;
  import org.omnetpp.figures.ConnectionFigure;
  import org.omnetpp.ned.editor.graph.commands.CreateConnectionCommand;
  import org.omnetpp.ned.editor.graph.commands.ReconnectCommand;
  import org.omnetpp.ned.editor.graph.parts.ModuleEditPart;
  import org.omnetpp.ned.model.ex.CompoundModuleElementEx;
  import org.omnetpp.ned.model.ex.ConnectionElementEx;
  import org.omnetpp.ned.model.interfaces.IConnectableElement;
  
  /**
   * Handle all connection related requests for graphically represented nodes (compound and submodules)
   *
   * @author rhornig
   */
  public class NedGraphicalNodeEditPolicy extends GraphicalNodeEditPolicy {
  
      // Used to give feedback during dragging
      @Override
      protected Connection createDummyConnection(Request req) {
          ConnectionFigure cf = new ConnectionFigure();
          cf.setArrowHeadEnabled(true);
          return cf;
      }
  
      /**
       * Feedback should be added to the scaled feedback layer.
       *
       * @see org.eclipse.gef.editpolicies.GraphicalEditPolicy#getFeedbackLayer()
       */
      @Override
      protected IFigure getFeedbackLayer() {
          return getLayer(LayerConstants.SCALED_FEEDBACK_LAYER);
      }
  
  
      /**
       * Returns either the module name or "" if the module is a compound
       */
      private static String getModuleNameForConnection(IConnectableElement connectable) {
          if (connectable instanceof CompoundModuleElementEx)
              return "";
          return connectable.getName();
      }
  
      // called during connection creation on the first click
      @Override
      protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
          ConnectionElementEx conn = (ConnectionElementEx)request.getNewObject();
          conn.setSrcModule(getModuleNameForConnection(getGraphNodeModel()));
          CreateConnectionCommand command = new CreateConnectionCommand(conn, getModuleEditPart().getCompoundModulePart().getModel());
          request.setStartCommand(command);
          return command;
      }
  
      // called when clicked on the second node during connection creation
      @Override
      protected Command getConnectionCompleteCommand(CreateConnectionRequest request) {
          CreateConnectionCommand command = (CreateConnectionCommand)request.getStartCommand();
          command.getConnection().setDestModule(getModuleNameForConnection(getGraphNodeModel()));
          return command;
      }
  
      @Override
      protected Command getReconnectTargetCommand(ReconnectRequest request) {
          ModuleEditPart srcEP = (ModuleEditPart)request.getConnectionEditPart().getSource();
          ModuleEditPart targetEP = (ModuleEditPart)request.getTarget();
          // allow the reconnection only inside the same compound module
          if (srcEP.getCompoundModulePart() != targetEP.getCompoundModulePart())
              return UnexecutableCommand.INSTANCE;
  
          ConnectionElementEx conn = (ConnectionElementEx)request.getConnectionEditPart().getModel();
          ReconnectCommand command = new ReconnectCommand(conn, true);
          command.getTemplateConnection().setDestModule(getModuleNameForConnection(getGraphNodeModel()));
          return command;
      }
  
      @Override
      protected Command getReconnectSourceCommand(ReconnectRequest request) {
          ModuleEditPart targetEP = (ModuleEditPart)request.getConnectionEditPart().getTarget();
          ModuleEditPart srcEP = (ModuleEditPart)request.getTarget();
          // allow the reconnection only inside the same compound module
          if (srcEP.getCompoundModulePart() != targetEP.getCompoundModulePart())
              return UnexecutableCommand.INSTANCE;
  
          ConnectionElementEx conn = (ConnectionElementEx)request.getConnectionEditPart().getModel();
          ReconnectCommand command = new ReconnectCommand(conn, false);
          command.getTemplateConnection().setSrcModule(getModuleNameForConnection(getGraphNodeModel()));
          return command;
      }
  
      protected ModuleEditPart getModuleEditPart() {
          return (ModuleEditPart)getHost();
      }
  
      protected IConnectableElement getGraphNodeModel() {
          return (IConnectableElement)getHost().getModel();
      }
  }