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;
  
  import java.util.List;
  
  import org.eclipse.core.resources.IProject;
  import org.eclipse.draw2d.ConnectionAnchor;
  import org.eclipse.draw2d.IFigure;
  import org.eclipse.draw2d.geometry.Point;
  import org.eclipse.gef.commands.Command;
  import org.omnetpp.common.displaymodel.IDisplayString;
  import org.omnetpp.common.util.StringUtils;
  import org.omnetpp.figures.SubmoduleFigure;
  import org.omnetpp.figures.anchors.GateAnchor;
  import org.omnetpp.ned.editor.graph.commands.ReconnectCommand;
  import org.omnetpp.ned.editor.graph.figures.SubmoduleFigureEx;
  import org.omnetpp.ned.editor.graph.properties.util.SubmoduleFullNameValidator;
  import org.omnetpp.ned.model.DisplayString;
  import org.omnetpp.ned.model.ex.ConnectionElementEx;
  import org.omnetpp.ned.model.ex.NedElementUtilEx;
  import org.omnetpp.ned.model.ex.SubmoduleElementEx;
  import org.omnetpp.ned.model.interfaces.INedTypeElement;
  
  /**
   * Controls the submodule figure according to the model changes.
   *
   * @author rhornig
   */
  public class SubmoduleEditPart extends ModuleEditPart {
      protected GateAnchor gateAnchor;
  
      @Override
      public void activate() {
          super.activate();
          renameValidator = new SubmoduleFullNameValidator(getModel());
      }
  
      /**
       * Returns a newly created Figure of this.
       */
      @Override
      protected IFigure createFigure() {
          SubmoduleFigure fig = new SubmoduleFigureEx();
  
          // set the pin decoration image for the image (The compound module requests an auto-layout
          // if we add an figure without pin. ie. submodule created in the text editor without
          // a display string
          fig.setPinVisible(getModel().getDisplayString().getLocation() != null);
  
          // range figure should appear on the background decoration layer
          fig.setRangeFigureLayer(getCompoundModulePart().getFigure().
                  getSubmoduleArea().getBackgroundDecorationLayer());
  
          gateAnchor = new GateAnchor(fig);
          return fig;
      }
  
      /**
       * Returns the Figure for this as an SubmoduleFigure.
       */
      public SubmoduleFigure getFigure() {
          return (SubmoduleFigure)super.getFigure();
      }
  
      /**
       * Helper function to return the model object with correct type
       */
      public SubmoduleElementEx getModel() {
          return (SubmoduleElementEx)super.getModel();
      }
  
      /**
       * Compute the source connection anchor to be assigned based on the current mouse
       * location and available gates.
       * @param p current mouse coordinates
       * @return The selected connection anchor
       */
      @Override
      public ConnectionAnchor getConnectionAnchorAt(Point p) {
          return gateAnchor;
      }
  
      /**
       * Returns a connection anchor registered for the given gate
       */
      @Override
      public GateAnchor getConnectionAnchor(ConnectionElementEx connection, String gate) {
          return gateAnchor;
      }
  
      /**
       * Returns a list of connections for which this is the srcModule.
       */
      @Override
      protected List<ConnectionElementEx> getModelSourceConnections() {
          // get the connections from out controller parent's model
          return getCompoundModulePart().getModel().getSrcConnectionsFor(getModel().getName());
      }
  
      /**
       * Returns a list of connections for which this is the destModule.
       */
      @Override
      protected List<ConnectionElementEx> getModelTargetConnections() {
          // get the connections from out controller parent's model
          return getCompoundModulePart().getModel().getDestConnectionsFor(getModel().getName());
      }
  
      /**
       * Updates the visual aspect of this.
       */
      @Override
      protected void refreshVisuals() {
          super.refreshVisuals();
  
          // set module name and vector size
          SubmoduleFigure submoduleFigure = getFigure();
          submoduleFigure.setName(NedElementUtilEx.getFullName(getModel()));
          submoduleFigure.setAlpha(getModel().isDynamic() ? 64 : 255);
  
          // parse a display string, so it's easier to get values from it.
          // for other visual properties
          DisplayString dps = getModel().getDisplayString();
  
          // get the scale factor for this submodule (coming from the containing compound module's display string)
          // set it in the figure, so size and range indicator can use it
          float scale = getScale();
          float iconScale = getIconScale();
  
          // get the project for image path resolution
          IProject project = getModel().getSelfOrEnclosingTypeElement().getNedTypeInfo().getProject();
  
          // set the rest of the display properties
          submoduleFigure.setDisplayString(dps, scale, iconScale, project);
  
          submoduleFigure.setQueueText(StringUtils.isNotBlank(dps.getAsString(IDisplayString.Prop.QUEUE_NAME)) ? "#" : "");
  
          // show/hide the pin marker
          submoduleFigure.setPinVisible(dps.getLocation() != null);
      }
  
      @Override
      public float getScale() {
          // get the container compound module's scaling factor
          return getCompoundModulePart().getScale();
      }
  
      @Override
      public float getIconScale() {
          return getCompoundModulePart().getIconScale();
      }
  
      @Override
      public boolean isEditable() {
          // editable only if the parent controllers model is the same as the model's parent
          // i.e. the submodule is defined in this compound module (not inherited)
          return super.isEditable() && getParent().getModel() == getModel().getCompoundModule();
      }
  
      @Override
      protected Command validateCommand(Command command) {
          // connection creation is allowed even if the submodule is non editable (but the containing
          // compound module is editable)
          if (command instanceof ReconnectCommand && getCompoundModulePart().isEditable())
              return command;
  
          return super.validateCommand(command);
      }
  
      @Override
      public CompoundModuleEditPart getCompoundModulePart() {
          return (CompoundModuleEditPart)getParent();
      }
  
      @Override
      public INedTypeElement getNedTypeElementToOpen() {
          return getModel().getTypeOrLikeTypeRef();  // open the effective type if pressed F3
      }
  }
  