Add an orientation field to each port. This field indicate the position when no trans...
Clément DAVID [Fri, 8 Jan 2010 10:08:02 +0000 (11:08 +0100)]
NOTE: iso-functionnality before any #5627 rework.

scilab/modules/xcos/etc/Xcos-style.xml
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/BasicBlock.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/BasicBlockInfo.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/codec/BasicPortCodec.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/port/BasicPort.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/port/command/CommandPort.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/port/control/ControlPort.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/port/input/InputPort.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/port/output/OutputPort.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/utils/BlockPositioning.java

index 58a9581..f3b4a5e 100644 (file)
@@ -53,7 +53,7 @@
   <add as="CommandPort" extend="Port">
     <add as="strokeColor" value="red"/>
     <add as="fillColor" value="red"/>
-    <add as="direction" value="south"/>
+    <add as="rotation" value="90"/>
     <add as="type" value="Command"/>
   </add>
 
@@ -61,7 +61,7 @@
   <add as="ControlPort" extend="Port">
     <add as="strokeColor" value="red"/>
     <add as="fillColor" value="red"/>
-    <add as="direction" value="south"/>
+    <add as="rotation" value="90"/>
     <add as="type" value="Control"/>
   </add>
 
   <add as="ExplicitInputPort" extend="Port">
     <add as="strokeColor" value="black"/>
     <add as="fillColor" value="black"/>
-    <add as="direction" value="east"/>
+    <add as="rotation" value="0"/>
   </add>
 
   <!-- Explicit Output -->
   <add as="ExplicitOutputPort" extend="Port">
     <add as="strokeColor" value="black"/>
     <add as="fillColor" value="black"/>
-    <add as="direction" value="east"/>
+    <add as="rotation" value="0"/>
   </add>
 
   <!-- Implicit Input -->
index 578ccb5..461cd72 100644 (file)
@@ -369,25 +369,25 @@ public class BasicBlock extends XcosUIDObject {
     
     public void addPort(InputPort port) {
        insert(port);
-       BlockPositioning.updatePortsPosition(this);
+       BlockPositioning.updateBlockView(this);
        port.setOrdering(BasicBlockInfo.getAllInputPorts(this, false).size());
     }
 
     public void addPort(OutputPort port) {
        insert(port);
-       BlockPositioning.updatePortsPosition(this);
+       BlockPositioning.updateBlockView(this);
        port.setOrdering(BasicBlockInfo.getAllOutputPorts(this, false).size());
     }
 
     public void addPort(CommandPort port) {
        insert(port);
-       BlockPositioning.updatePortsPosition(this);
+       BlockPositioning.updateBlockView(this);
        port.setOrdering(BasicBlockInfo.getAllCommandPorts(this, false).size());
     }
 
     public void addPort(ControlPort port) {
        insert(port);
-       BlockPositioning.updatePortsPosition(this);
+       BlockPositioning.updateBlockView(this);
        port.setOrdering(BasicBlockInfo.getAllControlPorts(this, false).size());
     }
 
index cc7af35..dcfcd93 100644 (file)
@@ -13,7 +13,9 @@
 package org.scilab.modules.xcos.io;
 
 import java.util.ArrayList;
+import java.util.EnumMap;
 import java.util.List;
+import java.util.Map;
 
 import org.scilab.modules.hdf5.scilabTypes.ScilabBoolean;
 import org.scilab.modules.hdf5.scilabTypes.ScilabDouble;
@@ -23,6 +25,7 @@ import org.scilab.modules.hdf5.scilabTypes.ScilabString;
 import org.scilab.modules.hdf5.scilabTypes.ScilabType;
 import org.scilab.modules.xcos.block.BasicBlock;
 import org.scilab.modules.xcos.port.BasicPort;
+import org.scilab.modules.xcos.port.BasicPort.Orientation;
 import org.scilab.modules.xcos.port.command.CommandPort;
 import org.scilab.modules.xcos.port.control.ControlPort;
 import org.scilab.modules.xcos.port.input.ExplicitInputPort;
@@ -443,4 +446,45 @@ public final class BasicBlockInfo {
 
        return data;
     }
+    
+    /**
+     * Get the associated port ordered by orientation.
+     * @param block The block we are working on
+     * @return Lists of ports where key are BasicPort.Orientation
+     */
+    public static Map<BasicPort.Orientation, List<BasicPort>> getAllOrientedPorts(BasicBlock block) {
+       EnumMap<BasicPort.Orientation, List<BasicPort>> map = new EnumMap<BasicPort.Orientation, List<BasicPort>>(BasicPort.Orientation.class);
+       List<BasicPort> northPorts = new ArrayList<BasicPort>();
+       List<BasicPort> southPorts = new ArrayList<BasicPort>();
+       List<BasicPort> eastPorts = new ArrayList<BasicPort>();
+       List<BasicPort> westPorts = new ArrayList<BasicPort>();
+       
+               final int childrenCount = block.getChildCount();
+               for (int i = 0; i < childrenCount; ++i) {
+                       BasicPort port = (BasicPort) block.getChildAt(i);
+                       switch (port.getDefaultOrientation()) {
+                       case NORTH:
+                               northPorts.add(port);
+                               break;
+                       case SOUTH:
+                               southPorts.add(port);
+                               break;
+                       case EAST:
+                               eastPorts.add(port);
+                               break;
+                       case WEST:
+                               westPorts.add(port);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       
+       map.put(Orientation.NORTH, northPorts);
+       map.put(Orientation.SOUTH, southPorts);
+       map.put(Orientation.EAST, eastPorts);
+       map.put(Orientation.WEST, westPorts);
+       
+       return map;
+    }
 }
index d2c46f1..5a761ec 100644 (file)
 package org.scilab.modules.xcos.io.codec;
 
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.scilab.modules.xcos.io.XcosObjectCodec;
 import org.scilab.modules.xcos.port.BasicPort;
+import org.scilab.modules.xcos.port.BasicPort.Orientation;
+import org.scilab.modules.xcos.port.command.CommandPort;
+import org.scilab.modules.xcos.port.control.ControlPort;
+import org.scilab.modules.xcos.port.input.ExplicitInputPort;
+import org.scilab.modules.xcos.port.input.InputPort;
+import org.scilab.modules.xcos.port.output.OutputPort;
+import org.scilab.modules.xcos.utils.XcosConstants;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -25,7 +34,12 @@ import com.mxgraph.io.mxCodec;
 public class BasicPortCodec extends XcosObjectCodec {
 
     private static final String DATA_TYPE = "dataType";
-
+    
+    private static final Pattern ROTATION_STYLE = Pattern.compile("(.*)(;rotation=(0|90|180|270))(.*)");
+    private static final int ROTATION_STYLE_BEFORE_GROUP = 1;
+    private static final int ROTATION_STYLE_VALUE_GROUP = 3;
+    private static final int ROTATION_STYLE_AFTER_GROUP = 4;
+    
     public BasicPortCodec(Object template) {
        super(template);
     }
@@ -52,19 +66,54 @@ public class BasicPortCodec extends XcosObjectCodec {
            ((BasicPort) obj).setDataType(BasicPort.DataType.valueOf(attr));
        }
 
-       //update style to replace direction by rotation
+       //update style from version to version.
        ((BasicPort)obj).setStyle(formatStyle(((Element) node).getAttribute(STYLE), (BasicPort) obj));
        
        return super.afterDecode(dec, node, obj);
     }
 
     private String formatStyle(String style, BasicPort obj) {
-       formatStyle(style);
+    String result;
+       
+    // Replace direction by rotation
+       result = formatStyle(style);
+       
+       // Replace rotation by defaultOrientation and the new rotation value.
+       result = updateDefaultOrientation(result, obj);
        
-       if (style.compareTo("") == 0) {
-           style = obj.getTypeName();
+       if (result.compareTo("") == 0) {
+               result = obj.getTypeName();
        }
-       return style;
+       return result;
     }
 
+    /**
+     * Replace the style rotation field by setting the obj defaultOrientation property.
+     * @param style The style applied to the element.
+     * @param obj The port we are working on.
+     * @return The new style value
+     * 
+     * @since 5.2.0+ 
+     */
+       private String updateDefaultOrientation(String style, BasicPort obj) {
+               String result = style;
+               
+               Matcher m = ROTATION_STYLE.matcher(style);
+               if (m.matches()) {
+                       
+                       // Parse the rotation field value
+                       String value = m.group(ROTATION_STYLE_VALUE_GROUP);
+                       int rotation = Integer.parseInt(value);
+                       
+                       // Update angle value
+                       rotation = obj.getDefaultOrientation().getAngle(rotation, false, false);
+                       obj.setAngle(rotation);
+                       
+                       // Update the field
+                       result = m.replaceAll(m.group(ROTATION_STYLE_BEFORE_GROUP)
+                                       + ";rotation=" + rotation
+                                       + m.group(ROTATION_STYLE_AFTER_GROUP));
+               }
+               return result;
+       }
 }
index e5d2198..83c30f9 100644 (file)
@@ -21,6 +21,64 @@ import com.mxgraph.model.mxGeometry;
  */
 public abstract class BasicPort extends XcosUIDObject {
 
+       /**
+        * Represent a port orientation related to the associated block. These
+        * orientation semantics are valid when there is no rotation/mirror/flip
+        * applied to the block.
+        */
+       public static enum Orientation {
+               /** The port is on the left (west) side of the block */
+               WEST,
+               /** The port is on the top (north) side of the block */
+               NORTH,
+               /** The port is on the right (east) side of the block */
+               EAST,
+               /** The port is on the bottom (south) side of the block */
+               SOUTH;
+
+               /**
+                * Get the orientation angle where the associated block angle is
+                * blockAngle.
+                * 
+                * @param blockAngle
+                *            The value of the block angle
+                * @param flipped
+                *            The block flip state
+                * @param mirrored
+                *            The block mirror state
+                * @return The value of the angle.
+                */
+               public int getAngle(int blockAngle, boolean flipped, boolean mirrored) {
+                       int angle;
+
+                       /* Specific settings */
+                       switch (this) {
+                       case WEST:
+                       case EAST:
+                               angle = 0;
+                               if (flipped) {
+                                       angle = angle + 180;
+                               }
+                               break;
+
+                       case NORTH:
+                       case SOUTH:
+                               angle = 90;
+                               if (mirrored) {
+                                       angle = angle + 180;
+                               }
+                               break;
+
+                       default:
+                               angle = 0;
+                               break;
+                       }
+
+                       /* Calculate angle */
+                       return (angle + blockAngle) % 360;
+               }
+       }
+       
     private static final long serialVersionUID = -5022701071026919015L;
     private static final int DEFAULT_DATALINES = -1;
     private static final int DEFAULT_DATACOLUMNS = -2;
@@ -32,8 +90,8 @@ public abstract class BasicPort extends XcosUIDObject {
     private int dataLines;
     private int dataColumns;
     private DataType dataType = DataType.REAL_MATRIX;
-    private int initialAngle;
     private int angle;
+    private Orientation defaultOrientation;
     private transient String typeName;
 
     /** Type of any dataport */
@@ -172,22 +230,27 @@ public abstract class BasicPort extends XcosUIDObject {
        super.setStyle(style);
     }
 
-    public void setInitialAngle(int initialAngle) {
-       this.initialAngle = initialAngle;
-    }
-
-    public int getInitialAngle() {
-       return initialAngle;
-    }
-
     public void setAngle(int angle) {
-       this.angle = (initialAngle + angle) % 360;
+       this.angle = angle % 360;
     }
 
     public int getAngle() {
        return angle;
     }
 
+       /** @return The default orientation of this port */
+       public final Orientation getDefaultOrientation() {
+               return defaultOrientation;
+       }
+
+       /**
+        * @param defaultOrientation
+        *            The default orientation of this port
+        */
+       public final void setDefaultOrientation(Orientation defaultOrientation) {
+               this.defaultOrientation = defaultOrientation;
+       }
+    
     public String getToolTipText() {
        StringBuffer result = new StringBuffer();
        result.append("<html>");
index 7a0a425..dd64f30 100644 (file)
@@ -21,7 +21,7 @@ public class CommandPort extends BasicPort {
     
     public CommandPort() {
        super("CommandPort");
-       setInitialAngle(90);
+       setDefaultOrientation(Orientation.SOUTH);
     }
 
     public Type getType() {
index b025a14..210133b 100644 (file)
@@ -20,7 +20,7 @@ public class ControlPort extends BasicPort {
 
     public ControlPort() {
        super("ControlPort");
-       setInitialAngle(90);
+       setDefaultOrientation(Orientation.NORTH);
     }
 
     public Type getType() {
index 732a1b9..c88e38b 100644 (file)
@@ -20,6 +20,6 @@ public abstract class InputPort extends BasicPort {
 
     protected InputPort(String type) {
        super(type);
-       setInitialAngle(0);
+       setDefaultOrientation(Orientation.WEST);
     }
 }
index e1e6211..2dd42e3 100644 (file)
@@ -20,6 +20,6 @@ public abstract class OutputPort extends BasicPort {
 
     public OutputPort(String type) {
        super(type);
-       setInitialAngle(0);
+       setDefaultOrientation(Orientation.EAST);
     }
 }
index 9e10b5b..45460b9 100644 (file)
@@ -14,14 +14,17 @@ package org.scilab.modules.xcos.utils;
 
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.scilab.modules.xcos.block.BasicBlock;
 import org.scilab.modules.xcos.io.BasicBlockInfo;
 import org.scilab.modules.xcos.port.BasicPort;
+import org.scilab.modules.xcos.port.BasicPort.Orientation;
 
 import com.mxgraph.model.mxGeometry;
-import com.mxgraph.util.mxConstants;
 import com.mxgraph.util.mxUtils;
 
 /**
@@ -38,16 +41,16 @@ public final class BlockPositioning {
      * @param ports The ports we have to move on the side.
      */
     public static void updateWestPortsPosition(BasicBlock block, List< ? extends BasicPort> ports) {
-       mxGeometry blockGeom = block.getGeometry();
-       if (blockGeom == null) {
-           return;
-       }
+       final mxGeometry blockGeom = block.getGeometry();
+       final int portsSize = ports.size();
+       
+       assert blockGeom != null;
        
        beginUpdate(block);
-       for (int i = 0; i < ports.size(); ++i) {
+       for (int i = 0; i < portsSize; ++i) {
            mxGeometry portGeom = ((BasicPort) ports.get(i)).getGeometry();
            portGeom.setX(-portGeom.getWidth());
-           portGeom.setY((i + 1.0) * (blockGeom.getHeight() / (ports.size() + 1.0))
+           portGeom.setY((i + 1.0) * (blockGeom.getHeight() / (portsSize + 1.0))
                    - (portGeom.getHeight() / 2.0));
        }
        endUpdate(block);
@@ -59,15 +62,15 @@ public final class BlockPositioning {
      * @param ports The ports we have to move on the side.
      */
     public static void updateNorthPortsPosition(BasicBlock block, List< ? extends BasicPort> ports) {
-       mxGeometry blockGeom = block.getGeometry();
-       if (blockGeom == null) {
-           return;
-       }
+       final mxGeometry blockGeom = block.getGeometry();
+       final int portsSize = ports.size();
+       
+       assert blockGeom != null;
        
        beginUpdate(block);
-       for (int i = 0; i < ports.size(); ++i) {
+       for (int i = 0; i < portsSize; ++i) {
            mxGeometry portGeom = ((BasicPort) ports.get(i)).getGeometry();
-           portGeom.setX((i + 1.0) * (blockGeom.getWidth() / (ports.size() + 1.0))
+           portGeom.setX((i + 1.0) * (blockGeom.getWidth() / (portsSize + 1.0))
                    - (portGeom.getWidth() / 2.0));
            portGeom.setY(-portGeom.getHeight());
        }
@@ -80,16 +83,16 @@ public final class BlockPositioning {
      * @param ports The ports we have to move on the side.
      */
     public static void updateEastPortsPosition(BasicBlock block, List< ? extends BasicPort> ports) {
-       mxGeometry blockGeom = block.getGeometry();
-       if (blockGeom == null) {
-           return;
-       }
+       final mxGeometry blockGeom = block.getGeometry();
+       final int portsSize = ports.size();
+       
+       assert blockGeom != null;
        
        beginUpdate(block);
-       for (int i = 0; i < ports.size(); ++i) {
+       for (int i = 0; i < portsSize; ++i) {
            mxGeometry portGeom = ((BasicPort) ports.get(i)).getGeometry();
            portGeom.setX(blockGeom.getWidth());
-           portGeom.setY((i + 1.0) * (blockGeom.getHeight() / (ports.size() + 1.0))
+           portGeom.setY((i + 1.0) * (blockGeom.getHeight() / (portsSize + 1.0))
                    - (portGeom.getHeight() / 2.0));
        }
        endUpdate(block);
@@ -101,15 +104,15 @@ public final class BlockPositioning {
      * @param ports The ports we have to move on the side.
      */
     public static void updateSouthPortsPosition(BasicBlock block, List< ? extends BasicPort> ports) {
-       mxGeometry blockGeom = block.getGeometry();
-       if (blockGeom == null) {
-           return;
-       }
+       final mxGeometry blockGeom = block.getGeometry();
+       final int portsSize = ports.size();
+       
+       assert blockGeom != null;
        
        beginUpdate(block);
-       for (int i = 0; i < ports.size(); ++i) {
+       for (int i = 0; i < portsSize; ++i) {
            mxGeometry portGeom = ((BasicPort) ports.get(i)).getGeometry();
-           portGeom.setX((i + 1.0) * (blockGeom.getWidth() / (ports.size() + 1.0))
+           portGeom.setX((i + 1.0) * (blockGeom.getWidth() / (portsSize + 1.0))
                    - (portGeom.getWidth() / 2.0));
            portGeom.setY(blockGeom.getHeight());
        }
@@ -121,156 +124,154 @@ public final class BlockPositioning {
      * @param block The block we have to work on.
      */
     public static void updatePortsPosition(BasicBlock block) {
-       // Block -> EAST
-       // East <=> Out / North <=> Control / West <=> In / South <=> Command
-       if (block.getAngle() == 0) {
-           if (block.getMirror()) {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, block.getFlip()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, block.getFlip()));
-           } else {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, block.getFlip()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, block.getFlip()));
-           }
-           
-           if (block.getFlip()) {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, block.getMirror()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, block.getMirror()));
-           } else {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, block.getMirror()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, block.getMirror()));
-           }
-       }
-       // Block -> NORTH
-       // East <=> Command / North <=> Out / West <=> Control / South <=> In
-       if (block.getAngle() == 270) {
-           if (block.getMirror()) {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, !block.getFlip()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, !block.getFlip()));
-           } else {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, !block.getFlip()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, !block.getFlip()));
-           }
-           
-           if (block.getFlip()) {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, block.getMirror()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, block.getMirror()));
-           } else {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, block.getMirror()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, block.getMirror()));
-           }
-       }
-       // Block -> WEST
-       // East <=> In / North <=> Command / West <=> Out / South <=> Control
-       if (block.getAngle() == 180) {
-           if (block.getMirror()) {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, !block.getFlip()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, !block.getFlip()));
-           } else {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, !block.getFlip()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, !block.getFlip()));
-           }
-       
-           if (block.getFlip()) {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, !block.getMirror()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, !block.getMirror()));
-           } else {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, !block.getMirror()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, !block.getMirror()));
-           }
-       }
-       // Block -> SOUTH
-       // East <=> Control / North <=> In / West <=> Command / South <=> Out
-       if (block.getAngle() == 90) {
-           if (block.getMirror()) {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, block.getFlip()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, block.getFlip()));
-           } else {
-               updateEastPortsPosition(block, BasicBlockInfo.getAllControlPorts(block, block.getFlip()));
-               updateWestPortsPosition(block, BasicBlockInfo.getAllCommandPorts(block, block.getFlip()));
-           }
+               final Map<BasicPort.Orientation, List<BasicPort>> ports = BasicBlockInfo
+                               .getAllOrientedPorts(block);
 
-           if (block.getFlip()) {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, !block.getMirror()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, !block.getMirror()));
-           } else {
-               updateSouthPortsPosition(block, BasicBlockInfo.getAllOutputPorts(block, !block.getMirror()));
-               updateNorthPortsPosition(block, BasicBlockInfo.getAllInputPorts(block, !block.getMirror()));
-           }
+               beginUpdate(block);
+               for (Orientation iter : Orientation.values()) {
+                       List<BasicPort> orientedPorts = ports.get(iter);
+                       if (orientedPorts != null && !orientedPorts.isEmpty()) {
+                               updatePortsPositions(block, orientedPorts, iter);
+                       }
+               }
+               endUpdate(block);
        }
-    }    
 
-    /**
-     * Rotate the ports associated to the block.
-     * @param block The parent block
-     * @param ports The port we have to rotate
-     * @param angle The rotation angle.
-     */
-    public static void rotatePorts(BasicBlock block, List< ? extends BasicPort> ports , int angle) {
+       /**
+        * Update the port position for the specified orientation. This function
+        * manage the flip and mirror properties.
+        * 
+        * @param block
+        *            The block we are working on
+        * @param ports
+        *            The ports at with the specified orientation
+        * @param iter
+        *            The orientation.
+        */
+       private static void updatePortsPositions(BasicBlock block,
+                       List<BasicPort> ports, Orientation iter) {
+               final List<BasicPort> invertedPorts = new ArrayList<BasicPort>(ports) {
+                       {
+                               Collections.reverse(this);
+                       }
+               };
+               final boolean mirrored = block.getMirror();
+               final boolean flipped = block.getFlip();
+               final int angle = block.getAngle();
+               List<BasicPort> working = ports;
+               
+               /* List order modification with the flip flag */
+               if (flipped) {
+                       if (iter == Orientation.NORTH || iter == Orientation.SOUTH) {
+                               working = invertedPorts;
+                       }
+               }
 
-       int newAngle = angle;
-       if (block.getFlip()) {
-           newAngle += 180;
-           newAngle %= 360;
+               /* List order modification with the mirror flag */
+               if (mirrored) {
+                       if (iter == Orientation.EAST || iter == Orientation.WEST) {
+                               working = invertedPorts;
+                       }
+               }
+               
+               /*
+                * Ugly modification of the iter to update at the right position
+                * Works only for 0 - 90 - 180 - 270 angles.
+                */
+               final int nbOfOrientations = Orientation.values().length; // 4
+               Orientation rotated = iter;
+               
+               /* Flip & Mirror management */
+               if (flipped) {
+                       if (rotated == Orientation.EAST || rotated == Orientation.WEST) {
+                               rotated = Orientation.values()[(rotated.ordinal() + 2)
+                                               % nbOfOrientations];
+                       }
+               }
+               if (mirrored) {
+                       if (rotated == Orientation.NORTH || rotated == Orientation.SOUTH) {
+                               rotated = Orientation.values()[(rotated.ordinal() + 2)
+                                               % nbOfOrientations];
+                       }
+               }
+               
+               updatePortsPosition(block, rotated, angle, working);
        }
 
-       if (block.getMirror()) {
-           newAngle += 180;
-           newAngle %= 360;
-       }
-       
-       beginUpdate(block);
-       for (Object obj : ports) {
-
-           if (obj instanceof BasicPort) {
-               BasicPort port = (BasicPort) obj;
-               if (port.getAngle() != newAngle)  {
-                   port.setAngle(newAngle);
-                   int newAngle2 = port.getAngle();
-                                       mxUtils.setCellStyles(block.getParentDiagram().getModel(),
-                                                       new Object[] {port }, mxConstants.STYLE_ROTATION,
-                                                       new Integer(newAngle2).toString());
+       /**
+        * Update the ports positions according to the angle. This function doesn't handle order inversion. 
+        * @param block The block we are working on
+        * @param iter The current port orientation
+        * @param angle The angle we have to rotate
+        * @param working The ordered ports we are working on.
+        */
+       private static void updatePortsPosition(BasicBlock block, Orientation iter,
+                       final int angle, List<BasicPort> working) {
+               /*
+                * Ugly modification of the iter to update at the right position
+                * Works only for 0 - 90 - 180 - 270 angles.
+                */
+               final int nbOfOrientations = Orientation.values().length; // 4
+               Orientation rotated = iter;
+               
+               /* Angle management */
+               if (angle == 90) {
+                       rotated = Orientation.values()[(rotated.ordinal() + 1)
+                                       % nbOfOrientations];
+               } else if (angle == 180) {
+                       rotated = Orientation.values()[(rotated.ordinal() + 2)
+                                       % nbOfOrientations];
+               } else if (angle == 270) {
+                       rotated = Orientation.values()[(rotated.ordinal() + 3)
+                                       % nbOfOrientations];
                }
-           }
-       }
-       endUpdate(block);
-    }
 
-    /**
-     * Get the block rotation angle for the data typed ports.
-     * @param block The bloc to work on
-     * @return The angle value.
-     */
-    public static int getDataPortsAngle(BasicBlock block) {
-       if (block.getMirror()) {
-           return (block.getAngle() + 180) % 360;
-       } else {
-           return block.getAngle();   
-       }
-    }
+               /* Call the associated function */
+               switch (rotated) {
+               case NORTH:
+                       updateNorthPortsPosition(block, working);
+                       break;
+               case SOUTH:
+                       updateSouthPortsPosition(block, working);
+                       break;
+               case EAST:
+                       updateEastPortsPosition(block, working);
+                       break;
+               case WEST:
+                       updateWestPortsPosition(block, working);
+                       break;
 
-    /**
-     * Get the block rotation angle for the event typed ports.
-     * @param block The bloc to work on
-     * @return The angle value.
-     */
-    public static int getEventPortsAngle(BasicBlock block) {
-       if (block.getFlip()) {
-           return (block.getAngle() + 90) % 360;
-       } else {
-           return (block.getAngle() + 270) % 360;
+               default:
+                       break;
+               }
        }
-    }
     
     /**
      * Rotate all the port of the block.
      * @param block The block to work on.
      */
-    public static void rotateAllPorts(BasicBlock block) {
-       rotatePorts(block, BasicBlockInfo.getAllInputPorts(block, false), getDataPortsAngle(block));
-       rotatePorts(block, BasicBlockInfo.getAllOutputPorts(block, false), getDataPortsAngle(block));
-       rotatePorts(block, BasicBlockInfo.getAllCommandPorts(block, false), getEventPortsAngle(block));
-       rotatePorts(block, BasicBlockInfo.getAllControlPorts(block, false), getEventPortsAngle(block));
-    }
+       public static void rotateAllPorts(BasicBlock block) {
+               final int angle = block.getAngle();
+               final boolean flipped = block.getFlip();
+               final boolean mirrored = block.getMirror();
+
+               final int childrenCount = block.getChildCount();
+               for (int i = 0; i < childrenCount; ++i) {
+                       final BasicPort port = (BasicPort) block.getChildAt(i);
+                       final Orientation orientation = port.getDefaultOrientation();
+
+                       beginUpdate(block);
+
+                       /* Apply angle */
+                       port.setAngle(orientation.getAngle(angle, flipped, mirrored));
+                       int newAngle2 = port.getAngle();
+                       mxUtils.setCellStyles(block.getParentDiagram().getModel(),
+                                       new Object[] {port }, XcosConstants.STYLE_ROTATION,
+                                       new Integer(newAngle2).toString());
+
+                       endUpdate(block);
+               }
+       }
 
     /**
      * Update the geometry of the block's ports.
@@ -286,6 +287,7 @@ public final class BlockPositioning {
            updatePortsPosition(block);
            rotateAllPorts(block);
            block.getParentDiagram().getModel().endUpdate();
+           block.getParentDiagram().refresh();
        }
     }