Xcos MVC: handle XCOS / ZCOS file loading 28/17328/3
Clément DAVID [Wed, 14 Oct 2015 15:04:12 +0000 (17:04 +0200)]
 * Restore the scicos decoders for mixed file loading
 * Manage the mirror property on the Java side
 * Implement partial var2vec / vec2var to handle old diagram loading

Change-Id: I0cb4cb92ee9ea80629c43926c93ee11c7849c3ef

41 files changed:
scilab/.gitignore
scilab/modules/xcos/src/java/org/scilab/modules/xcos/JavaControllerJNI.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfDouble.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfInt.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfScicosID.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfString.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/Xcos.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/actions/DebugLevelAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/actions/SetContextAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/actions/SetupAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/BasicBlock.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/actions/FlipAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/actions/MirrorAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/io/ContextUpdate.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/explorer/BrowserTreeNodeData.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/ScicosParameters.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/XcosCell.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/XcosCellFactory.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/ScilabTypeCoder.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/codec/XcosDiagramCodec.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/CustomHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/JGraphXHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/RawDataHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/AbstractElement.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BasicBlockInfo.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockGraphicElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockModelElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockPartsElement.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/DiagramElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/InputPortElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/LabelElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/LinkElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/OutputPortElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/ScicosParametersElement.java [new file with mode: 0644]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/palette/PreLoadedElement.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/palette/StyleElement.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/utils/BlockPositioning.java
scilab/modules/xcos/src/jni/JavaController.i
scilab/modules/xcos/src/jni/JavaController_wrap.cxx

index 1d07265..15363be 100644 (file)
@@ -119,6 +119,7 @@ workspace/
 
 # vim files
 /tags
+*.swp
 
 # MacOS files
 .DS_Store
index b661fa0..6f9315e 100644 (file)
@@ -61,6 +61,7 @@ public class JavaControllerJNI {
   public final static native void VectorOfInt_set(long jarg1, VectorOfInt jarg1_, int jarg2, int jarg3);
   public final static native void VectorOfInt_add__SWIG_1(long jarg1, VectorOfInt jarg1_, int jarg2, int jarg3);
   public final static native boolean VectorOfInt_remove(long jarg1, VectorOfInt jarg1_, int jarg2);
+  public final static native java.nio.ByteBuffer VectorOfInt_asByteBuffer(long jarg1, VectorOfInt jarg1_, int jarg2, int jarg3);
   public final static native void delete_VectorOfInt(long jarg1);
   public final static native long new_VectorOfBool__SWIG_0();
   public final static native long new_VectorOfBool__SWIG_1(long jarg1);
@@ -89,6 +90,7 @@ public class JavaControllerJNI {
   public final static native void VectorOfDouble_set(long jarg1, VectorOfDouble jarg1_, int jarg2, double jarg3);
   public final static native void VectorOfDouble_add__SWIG_1(long jarg1, VectorOfDouble jarg1_, int jarg2, double jarg3);
   public final static native boolean VectorOfDouble_remove(long jarg1, VectorOfDouble jarg1_, double jarg2);
+  public final static native java.nio.ByteBuffer VectorOfDouble_asByteBuffer(long jarg1, VectorOfDouble jarg1_, int jarg2, int jarg3);
   public final static native void delete_VectorOfDouble(long jarg1);
   public final static native long new_VectorOfString__SWIG_0();
   public final static native long new_VectorOfString__SWIG_1(long jarg1);
@@ -104,6 +106,7 @@ public class JavaControllerJNI {
   public final static native void VectorOfString_set(long jarg1, VectorOfString jarg1_, int jarg2, String jarg3);
   public final static native void VectorOfString_add__SWIG_1(long jarg1, VectorOfString jarg1_, int jarg2, String jarg3);
   public final static native boolean VectorOfString_remove(long jarg1, VectorOfString jarg1_, String jarg2);
+  public final static native java.nio.ByteBuffer VectorOfString_asByteBuffer(long jarg1, VectorOfString jarg1_, int jarg2, int jarg3);
   public final static native void delete_VectorOfString(long jarg1);
   public final static native long new_VectorOfScicosID__SWIG_0();
   public final static native long new_VectorOfScicosID__SWIG_1(long jarg1);
@@ -119,6 +122,7 @@ public class JavaControllerJNI {
   public final static native void VectorOfScicosID_set(long jarg1, VectorOfScicosID jarg1_, int jarg2, long jarg3);
   public final static native void VectorOfScicosID_add__SWIG_1(long jarg1, VectorOfScicosID jarg1_, int jarg2, long jarg3);
   public final static native boolean VectorOfScicosID_remove(long jarg1, VectorOfScicosID jarg1_, long jarg2);
+  public final static native java.nio.ByteBuffer VectorOfScicosID_asByteBuffer(long jarg1, VectorOfScicosID jarg1_, int jarg2, int jarg3);
   public final static native void delete_VectorOfScicosID(long jarg1);
   public final static native void register_view(String jarg1, long jarg2, View jarg2_);
   public final static native void unregister_view(long jarg1, View jarg1_);
index ed2d7a3..6c11564 100644 (file)
@@ -91,4 +91,10 @@ public class VectorOfDouble {
     return JavaControllerJNI.VectorOfDouble_remove(swigCPtr, this, val);
   }
 
+  public java.nio.ByteBuffer asByteBuffer(int i, int capacity) {
+    java.nio.ByteBuffer buffer = JavaControllerJNI.VectorOfDouble_asByteBuffer(swigCPtr, this, i, capacity);
+    buffer.order(java.nio.ByteOrder.nativeOrder());
+    return buffer;
+  }
+
 }
index a245c31..1e4388f 100644 (file)
@@ -91,4 +91,10 @@ public class VectorOfInt {
     return JavaControllerJNI.VectorOfInt_remove(swigCPtr, this, val);
   }
 
+  public java.nio.ByteBuffer asByteBuffer(int i, int capacity) {
+    java.nio.ByteBuffer buffer = JavaControllerJNI.VectorOfInt_asByteBuffer(swigCPtr, this, i, capacity);
+    buffer.order(java.nio.ByteOrder.nativeOrder());
+    return buffer;
+  }
+
 }
index 7249e7f..d77a233 100644 (file)
@@ -91,4 +91,10 @@ public class VectorOfScicosID {
     return JavaControllerJNI.VectorOfScicosID_remove(swigCPtr, this, val);
   }
 
+  public java.nio.ByteBuffer asByteBuffer(int i, int capacity) {
+    java.nio.ByteBuffer buffer = JavaControllerJNI.VectorOfScicosID_asByteBuffer(swigCPtr, this, i, capacity);
+    buffer.order(java.nio.ByteOrder.nativeOrder());
+    return buffer;
+  }
+
 }
index 8c372ff..a372ca3 100644 (file)
@@ -91,4 +91,10 @@ public class VectorOfString {
     return JavaControllerJNI.VectorOfString_remove(swigCPtr, this, val);
   }
 
+  public java.nio.ByteBuffer asByteBuffer(int i, int capacity) {
+    java.nio.ByteBuffer buffer = JavaControllerJNI.VectorOfString_asByteBuffer(swigCPtr, this, i, capacity);
+    buffer.order(java.nio.ByteOrder.nativeOrder());
+    return buffer;
+  }
+
 }
index e65b7be..fa9444e 100644 (file)
@@ -142,8 +142,7 @@ public final class Xcos {
      */
     private Xcos(final XcosTabFactory factory) {
         /*
-         * Read the configuration to support dynamic (before Xcos launch)
-         * settings.
+         * Read the configuration to support dynamic (before Xcos launch) settings.
          */
         try {
             LogManager.getLogManager().readConfiguration();
@@ -190,7 +189,6 @@ public final class Xcos {
         }
         ScilabTabFactory.getInstance().addTabFactory(this.factory);
 
-
     }
 
     @Override
@@ -207,8 +205,7 @@ public final class Xcos {
      *
      * This method use runtime class loading to handle ClassNotFoundException.
      *
-     * This method catch any exception and rethrow it with a well defined
-     * message. Thus it doesn't pass the IllegalCatch metrics.
+     * This method catch any exception and rethrow it with a well defined message. Thus it doesn't pass the IllegalCatch metrics.
      */
     // CSOFF: IllegalCatch
     // CSOFF: MagicNumber
@@ -333,7 +330,6 @@ public final class Xcos {
         return opened;
     }
 
-
     public Long openedDiagramUID(File f) {
         Long opened = Long.valueOf(0);
         if (f == null) {
@@ -403,8 +399,7 @@ public final class Xcos {
     /**
      * Open a file from it's filename.
      *
-     * This method must be called on the EDT thread. For other use, please use
-     * the {@link #xcos(String, String)} method.
+     * This method must be called on the EDT thread. For other use, please use the {@link #xcos(String, String)} method.
      *
      * @param file
      *            the file to open. If null an empty diagram is created.
@@ -548,7 +543,7 @@ public final class Xcos {
     /**
      * Clear the browser state and unregister the current view.
      */
-    public void clearBrowser()  {
+    public void clearBrowser() {
         if (browser != null) {
             JavaController.unregister_view(browser);
             browser = null;
@@ -571,8 +566,7 @@ public final class Xcos {
     }
 
     /**
-     * Add a diagram to the diagram list for a file. Be sure to set the right
-     * opened status on the diagram before calling this method.
+     * Add a diagram to the diagram list for a file. Be sure to set the right opened status on the diagram before calling this method.
      *
      * @param f
      *            the file
@@ -616,7 +610,7 @@ public final class Xcos {
             }
 
             @Override
-            public boolean addAll(Collection <? extends XcosDiagram > c) {
+            public boolean addAll(Collection<? extends XcosDiagram> c) {
                 final boolean status = super.addAll(c);
                 DiagramComparator.sort(this);
                 return status;
@@ -755,8 +749,7 @@ public final class Xcos {
     /**
      * Close the current xcos session.
      *
-     * This method must be called on the EDT thread. For other use, please use
-     * the {@link #closeXcosFromScilab()} method.
+     * This method must be called on the EDT thread. For other use, please use the {@link #closeXcosFromScilab()} method.
      */
     public static synchronized void closeSession(final boolean ask) {
         if (!SwingUtilities.isEventDispatchThread()) {
@@ -804,8 +797,7 @@ public final class Xcos {
     /*
      * Scilab exported methods.
      *
-     * All the following methods must use SwingUtilities method to assert that
-     * the operations will be called on the EDT thread.
+     * All the following methods must use SwingUtilities method to assert that the operations will be called on the EDT thread.
      *
      * @see modules/xcos/src/jni/Xcos.giws.xml
      *
@@ -852,11 +844,15 @@ public final class Xcos {
     /**
      * Load an xcos diagram without using Scilab at all.
      *
-     * <P>This support a reduced number of format and should be mainly used to test the decoder
+     * <P>
+     * This support a reduced number of format and should be mainly used to test the decoder
      *
-     * @param file the file
-     * @param diagramId the diagram to load into
-     * @throws Exception on loading error
+     * @param file
+     *            the file
+     * @param diagramId
+     *            the diagram to load into
+     * @throws Exception
+     *             on loading error
      */
     @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
     public static void xcosDiagramToScilab(String file, long diagramId) throws Exception {
@@ -877,8 +873,7 @@ public final class Xcos {
     /**
      * Close the current xcos session from any thread.
      *
-     * This method invoke Xcos operation on the EDT thread. Please prefer using
-     * {@link #closeSession()} when the caller is on the EDT thread.
+     * This method invoke Xcos operation on the EDT thread. Please prefer using {@link #closeSession()} when the caller is on the EDT thread.
      */
     @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
     public static void closeXcosFromScilab() {
@@ -907,8 +902,7 @@ public final class Xcos {
     }
 
     /**
-     * Look in each diagram to find the block corresponding to the given uid and
-     * display a warning message.
+     * Look in each diagram to find the block corresponding to the given uid and display a warning message.
      *
      * This method invoke Xcos operation on the EDT thread.
      *
@@ -964,7 +958,6 @@ public final class Xcos {
                 return;
             }
 
-
         }
     }
 
@@ -972,14 +965,12 @@ public final class Xcos {
         mxCell[] found = new mxCell[uid.length];
         XcosView view = (XcosView) JavaController.lookup_view(Xcos.class.getName());
 
-        final String[] sortedUIDs = Arrays.copyOf(uid,  uid.length);
+        final String[] sortedUIDs = Arrays.copyOf(uid, uid.length);
         Arrays.sort(sortedUIDs);
 
         view.getVisibleObjects().values().stream()
-        //look for the visible objects in the UID set
-        .filter(o -> o instanceof mxCell)
-        .map(o -> (mxCell) o)
-        .filter(o -> Arrays.binarySearch(sortedUIDs, o.getId()) >= 0)
+        // look for the visible objects in the UID set
+        .filter(o -> o instanceof mxCell).map(o -> (mxCell) o).filter(o -> Arrays.binarySearch(sortedUIDs, o.getId()) >= 0)
 
         // push the results to the resulting array
         .forEach(o -> found[Arrays.asList(uid).indexOf(o.getId())] = o);
index 6a34613..243cf1d 100644 (file)
@@ -19,6 +19,7 @@ import org.scilab.modules.graph.ScilabComponent;
 import org.scilab.modules.graph.ScilabGraph;
 import org.scilab.modules.gui.menuitem.MenuItem;
 import org.scilab.modules.xcos.actions.dialog.DebugLevelDialog;
+import org.scilab.modules.xcos.graph.ScicosParameters;
 import org.scilab.modules.xcos.graph.XcosDiagram;
 import org.scilab.modules.xcos.utils.XcosMessages;
 
@@ -41,12 +42,9 @@ public final class DebugLevelAction extends SimulationNotRunningAction {
      */
     public static enum DebugLevel {
         /** No trace nor debug */
-        ZERO(0, XcosMessages.DEBUGLEVEL_0),
-        /** Discrete/Continous switch */
-        ONE(1, XcosMessages.DEBUGLEVEL_1),
-        /** Per block trace */
-        TWO(2, XcosMessages.DEBUGLEVEL_2),
-        /** Debug blocks without trace */
+        ZERO(0, XcosMessages.DEBUGLEVEL_0), /** Discrete/Continous switch */
+        ONE(1, XcosMessages.DEBUGLEVEL_1), /** Per block trace */
+        TWO(2, XcosMessages.DEBUGLEVEL_2), /** Debug blocks without trace */
         THREE(3, XcosMessages.DEBUGLEVEL_3);
 
         private int level;
@@ -107,8 +105,7 @@ public final class DebugLevelAction extends SimulationNotRunningAction {
             return;
         }
 
-        final DebugLevelDialog dialog = new DebugLevelDialog(
-            graph.getAsComponent(), graph.getScicosParameters());
+        final DebugLevelDialog dialog = new DebugLevelDialog(graph.getAsComponent(), new ScicosParameters(graph.getUID(), graph.getKind()));
 
         dialog.pack();
         dialog.setVisible(true);
index d9d5b59..148df33 100644 (file)
@@ -19,6 +19,7 @@ import org.scilab.modules.graph.ScilabComponent;
 import org.scilab.modules.graph.ScilabGraph;
 import org.scilab.modules.gui.menuitem.MenuItem;
 import org.scilab.modules.xcos.actions.dialog.SetContextDialog;
+import org.scilab.modules.xcos.graph.ScicosParameters;
 import org.scilab.modules.xcos.graph.XcosDiagram;
 import org.scilab.modules.xcos.utils.XcosMessages;
 
@@ -74,8 +75,7 @@ public final class SetContextAction extends SimulationNotRunningAction {
             return;
         }
 
-        final SetContextDialog dialog = new SetContextDialog(
-            comp, graph, graph.getScicosParameters());
+        final SetContextDialog dialog = new SetContextDialog(comp, graph, new ScicosParameters(graph.getUID(), graph.getKind()));
 
         dialog.pack();
         dialog.setVisible(true);
index e77f65e..48b346e 100644 (file)
@@ -19,6 +19,7 @@ import org.scilab.modules.graph.ScilabComponent;
 import org.scilab.modules.graph.ScilabGraph;
 import org.scilab.modules.gui.menuitem.MenuItem;
 import org.scilab.modules.xcos.actions.dialog.SetupDialog;
+import org.scilab.modules.xcos.graph.ScicosParameters;
 import org.scilab.modules.xcos.graph.XcosDiagram;
 import org.scilab.modules.xcos.utils.XcosMessages;
 
@@ -74,8 +75,7 @@ public final class SetupAction extends SimulationNotRunningAction {
             return;
         }
 
-        final SetupDialog dialog = new SetupDialog(comp,
-                graph, graph.getScicosParameters());
+        final SetupDialog dialog = new SetupDialog(comp, graph, new ScicosParameters(graph.getUID(), graph.getKind()));
 
         dialog.pack();
         dialog.setVisible(true);
index b1a08b3..c6b7b81 100644 (file)
@@ -78,7 +78,7 @@ public class BasicBlock extends XcosCell implements Serializable {
     /**
      * Sorted kind of input, useful to sort them by kind
      */
-    private static final Class<?>[] sortedChildrenClass = {InputPort.class, OutputPort.class, ControlPort.class, CommandPort.class, Object.class};
+    private static final Class<?>[] sortedChildrenClass = { InputPort.class, OutputPort.class, ControlPort.class, CommandPort.class, Object.class };
 
     /*
      * Default values
@@ -103,8 +103,7 @@ public class BasicBlock extends XcosCell implements Serializable {
     private static final double DEFAULT_HEIGHT = 40.0;
 
     /**
-     * Internal method to get a base index to compare with depending on the cell
-     * type.
+     * Internal method to get a base index to compare with depending on the cell type.
      *
      * @param cell
      *            the cell
@@ -138,46 +137,29 @@ public class BasicBlock extends XcosCell implements Serializable {
     private boolean locked;
 
     /**
-     * Represent a simulation function type compatible with Scilab/Scicos
-     * function type descriptors.
+     * Represent a simulation function type compatible with Scilab/Scicos function type descriptors.
      */
     public static enum SimulationFunctionType {
         /** event select; reduced at compilation */
-        ESELECT(-2.0),
-        /** if then else; reduced at compilation */
-        IFTHENELSE(-1.0),
-        /** first common block */
-        DEFAULT(0.0),
-        /** first native block */
-        TYPE_1(1.0),
-        /** second native block */
-        TYPE_2(2.0),
-        /** third native block */
-        TYPE_3(3.0),
-        /** forth native block */
-        C_OR_FORTRAN(4.0),
-        /** Scilab blocks */
-        SCILAB(5.0),
-        /** Debug blocks */
-        DEBUG(99),
-        /** dynamic {@link #TYPE_1} Fortran blocks (fortran_block.sci) */
-        DYNAMIC_FORTRAN_1(1001.0),
-        /** dynamic {@link #TYPE_1} C blocks (c_block.sci) */
-        DYNAMIC_C_1(2001.0),
-        /** Explicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
-        DYNAMIC_EXPLICIT_4(2004.0),
-        /** Implicit {@link #TYPE_1} Fortran blocks (DIFF_f.sci) */
-        OLDBLOCKS(10001.0),
-        /** Implicit {@link #C_OR_FORTRAN} blocks */
-        IMPLICIT_C_OR_FORTRAN(10004.0),
-        /** Implicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
-        DYNAMIC_IMPLICIT_4(12004.0),
-        /** Modelica {@link #C_OR_FORTRAN} blocks */
-        MODELICA(30004.0),
-        /** Magic types */
-        UNKNOWN(5.0);
-
-        private double value;
+        ESELECT(-2), /** if then else; reduced at compilation */
+        IFTHENELSE(-1), /** first common block */
+        DEFAULT(0), /** first native block */
+        TYPE_1(1), /** second native block */
+        TYPE_2(2), /** third native block */
+        TYPE_3(3), /** forth native block */
+        C_OR_FORTRAN(4), /** Scilab blocks */
+        SCILAB(5), /** Debug blocks */
+        DEBUG(99), /** dynamic {@link #TYPE_1} Fortran blocks (fortran_block.sci) */
+        DYNAMIC_FORTRAN_1(1001), /** dynamic {@link #TYPE_1} C blocks (c_block.sci) */
+        DYNAMIC_C_1(2001), /** Explicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
+        DYNAMIC_EXPLICIT_4(2004), /** Implicit {@link #TYPE_1} Fortran blocks (DIFF_f.sci) */
+        OLDBLOCKS(10001), /** Implicit {@link #C_OR_FORTRAN} blocks */
+        IMPLICIT_C_OR_FORTRAN(10004), /** Implicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
+        DYNAMIC_IMPLICIT_4(12004), /** Modelica {@link #C_OR_FORTRAN} blocks */
+        MODELICA(30004), /** Magic types */
+        UNKNOWN(5);
+
+        private int value;
 
         /**
          * Default constructor
@@ -185,7 +167,7 @@ public class BasicBlock extends XcosCell implements Serializable {
          * @param scilabValue
          *            Scilab/Scicos function type descriptor
          */
-        private SimulationFunctionType(double scilabValue) {
+        private SimulationFunctionType(int scilabValue) {
             value = scilabValue;
         }
 
@@ -198,7 +180,7 @@ public class BasicBlock extends XcosCell implements Serializable {
          */
         public static SimulationFunctionType convertScilabValue(int scilabValue) {
             for (SimulationFunctionType iter : SimulationFunctionType.values()) {
-                if (iter.getAsDouble() == scilabValue) {
+                if (iter.getValue() == scilabValue) {
                     return iter;
                 }
             }
@@ -210,7 +192,7 @@ public class BasicBlock extends XcosCell implements Serializable {
          *
          * @return The corresponding Scilab/Scicos descriptor
          */
-        public double getAsDouble() {
+        public int getValue() {
             return value;
         }
     };
@@ -256,69 +238,69 @@ public class BasicBlock extends XcosCell implements Serializable {
      *            the new block instance
      */
     private void updateChildren(BasicBlock modifiedBlock) {
-        //        if (modifiedBlock == null) {
-        //            return;
-        //        }
+        // if (modifiedBlock == null) {
+        // return;
+        // }
         //
-        //        XcosDiagram graph = getParentDiagram();
-        //        if (graph == null) {
-        //            setParentDiagram(Xcos.findParent(this));
-        //            graph = getParentDiagram();
-        //            LOG.finest(PARENT_DIAGRAM_WAS_NULL);
-        //        }
+        // XcosDiagram graph = getParentDiagram();
+        // if (graph == null) {
+        // setParentDiagram(Xcos.findParent(this));
+        // graph = getParentDiagram();
+        // LOG.finest(PARENT_DIAGRAM_WAS_NULL);
+        // }
         //
-        //        /*
-        //         * Checked as port classes only
-        //         */
-        //        @SuppressWarnings("unchecked")
-        //        Set < Class <? extends mxICell >> types = new HashSet < Class <? extends mxICell >> (Arrays.asList(InputPort.class, OutputPort.class, ControlPort.class,
-        //                CommandPort.class));
+        // /*
+        // * Checked as port classes only
+        // */
+        // @SuppressWarnings("unchecked")
+        // Set < Class <? extends mxICell >> types = new HashSet < Class <? extends mxICell >> (Arrays.asList(InputPort.class, OutputPort.class, ControlPort.class,
+        // CommandPort.class));
         //
-        //        Map < Class <? extends mxICell > , Deque<mxICell >> annotatedOlds = getTypedChildren(types);
-        //        Map < Class <? extends mxICell > , Deque<mxICell >> annotatedNews = modifiedBlock.getTypedChildren(types);
+        // Map < Class <? extends mxICell > , Deque<mxICell >> annotatedOlds = getTypedChildren(types);
+        // Map < Class <? extends mxICell > , Deque<mxICell >> annotatedNews = modifiedBlock.getTypedChildren(types);
         //
-        //        getParentDiagram().getModel().beginUpdate();
-        //        try {
-        //            for (Class <? extends mxICell > klass : types) {
-        //                final Deque<mxICell> olds = annotatedOlds.get(klass);
-        //                final Deque<mxICell> news = annotatedNews.get(klass);
+        // getParentDiagram().getModel().beginUpdate();
+        // try {
+        // for (Class <? extends mxICell > klass : types) {
+        // final Deque<mxICell> olds = annotatedOlds.get(klass);
+        // final Deque<mxICell> news = annotatedNews.get(klass);
         //
-        //                // updated ports
-        //                while (!olds.isEmpty() && !news.isEmpty()) {
-        //                    mxICell previous = olds.poll();
-        //                    mxICell modified = news.poll();
+        // // updated ports
+        // while (!olds.isEmpty() && !news.isEmpty()) {
+        // mxICell previous = olds.poll();
+        // mxICell modified = news.poll();
         //
-        //                    final int previousIndex = children.indexOf(previous);
+        // final int previousIndex = children.indexOf(previous);
         //
-        //                    // relink
-        //                    if (previous.getEdgeCount() != 0) {
-        //                        final mxICell edge = previous.getEdgeAt(0);
-        //                        final boolean isOutgoing = previous == edge.getTerminal(true);
-        //                        previous.removeEdge(edge, isOutgoing);
-        //                        modified.insertEdge(edge, isOutgoing);
-        //                    }
+        // // relink
+        // if (previous.getEdgeCount() != 0) {
+        // final mxICell edge = previous.getEdgeAt(0);
+        // final boolean isOutgoing = previous == edge.getTerminal(true);
+        // previous.removeEdge(edge, isOutgoing);
+        // modified.insertEdge(edge, isOutgoing);
+        // }
         //
-        //                    getParentDiagram().removeCells(new Object[] { previous }, false);
-        //                    getParentDiagram().addCells(new Object[] { modified }, this, previousIndex);
+        // getParentDiagram().removeCells(new Object[] { previous }, false);
+        // getParentDiagram().addCells(new Object[] { modified }, this, previousIndex);
         //
-        //                    // Clone the geometry to avoid empty geometry on new cells.
-        //                    getParentDiagram().getModel().setGeometry(modified, (mxGeometry) previous.getGeometry().clone());
+        // // Clone the geometry to avoid empty geometry on new cells.
+        // getParentDiagram().getModel().setGeometry(modified, (mxGeometry) previous.getGeometry().clone());
         //
-        //                }
+        // }
         //
-        //                // removed ports
-        //                if (!olds.isEmpty()) {
-        //                    getParentDiagram().removeCells(olds.toArray(), true);
-        //                }
+        // // removed ports
+        // if (!olds.isEmpty()) {
+        // getParentDiagram().removeCells(olds.toArray(), true);
+        // }
         //
-        //                // added ports
-        //                if (!news.isEmpty()) {
-        //                    getParentDiagram().addCells(news.toArray(), this);
-        //                }
-        //            }
-        //        } finally {
-        //            getParentDiagram().getModel().endUpdate();
-        //        }
+        // // added ports
+        // if (!news.isEmpty()) {
+        // getParentDiagram().addCells(news.toArray(), this);
+        // }
+        // }
+        // } finally {
+        // getParentDiagram().getModel().endUpdate();
+        // }
     }
 
     /**
@@ -328,11 +310,11 @@ public class BasicBlock extends XcosCell implements Serializable {
      *            the classes to search for.
      * @return a map which linked foreach type the corresponding cell index in the children.
      */
-    public Map < Class<? extends mxICell> , ArrayList<Integer> > getTypedChildrenIndexes(Set< Class<? extends mxICell> > types) {
-        Map < Class<? extends mxICell> , ArrayList<Integer> > oldPorts = new HashMap < Class<? extends mxICell> , ArrayList<Integer> > ();
+    public Map<Class<? extends mxICell>, ArrayList<Integer>> getTypedChildrenIndexes(Set<Class<? extends mxICell>> types) {
+        Map<Class<? extends mxICell>, ArrayList<Integer>> oldPorts = new HashMap<Class<? extends mxICell>, ArrayList<Integer>>();
 
         // Allocate all types set
-        for (Class <? extends mxICell > type : types) {
+        for (Class<? extends mxICell> type : types) {
             oldPorts.put(type, new ArrayList<>());
         }
 
@@ -344,7 +326,7 @@ public class BasicBlock extends XcosCell implements Serializable {
         for (int i = 0; i < children.size(); i++) {
             final Object cell = children.get(i);
 
-            Class <? extends Object > klass = cell.getClass();
+            Class<? extends Object> klass = cell.getClass();
             while (klass != null) {
                 if (types.contains(klass)) {
                     break;
@@ -365,8 +347,8 @@ public class BasicBlock extends XcosCell implements Serializable {
         return getTypedChildrenIndexes(Collections.singleton(type)).get(type);
     }
 
-    public Map < Class<? extends mxICell> , ArrayList<Long> > getTypedChildrenUIDs(Set< Class<? extends mxICell> > types) {
-        Map < Class<? extends mxICell> , ArrayList<Long> > ports = new HashMap<> ();
+    public Map<Class<? extends mxICell>, ArrayList<Long>> getTypedChildrenUIDs(Set<Class<? extends mxICell>> types) {
+        Map<Class<? extends mxICell>, ArrayList<Long>> ports = new HashMap<>();
 
         // Allocate all types set
         types.stream().forEach(t -> ports.put(t, new ArrayList<>()));
@@ -379,7 +361,7 @@ public class BasicBlock extends XcosCell implements Serializable {
         for (int i = 0; i < children.size(); i++) {
             final Object cell = children.get(i);
 
-            Class <? extends Object > klass = cell.getClass();
+            Class<? extends Object> klass = cell.getClass();
             while (klass != null) {
                 if (types.contains(klass)) {
                     break;
@@ -410,85 +392,85 @@ public class BasicBlock extends XcosCell implements Serializable {
      */
     public void openBlockSettings() {
         // FIXME: implement something
-        //        final XcosDiagram graph;
-        //        if (getParentDiagram() == null) {
-        //            setParentDiagram(Xcos.findParent(this));
-        //            graph = getParentDiagram();
-        //            LOG.finest(PARENT_DIAGRAM_WAS_NULL);
-        //        } else {
-        //            graph = getParentDiagram();
-        //        }
-        //        if (graph instanceof PaletteDiagram) {
-        //            return;
-        //        }
+        // final XcosDiagram graph;
+        // if (getParentDiagram() == null) {
+        // setParentDiagram(Xcos.findParent(this));
+        // graph = getParentDiagram();
+        // LOG.finest(PARENT_DIAGRAM_WAS_NULL);
+        // } else {
+        // graph = getParentDiagram();
+        // }
+        // if (graph instanceof PaletteDiagram) {
+        // return;
+        // }
         //
-        //        if (context == null) {
-        //            throw new IllegalArgumentException();
-        //        }
+        // if (context == null) {
+        // throw new IllegalArgumentException();
+        // }
         //
-        //        // prevent to open twice
-        //        if (isLocked()) {
-        //            return;
-        //        }
+        // // prevent to open twice
+        // if (isLocked()) {
+        // return;
+        // }
         //
-        //        graph.setCellsLocked(true);
-        //        graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        // graph.setCellsLocked(true);
+        // graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
         //
-        //        // sort children according to the ordering parameter (useful on
-        //        // scilab-5.2.x diagrams)
-        //        sortChildren();
+        // // sort children according to the ordering parameter (useful on
+        // // scilab-5.2.x diagrams)
+        // sortChildren();
         //
-        //        final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
-        //        if (handler == null) {
-        //            return;
-        //        }
+        // final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
+        // if (handler == null) {
+        // return;
+        // }
         //
-        //        try {
-        //            // Write scs_m
-        //            handler.writeBlock(this);
-        //            // Write context
-        //            handler.writeContext(context);
+        // try {
+        // // Write scs_m
+        // handler.writeBlock(this);
+        // // Write context
+        // handler.writeContext(context);
         //
-        //            final ActionListener action = new ActionListener() {
-        //                @Override
-        //                public void actionPerformed(ActionEvent e) {
-        //                    LOG.finest("Updating data.");
+        // final ActionListener action = new ActionListener() {
+        // @Override
+        // public void actionPerformed(ActionEvent e) {
+        // LOG.finest("Updating data.");
         //
-        //                    graph.getView().clear(this, true, true);
+        // graph.getView().clear(this, true, true);
         //
-        //                    // Now read new Block
-        //                    graph.getModel().beginUpdate();
-        //                    try {
-        //                        final BasicBlock modifiedBlock = handler.readBlock();
-        //                        updateBlockSettings(modifiedBlock);
+        // // Now read new Block
+        // graph.getModel().beginUpdate();
+        // try {
+        // final BasicBlock modifiedBlock = handler.readBlock();
+        // updateBlockSettings(modifiedBlock);
         //
-        //                        graph.fireEvent(new mxEventObject(XcosEvent.ADD_PORTS, XcosConstants.EVENT_BLOCK_UPDATED, BasicBlock.this));
-        //                    } catch (ScicosFormatException ex) {
-        //                        LOG.severe(ex.toString());
-        //                    } finally {
-        //                        graph.getModel().endUpdate();
-        //                        setLocked(false);
+        // graph.fireEvent(new mxEventObject(XcosEvent.ADD_PORTS, XcosConstants.EVENT_BLOCK_UPDATED, BasicBlock.this));
+        // } catch (ScicosFormatException ex) {
+        // LOG.severe(ex.toString());
+        // } finally {
+        // graph.getModel().endUpdate();
+        // setLocked(false);
         //
-        //                        handler.release();
+        // handler.release();
         //
-        //                        graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-        //                        graph.setCellsLocked(false);
-        //                    }
-        //                }
-        //            };
+        // graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+        // graph.setCellsLocked(false);
+        // }
+        // }
+        // };
         //
-        //            setLocked(true);
-        //            ScilabInterpreterManagement.asynchronousScilabExec(action, "blk = xcosBlockInterface", getInterfaceFunctionName().toCharArray(), "set",
-        //                    ScilabDirectHandler.BLK.toCharArray(), ScilabDirectHandler.CONTEXT.toCharArray());
-        //        } catch (InterpreterException e) {
-        //            LOG.severe(e.toString());
-        //            setLocked(false);
+        // setLocked(true);
+        // ScilabInterpreterManagement.asynchronousScilabExec(action, "blk = xcosBlockInterface", getInterfaceFunctionName().toCharArray(), "set",
+        // ScilabDirectHandler.BLK.toCharArray(), ScilabDirectHandler.CONTEXT.toCharArray());
+        // } catch (InterpreterException e) {
+        // LOG.severe(e.toString());
+        // setLocked(false);
         //
-        //            handler.release();
+        // handler.release();
         //
-        //            graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-        //            graph.setCellsLocked(false);
-        //        }
+        // graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+        // graph.setCellsLocked(false);
+        // }
     }
 
     /**
@@ -497,11 +479,11 @@ public class BasicBlock extends XcosCell implements Serializable {
      */
     public void openContextMenu(ScilabGraph graph) {
         ContextMenu menu = null;
-        //        if (getParentDiagram() instanceof PaletteDiagram) {
-        //            menu = createPaletteContextMenu(graph);
-        //        } else {
+        // if (getParentDiagram() instanceof PaletteDiagram) {
+        // menu = createPaletteContextMenu(graph);
+        // } else {
         menu = createContextMenu(graph);
-        //        }
+        // }
         menu.setVisible(true);
     }
 
@@ -626,8 +608,8 @@ public class BasicBlock extends XcosCell implements Serializable {
 
         menu.setVisible(true);
 
-        ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo()
-                .getLocation().y);
+        ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x,
+                MouseInfo.getPointerInfo().getLocation().y);
 
         return menu;
     }
@@ -642,7 +624,7 @@ public class BasicBlock extends XcosCell implements Serializable {
     // CSOFF: JavaNCSS
     public ContextMenu createContextMenu(ScilabGraph graph) {
         ContextMenu menu = ScilabContextMenu.createContextMenu();
-        Map < Class <? extends DefaultAction > , Menu > menuList = new HashMap < Class <? extends DefaultAction > , Menu > ();
+        Map<Class<? extends DefaultAction>, Menu> menuList = new HashMap<Class<? extends DefaultAction>, Menu>();
 
         MenuItem value = BlockParametersAction.createMenu(graph);
         menuList.put(BlockParametersAction.class, value);
@@ -715,8 +697,8 @@ public class BasicBlock extends XcosCell implements Serializable {
         /*--- */
         menu.add(BlockDocumentationAction.createMenu(graph));
 
-        ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo()
-                .getLocation().y);
+        ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x,
+                MouseInfo.getPointerInfo().getLocation().y);
 
         customizeMenu(menuList);
 
@@ -729,11 +711,10 @@ public class BasicBlock extends XcosCell implements Serializable {
      * @param menuList
      *            list of menu
      */
-    protected void customizeMenu(Map < Class <? extends DefaultAction > , Menu > menuList) {
+    protected void customizeMenu(Map<Class<? extends DefaultAction>, Menu> menuList) {
         // To be overridden by sub-classes
     }
 
-
     /**
      * Set the default block position on the geom
      *
index 5776d47..de23a02 100644 (file)
@@ -40,8 +40,7 @@ public class FlipAction extends VertexSelectionDependantAction {
     /** Mnemonic key of the action */
     public static final int MNEMONIC_KEY = KeyEvent.VK_F;
     /** Accelerator key for the action */
-    public static final int ACCELERATOR_KEY = Toolkit.getDefaultToolkit()
-            .getMenuShortcutKeyMask();
+    public static final int ACCELERATOR_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
 
     /**
      * Constructor
@@ -73,8 +72,7 @@ public class FlipAction extends VertexSelectionDependantAction {
     public void actionPerformed(ActionEvent e) {
         if (((XcosDiagram) getGraph(null)).getSelectionCells().length != 0) {
 
-            Object[] allCells = ((XcosDiagram) getGraph(null))
-                                .getSelectionCells();
+            Object[] allCells = ((XcosDiagram) getGraph(null)).getSelectionCells();
 
             JavaController controller = new JavaController();
             VectorOfDouble mvcAngle = new VectorOfDouble();
@@ -84,7 +82,12 @@ public class FlipAction extends VertexSelectionDependantAction {
                 if (allCells[i] instanceof BasicBlock) {
                     long uid = ((BasicBlock) allCells[i]).getUID();
                     controller.getObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
-                    mvcAngle.set(0, mvcAngle.get(0) + 8d);
+
+                    // retrieve then toggle a bit
+                    int mirrorAndFlip = (int) mvcAngle.get(0);
+                    mirrorAndFlip ^= 0x0001;
+
+                    mvcAngle.set(0, mirrorAndFlip);
                     controller.setObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
                 }
             }
index 1358380..7e82fa9 100644 (file)
@@ -39,8 +39,7 @@ public class MirrorAction extends VertexSelectionDependantAction {
     /** Mnemonic key of the action */
     public static final int MNEMONIC_KEY = KeyEvent.VK_M;
     /** Accelerator key for the action */
-    public static final int ACCELERATOR_KEY = Toolkit.getDefaultToolkit()
-            .getMenuShortcutKeyMask();
+    public static final int ACCELERATOR_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
 
     /**
      * Constructor
@@ -72,8 +71,7 @@ public class MirrorAction extends VertexSelectionDependantAction {
     public void actionPerformed(ActionEvent e) {
         if (((XcosDiagram) getGraph(null)).getSelectionCells().length != 0) {
 
-            Object[] allCells = ((XcosDiagram) getGraph(null))
-                                .getSelectionCells();
+            Object[] allCells = ((XcosDiagram) getGraph(null)).getSelectionCells();
 
             JavaController controller = new JavaController();
             VectorOfDouble mvcAngle = new VectorOfDouble();
@@ -83,7 +81,12 @@ public class MirrorAction extends VertexSelectionDependantAction {
                 if (allCells[i] instanceof BasicBlock) {
                     long uid = ((BasicBlock) allCells[i]).getUID();
                     controller.getObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
-                    mvcAngle.set(0, mvcAngle.get(0) + 4d);
+
+                    // retrieve then toggle a bit
+                    int mirrorAndFlip = (int) mvcAngle.get(0);
+                    mirrorAndFlip ^= 0x0002;
+
+                    mvcAngle.set(0, mirrorAndFlip);
                     controller.setObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
                 }
             }
index 46c58f6..b3fb6e7 100644 (file)
@@ -111,7 +111,8 @@ public abstract class ContextUpdate extends BasicBlock {
     /**
      * Implement a listener to update the
      * {@link ContextUpdate#isContextDependent} flag.
-    @SuppressWarnings(value = { "serial" })
+     *
+     * @SuppressWarnings(value = { "serial" })
      */
     private static final class ExprsChangeAdapter implements PropertyChangeListener, Serializable {
         private static final Pattern INTEGER_PATTERN = Pattern.compile("\\d+");
@@ -177,10 +178,10 @@ public abstract class ContextUpdate extends BasicBlock {
         /** Map an implicit output port to an implicit output block */
         ImplicitOutBlock(ImplicitOutBlock.class, ImplicitOutputPort.class, ImplicitInputPort.class, OutputPort.class);
 
-        private final Class <? extends ContextUpdate > ioBlock;
-        private final Class <? extends BasicPort > port;
-        private final Class <? extends BasicPort > opposite;
-        private final Class <? extends BasicPort > assignement;
+        private final Class<? extends ContextUpdate> ioBlock;
+        private final Class<? extends BasicPort> port;
+        private final Class<? extends BasicPort> opposite;
+        private final Class<? extends BasicPort> assignement;
 
         /**
          * @param ioBlock
@@ -190,7 +191,8 @@ public abstract class ContextUpdate extends BasicBlock {
          * @param opposite
          *            the opposite port class
          */
-        private IOBlocks(Class <? extends ContextUpdate > ioBlock, Class <? extends BasicPort > port, Class <? extends BasicPort > opposite, Class <? extends BasicPort > assignement) {
+        private IOBlocks(Class<? extends ContextUpdate> ioBlock, Class<? extends BasicPort> port, Class<? extends BasicPort> opposite,
+        Class<? extends BasicPort> assignement) {
             this.ioBlock = ioBlock;
             this.port = port;
             this.opposite = opposite;
@@ -238,11 +240,11 @@ public abstract class ContextUpdate extends BasicBlock {
          *            the filter klass
          * @return the list of ports
          */
-        public static List<mxICell> getPorts(SuperBlock parent, Class <? extends ContextUpdate > klass) {
+        public static List<mxICell> getPorts(SuperBlock parent, Class<? extends ContextUpdate> klass) {
             List<mxICell> ret = new ArrayList<mxICell>();
 
             /* Get the corresponding klass */
-            Class <? extends BasicPort > portKlass = null;
+            Class<? extends BasicPort> portKlass = null;
             for (IOBlocks b : IOBlocks.values()) {
                 if (b.getReferencedClass().equals(klass)) {
                     portKlass = b.getAssignementCompatiblePortClass();
@@ -271,7 +273,7 @@ public abstract class ContextUpdate extends BasicBlock {
          *            the klass
          * @return the opposite of klass
          */
-        public static Class <? extends BasicPort > getOpposite(Class <? extends BasicPort > klass) {
+        public static Class<? extends BasicPort> getOpposite(Class<? extends BasicPort> klass) {
             for (IOBlocks b : IOBlocks.values()) {
                 if (b.getReferencedPortClass() == klass) {
                     return b.getOppositeClass();
@@ -294,7 +296,8 @@ public abstract class ContextUpdate extends BasicBlock {
                     try {
                         JavaController controller = new JavaController();
 
-                        // FIXME: dunno if I should disable the view there : CHECK
+                        // FIXME: dunno if I should disable the view there :
+                        // CHECK
                         JavaController.unregister_view(disabledView);
 
                         Constructor<? extends ContextUpdate> blockCstr = io.getReferencedClass().getConstructor(Long.TYPE);
@@ -333,25 +336,25 @@ public abstract class ContextUpdate extends BasicBlock {
         /**
          * @return referenced class
          */
-        public Class <? extends ContextUpdate > getReferencedClass() {
+        public Class<? extends ContextUpdate> getReferencedClass() {
             return ioBlock;
         }
 
         /**
          * @return the port referenced class
          */
-        public Class <? extends BasicPort > getReferencedPortClass() {
+        public Class<? extends BasicPort> getReferencedPortClass() {
             return port;
         }
 
-        public Class <? extends BasicPort > getAssignementCompatiblePortClass() {
+        public Class<? extends BasicPort> getAssignementCompatiblePortClass() {
             return assignement;
         }
 
         /**
          * @return the port opposite class
          */
-        public Class <? extends BasicPort > getOppositeClass() {
+        public Class<? extends BasicPort> getOppositeClass() {
             return opposite;
         }
     }
@@ -382,32 +385,34 @@ public abstract class ContextUpdate extends BasicBlock {
 
         LOG_LOCAL.finest("Update the I/O value from the context");
 
-        //        final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
-        //        if (handler == null) {
-        //            return;
-        //        }
+        // final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
+        // if (handler == null) {
+        // return;
+        // }
         //
-        //        try {
-        //            // Write scs_m
-        //            handler.writeBlock(this);
-        //            // Write context
-        //            handler.writeContext(context);
+        // try {
+        // // Write scs_m
+        // handler.writeBlock(this);
+        // // Write context
+        // handler.writeContext(context);
         //
-        //            String cmd = ScilabInterpreterManagement.buildCall("blk = xcosBlockEval", getInterfaceFunctionName().toCharArray(),
-        //                         ScilabDirectHandler.BLK.toCharArray(), ScilabDirectHandler.CONTEXT.toCharArray());
+        // String cmd = ScilabInterpreterManagement.buildCall("blk =
+        // xcosBlockEval", getInterfaceFunctionName().toCharArray(),
+        // ScilabDirectHandler.BLK.toCharArray(),
+        // ScilabDirectHandler.CONTEXT.toCharArray());
         //
-        //            try {
-        //                ScilabInterpreterManagement.synchronousScilabExec(cmd);
-        //            } catch (InterpreterException e) {
-        //                e.printStackTrace();
-        //            }
-        //            BasicBlock modifiedBlock = handler.readBlock();
-        //            updateBlockSettings(modifiedBlock);
+        // try {
+        // ScilabInterpreterManagement.synchronousScilabExec(cmd);
+        // } catch (InterpreterException e) {
+        // e.printStackTrace();
+        // }
+        // BasicBlock modifiedBlock = handler.readBlock();
+        // updateBlockSettings(modifiedBlock);
         //
-        //        } catch (ScicosFormatException e) {
-        //            LOG_LOCAL.severe(e.toString());
-        //        } finally {
-        //            handler.release();
-        //        }
+        // } catch (ScicosFormatException e) {
+        // LOG_LOCAL.severe(e.toString());
+        // } finally {
+        // handler.release();
+        // }
     }
 }
index 60ba6c3..01601b5 100644 (file)
@@ -46,7 +46,6 @@ public class BrowserTreeNodeData {
         refCount = 0;
     }
 
-
     /*
      * Getters and Setters
      */
@@ -81,7 +80,9 @@ public class BrowserTreeNodeData {
 
     /**
      * Compute and fill in the HTML data for node's parameters
-     * @param document the currently rendered document
+     *
+     * @param document
+     *            the currently rendered document
      * @throws IOException
      * @throws BadLocationException
      */
@@ -144,7 +145,8 @@ public class BrowserTreeNodeData {
         tag(htmlTable, "caption", "Graphics");
         tag(htmlTable, "tr", tag("td", "orig").append(tag("td", escapeVector(',', geom.get(0), geom.get(1)))));
         tag(htmlTable, "tr", tag("td", "sz").append(tag("td", escapeVector(',', geom.get(2), geom.get(3)))));
-        tag(htmlTable, "tr", tag("td", "flip").append(tag("td", (angle.get(0) == 0.0) ? "%f" : "%t")));
+        tag(htmlTable, "tr", tag("td", "flip").append(tag("td", ((((int) angle.get(0)) & 0x0001) != 0) ? "%t" : "%f")));
+        tag(htmlTable, "tr", tag("td", "mirror").append(tag("td", ((((int) angle.get(0)) & 0x0002) != 0) ? "%t" : "%f")));
         tag(htmlTable, "tr", tag("td", "theta").append(tag("td", CURRENT_FORMAT.format(angle.get(1)))));
         tag(htmlTable, "tr", tag("td", "exprs").append(tag("td", escapeVector(';', exprs))));
         tag(htmlTable, "tr", tag("td", "id").append(tag("td", title[0])));
@@ -231,7 +233,6 @@ public class BrowserTreeNodeData {
             str.append('"').append(v[v.length - 1]).append('"');
         }
 
-
         if (v.length > 1) {
             str.append(']');
         }
@@ -298,7 +299,9 @@ public class BrowserTreeNodeData {
         }
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see java.lang.Object#hashCode()
      */
     @Override
@@ -309,7 +312,9 @@ public class BrowserTreeNodeData {
         return result;
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
index f5df23d..ef82b60 100644 (file)
@@ -30,9 +30,7 @@ import org.scilab.modules.xcos.preferences.XcosOptions;
  *
  * This class is a java beans and follow standard properties accessors.
  *
- * @see <a
- *      href="http://java.sun.com/docs/books/tutorial/javabeans/properties/bound.html">JavaBeans
- *      Bound Properties</a>
+ * @see <a href="http://java.sun.com/docs/books/tutorial/javabeans/properties/bound.html">JavaBeans Bound Properties</a>
  */
 @SuppressWarnings(value = { "serial" })
 public class ScicosParameters implements Serializable, Cloneable {
@@ -107,7 +105,8 @@ public class ScicosParameters implements Serializable, Cloneable {
     /**
      * Reference to the diagram
      */
-    private final long diagramId;
+    private final long uid;
+    private final Kind kind;
 
     /*
      * Beans support, used to follow instance modification and validate changes.
@@ -119,8 +118,9 @@ public class ScicosParameters implements Serializable, Cloneable {
      *
      * Initialize parameters with their default values.
      */
-    public ScicosParameters(final long diagramId) {
-        this.diagramId = diagramId;
+    public ScicosParameters(final long uid, final Kind kind) {
+        this.uid = uid;
+        this.kind = kind;
 
         /*
          * This call will update static values from the configuration.
@@ -128,27 +128,41 @@ public class ScicosParameters implements Serializable, Cloneable {
         XcosOptions.getSimulation();
     }
 
+    public long getUID() {
+        return uid;
+    }
+
+    public Kind getKind() {
+        return kind;
+    }
+
     /**
      * Returns the properties values
-     * @param controller the controller instance
+     *
+     * @param controller
+     *            the controller instance
      * @return the current properties
      */
     public VectorOfDouble getProperties(final JavaController controller) {
         VectorOfDouble v = new VectorOfDouble(7);
-        controller.getObjectProperty(diagramId, Kind.DIAGRAM, ObjectProperties.PROPERTIES, v);
+        controller.getObjectProperty(getUID(), getKind(), ObjectProperties.PROPERTIES, v);
         return v;
     }
 
     /**
      * Set the properties
-     * @param controller the controller instance
-     * @param v the values to set
-     * @throws PropertyVetoException in case of the values are not valid
+     *
+     * @param controller
+     *            the controller instance
+     * @param v
+     *            the values to set
+     * @throws PropertyVetoException
+     *             in case of the values are not valid
      */
     public void setProperties(final JavaController controller, VectorOfDouble v) throws PropertyVetoException {
         VectorOfDouble oldValue = getProperties(controller);
         vcs.fireVetoableChange(FINAL_INTEGRATION_TIME_CHANGE, oldValue, v);
-        controller.setObjectProperty(diagramId, Kind.DIAGRAM, ObjectProperties.PROPERTIES, v);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.PROPERTIES, v);
     }
 
     /**
@@ -156,14 +170,15 @@ public class ScicosParameters implements Serializable, Cloneable {
      */
     public VectorOfString getContext(final JavaController controller) {
         VectorOfString v = new VectorOfString();
-        controller.getObjectProperty(diagramId, Kind.DIAGRAM, ObjectProperties.DIAGRAM_CONTEXT, v);
+        controller.getObjectProperty(getUID(), getKind(), ObjectProperties.DIAGRAM_CONTEXT, v);
         return v;
     }
 
     /**
      * Set the associated context if there is noticeable changes.
      *
-     * @param controller the controller
+     * @param controller
+     *            the controller
      * @param v
      *            set context
      * @throws PropertyVetoException
@@ -172,16 +187,17 @@ public class ScicosParameters implements Serializable, Cloneable {
     public void setContext(final JavaController controller, VectorOfString v) throws PropertyVetoException {
         VectorOfString oldValue = getContext(controller);
         vcs.fireVetoableChange(CONTEXT_CHANGE, oldValue, v);
-        controller.setObjectProperty(diagramId, Kind.DIAGRAM, ObjectProperties.DIAGRAM_CONTEXT, v);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DIAGRAM_CONTEXT, v);
     }
 
     /**
-     * @param controller the controller instance
+     * @param controller
+     *            the controller instance
      * @return current version
      */
     public String getVersion(final JavaController controller) {
         String[] v = new String[1];
-        controller.getObjectProperty(diagramId, Kind.DIAGRAM, ObjectProperties.VERSION_NUMBER, v);
+        controller.getObjectProperty(getUID(), getKind(), ObjectProperties.VERSION_NUMBER, v);
         return v[0];
     }
 
@@ -209,8 +225,7 @@ public class ScicosParameters implements Serializable, Cloneable {
      */
 
     /**
-     * Each setXXX method fire a vetoable change event. This method register a
-     * new listener for all events.
+     * Each setXXX method fire a vetoable change event. This method register a new listener for all events.
      *
      * @param listener
      *            A listener
@@ -220,9 +235,7 @@ public class ScicosParameters implements Serializable, Cloneable {
     }
 
     /**
-     * Each setXXX method fire a vetoable change event. This method register a
-     * new listener for a specific event. Each event name is equal to the field
-     * name.
+     * Each setXXX method fire a vetoable change event. This method register a new listener for a specific event. Each event name is equal to the field name.
      *
      * @param propertyName
      *            the property name
@@ -234,8 +247,7 @@ public class ScicosParameters implements Serializable, Cloneable {
     }
 
     /**
-     * Each setXXX method fire a vetoable change event. This method remove a
-     * listener for all events.
+     * Each setXXX method fire a vetoable change event. This method remove a listener for all events.
      *
      * @param listener
      *            A listener
@@ -245,9 +257,7 @@ public class ScicosParameters implements Serializable, Cloneable {
     }
 
     /**
-     * Each setXXX method fire a vetoable change event. This method remove a
-     * listener for a specific event. Each event name is equal to the field
-     * name.
+     * Each setXXX method fire a vetoable change event. This method remove a listener for a specific event. Each event name is equal to the field name.
      *
      * @param propertyName
      *            the property name
index df70067..110facb 100644 (file)
@@ -16,8 +16,6 @@ package org.scilab.modules.xcos.graph;
 import java.awt.GraphicsEnvironment;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -125,33 +123,19 @@ public class XcosDiagram extends ScilabGraph {
     public static final String HASH_IDENTIFIER = "#identifier";
 
     /**
-     * Default geometry used while adding a label to a block (on the middle and
-     * below the bottom of the parent block)
+     * Default geometry used while adding a label to a block (on the middle and below the bottom of the parent block)
      */
     private static final mxGeometry DEFAULT_LABEL_GEOMETRY = new mxGeometry(0.5, 1.1, 0.0, 0.0);
 
-    /*
-     * diagram data
-     */
-
-    // the associated parameters
-    private final ScicosParameters scicosParameters;
-
     /**
      * Constructor
      *
-     * @param withVisibleFeatures true if the visible features should be activated, false otherwise. Disable it on encode/decode leads to a huge performance gain.
+     * @param withVisibleFeatures
+     *            true if the visible features should be activated, false otherwise. Disable it on encode/decode leads to a huge performance gain.
      */
     public XcosDiagram(final long diagramId, final Kind kind) {
         super(new mxGraphModel(), Xcos.getInstance().getStyleSheet());
 
-        // Scicos related setup
-        if (kind == Kind.DIAGRAM) {
-            scicosParameters = new ScicosParameters(diagramId);
-        } else {
-            scicosParameters = null;
-        }
-
         // add the default parent (the JGraphX layer)
         XcosCell parent = new XcosCell(diagramId, kind);
         new JavaController().referenceObject(diagramId);
@@ -176,8 +160,7 @@ public class XcosDiagram extends ScilabGraph {
         /* Labels use HTML if not equal to interface function name */
         setHtmlLabels(true);
         /*
-         * by default every label is movable, see
-         * XcosDiagram##isLabelMovable(java.lang.Object) for restrictions
+         * by default every label is movable, see XcosDiagram##isLabelMovable(java.lang.Object) for restrictions
          */
         setVertexLabelsMovable(true);
         setEdgeLabelsMovable(true);
@@ -227,7 +210,7 @@ public class XcosDiagram extends ScilabGraph {
      *            the block list
      * @return the sorted block list (same instance)
      */
-    public List <? extends BasicBlock > iparSort(final List <? extends BasicBlock > blocks) {
+    public List<? extends BasicBlock> iparSort(final List<? extends BasicBlock> blocks) {
         Collections.sort(blocks, new Comparator<BasicBlock>() {
             @Override
             public int compare(BasicBlock o1, BasicBlock o2) {
@@ -309,7 +292,7 @@ public class XcosDiagram extends ScilabGraph {
     @SuppressWarnings("unchecked")
     protected void fillContext(final Hashtable<Object, Object> context) {
         if (!context.containsKey(IN)) {
-            context.put(IN, iparSort(getAllTypedBlock( new Class [] { ExplicitInBlock.class, ImplicitInBlock.class })));
+            context.put(IN, iparSort(getAllTypedBlock(new Class[] { ExplicitInBlock.class, ImplicitInBlock.class })));
         }
         if (!context.containsKey(OUT)) {
             context.put(OUT, iparSort(getAllTypedBlock(new Class[] { ExplicitOutBlock.class, ImplicitOutBlock.class })));
@@ -376,7 +359,7 @@ public class XcosDiagram extends ScilabGraph {
          */
 
         // get the real index
-        final List <? extends BasicBlock > blocks = (List <? extends BasicBlock > ) context.get(key);
+        final List<? extends BasicBlock> blocks = (List<? extends BasicBlock>) context.get(key);
         final int realIndex = blocks.indexOf(block) + 1;
 
         // get the user index
@@ -403,9 +386,6 @@ public class XcosDiagram extends ScilabGraph {
         return err;
     }
 
-
-
-
     /*
      * Static diagram listeners
      */
@@ -440,8 +420,7 @@ public class XcosDiagram extends ScilabGraph {
          *            the source instance
          * @param evt
          *            the event data
-         * @see com.mxgraph.util.mxEventSource.mxIEventListener#invoke(java.lang.Object,
-         *      com.mxgraph.util.mxEventObject)
+         * @see com.mxgraph.util.mxEventSource.mxIEventListener#invoke(java.lang.Object, com.mxgraph.util.mxEventObject)
          */
         @Override
         public void invoke(final Object source, final mxEventObject evt) {
@@ -490,8 +469,7 @@ public class XcosDiagram extends ScilabGraph {
          *            the source instance
          * @param evt
          *            the event data
-         * @see com.mxgraph.util.mxEventSource.mxIEventListener#invoke(java.lang.Object,
-         *      com.mxgraph.util.mxEventObject)
+         * @see com.mxgraph.util.mxEventSource.mxIEventListener#invoke(java.lang.Object, com.mxgraph.util.mxEventObject)
          */
         @Override
         public void invoke(final Object source, final mxEventObject evt) {
@@ -504,47 +482,47 @@ public class XcosDiagram extends ScilabGraph {
             model.beginUpdate();
             try {
                 // FIXME manage that for the MVC
-                //                for (final Object object : changedCells) {
-                //                    if (object instanceof BasicBlock) {
-                //                        final BasicBlock current = (BasicBlock) object;
-                //                        final XcosDiagram graph = current.getParentDiagram();
+                // for (final Object object : changedCells) {
+                // if (object instanceof BasicBlock) {
+                // final BasicBlock current = (BasicBlock) object;
+                // final XcosDiagram graph = current.getParentDiagram();
                 //
-                //                        // When we change the style property we have to update
-                //                        // some BasiBlock fields
-                //                        if (changes.get(0) instanceof mxStyleChange) {
-                //                            current.updateFieldsFromStyle();
-                //                        }
+                // // When we change the style property we have to update
+                // // some BasiBlock fields
+                // if (changes.get(0) instanceof mxStyleChange) {
+                // current.updateFieldsFromStyle();
+                // }
                 //
-                //                        // update the superblock container ports if the block is
-                //                        // inside a superblock diagram
-                //                        if (graph instanceof SuperBlockDiagram) {
-                //                            SuperBlockDiagram superdiagram = (SuperBlockDiagram) current.getParentDiagram();
-                //                            SuperBlock superblock = superdiagram.getContainer();
-                //                            superblock.updateExportedPort();
-                //                        }
+                // // update the superblock container ports if the block is
+                // // inside a superblock diagram
+                // if (graph instanceof SuperBlockDiagram) {
+                // SuperBlockDiagram superdiagram = (SuperBlockDiagram) current.getParentDiagram();
+                // SuperBlock superblock = superdiagram.getContainer();
+                // superblock.updateExportedPort();
+                // }
                 //
-                //                        // Update the block position
-                //                        BlockPositioning.updateBlockView(current);
+                // // Update the block position
+                // BlockPositioning.updateBlockView(current);
                 //
-                //                        // force a refresh of the block ports and links
-                //                        // connected to these ports
-                //                        final int childCount = model.getChildCount(current);
-                //                        for (int i = 0; i < childCount; i++) {
-                //                            final Object port = model.getChildAt(current, i);
-                //                            graph.getView().clear(port, true, true);
-                //                            final int edgeCount = model.getEdgeCount(port);
-                //                            for (int j = 0; j < edgeCount; j++) {
-                //                                final Object edge = model.getEdgeAt(port, j);
-                //                                graph.getView().clear(edge, true, true);
-                //                            }
-                //                        }
-                //                        // force a refresh of the block
-                //                        graph.getView().clear(current, true, true);
+                // // force a refresh of the block ports and links
+                // // connected to these ports
+                // final int childCount = model.getChildCount(current);
+                // for (int i = 0; i < childCount; i++) {
+                // final Object port = model.getChildAt(current, i);
+                // graph.getView().clear(port, true, true);
+                // final int edgeCount = model.getEdgeCount(port);
+                // for (int j = 0; j < edgeCount; j++) {
+                // final Object edge = model.getEdgeAt(port, j);
+                // graph.getView().clear(edge, true, true);
+                // }
+                // }
+                // // force a refresh of the block
+                // graph.getView().clear(current, true, true);
                 //
-                //                        graph.getView().validate();
-                //                        graph.repaint();
-                //                    }
-                //                }
+                // graph.getView().validate();
+                // graph.repaint();
+                // }
+                // }
             } finally {
                 model.endUpdate();
             }
@@ -580,8 +558,7 @@ public class XcosDiagram extends ScilabGraph {
          *            the diagram
          * @param evt
          *            the event
-         * @see com.mxgraph.util.mxEventSource.mxIEventListener#invoke(java.lang.Object,
-         *      com.mxgraph.util.mxEventObject)
+         * @see com.mxgraph.util.mxEventSource.mxIEventListener#invoke(java.lang.Object, com.mxgraph.util.mxEventObject)
          */
         @Override
         public void invoke(Object sender, mxEventObject evt) {
@@ -606,9 +583,7 @@ public class XcosDiagram extends ScilabGraph {
     }
 
     /**
-     * Hook method that creates the new edge for insertEdge. This implementation
-     * does not set the source and target of the edge, these are set when the
-     * edge is added to the model.
+     * Hook method that creates the new edge for insertEdge. This implementation does not set the source and target of the edge, these are set when the edge is added to the model.
      *
      * @param parent
      *            Cell that specifies the parent of the new edge.
@@ -623,9 +598,7 @@ public class XcosDiagram extends ScilabGraph {
      * @param style
      *            Optional string that defines the cell style.
      * @return Returns the new edge to be inserted.
-     * @see com.mxgraph.view.mxGraph#createEdge(java.lang.Object,
-     *      java.lang.String, java.lang.Object, java.lang.Object,
-     *      java.lang.Object, java.lang.String)
+     * @see com.mxgraph.view.mxGraph#createEdge(java.lang.Object, java.lang.String, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.String)
      */
     @Override
     public Object createEdge(Object parent, String id, Object value, Object source, Object target, String style) {
@@ -692,8 +665,7 @@ public class XcosDiagram extends ScilabGraph {
      * @param index
      *            the index of the edge
      * @return the added edge or null.
-     * @see com.mxgraph.view.mxGraph#addEdge(java.lang.Object, java.lang.Object,
-     *      java.lang.Object, java.lang.Object, java.lang.Integer)
+     * @see com.mxgraph.view.mxGraph#addEdge(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Integer)
      */
     @Override
     public Object addCell(Object cell, Object parent, Integer index, Object source, Object target) {
@@ -866,7 +838,6 @@ public class XcosDiagram extends ScilabGraph {
                 orig = new mxPoint();
             }
 
-
             addCell(splitBlock);
             // force resize and align on the grid
             resizeCell(splitBlock, new mxRectangle(splitPoint.getX(), splitPoint.getY(), 0, 0));
@@ -912,8 +883,7 @@ public class XcosDiagram extends ScilabGraph {
     /**
      * Connect two port together with the associated points.
      *
-     * This method perform the connection in two step in order to generate the
-     * right UndoableChangeEdits.
+     * This method perform the connection in two step in order to generate the right UndoableChangeEdits.
      *
      * @param src
      *            the source port
@@ -956,8 +926,7 @@ public class XcosDiagram extends ScilabGraph {
     /**
      * Initialize component settings for a graph.
      *
-     * This method *must* be used to setup the component after any
-     * reassociation.
+     * This method *must* be used to setup the component after any reassociation.
      */
     public void initComponent() {
         getAsComponent().setToolTips(true);
@@ -981,20 +950,21 @@ public class XcosDiagram extends ScilabGraph {
          * Reinstall related listeners
          */
 
+        // FIXME handle that only for visible diagrams
         // Property change Listener
         // Will say if a diagram has been modified or not.
-        final PropertyChangeListener p = new PropertyChangeListener() {
-            @Override
-            public void propertyChange(final PropertyChangeEvent e) {
-                if (e.getPropertyName().compareTo(MODIFIED) == 0) {
-                    if (!e.getOldValue().equals(e.getNewValue())) {
-                        updateTabTitle();
-                    }
-                }
-            }
-        };
-        getAsComponent().removePropertyChangeListener(MODIFIED, p);
-        getAsComponent().addPropertyChangeListener(MODIFIED, p);
+        // final PropertyChangeListener p = new PropertyChangeListener() {
+        // @Override
+        // public void propertyChange(final PropertyChangeEvent e) {
+        // if (e.getPropertyName().compareTo(MODIFIED) == 0) {
+        // if (!e.getOldValue().equals(e.getNewValue())) {
+        // updateTabTitle();
+        // }
+        // }
+        // }
+        // };
+        // getAsComponent().removePropertyChangeListener(MODIFIED, p);
+        // getAsComponent().addPropertyChangeListener(MODIFIED, p);
     }
 
     /**
@@ -1004,15 +974,17 @@ public class XcosDiagram extends ScilabGraph {
         final List<mxMultiplicity> multiplicities = new ArrayList<mxMultiplicity>();
 
         // Input data port
-        multiplicities.add(new PortCheck(ExplicitInputPort.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(ExplicitInputPort.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = -4987163442006736665L;
+
             {
                 add(ExplicitOutputPort.class);
                 add(ExplicitLink.class);
             }
         }), XcosMessages.LINK_ERROR_EXPLICIT_IN));
-        multiplicities.add(new PortCheck(ImplicitInputPort.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(ImplicitInputPort.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = 886376532181210926L;
+
             {
                 add(ImplicitOutputPort.class);
                 add(ImplicitInputPort.class);
@@ -1021,14 +993,16 @@ public class XcosDiagram extends ScilabGraph {
         }), XcosMessages.LINK_ERROR_IMPLICIT_IN));
 
         // Output data port
-        multiplicities.add(new PortCheck(ExplicitOutputPort.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(ExplicitOutputPort.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = 4594127972486054821L;
+
             {
                 add(ExplicitInputPort.class);
             }
         }), XcosMessages.LINK_ERROR_EXPLICIT_OUT));
-        multiplicities.add(new PortCheck(ImplicitOutputPort.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(ImplicitOutputPort.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = -3719677806532507973L;
+
             {
                 add(ImplicitInputPort.class);
                 add(ImplicitOutputPort.class);
@@ -1037,8 +1011,9 @@ public class XcosDiagram extends ScilabGraph {
         }), XcosMessages.LINK_ERROR_IMPLICIT_OUT));
 
         // Control port
-        multiplicities.add(new PortCheck(ControlPort.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(ControlPort.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = 2941077191386058497L;
+
             {
                 add(CommandPort.class);
                 add(CommandControlLink.class);
@@ -1046,15 +1021,16 @@ public class XcosDiagram extends ScilabGraph {
         }), XcosMessages.LINK_ERROR_EVENT_IN));
 
         // Command port
-        multiplicities.add(new PortCheck(CommandPort.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(CommandPort.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = -3470370027962480362L;
+
             {
                 add(ControlPort.class);
             }
         }), XcosMessages.LINK_ERROR_EVENT_OUT));
 
         // ExplicitLink connections
-        multiplicities.add(new PortCheck(ExplicitLink.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(ExplicitLink.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = 7423543162930147373L;
 
             {
@@ -1063,7 +1039,7 @@ public class XcosDiagram extends ScilabGraph {
         }), XcosMessages.LINK_ERROR_EVENT_OUT));
 
         // ImplicitLink connections
-        multiplicities.add(new PortCheck(ImplicitLink.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(ImplicitLink.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = 7775100011122283282L;
 
             {
@@ -1073,7 +1049,7 @@ public class XcosDiagram extends ScilabGraph {
         }), XcosMessages.LINK_ERROR_EVENT_OUT));
 
         // CommandControlLink connections
-        multiplicities.add(new PortCheck(CommandControlLink.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(CommandControlLink.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = 3260421433507192386L;
 
             {
@@ -1082,7 +1058,7 @@ public class XcosDiagram extends ScilabGraph {
         }), XcosMessages.LINK_ERROR_EVENT_OUT));
 
         // Already connected port
-        multiplicities.add(new PortCheck(BasicPort.class, Collections.unmodifiableList(new ArrayList < Class <? extends mxCell >> () {
+        multiplicities.add(new PortCheck(BasicPort.class, Collections.unmodifiableList(new ArrayList<Class<? extends mxCell>>() {
             private static final long serialVersionUID = 6376349598052836660L;
 
             {
@@ -1114,8 +1090,7 @@ public class XcosDiagram extends ScilabGraph {
     }
 
     /**
-     * Removes the given cells from the graph including all connected edges if
-     * includeEdges is true. The change is carried out using cellsRemoved.
+     * Removes the given cells from the graph including all connected edges if includeEdges is true. The change is carried out using cellsRemoved.
      *
      * @param cells
      *            the cells to be removed
@@ -1193,8 +1168,7 @@ public class XcosDiagram extends ScilabGraph {
                 final boolean out2Removed = removedCells.contains(out2Link);
 
                 /*
-                 * Explicit case, if the in link is deleted; all the out links
-                 * also should.
+                 * Explicit case, if the in link is deleted; all the out links also should.
                  */
                 if (inLink instanceof ExplicitLink && inRemoved) {
                     if (removedCells.add(out1Link)) {
@@ -1265,9 +1239,9 @@ public class XcosDiagram extends ScilabGraph {
      *            the "while loop" set
      */
     private void addTerminalParent(mxICell terminal, Collection<Object> removedCells, Collection<Object> loopCells) {
-        assert (terminal == null || terminal instanceof BasicPort);
-        assert (removedCells != null);
-        assert (loopCells != null);
+        assert(terminal == null || terminal instanceof BasicPort);
+        assert(removedCells != null);
+        assert(loopCells != null);
 
         // getting terminal parent
         mxICell target = null;
@@ -1344,9 +1318,7 @@ public class XcosDiagram extends ScilabGraph {
     }
 
     /**
-     * Manage Group to be CellFoldable i.e with a (-) to reduce and a (+) to
-     * expand them. Labels (mxCell instance with value) should not have a
-     * visible foldable sign.
+     * Manage Group to be CellFoldable i.e with a (-) to reduce and a (+) to expand them. Labels (mxCell instance with value) should not have a visible foldable sign.
      *
      * @param cell
      *            the selected cell
@@ -1536,8 +1508,7 @@ public class XcosDiagram extends ScilabGraph {
      *
      * @param cell
      *            the cell object
-     * @return a representative the string (block name) or a style specific
-     *         style.
+     * @return a representative the string (block name) or a style specific style.
      * @see com.mxgraph.view.mxGraph#convertValueToString(java.lang.Object)
      */
     @Override
@@ -1556,7 +1527,7 @@ public class XcosDiagram extends ScilabGraph {
                         controller.getObjectProperty(((BasicBlock) cell).getUID(), Kind.BLOCK, ObjectProperties.EXPRS, v);
 
                         // FIXME : decode these exprs
-                        //                        ret = String.format(displayedLabel, ((BasicBlock) cell).getExprsFormat());
+                        // ret = String.format(displayedLabel, ((BasicBlock) cell).getExprsFormat());
                         ret = String.format(displayedLabel, "Not handled exprs ; please report a bug");
                     } catch (IllegalFormatException e) {
                         LOG.severe(e.toString());
@@ -1621,13 +1592,6 @@ public class XcosDiagram extends ScilabGraph {
     }
 
     /**
-     * @return the parameters
-     */
-    public ScicosParameters getScicosParameters() {
-        return scicosParameters;
-    }
-
-    /**
      * @return the model ID
      */
     public long getUID() {
@@ -1692,10 +1656,7 @@ public class XcosDiagram extends ScilabGraph {
                 final String title = getTitle();
                 if (title != null) {
                     /*
-                     * Escape file to handle not supported character in file
-                     * name (may be Windows only) see
-                     * http://msdn.microsoft.com/en
-                     * -us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
+                     * Escape file to handle not supported character in file name (may be Windows only) see http://msdn.microsoft.com/en -us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
                      */
                     final char[] regex = "<>:\"/\\|?*".toCharArray();
                     String escaped = title;
@@ -1727,11 +1688,9 @@ public class XcosDiagram extends ScilabGraph {
         final String filename = writeFile.getName();
 
         /*
-         * Look for the user extension if it does not exists, append a default
-         * one
+         * Look for the user extension if it does not exists, append a default one
          *
-         * if the specified extension is handled, update the save format ; else
-         * append a default extension and use the default format
+         * if the specified extension is handled, update the save format ; else append a default extension and use the default format
          */
         XcosFileType userExtension = XcosFileType.findFileType(filename);
         if (userExtension == null) {
@@ -1745,12 +1704,11 @@ public class XcosDiagram extends ScilabGraph {
         }
 
         /*
-         * If the file exists, ask for confirmation if this is not the
-         * previously saved file
+         * If the file exists, ask for confirmation if this is not the previously saved file
          */
         if (writeFile.exists() && !writeFile.equals(getSavedFile())) {
-            final boolean overwrite = ScilabModalDialog.show(XcosTab.get(this), XcosMessages.OVERWRITE_EXISTING_FILE, XcosMessages.XCOS,
-                                      IconType.QUESTION_ICON, ButtonType.YES_NO) == AnswerOption.YES_OPTION;
+            final boolean overwrite = ScilabModalDialog.show(XcosTab.get(this), XcosMessages.OVERWRITE_EXISTING_FILE, XcosMessages.XCOS, IconType.QUESTION_ICON,
+                                      ButtonType.YES_NO) == AnswerOption.YES_OPTION;
 
             if (!overwrite) {
                 info(XcosMessages.EMPTY_INFO);
@@ -1809,7 +1767,6 @@ public class XcosDiagram extends ScilabGraph {
     @Override
     public void setTitle(final String title) {
         super.setTitle(title);
-        updateTabTitle();
 
         JavaController controller = new JavaController();
         controller.setObjectProperty(getUID(), getKind(), ObjectProperties.TITLE, title);
@@ -1856,7 +1813,8 @@ public class XcosDiagram extends ScilabGraph {
     /**
      * Load a file with different method depending on it extension
      *
-     * @param controller the used controller
+     * @param controller
+     *            the used controller
      * @param file
      *            File to load (can be null)
      */
@@ -1949,8 +1907,7 @@ public class XcosDiagram extends ScilabGraph {
         controller.getObjectProperty(getUID(), getKind(), ObjectProperties.PARENT_DIAGRAM, parent);
 
         Collection<XcosDiagram> diagrams = Xcos.getInstance().getDiagrams(parent[0]);
-        return diagrams.stream().filter(d -> d.getUID() == parent[0])
-               .findFirst().get();
+        return diagrams.stream().filter(d -> d.getUID() == parent[0]).findFirst().get();
     }
 
     /**
@@ -1993,8 +1950,7 @@ public class XcosDiagram extends ScilabGraph {
     }
 
     /**
-     * Find the block corresponding to the given uid and display a warning
-     * message.
+     * Find the block corresponding to the given uid and display a warning message.
      *
      * @param uid
      *            - A String as UID.
@@ -2037,44 +1993,43 @@ public class XcosDiagram extends ScilabGraph {
      * Set the current diagram in a modified state
      *
      * @param modified
-     *            True or False whether the current diagram must be saved or
-     *            not.
+     *            True or False whether the current diagram must be saved or not.
      */
     @Override
     public void setModified(final boolean modified) {
         super.setModified(modified);
-        updateTabTitle();
+        // FIXME update the tab title on the caller
+        // updateTabTitle();
     }
 
     /**
      * Evaluate the current context
      *
-     * @return The resulting data. Keys are variable names and Values are
-     *         evaluated values.
+     * @return The resulting data. Keys are variable names and Values are evaluated values.
      */
     public Map<String, String> evaluateContext() {
         Map<String, String> result = Collections.emptyMap();
         // FIXME: evaluate the context on scilab 6 ?
-        //        final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
-        //        if (handler == null) {
-        //            return result;
-        //        }
+        // final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
+        // if (handler == null) {
+        // return result;
+        // }
         //
-        //        try {
-        //            // first write the context strings
-        //            handler.writeContext(getContext());
+        // try {
+        // // first write the context strings
+        // handler.writeContext(getContext());
         //
-        //            // evaluate using script2var
-        //            ScilabInterpreterManagement.synchronousScilabExec(ScilabDirectHandler.CONTEXT + " = script2var(" + ScilabDirectHandler.CONTEXT + ", struct());");
+        // // evaluate using script2var
+        // ScilabInterpreterManagement.synchronousScilabExec(ScilabDirectHandler.CONTEXT + " = script2var(" + ScilabDirectHandler.CONTEXT + ", struct());");
         //
-        //            // read the structure
-        //            result = handler.readContext();
-        //        } catch (final InterpreterException e) {
-        //            info("Unable to evaluate the contexte");
-        //            e.printStackTrace();
-        //        } finally {
-        //            handler.release();
-        //        }
+        // // read the structure
+        // result = handler.readContext();
+        // } catch (final InterpreterException e) {
+        // info("Unable to evaluate the contexte");
+        // e.printStackTrace();
+        // } finally {
+        // handler.release();
+        // }
 
         return result;
     }
@@ -2087,8 +2042,7 @@ public class XcosDiagram extends ScilabGraph {
      * @param cells
      *            the cells to be dropped
      * @return the drop status
-     * @see com.mxgraph.view.mxGraph#isValidDropTarget(java.lang.Object,
-     *      java.lang.Object[])
+     * @see com.mxgraph.view.mxGraph#isValidDropTarget(java.lang.Object, java.lang.Object[])
      */
     @Override
     public boolean isValidDropTarget(final Object cell, final Object[] cells) {
@@ -2105,8 +2059,7 @@ public class XcosDiagram extends ScilabGraph {
     protected mxGraphSelectionModel createSelectionModel() {
         return new mxGraphSelectionModel(this) {
             /**
-             * When we only want to select a cell which is a port, select the
-             * parent block.
+             * When we only want to select a cell which is a port, select the parent block.
              *
              * @param cell
              *            the cell
index 793ce38..315234f 100644 (file)
@@ -27,7 +27,6 @@ import com.mxgraph.model.mxGeometry;
 import com.mxgraph.model.mxICell;
 import com.mxgraph.util.mxPoint;
 
-
 public class XcosCell extends ScilabGraphUniqueObject {
     private static final long serialVersionUID = 1L;
 
@@ -38,8 +37,10 @@ public class XcosCell extends ScilabGraphUniqueObject {
      *
      * This Java object owns the corresponding MVC object and thus will unrefererence it on GC.
      *
-     * @param uid the associated MVC identifier
-     * @param kind the associated MVC kind
+     * @param uid
+     *            the associated MVC identifier
+     * @param kind
+     *            the associated MVC kind
      */
     public XcosCell(long uid, Kind kind) {
         owner = new ScicosObjectOwner(uid, kind);
@@ -71,7 +72,9 @@ public class XcosCell extends ScilabGraphUniqueObject {
      * Override setters and hierarchy modifiers to propagate changes to the model
      */
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see com.mxgraph.model.mxCell#setValue(java.lang.Object)
      */
     @Override
@@ -96,7 +99,9 @@ public class XcosCell extends ScilabGraphUniqueObject {
         }
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see com.mxgraph.model.mxCell#setId(java.lang.String)
      */
     @Override
@@ -122,7 +127,9 @@ public class XcosCell extends ScilabGraphUniqueObject {
         }
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see com.mxgraph.model.mxCell#setGeometry(com.mxgraph.model.mxGeometry)
      */
     @Override
@@ -180,8 +187,7 @@ public class XcosCell extends ScilabGraphUniqueObject {
                 }
 
                 /*
-                 * At that point, the sourcePoint, targetPoint and points are valid values (but may be unknown)
-                 * encode them to the the CONTROL_POINTS
+                 * At that point, the sourcePoint, targetPoint and points are valid values (but may be unknown) encode them to the the CONTROL_POINTS
                  */
 
                 // Allocate some space to contains them all
@@ -194,7 +200,7 @@ public class XcosCell extends ScilabGraphUniqueObject {
                 v.set(2 * i + 1, sourcePoint.getY());
                 i++;
 
-                for (; i < nbOfPoints - 1 ; i++) {
+                for (; i < nbOfPoints - 1; i++) {
                     v.set(2 * i, points.get(i - 1).getX());
                     v.set(2 * i + 1, points.get(i - 1).getY());
                 }
@@ -214,7 +220,9 @@ public class XcosCell extends ScilabGraphUniqueObject {
         }
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see com.mxgraph.model.mxCell#setStyle(java.lang.String)
      */
     @Override
@@ -237,7 +245,9 @@ public class XcosCell extends ScilabGraphUniqueObject {
 
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see com.mxgraph.model.mxCell#setParent(com.mxgraph.model.mxICell)
      */
     @Override
@@ -296,7 +306,9 @@ public class XcosCell extends ScilabGraphUniqueObject {
         return cell;
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see com.mxgraph.model.mxCell#insert(com.mxgraph.model.mxICell, int)
      */
     @Override
@@ -353,7 +365,7 @@ public class XcosCell extends ScilabGraphUniqueObject {
                 break;
         }
 
-        // FIXME manage the index argument
+        // FIXME manage the index argument, possibly by counting the JGraphX children by kind
         if (property != null) {
             controller.getObjectProperty(getUID(), getKind(), property, children);
             children.add(c.getUID());
@@ -370,7 +382,9 @@ public class XcosCell extends ScilabGraphUniqueObject {
         controller.setObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see com.mxgraph.model.mxCell#remove(com.mxgraph.model.mxICell)
      */
     @Override
index 20f653d..892b4f9 100644 (file)
@@ -64,14 +64,18 @@ public final class XcosCellFactory {
 
     /**
      * This is a notify method mapped as a Scilab gateway used to alert with the loaded UID
-     * @param uid the loaded UID
-     * @param kind the kind of the created object (as an int)
+     *
+     * @param uid
+     *            the loaded UID
+     * @param kind
+     *            the kind of the created object (as an int)
      */
     @ScilabExported(module = "xcos", filename = "XcosCellFactory.giws.xml")
     public static void created(long uid, int kind) {
         lastCreated = new ScicosObjectOwner(uid, Kind.values()[kind]);
 
     }
+
     private static ScicosObjectOwner lastCreated = null;
 
     /*
@@ -83,8 +87,10 @@ public final class XcosCellFactory {
      *
      * This method execute the file and register a
      *
-     * @param controller the controller
-     * @param filename the file to execute
+     * @param controller
+     *            the controller
+     * @param filename
+     *            the file to execute
      * @return an allocated XcosDiagram
      */
     public static XcosDiagram createDiagramFromCOSF(final JavaController controller, String filename) {
@@ -94,10 +100,7 @@ public final class XcosCellFactory {
         XcosDiagram diagram;
         try {
             synchronousScilabExec(
-                "function f(), " +
-                buildCall("exec", filename, -1) +
-                buildCall("xcosCellCreated", "scs_m".toCharArray()) +
-                "endfunction; f();");
+                "function f(), " + buildCall("exec", filename, -1) + buildCall("xcosCellCreated", "scs_m".toCharArray()) + "endfunction; f();");
 
             if (lastCreated.getKind() == Kind.DIAGRAM) {
                 diagram = new XcosDiagram(lastCreated.getUID(), lastCreated.getKind());
@@ -117,8 +120,11 @@ public final class XcosCellFactory {
 
     /**
      * Insert the diagram MVC children into the JGraphX model
-     * @param controller the shared controller
-     * @param diagram the current diagram instance
+     *
+     * @param controller
+     *            the shared controller
+     * @param diagram
+     *            the current diagram instance
      */
     public static void insertChildren(JavaController controller, XcosDiagram diagram) {
         VectorOfScicosID children = new VectorOfScicosID();
@@ -145,10 +151,8 @@ public final class XcosCellFactory {
                     BasicBlock b = createBlock(controller, uid, kind);
                     cells[i] = b;
                     BlockPositioning.updatePortsPosition(diagram, b);
-                    b.getTypedChildrenIndexes(BasicPort.class).stream()
-                    .map(index -> b.getChildAt(index))
-                    .filter(c -> c instanceof BasicPort)
-                    .forEach( c -> ports.add((BasicPort) c));
+                    b.getTypedChildrenIndexes(BasicPort.class).stream().map(index -> b.getChildAt(index)).filter(c -> c instanceof BasicPort)
+                    .forEach(c -> ports.add((BasicPort) c));
                     break;
                 case LINK:
                     BasicLink l = createLink(controller, uid, kind);
@@ -190,8 +194,6 @@ public final class XcosCellFactory {
         diagram.addCells(cells);
     }
 
-
-
     /*
      * Block and Annotation management
      */
@@ -212,13 +214,12 @@ public final class XcosCellFactory {
      *
      * @param uid
      *            The associated UID value
-     * @param interfaceFunction the interface function
+     * @param interfaceFunction
+     *            the interface function
      * @return A new instance of a block.
      */
     public static BasicBlock createBlock(String interfaceFunction) {
-        Optional<BlockInterFunction> func = EnumSet.allOf(BlockInterFunction.class).stream()
-                                            .filter(f -> f.name().equals(interfaceFunction))
-                                            .findFirst();
+        Optional<BlockInterFunction> func = EnumSet.allOf(BlockInterFunction.class).stream().filter(f -> f.name().equals(interfaceFunction)).findFirst();
 
         final BasicBlock block;
         if (func.isPresent()) {
@@ -269,13 +270,13 @@ public final class XcosCellFactory {
         String[] interfaceFunction = new String[1];
         controller.getObjectProperty(uid, kind, ObjectProperties.INTERFACE_FUNCTION, interfaceFunction);
 
-        return createBlock(controller, interfaceFunction[0], uid);
+        final BlockInterFunction func = lookForInterfunction(interfaceFunction[0]);
+
+        return createBlock(controller, func, interfaceFunction[0], uid);
     }
 
-    private static BasicBlock createBlock(final JavaController controller, String interfaceFunction, long uid) {
-        Optional<BlockInterFunction> optFunc = EnumSet.allOf(BlockInterFunction.class).stream()
-                                               .filter(f -> f.name().equals(interfaceFunction))
-                                               .findFirst();
+    public static BlockInterFunction lookForInterfunction(String interfaceFunction) {
+        Optional<BlockInterFunction> optFunc = EnumSet.allOf(BlockInterFunction.class).stream().filter(f -> f.name().equals(interfaceFunction)).findFirst();
 
         final BlockInterFunction func;
         if (optFunc.isPresent()) {
@@ -283,24 +284,28 @@ public final class XcosCellFactory {
         } else {
             func = BlockInterFunction.BASIC_BLOCK;
         }
-
-        return createBlock(controller, func, interfaceFunction, uid);
+        return func;
     }
 
     /**
      * Instantiate a new block with the specified interface function and uid.
      *
-     * @param controller the Java controller to use
-     * @param func the interface function as an enum
-     * @param interfaceFunction the interface function name
-     * @param uid the allocated uid
+     * @param controller
+     *            the Java controller to use
+     * @param func
+     *            the interface function as an enum
+     * @param interfaceFunction
+     *            the interface function name
+     * @param uid
+     *            the allocated uid
      * @return A new instance of a block.
      */
-    private static BasicBlock createBlock(final JavaController controller, BlockInterFunction func, String interfaceFunction, long uid) {
+    public static BasicBlock createBlock(final JavaController controller, BlockInterFunction func, String interfaceFunction, long uid) {
         BasicBlock block = null;
         try {
             block = func.getKlass().getConstructor(Long.TYPE).newInstance(uid);
-        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException        | NoSuchMethodException | SecurityException e) {
+        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
+                     | SecurityException e) {
             // Something goes wrong, print it.
             e.printStackTrace();
             return block;
@@ -325,9 +330,6 @@ public final class XcosCellFactory {
 
         // FIXME find a way to reuse the Scicos compat handler from org.scilab.modules.xcos.io.scicos
 
-
-
-
         return block;
     }
 
@@ -340,27 +342,33 @@ public final class XcosCellFactory {
      *
      * This method does not manage the model transaction and should be used to preset the children of a block out of an {@link XcosDiagram}.
      *
-     * @param controller is the shared controller instance
-     * @param parent is the parent {@link mxCell} to modify
+     * @param controller
+     *            is the shared controller instance
+     * @param parent
+     *            is the parent {@link mxCell} to modify
      */
     private static void insertPortChildren(final JavaController controller, final XcosCell parent) {
-        final EnumSet<ObjectProperties> properties = EnumSet.of(ObjectProperties.INPUTS, ObjectProperties.OUTPUTS, ObjectProperties.EVENT_INPUTS, ObjectProperties.EVENT_OUTPUTS);
+        final EnumSet<ObjectProperties> properties = EnumSet.of(ObjectProperties.INPUTS, ObjectProperties.OUTPUTS, ObjectProperties.EVENT_INPUTS,
+                ObjectProperties.EVENT_OUTPUTS);
         insertPortChildren(controller, properties, parent);
     }
 
-
     /**
      * Helper used to create port children on a parent block.
      *
      * This method does not manage the model transaction and should be used to preset the children of a block out of an {@link XcosDiagram}.
      *
-     * @param controller is the shared controller instance
-     * @param properties specify the kind of port to insert and should be some of : <UL>
-     *        <LI>{@link ObjectProperties#INPUTS}
-     *        <LI>{@link ObjectProperties#OUTPUTS}
-     *        <LI>{@link ObjectProperties#EVENT_INPUTS}
-     *        <LI>{@link ObjectProperties#EVENT_OUTPUTS}
-     * @param parent is the parent {@link mxCell} to modify
+     * @param controller
+     *            is the shared controller instance
+     * @param properties
+     *            specify the kind of port to insert and should be some of :
+     *            <UL>
+     *            <LI>{@link ObjectProperties#INPUTS}
+     *            <LI>{@link ObjectProperties#OUTPUTS}
+     *            <LI>{@link ObjectProperties#EVENT_INPUTS}
+     *            <LI>{@link ObjectProperties#EVENT_OUTPUTS}
+     * @param parent
+     *            is the parent {@link mxCell} to modify
      */
     private static void insertPortChildren(final JavaController controller, final EnumSet<ObjectProperties> properties, final XcosCell parent) {
         for (ObjectProperties property : properties) {
@@ -373,13 +381,17 @@ public final class XcosCellFactory {
      *
      * This method does not manage the model transaction and should be used to preset the children of a block out of an {@link XcosDiagram}.
      *
-     * @param controller is the shared controller instance
-     * @param property specify the kind of port to insert and should be one of : <UL>
-     *        <LI>{@link ObjectProperties#INPUTS}
-     *        <LI>{@link ObjectProperties#OUTPUTS}
-     *        <LI>{@link ObjectProperties#EVENT_INPUTS}
-     *        <LI>{@link ObjectProperties#EVENT_OUTPUTS}
-     * @param parent is the parent {@link mxCell} to modify
+     * @param controller
+     *            is the shared controller instance
+     * @param property
+     *            specify the kind of port to insert and should be one of :
+     *            <UL>
+     *            <LI>{@link ObjectProperties#INPUTS}
+     *            <LI>{@link ObjectProperties#OUTPUTS}
+     *            <LI>{@link ObjectProperties#EVENT_INPUTS}
+     *            <LI>{@link ObjectProperties#EVENT_OUTPUTS}
+     * @param parent
+     *            is the parent {@link mxCell} to modify
      */
     private static void insertPortChildren(final JavaController controller, final ObjectProperties property, final XcosCell parent) {
         if (parent.getKind() != Kind.BLOCK) {
@@ -399,17 +411,21 @@ public final class XcosCellFactory {
     /**
      * Create a port for a specific uid
      *
-     * @param controller is the shared controller instance
-     * @param uid represent the allocated UID on the MVC
-     * @param property specify the kind of port to create and should be one of : <UL>
-     *        <LI>{@link ObjectProperties#INPUTS}
-     *        <LI>{@link ObjectProperties#OUTPUTS}
-     *        <LI>{@link ObjectProperties#EVENT_INPUTS}
-     *        <LI>{@link ObjectProperties#EVENT_OUTPUTS}
+     * @param controller
+     *            is the shared controller instance
+     * @param uid
+     *            represent the allocated UID on the MVC
+     * @param property
+     *            specify the kind of port to create and should be one of :
+     *            <UL>
+     *            <LI>{@link ObjectProperties#INPUTS}
+     *            <LI>{@link ObjectProperties#OUTPUTS}
+     *            <LI>{@link ObjectProperties#EVENT_INPUTS}
+     *            <LI>{@link ObjectProperties#EVENT_OUTPUTS}
      * @return a newly allocated port
      */
     private static final BasicPort createPort(final JavaController controller, long uid, final ObjectProperties property) {
-        boolean[] isImplicit = {false};
+        boolean[] isImplicit = { false };
 
         switch (property) {
             case INPUTS:
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/ScilabTypeCoder.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/ScilabTypeCoder.java
new file mode 100644 (file)
index 0000000..5f23f9c
--- /dev/null
@@ -0,0 +1,689 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2015 - Scilab Enterprises - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.scilab.modules.types.ScilabBoolean;
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabInteger;
+import org.scilab.modules.types.ScilabIntegerTypeEnum;
+import org.scilab.modules.types.ScilabList;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabTList;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.types.ScilabTypeEnum;
+import org.scilab.modules.xcos.VectorOfDouble;
+
+/**
+ * Encode and decode using a var2vec / vec2var compatible encoding.
+ *
+ * <p>
+ * This encoder is used to store arbitrary data to the model. Usually some properties are hard to map to both Java and C++ STL type system, using a shared encoding let us provide an implementation
+ * whatever the language is without sharing too low-level information.
+ */
+public class ScilabTypeCoder {
+
+    // MAGIC NUMBER inside
+    // directly stolen from internal.hxx to preserve the values
+    private static enum NativeScilabType {
+        ScilabNull, // no type, no data, nothing !
+        /* Internal Type */
+        ScilabInternal,
+        /* Generic Types */
+        ScilabGeneric,
+        ScilabInt8,
+        ScilabUInt8,
+        ScilabInt16,
+        ScilabUInt16,
+        ScilabInt32,
+        ScilabUInt32,
+        ScilabInt64,
+        ScilabUInt64,
+        ScilabString,
+        ScilabDouble,
+        ScilabBool,
+        ScilabFloat,
+        ScilabPolynom,
+        ScilabSinglePolynom,
+        /* Callable */
+        ScilabFunction,
+        ScilabMacro,
+        ScilabMacroFile,
+        /* Implicit List */
+        ScilabImplicitList,
+        /* Container */
+        ScilabContainer,
+        ScilabList,
+        ScilabTList,
+        ScilabMList,
+        ScilabSingleStruct,
+        ScilabStruct,
+        ScilabCell,
+        /* User */
+        ScilabUserType,
+        /* For list operation */
+        ScilabListOperation, // parent type
+        ScilabListInsertOperation,
+        ScilabListDeleteOperation,
+        ScilabListUndefinedOperation,
+        ScilabFile,
+        ScilabColon,
+        ScilabThreadId,
+        ScilabSparse,
+        ScilabSparseBool,
+        ScilabHandle,
+        ScilabVoid,
+        ScilabLibrary
+    }
+
+    class JavaScilabType {
+        final ScilabTypeEnum type;
+        final ScilabIntegerTypeEnum intType;
+
+        public JavaScilabType(ScilabTypeEnum type, ScilabIntegerTypeEnum intType) {
+            this.type = type;
+            this.intType = intType;
+        }
+    }
+
+    /** current position in the vec buffer */
+    int position = 0;
+
+    /** map a java type to native one */
+    private static WeakReference<Map<Integer, JavaScilabType>> weakTypeMap = new WeakReference<>(null);
+    private Map<Integer, JavaScilabType> typeMap;
+
+    public ScilabTypeCoder() {
+        typeMap = weakTypeMap.get();
+        if (typeMap == null) {
+            typeMap = new HashMap<>();
+            typeMap.put(NativeScilabType.ScilabDouble.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_matrix, null));
+            typeMap.put(NativeScilabType.ScilabInt8.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_int8));
+            typeMap.put(NativeScilabType.ScilabInt16.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_int16));
+            typeMap.put(NativeScilabType.ScilabInt32.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_int32));
+            typeMap.put(NativeScilabType.ScilabInt64.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_int64));
+            typeMap.put(NativeScilabType.ScilabUInt8.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_uint8));
+            typeMap.put(NativeScilabType.ScilabUInt16.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_uint16));
+            typeMap.put(NativeScilabType.ScilabUInt32.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_uint32));
+            typeMap.put(NativeScilabType.ScilabUInt64.ordinal(), new JavaScilabType(ScilabTypeEnum.sci_ints, ScilabIntegerTypeEnum.sci_uint64));
+
+            weakTypeMap = new WeakReference<Map<Integer, JavaScilabType>>(typeMap);
+        }
+    }
+
+    /*
+     * var2vec implementation
+     */
+
+    /**
+     * Encode any scilab type to a buffer
+     *
+     * @param var
+     *            the Scilab value to encode
+     * @return the encoded buffer
+     */
+    public VectorOfDouble var2vec(ScilabType var) {
+        final ScilabType value;
+        if (var == null) {
+            value = new ScilabDouble();
+        } else {
+            value = var;
+        }
+
+        return encode(value, new VectorOfDouble());
+    }
+
+    @SuppressWarnings("unchecked")
+    private VectorOfDouble encode(ScilabType var, VectorOfDouble vec) {
+        switch (var.getType()) {
+            case sci_matrix:
+                encode((ScilabDouble) var, vec);
+                break;
+            case sci_ints:
+                encode((ScilabInteger) var, vec);
+                break;
+            case sci_boolean:
+                encode((ScilabBoolean) var, vec);
+                break;
+            case sci_strings:
+                encode((ScilabString) var, vec);
+                break;
+            case sci_list:
+                encode((ArrayList<ScilabType>) var, vec);
+                break;
+            case sci_mlist:
+                encode((ArrayList<ScilabType>) var, vec);
+                break;
+            case sci_tlist:
+                encode((ArrayList<ScilabType>) var, vec);
+                break;
+            default:
+                break;
+        }
+
+        return vec;
+    }
+
+    /**
+     * Encode the double data
+     *
+     * @param var
+     *            the data to encode
+     * @param vec
+     *            the resulting buffer
+     */
+    private void encode(ScilabDouble var, VectorOfDouble vec) {
+        // Header
+        encodeHeader(var, vec, NativeScilabType.ScilabDouble);
+
+        // specific flag for managing the complex case
+        if (var.isReal()) {
+            vec.add(0);
+        } else {
+            vec.add(1);
+        }
+
+        // push the data
+        for (int i = 0; i < var.getHeight(); i++)
+            for (int j = 0; j < var.getWidth(); j++) {
+                vec.add(var.getRealElement(i, j));
+            }
+
+        // push the complex data
+        if (!var.isReal())
+            for (int i = 0; i < var.getHeight(); i++)
+                for (int j = 0; j < var.getWidth(); j++) {
+                    vec.add(var.getImaginaryElement(i, j));
+                }
+    }
+
+    private void encode(ScilabInteger var, VectorOfDouble vec) {
+        // pre-processing: native type identifier
+        final NativeScilabType detected;
+        switch (var.getPrec()) {
+            case sci_int16:
+                detected = NativeScilabType.ScilabInt16;
+                break;
+            case sci_int32:
+                detected = NativeScilabType.ScilabInt32;
+                break;
+            case sci_int64:
+                detected = NativeScilabType.ScilabInt64;
+                break;
+            case sci_int8:
+                detected = NativeScilabType.ScilabInt8;
+                break;
+            case sci_uint16:
+                detected = NativeScilabType.ScilabUInt16;
+                break;
+            case sci_uint32:
+                detected = NativeScilabType.ScilabUInt32;
+                break;
+            case sci_uint64:
+                detected = NativeScilabType.ScilabUInt64;
+                break;
+            case sci_uint8:
+                detected = NativeScilabType.ScilabUInt8;
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+
+        // pre-processing: retrieve the raw data per type
+        int sizeof;
+        long[][] longData = null;
+        short[][] shortData = null;
+        int[][] intData = null;
+        byte[][] byteData = null;
+        switch (var.getPrec()) {
+            case sci_int64:
+            case sci_uint64:
+                sizeof = Long.BYTES;
+                longData = var.getDataAsLong();
+                break;
+            case sci_int32:
+            case sci_uint32:
+                sizeof = Integer.BYTES;
+                intData = var.getDataAsInt();
+                break;
+            case sci_int16:
+            case sci_uint16:
+                sizeof = Short.BYTES;
+                shortData = var.getDataAsShort();
+                break;
+            case sci_int8:
+            case sci_uint8:
+                sizeof = Byte.BYTES;
+                byteData = var.getDataAsByte();
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+
+        // Header
+        encodeHeader(var, vec, detected);
+
+        // push the data on a pre-allocated space
+        final int requiredBytes = sizeof * var.getHeight() * var.getWidth();
+        final int doubleLen = (requiredBytes + Double.BYTES - 1) / Double.BYTES;
+        final int position = vec.size();
+        vec.resize(position + doubleLen);
+        ByteBuffer view = vec.asByteBuffer(position, doubleLen);
+
+        for (int i = 0; i < var.getHeight(); i++) {
+            for (int j = 0; j < var.getWidth(); j++) {
+                switch (var.getPrec()) {
+                    case sci_int64:
+                    case sci_uint64:
+                        view.putLong(longData[i][j]);
+                        break;
+                    case sci_int32:
+                    case sci_uint32:
+                        view.putInt(intData[i][j]);
+                        break;
+                    case sci_int16:
+                    case sci_uint16:
+                        view.putShort(shortData[i][j]);
+                        break;
+                    case sci_int8:
+                    case sci_uint8:
+                        view.put(byteData[i][j]);
+                        break;
+                }
+            }
+        }
+    }
+
+    private void encode(ScilabBoolean var, VectorOfDouble vec) {
+        // header
+        encodeHeader(var, vec, NativeScilabType.ScilabBool);
+
+        // put all the boolean as int accordingly to Scilab 6 implementation
+        final int requiredBytes = Integer.BYTES * var.getHeight() * var.getWidth();
+        final int doubleLen = (requiredBytes + Double.BYTES - 1) / Double.BYTES;
+        int position = vec.size();
+        vec.resize(position + doubleLen);
+
+        ByteBuffer buffer = vec.asByteBuffer(position, doubleLen);
+
+        for (int i = 0; i < var.getHeight(); i++) {
+            for (int j = 0; j < var.getWidth(); j++) {
+                buffer.putInt(var.getData()[i][j] ? 1 : 0);
+            }
+        }
+    }
+
+    private void encode(ScilabString var, VectorOfDouble vec) {
+        // header
+        encodeHeader(var, vec, NativeScilabType.ScilabString);
+
+        // add the offset table which contains the offset of each UTF-8 encoded strings
+        int offsetTableStart = vec.size();
+        vec.resize(offsetTableStart + var.getHeight() * var.getWidth());
+
+        // encode the strings as UTF-8 and store the associated offset
+        for (int i = 0; i < var.getHeight(); i++) {
+            for (int j = 0; j < var.getWidth(); j++) {
+                String str = var.getData()[i][j];
+                byte[] bytes = str.getBytes(Charset.forName("UTF-8"));
+                // append the terminal '\0'
+                final int requiredBytes = ((bytes.length + 1) * Byte.BYTES);
+                final int doubleLen = (requiredBytes + Double.BYTES - 1) / Double.BYTES;
+
+                // set the offset
+                vec.set(offsetTableStart++, doubleLen);
+
+                // push the data through a temporary byte buffer
+                int position = vec.size();
+                vec.resize(position + doubleLen);
+                vec.asByteBuffer(position, doubleLen).put(bytes);
+            }
+        }
+    }
+
+    private void encode(ArrayList<ScilabType> var, VectorOfDouble vec) {
+        // header
+        encodeHeader(var, vec, NativeScilabType.ScilabList);
+
+        // encode list content
+        for (ScilabType localVar : var) {
+            encode(localVar, vec);
+        }
+    }
+
+    /**
+     * Helper method to add an header of the detected type
+     *
+     * @param var
+     *            the scilab matrix type to encode
+     * @param vec
+     *            the raw encoded data container
+     * @param detected
+     *            the detected type
+     */
+    @SuppressWarnings({ "unchecked", "fallthrough" })
+    private void encodeHeader(Object var, VectorOfDouble vec, final NativeScilabType detected) {
+        ScilabType matrix = null;
+        ArrayList<ScilabType> list = null;
+        Map<String, ScilabType> map = null;
+
+        // defensive programming
+        switch (detected) {
+            case ScilabDouble:
+            case ScilabBool:
+            case ScilabInt8:
+            case ScilabInt16:
+            case ScilabInt32:
+            case ScilabInt64:
+            case ScilabUInt8:
+            case ScilabUInt16:
+            case ScilabUInt32:
+            case ScilabUInt64:
+            case ScilabString:
+                matrix = (ScilabType) var;
+                break;
+            case ScilabList:
+            case ScilabMList:
+            case ScilabTList:
+                list = (ArrayList<ScilabType>) var;
+                break;
+
+            case ScilabStruct:
+                map = (Map<String, ScilabType>) var;
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+
+        vec.add(detected.ordinal());
+        if (matrix != null) {
+            vec.add(2);
+            vec.add(matrix.getWidth());
+            vec.add(matrix.getHeight());
+        } else if (list != null) {
+            vec.add(list.size());
+        } else if (map != null) {
+            throw new IllegalStateException();
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /*
+     * vec2var implementation
+     */
+
+    /**
+     * Decode a scilab type from a buffer
+     *
+     * @param vec
+     *            the buffer containing encoded scilab types
+     * @return the decoded scilab type
+     */
+    public ScilabType vec2var(VectorOfDouble vec) {
+        position = 0;
+
+        ScilabType var = decodeHeader(vec);
+        return decode(vec, var);
+    }
+
+    @SuppressWarnings("unchecked")
+    private ScilabType decode(VectorOfDouble vec, ScilabType var) {
+        switch (var.getType()) {
+            case sci_matrix:
+                decode(vec, (ScilabDouble) var);
+                break;
+            case sci_ints:
+                decode(vec, (ScilabInteger) var);
+                break;
+            case sci_boolean:
+                decode(vec, (ScilabBoolean) var);
+                break;
+            case sci_strings:
+                decode(vec, (ScilabString) var);
+                break;
+            case sci_list:
+                decode(vec, (ArrayList<ScilabType>) var);
+                break;
+            case sci_mlist:
+                decode(vec, (ArrayList<ScilabType>) var);
+                break;
+            case sci_tlist:
+                decode(vec, (ArrayList<ScilabType>) var);
+                break;
+            default:
+                break;
+        }
+        return var;
+    }
+
+    private ScilabType decode(VectorOfDouble vec, ScilabDouble var) {
+        double[][] realPart = var.getRealPart();
+        for (int i = 0; i < var.getHeight(); i++)
+            for (int j = 0; j < var.getWidth(); j++) {
+                realPart[i][j] = vec.get(position++);
+            }
+
+        if (!var.isReal()) {
+            double[][] imaginaryPart = var.getImaginaryPart();
+
+            for (int i = 0; i < var.getHeight(); i++)
+                for (int j = 0; j < var.getWidth(); j++) {
+                    imaginaryPart[i][j] = vec.get(position++);
+                }
+        }
+        return var;
+    }
+
+    private ScilabType decode(VectorOfDouble vec, ScilabInteger var) {
+        final int sizeof;
+        long[][] longData = null;
+        short[][] shortData = null;
+        int[][] intData = null;
+        byte[][] byteData = null;
+
+        switch (var.getPrec()) {
+            case sci_int64:
+            case sci_uint64:
+                sizeof = Long.BYTES;
+                longData = var.getDataAsLong();
+                break;
+            case sci_int32:
+            case sci_uint32:
+                sizeof = Integer.BYTES;
+                intData = var.getDataAsInt();
+                break;
+            case sci_int16:
+            case sci_uint16:
+                sizeof = Short.BYTES;
+                shortData = var.getDataAsShort();
+                break;
+            case sci_int8:
+            case sci_uint8:
+                sizeof = Byte.BYTES;
+                byteData = var.getDataAsByte();
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+
+        final int doubleLen = (sizeof * var.getHeight() * var.getWidth()) / Double.BYTES + 1;
+        ByteBuffer view = vec.asByteBuffer(position, doubleLen);
+
+        for (int i = 0; i < var.getHeight(); i++) {
+            for (int j = 0; j < var.getWidth(); j++) {
+                switch (var.getPrec()) {
+                    case sci_int64:
+                    case sci_uint64:
+                        longData[i][j] = view.getLong();
+                        break;
+                    case sci_int32:
+                    case sci_uint32:
+                        intData[i][j] = view.getInt();
+                        break;
+                    case sci_int16:
+                    case sci_uint16:
+                        shortData[i][j] = view.getShort();
+                        break;
+                    case sci_int8:
+                    case sci_uint8:
+                        byteData[i][j] = view.get();
+                        break;
+                }
+            }
+        }
+        position += doubleLen;
+
+        return var;
+    }
+
+    private ScilabType decode(VectorOfDouble vec, ScilabBoolean var) {
+        final boolean[][] data = var.getData();
+
+        final int doubleLen = (Integer.BYTES * var.getHeight() * var.getWidth()) / Double.BYTES + 1;
+        ByteBuffer view = vec.asByteBuffer(position, doubleLen);
+
+        for (int i = 0; i < var.getHeight(); i++) {
+            for (int j = 0; j < var.getWidth(); j++) {
+                data[i][j] = view.getInt() != 0;
+            }
+        }
+        position += doubleLen;
+        return var;
+    }
+
+    private ScilabType decode(VectorOfDouble vec, ScilabString var) {
+        final String[][] data = var.getData();
+
+        // reconstruct the offset
+        int[][] offset = new int[var.getHeight()][var.getWidth()];
+        for (int i = 0; i < var.getHeight(); i++) {
+            for (int j = 0; j < var.getWidth(); j++) {
+                offset[i][j] = (int) vec.get(position++);
+            }
+        }
+
+        // reconstruct each String object
+        try {
+            for (int i = 0; i < var.getHeight(); i++) {
+                for (int j = 0; j < var.getWidth(); j++) {
+                    ByteBuffer view = vec.asByteBuffer(position, offset[i][j]);
+                    byte[] bytes = new byte[offset[i][j] * Double.BYTES];
+
+                    view.get(bytes);
+                    data[i][j] = new String(bytes, "UTF-8");
+
+                    position += offset[i][j];
+                }
+            }
+        } catch (UnsupportedEncodingException e) {
+            // ignore as UTF-8 is always available
+        }
+        return var;
+    }
+
+    private ScilabType decode(VectorOfDouble vec, ArrayList<ScilabType> var) {
+        for (int i = 0; i < var.size(); i++) {
+            var.set(i, vec2var(vec));
+        }
+        return (ScilabType) var;
+    }
+
+    @SuppressWarnings("fallthrough")
+    private ScilabType decodeHeader(VectorOfDouble vec) {
+        int nativeScilabType = (int) vec.get(position++);
+
+        // for data[][]-based type
+        int height = 0;
+        int width = 0;
+
+        // for ArrayList-based type
+        int listLen = 0;
+
+        final JavaScilabType type = typeMap.get(nativeScilabType);
+        switch (type.type) {
+            case sci_matrix:
+            case sci_boolean:
+            case sci_ints:
+            case sci_strings:
+                height = (int) vec.get(position++);
+                width = (int) vec.get(position++);
+                break;
+            case sci_list:
+            case sci_mlist:
+            case sci_tlist:
+                listLen = (int) vec.get(position++);
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+
+        // special case for complex double matrix
+        double[][] imagData = null;
+        if (type.type == ScilabTypeEnum.sci_matrix) {
+            boolean isComplex = vec.get(position++) != 0;
+
+            if (isComplex) {
+                imagData = new double[height][width];
+            }
+        }
+
+        // allocate the right type with the decoded properties
+        switch (type.type) {
+            case sci_matrix:
+                return new ScilabDouble(new double[height][width], imagData);
+            case sci_boolean:
+                return new ScilabBoolean(new boolean[height][width]);
+            case sci_ints:
+                switch (type.intType) {
+                    case sci_int8:
+                        return new ScilabInteger(new byte[height][width], false);
+                    case sci_int16:
+                        return new ScilabInteger(new short[height][width], false);
+                    case sci_int32:
+                        return new ScilabInteger(new int[height][width], false);
+                    case sci_int64:
+                        return new ScilabInteger(new long[height][width], false);
+                    case sci_uint8:
+                        return new ScilabInteger(new byte[height][width], true);
+                    case sci_uint16:
+                        return new ScilabInteger(new short[height][width], true);
+                    case sci_uint32:
+                        return new ScilabInteger(new int[height][width], true);
+                    case sci_uint64:
+                        return new ScilabInteger(new long[height][width], true);
+
+                }
+            case sci_strings:
+                return new ScilabString(new String[height][width]);
+            case sci_list:
+                return new ScilabList(Collections.nCopies(listLen, null));
+            case sci_mlist:
+                return new ScilabMList(new String[listLen], Collections.nCopies(listLen, null));
+            case sci_tlist:
+                return new ScilabTList(new String[listLen], Collections.nCopies(listLen, null));
+            default:
+                throw new IllegalArgumentException();
+
+        }
+    }
+}
index 5a6a4e8..b8b00ec 100644 (file)
@@ -37,7 +37,6 @@ import org.w3c.dom.NodeList;
 
 import com.mxgraph.io.mxCodec;
 import com.mxgraph.io.mxCodecRegistry;
-import com.mxgraph.model.mxCell;
 import com.mxgraph.model.mxGraphModel;
 import com.mxgraph.model.mxICell;
 
@@ -84,8 +83,7 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
      * @param exclude
      *            Optional array of fieldnames to be ignored.
      * @param idrefs
-     *            Optional array of fieldnames to be converted to/from
-     *            references.
+     *            Optional array of fieldnames to be converted to/from references.
      * @param mapping
      *            Optional mapping from field- to attributenames.
      */
@@ -99,9 +97,11 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
     public static void register() {
         JavaController controller = new JavaController();
 
-        ScilabGraphCodec diagramCodec = new XcosDiagramCodec(new XcosDiagram(controller.createObject(Kind.DIAGRAM), Kind.DIAGRAM), DIAGRAM_IGNORED_FIELDS, null, null);
+        ScilabGraphCodec diagramCodec = new XcosDiagramCodec(new XcosDiagram(controller.createObject(Kind.DIAGRAM), Kind.DIAGRAM), DIAGRAM_IGNORED_FIELDS, null,
+                null);
         mxCodecRegistry.register(diagramCodec);
-        ScilabGraphCodec superBlockDiagramCodec = new XcosDiagramCodec(new XcosDiagram(controller.createObject(Kind.BLOCK), Kind.BLOCK), SUPERBLOCKDIAGRAM_IGNORED_FIELDS, null, null);
+        ScilabGraphCodec superBlockDiagramCodec = new XcosDiagramCodec(new XcosDiagram(controller.createObject(Kind.BLOCK), Kind.BLOCK),
+                SUPERBLOCKDIAGRAM_IGNORED_FIELDS, null, null);
         mxCodecRegistry.register(superBlockDiagramCodec);
     }
 
@@ -120,9 +120,7 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
      *            Value of the property to be encoded.
      * @param node
      *            XML node that contains the encoded object.
-     * @see com.mxgraph.io.mxObjectCodec#encodeValue(com.mxgraph.io.mxCodec,
-     *      java.lang.Object, java.lang.String, java.lang.Object,
-     *      org.w3c.dom.Node)
+     * @see com.mxgraph.io.mxObjectCodec#encodeValue(com.mxgraph.io.mxCodec, java.lang.Object, java.lang.String, java.lang.Object, org.w3c.dom.Node)
      */
     @Override
     protected void encodeValue(mxCodec enc, Object obj, String fieldname, Object value, Node node) {
@@ -178,15 +176,14 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
      *            the {@link Current} field name
      * @param value
      *            the current field value
-     * @see com.mxgraph.io.mxObjectCodec#setFieldValue(java.lang.Object,
-     *      java.lang.String, java.lang.Object)
+     * @see com.mxgraph.io.mxObjectCodec#setFieldValue(java.lang.Object, java.lang.String, java.lang.Object)
      */
     @Override
     protected void setFieldValue(Object obj, String fieldname, Object value) {
         Field field;
         try {
             field = ScicosParameters.class.getDeclaredField(fieldname);
-            ScicosParameters params = ((XcosDiagram) obj).getScicosParameters();
+            ScicosParameters params = new ScicosParameters(((XcosDiagram) obj).getUID(), ((XcosDiagram) obj).getKind());
             super.setFieldValue(params, fieldname, value);
         } catch (SecurityException e) {
             field = null;
@@ -201,14 +198,7 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
             mxICell root = (mxICell) diag.getModel().getRoot();
 
             /*
-             * Restore the initial hierarchy
-             *  mxCell -> root
-             *   XcosCell -> default parent with diagram uid / kind
-             *    BasicBlock
-             *    BasicLink
-             *    .
-             *    .
-             *    .
+             * Restore the initial hierarchy mxCell -> root XcosCell -> default parent with diagram uid / kind BasicBlock BasicLink . . .
              */
 
             Object[] cells = diag.getChildCells(value);
@@ -224,14 +214,12 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
     }
 
     /**
-     * {@inheritDoc}
-     * <BR>
+     * {@inheritDoc} <BR>
      * <BR>
      * <B>UPDATED TO COVER</B>
      *
      * <UL>
-     * <LI>Strip out any node with an invalid parent id. (5.3.1 diagrams may
-     * contains invalid default parents, remove them.)</LI>
+     * <LI>Strip out any node with an invalid parent id. (5.3.1 diagrams may contains invalid default parents, remove them.)</LI>
      * <LI>Remove cell where id end with "#identifier#identifier"</LI>
      * </UL>
      */
@@ -300,15 +288,14 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
      * @param node
      *            the cureent node
      * @return the updated object
-     * @see org.scilab.modules.graph.io.ScilabGraphCodec#beforeEncode(com.mxgraph.io.mxCodec,
-     *      java.lang.Object, org.w3c.dom.Node)
+     * @see org.scilab.modules.graph.io.ScilabGraphCodec#beforeEncode(com.mxgraph.io.mxCodec, java.lang.Object, org.w3c.dom.Node)
      */
     @Override
     public Object beforeEncode(mxCodec enc, Object obj, Node node) {
         final Package p = Package.getPackage("org.scilab.modules.xcos");
 
-        trace(enc, node, new StringBuilder().append(Xcos.TRADENAME).append(SEP).append(Xcos.VERSION).append(SEP).append(p.getSpecificationVersion())
-              .append(SEP).append(p.getImplementationVersion()).toString());
+        trace(enc, node, new StringBuilder().append(Xcos.TRADENAME).append(SEP).append(Xcos.VERSION).append(SEP).append(p.getSpecificationVersion()).append(SEP)
+              .append(p.getImplementationVersion()).toString());
 
         return super.beforeEncode(enc, obj, node);
     }
@@ -323,8 +310,7 @@ public class XcosDiagramCodec extends ScilabGraphCodec {
      * @param obj
      *            Object decoded.
      * @return The Object transformed
-     * @see org.scilab.modules.graph.io.ScilabGraphCodec#afterDecode(com.mxgraph.io.mxCodec,
-     *      org.w3c.dom.Node, java.lang.Object)
+     * @see org.scilab.modules.graph.io.ScilabGraphCodec#afterDecode(com.mxgraph.io.mxCodec, org.w3c.dom.Node, java.lang.Object)
      */
     @Override
     public Object afterDecode(mxCodec dec, Node node, Object obj) {
index 13acb9f..44b4b66 100644 (file)
@@ -37,12 +37,16 @@ class CustomHandler implements ScilabHandler {
 
     /**
      * Default constructor
-     * @param saxHandler the shared sax handler
+     *
+     * @param saxHandler
+     *            the shared sax handler
      */
     CustomHandler(SAXHandler saxHandler) {
         this.saxHandler = saxHandler;
     }
 
+    @Override
+    @SuppressWarnings({ "fallthrough" })
     public Object startElement(HandledElement found, final Attributes atts) {
         long uid = 0l;
         String v;
@@ -160,6 +164,7 @@ class CustomHandler implements ScilabHandler {
         }
     }
 
+    @Override
     public void endElement(HandledElement found) {
         switch (found) {
             case Orientation:
index 3dc14d7..675ea4d 100644 (file)
@@ -28,6 +28,7 @@ class JGraphXHandler implements ScilabHandler {
         this.saxHandler = saxHandler;
     }
 
+    @Override
     public Object startElement(HandledElement found, Attributes atts) {
         String v;
 
@@ -99,6 +100,7 @@ class JGraphXHandler implements ScilabHandler {
         }
     }
 
+    @Override
     public void endElement(HandledElement found) {
         switch (found) {
             case mxCell:
@@ -116,6 +118,7 @@ class JGraphXHandler implements ScilabHandler {
 
                 cell.setGeometry(g);
             }
+            break;
             case mxPoint:
                 break;
             default:
index 6fa67a0..a2d2ded 100644 (file)
@@ -29,8 +29,12 @@ import org.scilab.modules.types.ScilabType;
 import org.scilab.modules.xcos.ObjectProperties;
 import org.scilab.modules.xcos.VectorOfDouble;
 import org.scilab.modules.xcos.VectorOfString;
+import org.scilab.modules.xcos.graph.XcosDiagram;
 import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
 import org.scilab.modules.xcos.graph.model.XcosCell;
+import org.scilab.modules.xcos.io.ScilabTypeCoder;
+import org.scilab.modules.xcos.io.scicos.DiagramElement;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException;
 import org.xml.sax.Attributes;
 
 import com.mxgraph.model.mxGeometry;
@@ -62,7 +66,9 @@ class RawDataHandler implements ScilabHandler {
 
     /**
      * Default constructor
-     * @param saxHandler the shared sax handler
+     *
+     * @param saxHandler
+     *            the shared sax handler
      */
     RawDataHandler(SAXHandler saxHandler) {
         this.saxHandler = saxHandler;
@@ -87,6 +93,7 @@ class RawDataHandler implements ScilabHandler {
      * Implement the ScilabHandler interface to decode the data
      */
 
+    @Override
     public Object startElement(HandledElement found, Attributes atts) {
         String v;
 
@@ -256,6 +263,7 @@ class RawDataHandler implements ScilabHandler {
                     default:
                         break;
                 }
+                break;
             }
             default:
                 throw new IllegalArgumentException();
@@ -266,13 +274,20 @@ class RawDataHandler implements ScilabHandler {
 
     /**
      * Allocate a {@link ScilabType} datatype accordingly to the decoded descriptors
-     * @param found the decoded element
-     * @param atts the attributes of the element
-     * @param height decoded height
-     * @param width decoded width
-     * @param scilabClass decoded scilabClass
+     *
+     * @param found
+     *            the decoded element
+     * @param atts
+     *            the attributes of the element
+     * @param height
+     *            decoded height
+     * @param width
+     *            decoded width
+     * @param scilabClass
+     *            decoded scilabClass
      * @return the container
      */
+    @SuppressWarnings("fallthrough")
     private Object allocateDataType(HandledElement found, Attributes atts, int height, int width, String scilabClass) {
         String v;
         final Object container;
@@ -338,6 +353,7 @@ class RawDataHandler implements ScilabHandler {
         return container;
     }
 
+    @Override
     public void endElement(HandledElement found) {
         switch (found) {
             case Array:
@@ -385,6 +401,7 @@ class RawDataHandler implements ScilabHandler {
                         saxHandler.controller.setObjectProperty(diagram.getUID(), diagram.getKind(), ObjectProperties.DIAGRAM_CONTEXT, ctx);
                         break;
                     }
+                    case STATE:
                     case DSTATE:
                     case NZCROSS:
                     case NMODE:
@@ -395,8 +412,13 @@ class RawDataHandler implements ScilabHandler {
                             return;
                         }
                         XcosCell cell = (XcosCell) parent;
-                        if (!(fieldValue.value instanceof ScilabDouble)) {
-                            // FIXME decode the rpar as a subdiagram using the legacy decoders
+                        if (fieldValue.value instanceof ScilabMList) {
+                            // CORNER CASE for partially decoded sub-diagram hierarchy
+                            // decode the rpar as a subdiagram using the legacy decoders
+                            try {
+                                new DiagramElement(saxHandler.controller).decode((ScilabMList) fieldValue.value, new XcosDiagram(cell.getUID(), cell.getKind()));
+                            } catch (ScicosFormatException e) {
+                            }
                             return;
                         }
                         ScilabDouble value = (ScilabDouble) fieldValue.value;
@@ -409,18 +431,18 @@ class RawDataHandler implements ScilabHandler {
                         saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), ObjectProperties.RPAR, vec);
                         break;
                     }
+                    case EXPRS:
                     case EQUATIONS:
+                    case OPAR:
                     case ODSTATE: {
                         // defensive programming
                         if (!(parent instanceof XcosCell)) {
                             return;
                         }
                         XcosCell cell = (XcosCell) parent;
-                        ScilabList value = (ScilabList) fieldValue.value;
+                        ScilabType value = (ScilabType) fieldValue.value;
 
-                        if (value.size() > 0) {
-                            System.err.println("RawDataHandler value not decoded: " + fieldValue.as);
-                        }
+                        saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), fieldValue.as, new ScilabTypeCoder().var2vec(value));
                         break;
                     }
                     default:
@@ -437,70 +459,4 @@ class RawDataHandler implements ScilabHandler {
                 throw new IllegalArgumentException();
         }
     }
-
-    /*
-     * Convert the decoded data to a var2vec encoded value
-     */
-
-    private static void addMatrixHeader(VectorOfDouble vec, ScilabType var) {
-        vec.add(var.getType().swigValue());
-        vec.add(2); // we do not manage hypermatrices yet
-        vec.add(var.getHeight());
-        vec.add(var.getWidth());
-    }
-
-    public static VectorOfDouble var2vec(VectorOfDouble vec, ScilabBoolean var) {
-        addMatrixHeader(vec, var);
-
-
-        return vec;
-    }
-
-    public static VectorOfDouble var2vec(VectorOfDouble vec, ScilabDouble var) {
-        addMatrixHeader(vec, var);
-
-        // FIXME encode the values
-
-        return vec;
-    }
-
-    public static VectorOfDouble var2vec(VectorOfDouble vec, ScilabInteger var) {
-        addMatrixHeader(vec, var);
-
-        // FIXME encode the values
-
-        return vec;
-    }
-
-    public static VectorOfDouble var2vec(VectorOfDouble vec, ScilabString var) {
-        addMatrixHeader(vec, var);
-
-        // FIXME encode the values
-
-        return vec;
-    }
-
-    public static VectorOfDouble var2vec(VectorOfDouble vec, ScilabList var) {
-
-
-        // FIXME encode the values
-
-        return vec;
-    }
-
-    public static VectorOfDouble var2vec(VectorOfDouble vec, ScilabTList var) {
-
-
-        // FIXME encode the values
-
-        return vec;
-    }
-
-    public static VectorOfDouble var2vec(VectorOfDouble vec, ScilabMList var) {
-
-
-        // FIXME encode the values
-
-        return vec;
-    }
 }
\ No newline at end of file
index 5f47a95..6e49912 100644 (file)
@@ -16,6 +16,7 @@ import org.scilab.modules.types.ScilabDouble;
 import org.scilab.modules.types.ScilabList;
 import org.scilab.modules.types.ScilabString;
 import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
 
 /**
  * Root implementation for any Element.
@@ -27,10 +28,14 @@ import org.scilab.modules.types.ScilabType;
  *
  */
 public abstract class AbstractElement<T> implements Element<T> {
+    final JavaController controller;
+
     /**
      * Default constructor
+     * @param controller the shared controller
      */
-    protected AbstractElement() {
+    protected AbstractElement(final JavaController controller) {
+        this.controller = controller;
     }
 
     /**
@@ -66,6 +71,20 @@ public abstract class AbstractElement<T> implements Element<T> {
     };
 
     /**
+     * Disable the encode for all sub-classes by encoding nothing
+     *
+     * @param from the associated Java object
+     * @param element a scilab type to encode
+     * @param from
+     *            the source instance
+     * @return the element parameter
+     */
+    @Override
+    public ScilabType encode(T from, ScilabType element) {
+        return element;
+    }
+
+    /**
      * Default implementation is empty.
      *
      * @param from
index d4be8a1..fd59670 100644 (file)
@@ -27,8 +27,7 @@ import org.scilab.modules.xcos.port.Orientation;
 import com.mxgraph.model.mxICell;
 
 /**
- * Convert BasicBlock pure objects to a mixed BasicBlock objects (update the
- * scicos information)
+ * Convert BasicBlock pure objects to a mixed BasicBlock objects (update the scicos information)
  */
 public final class BasicBlockInfo {
     /**
@@ -44,7 +43,7 @@ public final class BasicBlockInfo {
      *            the ports
      * @return array of links id
      */
-    protected static ScilabDouble getAllLinkId(List <? extends BasicPort > ports) {
+    protected static ScilabDouble getAllLinkId(List<? extends BasicPort> ports) {
         if (ports.isEmpty()) {
             return new ScilabDouble();
         }
@@ -110,6 +109,38 @@ public final class BasicBlockInfo {
     }
 
     /**
+     * Get the n-th port for a n position.
+     *
+     * This method assume that the port are sorted and that the {@link BasicPort#getOrdering()} is filled with the right value.
+     *
+     * @param block
+     *            the block
+     * @param position
+     *            the position to look for
+     * @return a list of applicable ports
+     */
+    public static List<BasicPort> getAllPortsAtPosition(final BasicBlock block, final int position) {
+        final List<BasicPort> data = new ArrayList<BasicPort>();
+        if (block == null) {
+            return data;
+        }
+
+        final int childrenCount = block.getChildCount();
+        for (int i = 0; i < childrenCount; ++i) {
+            final mxICell cell = block.getChildAt(i);
+            if (cell instanceof BasicPort) {
+                final BasicPort p = ((BasicPort) cell);
+                // FIXME is it really needed
+                // if (p.getOrdering() == position) {
+                data.add(p);
+                // }
+            }
+        }
+
+        return data;
+    }
+
+    /**
      * Get the associated port ordered by orientation.
      *
      * @param block
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockElement.java
new file mode 100644 (file)
index 0000000..6dd95e0
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import static java.util.Arrays.asList;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabList;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.Kind;
+import org.scilab.modules.xcos.ObjectProperties;
+import org.scilab.modules.xcos.block.BasicBlock;
+import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.graph.model.BlockInterFunction;
+import org.scilab.modules.xcos.graph.model.XcosCellFactory;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongElementException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
+import org.scilab.modules.xcos.port.BasicPort;
+
+/**
+ * Perform a block transformation between Scicos and Xcos.
+ */
+// CSOFF: ClassDataAbstractionCoupling
+// CSOFF: ClassFanOutComplexity
+public final class BlockElement extends AbstractElement<BasicBlock> {
+    protected static final List<String> DATA_FIELD_NAMES = asList("Block", "graphics", "model", "gui", "doc");
+
+    private static final int INTERFUNCTION_INDEX = DATA_FIELD_NAMES.indexOf("gui");
+
+    /** Mutable field to easily get the data through methods */
+    private ScilabMList data;
+
+    /** Element used to decode/encode Scicos model part into a BasicBlock */
+    private final BlockModelElement modelElement;
+
+    /** Element used to decode/encode Scicos model part into a BasicBlock */
+    private final BlockGraphicElement graphicElement;
+
+    /*
+     * Decoder state
+     */
+
+    /**
+     * Current block ordering, the ordering change on each {@link BlockElement} instance so be careful when allocated a new {@link BlockElement}.
+     */
+    private int ordering;
+    private HashMap<Long, Integer> orderingMap;
+
+    /**
+     * Default constructor.
+     *
+     * The state change on each {@link BlockElement} instance so be careful when allocated a new {@link BlockElement}.
+     */
+    public BlockElement(final JavaController controller, final XcosDiagram diag) {
+        super(controller);
+
+        modelElement = new BlockModelElement(controller, diag);
+        graphicElement = new BlockGraphicElement(controller, diag);
+
+        ordering = 0;
+        orderingMap = new HashMap<>();
+    }
+
+    /**
+     * Decode the element into the block.
+     *
+     * @param element
+     *            The current Scilab data
+     * @param into
+     *            the target, if null a new instance is allocated and returned.
+     * @return the decoded block.
+     * @throws ScicosFormatException
+     *             when e decoding error occurred.
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    @Override
+    public BasicBlock decode(ScilabType element, BasicBlock into) throws ScicosFormatException {
+        data = (ScilabMList) element;
+        BasicBlock block = into;
+
+        validate();
+
+        /*
+         * Instantiate the block if it doesn't exist. Do not invoke scilab here on purpose to avoid threading issues
+         */
+        final String interfunction = ((ScilabString) data.get(INTERFUNCTION_INDEX)).getData()[0][0];
+        if (block == null) {
+            BlockInterFunction func = XcosCellFactory.lookForInterfunction(interfunction);
+            block = XcosCellFactory.createBlock(controller, func, interfunction, controller.createObject(Kind.BLOCK));
+        }
+
+        block = beforeDecode(element, block);
+
+        /*
+         * Allocate and setup ports
+         */
+        InputPortElement inElement = new InputPortElement(controller, data);
+        final int numberOfInputPorts = inElement.getNumberOfInputPort();
+        for (int i = 0; i < numberOfInputPorts; i++) {
+            final BasicPort port = inElement.decode(data, null);
+
+            // do not use BasicPort#addPort() to avoid the view update
+            block.insert(port, i);
+        }
+
+        OutputPortElement outElement = new OutputPortElement(controller, data);
+        final int numberOfOutputPorts = outElement.getNumberOfOutputPort();
+        for (int i = 0; i < numberOfOutputPorts; i++) {
+            final BasicPort port = outElement.decode(data, null);
+
+            // do not use BasicPort#addPort() to avoid the view update
+            block.insert(port, numberOfInputPorts + i);
+        }
+
+        /*
+         * Fill block with the data structure
+         */
+        int field = 1;
+        graphicElement.decode(data.get(field), block);
+
+        field++;
+        modelElement.decode(data.get(field), block);
+
+        field++;
+        controller.setObjectProperty(block.getUID(), block.getKind(), ObjectProperties.INTERFACE_FUNCTION, interfunction);
+
+        field++;
+        fillDocStructure(data.get(field), block);
+
+        /*
+         * Set state dependent information.
+         */
+        orderingMap.put(block.getUID(), ordering++);
+
+        block = afterDecode(element, block);
+
+        return block;
+    }
+
+    /**
+     * Use the Scicos documentation structure to get the previous Xcos IDs.
+     *
+     * @param scilabType
+     *            the scicos documentation field.
+     * @param into
+     *            the target instance.
+     */
+    private void fillDocStructure(ScilabType scilabType, BasicBlock into) {
+        /*
+         * The double type is used as the default one, generate on empty field.
+         */
+        if (scilabType instanceof ScilabDouble) {
+            return;
+        }
+
+        /*
+         * Classical behavior
+         */
+        ScilabList list = (ScilabList) scilabType;
+
+        if (list.size() > 0 && list.get(0) instanceof ScilabString) {
+            String uid = ((ScilabString) list.get(0)).getData()[0][0];
+            if (isValidUid(uid)) {
+                into.setId(uid);
+                return;
+            }
+        }
+    }
+
+    /**
+     * @param uid
+     *            The uid to check
+     * @return true if the uid is valid, false otherwise
+     */
+    private boolean isValidUid(String uid) {
+        final String[] components = uid.split(":");
+
+        boolean valid = components.length == 3;
+        if (valid) {
+            try {
+                Integer.parseInt(components[0], 16);
+                Long.parseLong(components[1], 16);
+                Integer.parseInt(components[2], 16);
+            } catch (IllegalArgumentException e) {
+                valid = false;
+            }
+        }
+        return valid;
+    }
+
+    /**
+     * Validate the current data.
+     *
+     * This method doesn't pass the metrics because it perform many test. Therefore all these tests are trivial and the conditioned action only throw an exception.
+     *
+     * @throws ScicosFormatException
+     *             when there is a validation error.
+     */
+    // CSOFF: CyclomaticComplexity
+    // CSOFF: NPathComplexity
+    private void validate() throws ScicosFormatException {
+        if (!canDecode(data)) {
+            throw new WrongElementException();
+        }
+
+        int field = 0;
+
+        // we test if the structure as enough field
+        if (data.size() != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        /*
+         * Checking the MList header
+         */
+
+        // Check the first field
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+        final String[] header = ((ScilabString) data.get(field)).getData()[0];
+
+        // Checking for the field names
+        if (header.length != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+        for (int i = 0; i < header.length; i++) {
+            if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
+                throw new WrongStructureException(DATA_FIELD_NAMES);
+            }
+        }
+
+        /*
+         * Checking the data
+         */
+
+        // the second field must contain list of all graphic property (how the
+        // block will be displayed )
+        field++;
+        if (!(data.get(field) instanceof ScilabMList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the third field must contains all the information needed to compile
+        // the block
+        field++;
+        if (!(data.get(field) instanceof ScilabMList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the fourth field must contains all the information needed to
+        // represent
+        // the block
+        field++;
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the last field must contain a list of nothing aka scicos doc
+        field++;
+        if (!(data.get(field) instanceof ScilabList) && !isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+    }
+
+    // CSON: CyclomaticComplexity
+    // CSON: NPathComplexity
+
+    /**
+     * Test if the current instance can be used to decode the element
+     *
+     * @param element
+     *            the current element
+     * @return true, if the element can be decoded, false otherwise
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabMList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0));
+    }
+}
+// CSON: ClassFanOutComplexity
+// CSON: ClassDataAbstractionCoupling
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockGraphicElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockGraphicElement.java
new file mode 100644 (file)
index 0000000..74a2685
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ * Copyright (C) 2011 - Scilab Enterprises - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import static java.util.Arrays.asList;
+
+import java.util.List;
+
+import org.scilab.modules.graph.utils.StyleMap;
+import org.scilab.modules.types.ScilabBoolean;
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabList;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabTList;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.ObjectProperties;
+import org.scilab.modules.xcos.VectorOfDouble;
+import org.scilab.modules.xcos.block.BasicBlock;
+import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.io.ScilabTypeCoder;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongElementException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
+import org.scilab.modules.xcos.utils.BlockPositioning;
+
+import com.mxgraph.model.mxCell;
+import com.mxgraph.util.mxConstants;
+
+/**
+ * Protected class which decode graphic fields of a block.
+ *
+ * This class is intentionally package-protected to prevent external use.
+ */
+// CSOFF: ClassDataAbstractionCoupling
+final class BlockGraphicElement extends BlockPartsElement {
+    /*
+     * "in_style", "out_style" and style have been added on the 5.3-5.4 dev. cycle they are not checked to be compatible with older versions.
+     */
+    protected static final List<String> DATA_FIELD_NAMES = asList("graphics", "orig", "sz", "flip", "theta", "exprs", "pin", "pout", "pein", "peout", "gr_i",
+            "id", "in_implicit", "out_implicit");
+    protected static final List<String> DATA_FIELD_NAMES_FULL = asList("graphics", "orig", "sz", "flip", "theta", "exprs", "pin", "pout", "pein", "peout",
+            "gr_i", "id", "in_implicit", "out_implicit", "in_style", "out_style", "in_label", "out_label", "style");
+
+    private static final int ORIGIN_INDEX = DATA_FIELD_NAMES_FULL.indexOf("orig");
+    private static final int DIMS_INDEX = DATA_FIELD_NAMES_FULL.indexOf("sz");
+    private static final int FLIP_INDEX = DATA_FIELD_NAMES_FULL.indexOf("flip");
+    private static final int EXPRS_INDEX = DATA_FIELD_NAMES_FULL.indexOf("exprs");
+    private static final int ID_INDEX = DATA_FIELD_NAMES_FULL.indexOf("id");
+    private static final int STYLE_INDEX = DATA_FIELD_NAMES_FULL.indexOf("style");
+
+    private static final int GRAPHICS_INSTRUCTION_SIZE = 8;
+    private static final double DEFAULT_SIZE_FACTOR = 20.0;
+
+    /** Mutable field to easily get the data through methods */
+    private ScilabMList data;
+
+    /** In-progress decoded diagram */
+    private final XcosDiagram diag;
+
+    /** Size factor use to scale Xcos-Scicos dimensions */
+    private final double sizeFactor;
+
+    /**
+     * Default constructor
+     */
+    public BlockGraphicElement(final JavaController controller) {
+        this(controller, null);
+    }
+
+    /**
+     * Default constructor with diagram
+     *
+     * @param diag
+     *            the diagram
+     */
+    public BlockGraphicElement(final JavaController controller, final XcosDiagram diag) {
+        super(controller);
+
+        this.diag = diag;
+
+        /*
+         * Out of a diagram update, use the DEFAULT_SIZE_FACTOR.
+         */
+        if (diag == null) {
+            sizeFactor = DEFAULT_SIZE_FACTOR;
+        } else {
+            sizeFactor = 1.0;
+        }
+    }
+
+    /**
+     * Default constructor with diagram
+     *
+     * @param diag
+     *            the diagram
+     * @param sizeFactor
+     *            the size factor
+     */
+    public BlockGraphicElement(final JavaController controller, final XcosDiagram diag, final double sizeFactor) {
+        super(controller);
+
+        this.diag = diag;
+        this.sizeFactor = sizeFactor;
+    }
+
+    /**
+     * Decode Scicos element into the block.
+     *
+     * This decode method doesn't coverage Port management because we need model information to handle it.
+     *
+     * @param element
+     *            the scicos element
+     * @param into
+     *            the previously instantiated block.
+     * @return the modified into block.
+     * @throws ScicosFormatException
+     *             on error.
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    @Override
+    public BasicBlock decode(ScilabType element, final BasicBlock into) throws ScicosFormatException {
+
+        if (into == null) {
+            throw new IllegalArgumentException();
+        }
+        BasicBlock block = into;
+
+        data = (ScilabMList) element;
+
+        validate();
+
+        block = beforeDecode(element, block);
+
+        /*
+         * fill the data
+         */
+        decodeDimension(block);
+        decodeOrigin(block);
+        decodeFlipAndRotation(block);
+        decodeIdCell(block);
+
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.EXPRS, new ScilabTypeCoder().var2vec(data.get(EXPRS_INDEX)));
+
+        if (data.size() > STYLE_INDEX && !isEmptyField(data.get(STYLE_INDEX))) {
+            final ScilabString style = (ScilabString) data.get(STYLE_INDEX);
+            final String s = style.getData()[0][0];
+
+            if (s != null && !s.isEmpty()) {
+                block.setStyle(s);
+            }
+        }
+
+        block = afterDecode(element, block);
+
+        return block;
+    }
+
+    /**
+     * Validate the current data.
+     *
+     * This method doesn't pass the metrics because it perform many test. Therefore all these tests are trivial and the conditioned action only throw an exception.
+     *
+     * @throws ScicosFormatException
+     *             when there is a validation error.
+     */
+    // CSOFF: CyclomaticComplexity
+    // CSOFF: NPathComplexity
+    // CSOFF: JavaNCSS
+    private void validate() throws ScicosFormatException {
+        if (!canDecode(data)) {
+            throw new WrongElementException();
+        }
+
+        int field = 0;
+
+        // we test if the structure as enough field
+        if (data.size() < DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        /*
+         * Checking the MList header
+         */
+
+        // Check the first field
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+        final String[] header = ((ScilabString) data.get(field)).getData()[0];
+
+        // Checking for the field names
+        if (header.length < DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+        for (int i = 0; i < DATA_FIELD_NAMES.size(); i++) {
+            if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
+                throw new WrongStructureException(DATA_FIELD_NAMES);
+            }
+        }
+
+        /*
+         * Checking the data
+         */
+
+        // orig : must contain the coord of the block
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // sz : must contains the size of the block
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // flip
+        field++;
+        if (!(data.get(field) instanceof ScilabBoolean)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // theta
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // exprs
+        field++;
+        if (!(data.get(field) instanceof ScilabString) && !(data.get(field) instanceof ScilabList) && !(data.get(field) instanceof ScilabTList)
+                && !isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // pin
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // pout
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // pein
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // peout
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // gr_i
+        // !! WARNING !! we do not care about gr_i because there are only
+        // block look related.
+        field++;
+
+        // id
+        field++;
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // in_implicit
+        field++;
+        if (!(data.get(field) instanceof ScilabString) && !isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // out_implicit
+        field++;
+        if (!(data.get(field) instanceof ScilabString) && !isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // field added on the 5.3-5.4 dev. cycle
+        // not checked due to compatibility
+        // in_style
+        // out_style
+        // style
+    }
+
+    // CSON: CyclomaticComplexity
+    // CSON: NPathComplexity
+    // CSON: JavaNCSS
+
+    /**
+     * Fill the block with the origin parameters
+     *
+     * @param into
+     *            the target instance
+     */
+    private void decodeOrigin(final BasicBlock into) {
+        /*
+         * Getting the values
+         */
+        double x;
+        double y;
+
+        final double[][] real = ((ScilabDouble) data.get(ORIGIN_INDEX)).getRealPart();
+        x = real[0][0];
+        final double[] vector = real[real.length - 1];
+        y = vector[vector.length - 1];
+
+        /*
+         * Apply compatibility patterns
+         */
+        x *= sizeFactor;
+        y *= sizeFactor;
+
+        /*
+         * Invert the y-axis value and translate it.
+         */
+        y = -y - into.getGeometry().getHeight();
+
+        /*
+         * fill parameter
+         */
+        into.getGeometry().setX(x);
+        into.getGeometry().setY(y);
+    }
+
+    /**
+     * Fill the block with the dimension parameters
+     *
+     * @param into
+     *            the target instance
+     */
+    private void decodeDimension(final BasicBlock into) {
+        /*
+         * Getting the values
+         */
+        double w;
+        double h;
+
+        final double[][] real = ((ScilabDouble) data.get(DIMS_INDEX)).getRealPart();
+        w = real[0][0];
+        final double[] vector = real[real.length - 1];
+        h = vector[vector.length - 1];
+
+        /*
+         * When a block has no parent diagram, the size should be updated. On a diagram decode, size is right.
+         */
+        h *= sizeFactor;
+        w *= sizeFactor;
+
+        /*
+         * fill parameter
+         */
+        into.getGeometry().setWidth(w);
+        into.getGeometry().setHeight(h);
+    }
+
+    /**
+     * Fill the block with the flip and theta parameters
+     *
+     * @param into
+     *            the target instance
+     */
+    private void decodeFlipAndRotation(final BasicBlock into) {
+        VectorOfDouble angle = new VectorOfDouble(2);
+
+        /*
+         * Flip management
+         */
+        if (!((ScilabBoolean) data.get(FLIP_INDEX)).getData()[0][0]) {
+            angle.set(0, 0x0001);
+        } else {
+            angle.set(0, 0x0000);
+        }
+
+        /*
+         * Rotation management
+         */
+        double theta = ((ScilabDouble) data.get(FLIP_INDEX + 1)).getRealPart()[0][0];
+        if (theta != 0) {
+            // convert to a valid value
+            theta = BlockPositioning.roundAngle(-theta);
+            angle.set(1, theta);
+
+            final StyleMap map = new StyleMap(into.getStyle());
+            map.put(mxConstants.STYLE_ROTATION, Double.toString(theta));
+            into.setStyle(map.toString());
+        }
+
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.ANGLE, angle);
+    }
+
+    /**
+     * Preserve the id if applicable
+     *
+     * @param into
+     *            the target instance
+     */
+    private void decodeIdCell(final BasicBlock into) {
+        if (diag == null) {
+            return;
+        }
+
+        final String[][] id = ((ScilabString) data.get(ID_INDEX)).getData();
+        if (id.length == 0 || id[0].length == 0 || id[0][0].isEmpty()) {
+            return;
+        }
+
+        /*
+         * Create the local identifier
+         */
+        final mxCell identifier = diag.createCellIdentifier(into);
+        identifier.setValue(id[0][0]);
+
+        into.insert(identifier);
+    }
+
+    /**
+     * Check if the element can be decoded.
+     *
+     * @param element
+     *            the Scicos element
+     * @return true, if the Scicos types match.
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabMList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0));
+    }
+}
+// CSON: ClassDataAbstractionCoupling
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockModelElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/BlockModelElement.java
new file mode 100644 (file)
index 0000000..0aa905f
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import static java.util.Arrays.asList;
+
+import java.util.List;
+
+import org.scilab.modules.types.ScilabBoolean;
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabList;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabTList;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.Kind;
+import org.scilab.modules.xcos.ObjectProperties;
+import org.scilab.modules.xcos.VectorOfDouble;
+import org.scilab.modules.xcos.VectorOfInt;
+import org.scilab.modules.xcos.block.BasicBlock;
+import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.io.ScilabTypeCoder;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongElementException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
+import org.scilab.modules.xcos.port.BasicPort;
+import org.scilab.modules.xcos.port.command.CommandPort;
+import org.scilab.modules.xcos.port.control.ControlPort;
+
+/**
+ * Protected class which decode model fields of a block.
+ *
+ * This class is intentionally package-protected to prevent external use.
+ */
+// CSOFF: ClassDataAbstractionCoupling
+final class BlockModelElement extends BlockPartsElement {
+    /*
+     * "uid" have been added on the 5.5.0 cycle. It is not checked to be compatible with older versions.
+     */
+    protected static final List<String> DATA_FIELD_NAMES = asList("model", "sim", "in", "in2", "intyp", "out", "out2", "outtyp", "evtin", "evtout", "state",
+            "dstate", "odstate", "rpar", "ipar", "opar", "blocktype", "firing", "dep_ut", "label", "nzcross", "nmode", "equations");
+    protected static final List<String> DATA_FIELD_NAMES_FULL = asList("model", "sim", "in", "in2", "intyp", "out", "out2", "outtyp", "evtin", "evtout",
+            "state", "dstate", "odstate", "rpar", "ipar", "opar", "blocktype", "firing", "dep_ut", "label", "nzcross", "nmode", "equations", "uid");
+
+    private static final int CTRL_PORT_INDEX = DATA_FIELD_NAMES.indexOf("evtin");
+    private static final int CMD_PORT_INDEX = DATA_FIELD_NAMES.indexOf("evtout");
+    private static final int STATE_INDEX = DATA_FIELD_NAMES.indexOf("state");
+    private static final int FIRING_INDEX = DATA_FIELD_NAMES.indexOf("firing");
+    private static final int DEPENDU_INDEX = DATA_FIELD_NAMES.indexOf("dep_ut");
+
+    /** Mutable field to easily get the data through methods */
+    private ScilabMList data;
+
+    /** In-progress decoded diagram */
+    private final XcosDiagram diag;
+
+    /**
+     * Default constructor
+     */
+    public BlockModelElement(final JavaController controller, final XcosDiagram diag) {
+        super(controller);
+
+        this.diag = diag;
+    }
+
+    /**
+     * Decode Scicos element into the block.
+     *
+     * This decode method doesn't coverage Port management because we need graphics information to handle it.
+     *
+     * @param element
+     *            the scicos element
+     * @param into
+     *            the previously instantiated block.
+     * @return the modified into block.
+     * @throws ScicosFormatException
+     *             on error.
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    @Override
+    public BasicBlock decode(ScilabType element, BasicBlock into) throws ScicosFormatException {
+
+        if (into == null) {
+            throw new IllegalArgumentException();
+        }
+
+        data = (ScilabMList) element;
+        BasicBlock local = into;
+
+        validate();
+
+        local = beforeDecode(element, local);
+
+        /*
+         * fill the data
+         */
+        fillSimulationFunction(local);
+        fillControlCommandPorts(local);
+        fillFirstRawParameters(local);
+        fillFiringParameters(local);
+        fillSecondRawParameters(local);
+
+        local = afterDecode(element, local);
+
+        return local;
+    }
+
+    /**
+     * Fill the simulation data into the block
+     *
+     * @param into
+     *            the target instance
+     */
+    private void fillSimulationFunction(BasicBlock into) {
+        String[] functionName = new String[1];
+        controller.getObjectProperty(into.getUID(), into.getKind(), ObjectProperties.SIM_FUNCTION_NAME, functionName);
+
+        int[] functionType = new int[1];
+        controller.getObjectProperty(into.getUID(), into.getKind(), ObjectProperties.SIM_FUNCTION_API, functionType);
+
+        if (data.get(1) instanceof ScilabString) {
+            functionName[0] = ((ScilabString) data.get(1)).getData()[0][0];
+        } else if ((data.get(1) instanceof ScilabList)) {
+            functionName[0] = ((ScilabString) ((ScilabList) data.get(1)).get(0)).getData()[0][0];
+            functionType[0] = (int) ((ScilabDouble) ((ScilabList) data.get(1)).get(1)).getRealPart()[0][0];
+        }
+
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.SIM_FUNCTION_NAME, functionName[0]);
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.SIM_FUNCTION_API, functionType[0]);
+    }
+
+    /**
+     * Fill the block with the control and command ports
+     *
+     * @param into
+     *            the target instance
+     */
+    private void fillControlCommandPorts(BasicBlock into) {
+        ScilabDouble dataNbControlPort = (ScilabDouble) data.get(CTRL_PORT_INDEX);
+        ScilabDouble dataNbCommandPort = (ScilabDouble) data.get(CMD_PORT_INDEX);
+
+        if (dataNbControlPort.getRealPart() != null) {
+            final int baseIndex = into.getChildCount();
+
+            int nbControlPort = dataNbControlPort.getHeight();
+            for (int i = 0; i < nbControlPort; i++) {
+                final BasicPort port = new ControlPort(controller.createObject(Kind.PORT));
+
+                // do not use BasicPort#addPort() to avoid the view update
+                into.insert(port, baseIndex + i);
+            }
+        }
+
+        if (dataNbCommandPort.getRealPart() != null) {
+            final int baseIndex = into.getChildCount();
+
+            int nbCommandPort = dataNbCommandPort.getHeight();
+            for (int i = 0; i < nbCommandPort; i++) {
+                final BasicPort port = new CommandPort(controller.createObject(Kind.PORT));
+
+                // do not use BasicPort#addPort() to avoid the view update
+                into.insert(port, baseIndex + i);
+            }
+        }
+    }
+
+    /**
+     * Fill the block with the first raw parameters
+     *
+     * @param into
+     *            the target instance
+     */
+    private void fillFirstRawParameters(BasicBlock into) {
+        // state
+        int field = STATE_INDEX;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.STATE, toVectorOfDouble((ScilabDouble) data.get(field)));
+
+        // dstate
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.DSTATE, toVectorOfDouble((ScilabDouble) data.get(field)));
+
+        // odstate
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.ODSTATE, new ScilabTypeCoder().var2vec(data.get(field)));
+
+        // rpar
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.RPAR, toVectorOfDouble((ScilabDouble) data.get(field)));
+
+        // ipar
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.IPAR, toVectorOfInt((ScilabDouble) data.get(field)));
+
+        // opar
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.OPAR, new ScilabTypeCoder().var2vec(data.get(field)));
+
+        // blocktype
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.SIM_BLOCKTYPE, ((ScilabString) data.get(field)).getData()[0][0]);
+    }
+
+    /**
+     * Fill the block with the firing parameters
+     *
+     * @param into
+     *            the target instance
+     */
+    private void fillFiringParameters(BasicBlock into) {
+        /*
+         * A boolean can be used to indicate that no initial event will be emitted.
+         */
+        if (data.get(FIRING_INDEX) instanceof ScilabBoolean) {
+            return;
+        }
+
+        /*
+         * Normal behavior
+         */
+        final ScilabDouble firing = (ScilabDouble) data.get(FIRING_INDEX);
+
+        if (!isEmptyField(firing)) {
+            final List<CommandPort> allCommandPorts = BasicBlockInfo.getAllTypedPorts(into, false, CommandPort.class);
+
+            final boolean isColumnDominant = firing.getHeight() >= firing.getWidth();
+            final double[][] values = firing.getRealPart();
+            final int[] indexes = { 0, 0 };
+
+            for (int i = 0; i < allCommandPorts.size(); i++) {
+                CommandPort port = allCommandPorts.get(i);
+                controller.setObjectProperty(port.getUID(), port.getKind(), ObjectProperties.FIRING, values[indexes[0]][indexes[1]]);
+
+                incrementIndexes(indexes, isColumnDominant);
+            }
+        }
+    }
+
+    private VectorOfDouble toVectorOfDouble(ScilabDouble value) {
+        VectorOfDouble ret = new VectorOfDouble(value.getHeight());
+        for (int i = 0; i < value.getWidth(); i++) {
+            ret.set(i, value.getRealElement(i, 0));
+        }
+        return ret;
+    }
+
+    private VectorOfInt toVectorOfInt(ScilabDouble value) {
+        VectorOfInt ret = new VectorOfInt(value.getHeight());
+        for (int i = 0; i < value.getWidth(); i++) {
+            ret.set(i, (int) value.getRealElement(i, 0));
+        }
+        return ret;
+    }
+
+    /**
+     * Fill the block with the second raw parameters
+     *
+     * @param into
+     *            the target instance
+     * @throws WrongStructureException
+     *             on wrong value
+     */
+    private void fillSecondRawParameters(BasicBlock into) throws WrongStructureException {
+        // dep-ut
+        int field = DEPENDU_INDEX;
+        final boolean[][] dependsOn = ((ScilabBoolean) data.get(field)).getData();
+        VectorOfInt v = new VectorOfInt(2);
+
+        if (dependsOn.length == 1 && dependsOn[0].length == 2) {
+            v.set(0, dependsOn[0][0] ? 1 : 0);
+            v.set(1, dependsOn[0][1] ? 1 : 0);
+        } else if (dependsOn.length == 2 && dependsOn[0].length == 1 && dependsOn[1].length == 1) {
+            v.set(0, dependsOn[0][0] ? 1 : 0);
+            v.set(1, dependsOn[1][0] ? 1 : 0);
+        } else {
+            throw new WrongStructureException(((ScilabString) data.get(0)).getData()[0][DEPENDU_INDEX]);
+        }
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.SIM_DEP_UT, v);
+
+        // label
+        // do nothing
+        field++;
+
+        // nzcross
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.NZCROSS, toVectorOfInt((ScilabDouble) data.get(field)));
+
+        // nmode
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.NMODE, toVectorOfInt((ScilabDouble) data.get(field)));
+
+        // equation
+        field++;
+        controller.setObjectProperty(into.getUID(), into.getKind(), ObjectProperties.EQUATIONS, new ScilabTypeCoder().var2vec(data.get(field)));
+
+        // uid
+        // compatibility check, for pre-5.5.0 diagrams
+        field++;
+        if (field >= data.size()) {
+            return;
+        }
+        final ScilabType uid = data.get(field);
+        if (uid instanceof ScilabString) {
+            final String id = ((ScilabString) uid).getData()[0][0];
+            if (id != null && !id.isEmpty()) {
+                into.setId(id);
+            }
+        }
+    }
+
+    /**
+     * Validate the current data.
+     *
+     * This method doesn't pass the metrics because it perform many test. Therefore all these tests are trivial and the conditioned action only throw an exception.
+     *
+     * @throws ScicosFormatException
+     *             when there is a validation error.
+     */
+    // CSOFF: CyclomaticComplexity
+    // CSOFF: NPathComplexity
+    // CSOFF: JavaNCSS
+    // CSOFF: MethodLength
+    private void validate() throws ScicosFormatException {
+        if (!canDecode(data)) {
+            throw new WrongElementException();
+        }
+
+        int field = 0;
+
+        // we test if the structure as enough field
+        if (data.size() < DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        /*
+         * Checking the MList header
+         */
+
+        // Check the first field
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+        final String[] header = ((ScilabString) data.get(field)).getData()[0];
+
+        // Checking for the field names
+        if (header.length < DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+        for (int i = 0; i < DATA_FIELD_NAMES.size(); i++) {
+            if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
+                throw new WrongStructureException(DATA_FIELD_NAMES);
+            }
+        }
+
+        /*
+         * Checking the data
+         */
+
+        // sim : String or list(String, int)
+        field++;
+        if (!(data.get(field) instanceof ScilabString) && !(data.get(field) instanceof ScilabList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // in
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // in2
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // intyp
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // out
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // out2
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // outtyp
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // evtin
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // evtout
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // state
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // dstate
+        // TODO: the ScilabString value is undocumented
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble) && !(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // odstate
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble) && !(data.get(field) instanceof ScilabList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // rpar
+        // SuperBlocks store all "included" data in rpar field.
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble) && !(data.get(field) instanceof ScilabMList) && !(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // ipar
+        // !! WARNING !! scifunc_block_m ipar = list(...)
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble) && !(data.get(field) instanceof ScilabList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // opar
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble) && !(data.get(field) instanceof ScilabList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // blocktype
+        field++;
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // firing
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble) && !(data.get(field) instanceof ScilabBoolean)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // dep-ut
+        field++;
+        if (!(data.get(field) instanceof ScilabBoolean)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // label
+        field++;
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // nzcross
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // nmode
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // equations
+        field++;
+        if (!(data.get(field) instanceof ScilabTList) && !isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // uid not checked, introduced in Scilab 5.5.0
+    }
+
+    // CSON: CyclomaticComplexity
+    // CSON: NPathComplexity
+    // CSON: JavaNCSS
+    // CSON: MethodLength
+
+    /**
+     * Check if the element can be decoded.
+     *
+     * @param element
+     *            the Scicos element
+     * @return true, if the Scicos types match.
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabMList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0));
+    }
+}
+// CSON: ClassDataAbstractionCoupling
index 9b6c8ac..160a710 100644 (file)
@@ -16,6 +16,7 @@ import org.scilab.modules.types.ScilabDouble;
 import org.scilab.modules.types.ScilabMList;
 import org.scilab.modules.types.ScilabString;
 import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
 import org.scilab.modules.xcos.block.BasicBlock;
 
 /**
@@ -37,7 +38,8 @@ abstract class BlockPartsElement extends AbstractElement<BasicBlock> {
     /**
      * Default constructor
      */
-    protected BlockPartsElement() {
+    protected BlockPartsElement(final JavaController controller) {
+        super(controller);
     }
 
     /**
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/DiagramElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/DiagramElement.java
new file mode 100644 (file)
index 0000000..555a700
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import static java.util.Arrays.asList;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.scilab.modules.types.ScilabBoolean;
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabList;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabTList;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.block.BasicBlock;
+import org.scilab.modules.xcos.block.SuperBlock;
+import org.scilab.modules.xcos.block.io.ContextUpdate.IOBlocks;
+import org.scilab.modules.xcos.graph.ScicosParameters;
+import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.VersionMismatchException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
+import org.scilab.modules.xcos.link.BasicLink;
+import org.scilab.modules.xcos.port.BasicPort;
+import org.scilab.modules.xcos.utils.BlockPositioning;
+
+import com.mxgraph.model.mxCell;
+import com.mxgraph.model.mxGeometry;
+import com.mxgraph.model.mxGraphModel;
+import com.mxgraph.model.mxICell;
+import com.mxgraph.model.mxIGraphModel;
+import com.mxgraph.util.mxPoint;
+
+/**
+ * Perform a diagram transformation between Scicos and Xcos.
+ */
+// CSOFF: ClassDataAbstractionCoupling
+// CSOFF: ClassFanOutComplexity
+public final class DiagramElement extends AbstractElement<XcosDiagram> {
+    protected static final List<String> DATA_FIELD_NAMES = asList("diagram", "props", "objs");
+    protected static final List<String> DATA_FIELD_NAMES_FULL = asList("diagram", "props", "objs", "version", "contrib");
+    private static final List<String> VERSIONS = asList("", "scicos4.2", "scicos4.3", "scicos4.4");
+
+    private static final int OBJS_INDEX = DATA_FIELD_NAMES_FULL.indexOf("objs");
+    private static final int VERSION_INDEX = DATA_FIELD_NAMES_FULL.indexOf("version");
+
+    private static final double H_MARGIN = 40.0;
+    private static final double V_MARGIN = 40.0;
+
+    /** Diagram properties MList header (scs_m.props) */
+    private static final String[] PROPS_FIELDS = { "params", "wpar", "title", "tol", "tf", "context", "void1", "options", "void2", "void3", "doc" };
+
+    /** Index of the title in the props field */
+    private static final int TITLE_INDEX = 2;
+
+    /** Diagram options MList header (scs_m.props.options) */
+    private static final String[] OPTS_FIELDS = { "scsopt", "3D", "Background", "Link", "ID", "Cmap" };
+    /**
+     * Window properties (scs_m.props.wpar).
+     *
+     * This property has no impact among simulation
+     */
+    private static final double[][] WPAR = { { 600, 450, 0, 0, 600, 450 } };
+
+    // The window parameters and diagram options are not used in the simulation
+    // thus we set it to default values.
+    // As the values are scicos dependent we avoid using constant references.
+    // CSOFF: MagicNumber
+    private static final ScilabTList DIAGRAM_OPTIONS = new ScilabTList(OPTS_FIELDS,
+            Arrays.asList(
+                new ScilabList(// 3D
+                    Arrays.asList(new ScilabBoolean(true), new ScilabDouble(33))),
+    new ScilabDouble(new double[][] { { 8, 1 } }), // Background
+    new ScilabDouble(new double[][] { { 1, 5 } }), // Link
+    new ScilabList(// ID
+    Arrays.asList(new ScilabDouble(new double[][] { { 5, 1 } }), new ScilabDouble(new double[][] { { 4, 1 } }))),
+    new ScilabDouble(new double[][] { { 0.8, 0.8, 0.8 } }) // Cmap
+            ));
+    // CSON: MagicNumber
+
+    private ScilabMList base;
+
+    private double minimalYaxisValue = Double.POSITIVE_INFINITY;
+    private double minimalXaxisValue = Double.POSITIVE_INFINITY;
+
+    /**
+     * Default constructor
+     */
+    public DiagramElement(final JavaController controller) {
+        super(controller);
+    }
+
+    /**
+     * Decode the diagram with version validation.
+     *
+     * @param element
+     *            the diagram Scicos element
+     * @param into
+     *            the Xcos instance, if null, a new instance is returned.
+     * @return the modified into parameters
+     * @throws ScicosFormatException
+     *             when a decoding error occurs
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    @Override
+    public XcosDiagram decode(ScilabType element, XcosDiagram into) throws ScicosFormatException {
+        return decode(element, into, true);
+    }
+
+    /**
+     * Decode the diagram
+     *
+     * @param element
+     *            the diagram Scicos element
+     * @param into
+     *            the Xcos instance, if null, a new instance is returned.
+     * @param validate
+     *            true, if the diagram version will be checked. false otherwise.
+     * @return the modified into parameters
+     * @throws ScicosFormatException
+     *             when a decoding error occurs
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    public XcosDiagram decode(ScilabType element, XcosDiagram into, boolean validate) throws ScicosFormatException {
+        base = (ScilabMList) element;
+
+        XcosDiagram diag = into;
+        if (diag == null) {
+            throw new IllegalArgumentException();
+        }
+
+        diag = beforeDecode(element, diag);
+        diag.getModel().beginUpdate();
+
+        // Validate the base field
+        String wrongVersion = null;
+        try {
+            validate(validate);
+        } catch (VersionMismatchException e) {
+            wrongVersion = e.getWrongVersion();
+        }
+
+        // Fill the diag
+        decodeDiagram(diag, validate);
+
+        diag.getModel().endUpdate();
+        diag = afterDecode(element, diag);
+
+        // Rethrow the version exception after a decode.
+        if (wrongVersion != null) {
+            throw new VersionMismatchException(wrongVersion);
+        }
+
+        return diag;
+    }
+
+    /**
+     * Decode the diagram
+     *
+     * @param diag
+     *            the current diagram
+     * @param validate
+     *            if true, enable graphic updates ; false disable them
+     * @throws ScicosFormatException
+     *             on decoding error
+     */
+    private void decodeDiagram(XcosDiagram diag, boolean validate) throws ScicosFormatException {
+        // Fill the local parameters
+        // NOTE: the title field is checked on the ScicosParametersElement
+        final String title = ((ScilabString) ((ScilabTList) base.get(1)).get(2)).getData()[0][0];
+        diag.setTitle(title);
+
+        // Fill the diagram attributes
+        ScicosParametersElement params = new ScicosParametersElement(controller);
+        params.decode(base.get(1), new ScicosParameters(diag.getUID(), diag.getKind()));
+
+        // Decode the objs attributes
+        decodeObjs(diag);
+        // Update the objs properties if applicable
+        updateObjs(diag, validate);
+    }
+
+    /**
+     * Decode the objs list into cells
+     *
+     * @param diag
+     *            the target instance
+     * @throws ScicosFormatException
+     *             on error
+     */
+    private void decodeObjs(final XcosDiagram diag) throws ScicosFormatException {
+        final int nbOfObjs = ((ScilabList) base.get(OBJS_INDEX)).size();
+        final HashMap<Integer, BasicBlock> blocks = new HashMap<Integer, BasicBlock>(nbOfObjs, 1.0f);
+
+        final BlockElement blockElement = new BlockElement(controller, diag);
+        final LinkElement linkElement = new LinkElement(controller, blocks);
+        final LabelElement labelElement = new LabelElement(controller);
+
+        /*
+         * Decode blocks
+         */
+        for (int i = 0; i < nbOfObjs; i++) {
+            final ScilabMList data = (ScilabMList) ((ScilabList) base.get(OBJS_INDEX)).get(i);
+            Object cell = null;
+
+            if (blockElement.canDecode(data)) {
+                BasicBlock block = blockElement.decode(data, null);
+                blocks.put(i, block);
+                cell = block;
+
+                BlockPositioning.updateBlockView(diag, block);
+
+                minimalYaxisValue = Math.min(minimalYaxisValue, ((mxCell) cell).getGeometry().getY());
+                minimalXaxisValue = Math.min(minimalXaxisValue, ((mxCell) cell).getGeometry().getX());
+            } else if (labelElement.canDecode(data)) {
+                cell = labelElement.decode(data, null);
+
+                minimalYaxisValue = Math.min(minimalYaxisValue, ((mxCell) cell).getGeometry().getY());
+                minimalXaxisValue = Math.min(minimalXaxisValue, ((mxCell) cell).getGeometry().getX());
+            }
+
+            if (cell != null) {
+                diag.addCell(cell);
+            }
+        }
+
+        /*
+         * Decode links
+         */
+        for (int i = 0; i < nbOfObjs; i++) {
+            final ScilabMList data = (ScilabMList) ((ScilabList) base.get(OBJS_INDEX)).get(i);
+            Object cell = null;
+
+            if (linkElement.canDecode(data)) {
+                BasicLink link = linkElement.decode(data, null);
+                cell = link;
+
+                final List<mxPoint> points = ((mxCell) cell).getGeometry().getPoints();
+                for (final mxPoint p : points) {
+                    minimalYaxisValue = Math.min(minimalYaxisValue, p.getY());
+                    minimalXaxisValue = Math.min(minimalXaxisValue, p.getX());
+                }
+            }
+
+            if (cell != null) {
+                diag.addCell(cell);
+            }
+        }
+    }
+
+    /**
+     * Update the diagram object after decode
+     *
+     * @param diag
+     *            the diagram to update
+     * @param validate
+     *            perform graphic updates, or not
+     */
+    private void updateObjs(final XcosDiagram diag, boolean validate) {
+        final mxGraphModel model = (mxGraphModel) diag.getModel();
+
+        final double minY = -minimalYaxisValue + V_MARGIN;
+        final double minX = -minimalXaxisValue + H_MARGIN;
+        for (final Object cell : model.getCells().values()) {
+            updateMinimalSize(cell, model);
+            translate(cell, model, minX, minY);
+            if (validate) {
+                updateLabels(cell, model);
+            }
+        }
+    }
+
+    // update the cell size to be at least selectable
+    private static final void updateMinimalSize(final Object cell, final mxIGraphModel model) {
+        if (!(cell instanceof BasicBlock)) {
+            return;
+        }
+
+        final double min = 7.0;
+
+        final mxGeometry geom = model.getGeometry(cell);
+        if (geom == null) {
+            return;
+        }
+
+        final double dx;
+        if (geom.getWidth() < min) {
+            dx = (geom.getWidth() - min) / 2;
+            geom.setWidth(min);
+        } else {
+            dx = 0.0;
+        }
+        final double dy;
+        if (geom.getHeight() < min) {
+            dy = (geom.getHeight() - min) / 2;
+            geom.setHeight(min);
+        } else {
+            dy = 0.0;
+        }
+
+        geom.translate(dx, dy);
+    }
+
+    // Translate the y axis for blocks and links
+    private static final void translate(final Object cell, final mxIGraphModel model, final double minX, final double minY) {
+        if (cell instanceof BasicPort) {
+            return;
+        }
+
+        final mxGeometry geom = model.getGeometry(cell);
+        if (geom != null) {
+            geom.translate(minX, minY);
+        }
+    }
+
+    // update the labels of ports for SuperBlock
+    private static final void updateLabels(final Object cell, final mxIGraphModel model) {
+        if (!(cell instanceof SuperBlock)) {
+            return;
+        }
+        final SuperBlock parent = (SuperBlock) cell;
+
+        // Assume that the children are sorted after decode
+        final Map<IOBlocks, List<mxICell>> ports = IOBlocks.getAllPorts(parent);
+        // FIXME is it really needed
+        // final Map<IOBlocks, List<BasicBlock>> blocks = IOBlocks.getAllBlocks(parent);
+        //
+        // for (final IOBlocks io : IOBlocks.values()) {
+        // final List<mxICell> port = ports.get(io);
+        // final List<BasicBlock> block = blocks.get(io);
+        //
+        // final int len = Math.min(port.size(), block.size());
+        // for (int i = 0; i < len; i++) {
+        // final mxICell p = port.get(i);
+        // final mxICell b = block.get(i);
+        //
+        // // if the I/O block has a port child and a label child,
+        // // update
+        // if (b.getChildCount() > 1) {
+        // final Object value = b.getChildAt(b.getChildCount() - 1).getValue();
+        // p.setValue(value);
+        // }
+        // }
+        // }
+    }
+
+    /**
+     * Check that the current ScilabType is a valid Diagram.
+     *
+     * This method doesn't pass the metrics because it perform many test. Therefore all these tests are trivial and the conditioned action only throw an exception.
+     *
+     * @param checkVersion
+     *            true, when the check validate the version
+     * @throws ScicosFormatException
+     *             When the diagram is not valid
+     */
+    // CSOFF: CyclomaticComplexity
+    // CSOFF: NPathComplexity
+    private void validate(boolean checkVersion) throws ScicosFormatException {
+
+        // Have we enough fields ?
+        if (base.size() < DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        int field = 0;
+
+        /*
+         * Checking the MList header
+         */
+
+        // Check the first field
+        if (!(base.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+        String[] header = ((ScilabString) base.get(field)).getData()[0];
+
+        // Check the number of fields
+        if (header.length < DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        // Check the first fields values
+        for (int i = 0; i < DATA_FIELD_NAMES.size(); i++) {
+            if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
+                throw new WrongStructureException(DATA_FIELD_NAMES);
+            }
+        }
+
+        /*
+         * Checking the data types
+         */
+
+        // the second field must contain list of props
+        field++;
+        if (!(base.get(field) instanceof ScilabTList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the third field must contains lists of blocks and links
+        field++;
+        if (!(base.get(field) instanceof ScilabList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the last field must contain the scicos version used
+        field++;
+
+        // doesn't check version if not present (optional field)
+        if (base.size() <= field) {
+            return;
+        }
+
+        if (!(base.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        /*
+         * Check the version if applicable
+         */
+        if (checkVersion) {
+            String scicosVersion = ((ScilabString) base.get(field)).getData()[0][0];
+            if (!VERSIONS.contains(scicosVersion)) {
+                throw new VersionMismatchException(scicosVersion);
+            }
+        }
+    }
+
+    // CSON: CyclomaticComplexity
+    // CSON: NPathComplexity
+
+    /**
+     * @param element
+     *            the base element
+     * @return true if the header is valid, false otherwise
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        if (!(element instanceof ScilabMList)) {
+            return false;
+        }
+
+        base = (ScilabMList) element;
+
+        /*
+         * Checking header
+         */
+        final String type = ((ScilabString) base.get(0)).getData()[0][0];
+        final boolean typeIsValid = type.equals(DATA_FIELD_NAMES.get(0));
+
+        /*
+         * Check the version if applicable
+         */
+        final String scicosVersion;
+        if (base.size() > VERSION_INDEX) {
+            scicosVersion = ((ScilabString) base.get(VERSION_INDEX)).getData()[0][0];
+        } else {
+            scicosVersion = "";
+        }
+        final boolean versionIsValid = VERSIONS.contains(scicosVersion);
+        return typeIsValid && versionIsValid;
+    }
+}
+// CSON: ClassDataAbstractionCoupling
+// CSON: ClassFanOutComplexity
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/InputPortElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/InputPortElement.java
new file mode 100644 (file)
index 0000000..267b829
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import java.util.List;
+
+import org.scilab.modules.graph.utils.StyleMap;
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.Kind;
+import org.scilab.modules.xcos.ObjectProperties;
+import org.scilab.modules.xcos.VectorOfInt;
+import org.scilab.modules.xcos.port.input.ExplicitInputPort;
+import org.scilab.modules.xcos.port.input.ImplicitInputPort;
+import org.scilab.modules.xcos.port.input.InputPort;
+
+/**
+ * Perform an input port transformation between Scicos and Xcos.
+ *
+ * On this element we doesn't validate the Scicos values has they have been already checked on the {@link BlockElement}.
+ */
+public final class InputPortElement extends AbstractElement<InputPort> {
+    protected static final List<String> DATA_FIELD_NAMES = BlockElement.DATA_FIELD_NAMES;
+
+    protected static final List<String> GRAPHICS_DATA_FIELD_NAMES_FULL = BlockGraphicElement.DATA_FIELD_NAMES_FULL;
+    protected static final List<String> MODEL_DATA_FIELD_NAMES = BlockModelElement.DATA_FIELD_NAMES;
+
+    private static final int GRAPHICS_INDEX = DATA_FIELD_NAMES.indexOf("graphics");
+    private static final int MODEL_INDEX = DATA_FIELD_NAMES.indexOf("model");
+
+    private static final int GRAPHICS_PIN_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("pin");
+    private static final int GRAPHICS_INIMPL_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("in_implicit");
+    private static final int GRAPHICS_INSTYLE_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("in_style");
+    private static final int GRAPHICS_INLABEL_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("in_label");
+
+    private static final int MODEL_IN_DATALINE_INDEX = MODEL_DATA_FIELD_NAMES.indexOf("in");
+    private static final int MODEL_IN_DATACOL_INDEX = MODEL_DATA_FIELD_NAMES.indexOf("in2");
+    private static final int MODEL_IN_DATATYPE_INDEX = MODEL_DATA_FIELD_NAMES.indexOf("intyp");
+
+    private static final String EXPLICIT = "E";
+    private static final String IMPLICIT = "I";
+
+    /** Mutable fields to easily get the data through methods */
+    private ScilabMList data;
+    private final ScilabMList graphics;
+    private final ScilabMList model;
+
+    private int alreadyDecodedCount;
+    private boolean allColumnsAreZeros = true;
+
+    /**
+     * Default constructor
+     *
+     * @param element
+     *            the Scicos block parameters used by this element.
+     */
+    public InputPortElement(final JavaController controller, ScilabType element) {
+        super(controller);
+
+        data = (ScilabMList) element;
+        graphics = (ScilabMList) data.get(GRAPHICS_INDEX);
+        model = (ScilabMList) data.get(MODEL_INDEX);
+    }
+
+    /**
+     * @return the number of input port for the element.
+     */
+    public int getNumberOfInputPort() {
+        return model.get(MODEL_IN_DATALINE_INDEX).getHeight();
+    }
+
+    /**
+     * Decode Scicos element into the block.
+     *
+     * @param element
+     *            the scicos element
+     * @param into
+     *            the previously instantiated block.
+     * @return the modified into block.
+     * @throws ScicosFormatException
+     *             on error.
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    @Override
+    public InputPort decode(ScilabType element, InputPort into) throws ScicosFormatException {
+
+        InputPort port;
+        data = (ScilabMList) element;
+
+        port = allocatePort();
+
+        port = beforeDecode(element, port);
+
+        decodeModel(port);
+        decodeGraphics(port);
+
+        // Update the index counter
+        alreadyDecodedCount++;
+
+        port = afterDecode(element, port);
+
+        return port;
+    }
+
+    /**
+     * Allocate a port according to the explicit/implicit values.
+     *
+     * @return a new typed port
+     */
+    private InputPort allocatePort() {
+        InputPort ret;
+
+        /*
+         * backward compatibility, use explicit as default.
+         */
+        if (graphics.size() <= GRAPHICS_INIMPL_INDEX) {
+            return new ExplicitInputPort(controller.createObject(Kind.PORT));
+        }
+        ScilabType inImpl = graphics.get(GRAPHICS_INIMPL_INDEX);
+
+        /*
+         * backward compatibility, use explicit as default.
+         */
+        if (isEmptyField(inImpl)) {
+            return new ExplicitInputPort(controller.createObject(Kind.PORT));
+        }
+
+        final ScilabString inImplicit = (ScilabString) inImpl;
+
+        /*
+         * backward compatibility, use explicit as default.
+         */
+        if (isEmptyField(inImplicit)) {
+            return new ExplicitInputPort(controller.createObject(Kind.PORT));
+        }
+
+        final boolean isColumnDominant = inImplicit.getHeight() >= inImplicit.getWidth();
+        final int[] indexes = getIndexes(alreadyDecodedCount, isColumnDominant);
+        final String[][] inimpl = inImplicit.getData();
+
+        // can we safely access the indexed data ?
+        final boolean isSet = canGet(inImplicit, indexes);
+
+        /*
+         * when the type is set, create a new port instance; create an explicit typed port otherwise.
+         */
+        if (isSet && inimpl[indexes[0]][indexes[1]].equals(EXPLICIT)) {
+            ret = new ExplicitInputPort(controller.createObject(Kind.PORT));
+        } else if (isSet && inimpl[indexes[0]][indexes[1]].equals(IMPLICIT)) {
+            ret = new ImplicitInputPort(controller.createObject(Kind.PORT));
+        } else {
+            // when not specified, use explicit
+            ret = new ExplicitInputPort(controller.createObject(Kind.PORT));
+        }
+
+        return ret;
+    }
+
+    /**
+     * Fill the port with the parameters from the model structure.
+     *
+     * @param port
+     *            the target instance
+     */
+    private void decodeModel(InputPort port) {
+        ScilabDouble dataLines = (ScilabDouble) model.get(MODEL_IN_DATALINE_INDEX);
+        ScilabDouble dataColumns = (ScilabDouble) model.get(MODEL_IN_DATACOL_INDEX);
+        ScilabDouble dataType = (ScilabDouble) model.get(MODEL_IN_DATATYPE_INDEX);
+
+        // The number of row of the port
+        int nbLines;
+        if (dataLines.getRealPart() != null) {
+            nbLines = (int) dataLines.getRealPart()[alreadyDecodedCount][0];
+        } else {
+            nbLines = 1;
+        }
+
+        // The number of column of the port
+        int nbColumns;
+        if (dataColumns.getRealPart() != null) {
+            try {
+                nbColumns = (int) dataColumns.getRealPart()[alreadyDecodedCount][0];
+            } catch (ArrayIndexOutOfBoundsException e) {
+                nbColumns = 1;
+            }
+        } else {
+            nbColumns = 1;
+        }
+
+        // port scilab type
+        int type;
+        if (dataType.getRealPart() != null) {
+            try {
+                type = (int) dataType.getRealPart()[alreadyDecodedCount][0];
+            } catch (ArrayIndexOutOfBoundsException e) {
+                type = 1;
+            }
+        } else {
+            type = 1;
+        }
+
+        VectorOfInt v = new VectorOfInt(3);
+        v.set(0, nbLines);
+        v.set(1, nbColumns);
+        v.set(2, type);
+        controller.setObjectProperty(port.getUID(), port.getKind(), ObjectProperties.DATATYPE, v);
+    }
+
+    /**
+     * Fill the port with the parameters from the graphics structure.
+     *
+     * @param port
+     *            the target instance
+     */
+    private void decodeGraphics(InputPort port) {
+        // protection against previously stored blocks
+        if (graphics.size() > GRAPHICS_INSTYLE_INDEX && !isEmptyField(graphics.get(GRAPHICS_INSTYLE_INDEX))) {
+            final ScilabString styles = (ScilabString) graphics.get(GRAPHICS_INSTYLE_INDEX);
+
+            boolean isColumnDominant = styles.getHeight() >= styles.getWidth();
+            int[] indexes = getIndexes(alreadyDecodedCount, isColumnDominant);
+
+            if (canGet(styles, indexes)) {
+                final String style;
+
+                style = styles.getData()[indexes[0]][indexes[1]];
+                port.setStyle(new StyleMap(port.getStyle()).putAll(style).toString());
+            }
+        }
+
+        // protection against previously stored blocks
+        if (graphics.size() > GRAPHICS_INLABEL_INDEX && !isEmptyField(graphics.get(GRAPHICS_INLABEL_INDEX))) {
+            final ScilabString labels = (ScilabString) graphics.get(GRAPHICS_INLABEL_INDEX);
+
+            boolean isColumnDominant = labels.getHeight() >= labels.getWidth();
+            int[] indexes = getIndexes(alreadyDecodedCount, isColumnDominant);
+
+            if (canGet(labels, indexes)) {
+                final String label = labels.getData()[indexes[0]][indexes[1]];
+
+                if (label != null) {
+                    port.setValue(label);
+                } else {
+                    port.setValue("");
+                }
+            }
+        }
+    }
+
+    /**
+     * Test if the current instance can be used to decode the element
+     *
+     * @param element
+     *            the current element
+     * @return true, if the element can be decoded, false otherwise
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabMList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0)) && getNumberOfInputPort() > alreadyDecodedCount;
+    }
+}
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/LabelElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/LabelElement.java
new file mode 100644 (file)
index 0000000..25a4ebe
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import static java.util.Arrays.asList;
+
+import java.util.List;
+
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.Kind;
+import org.scilab.modules.xcos.block.TextBlock;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongElementException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
+
+/**
+ * Perform label transformation between Xcos and Scicos.
+ */
+public final class LabelElement extends AbstractElement<TextBlock> {
+    protected static final List<String> DATA_FIELD_NAMES = asList("Text", "graphics", "model", "void", "gui");
+
+    /** Mutable field to easily get the data through methods */
+    private ScilabMList data;
+
+    /** Element used to decode/encode Scicos model part into a BasicBlock */
+    private final BlockModelElement modelElement = new BlockModelElement(controller, null);
+
+    /** Element used to decode/encode Scicos model part into a BasicBlock */
+    private final BlockGraphicElement graphicElement = new BlockGraphicElement(controller, null, 1.0);
+
+    /**
+     * Default constructor
+     */
+    public LabelElement(final JavaController controller) {
+        super(controller);
+    }
+
+    /**
+     * Decode the element into the block.
+     *
+     * @param element
+     *            The current Scilab data
+     * @param into
+     *            the target, if null a new instance is allocated and returned.
+     * @return the decoded block.
+     * @throws ScicosFormatException
+     *             when e decoding error occurred.
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType,
+     *      java.lang.Object)
+     */
+    @Override
+    public TextBlock decode(ScilabType element, TextBlock into) throws ScicosFormatException {
+        TextBlock block = into;
+        data = (ScilabMList) element;
+
+        validate();
+
+        if (into == null) {
+            block = new TextBlock(controller.createObject(Kind.ANNOTATION));
+        }
+
+        block = beforeDecode(element, block);
+
+        /*
+         * Fill block with the data structure
+         */
+        int field = 1;
+        graphicElement.decode(data.get(field), block);
+
+        field++;
+        modelElement.decode(data.get(field), block);
+
+        // interfunction, keep the default one
+        field++;
+
+        // doc, do nothing
+        field++;
+
+        block = afterDecode(element, block);
+
+        return block;
+    }
+
+    /**
+     * Validate the current data.
+     *
+     * This method doesn't pass the metrics because it perform many test.
+     * Therefore all these tests are trivial and the conditioned action only
+     * throw an exception.
+     *
+     * @throws ScicosFormatException
+     *             when there is a validation error.
+     */
+    // CSOFF: CyclomaticComplexity
+    // CSOFF: NPathComplexity
+    private void validate() throws ScicosFormatException {
+        if (!canDecode(data)) {
+            throw new WrongElementException();
+        }
+
+        int field = 0;
+
+        // we test if the structure as enough field
+        if (data.size() != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        /*
+         * Checking the MList header
+         */
+
+        // Check the first field
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+        final String[] header = ((ScilabString) data.get(field)).getData()[0];
+
+        // Checking for the field names
+        if (header.length != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+        for (int i = 0; i < header.length; i++) {
+            if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
+                throw new WrongStructureException(DATA_FIELD_NAMES);
+            }
+        }
+
+        /*
+         * Checking the data
+         */
+
+        // the second field must contain list of all graphic property (how the
+        // block will be displayed )
+        field++;
+        if (!(data.get(field) instanceof ScilabMList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the third field must contains all the information needed to compile
+        // the block
+        field++;
+        if (!(data.get(field) instanceof ScilabMList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the fourth field must contains an empty string
+        field++;
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // the last field must contain a gui name
+        field++;
+        if (!(data.get(field) instanceof ScilabString) && isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+    }
+
+    // CSON: CyclomaticComplexity
+    // CSON: NPathComplexity
+
+    /**
+     * Test if the current implementation can be used to decode the element.
+     *
+     * @param element
+     *            the element to test
+     * @return true when the implementation is the right one, false otherwise.
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabMList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0));
+    }
+}
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/LinkElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/LinkElement.java
new file mode 100644 (file)
index 0000000..dee8ad8
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import static java.util.Arrays.asList;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.Kind;
+import org.scilab.modules.xcos.ObjectProperties;
+import org.scilab.modules.xcos.block.BasicBlock;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongElementException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
+import org.scilab.modules.xcos.link.BasicLink;
+import org.scilab.modules.xcos.link.LinkPortMap;
+import org.scilab.modules.xcos.port.BasicPort;
+
+import com.mxgraph.model.mxGeometry;
+import com.mxgraph.util.mxPoint;
+
+/**
+ * Perform a link transformation between Scicos and Xcos.
+ */
+// CSOFF: ClassDataAbstractionCoupling
+// CSOFF: FanOutComplexity
+public final class LinkElement extends AbstractElement<BasicLink> {
+    protected static final List<String> DATA_FIELD_NAMES = asList("Link", "xx", "yy", "id", "thick", "ct", "from", "to");
+
+    private static final int XX_INDEX = DATA_FIELD_NAMES.indexOf("xx");
+    private static final int YY_INDEX = DATA_FIELD_NAMES.indexOf("yy");
+    private static final int CT_INDEX = DATA_FIELD_NAMES.indexOf("ct");
+    private static final int FROM_INDEX = DATA_FIELD_NAMES.indexOf("from");
+    private static final int TO_INDEX = DATA_FIELD_NAMES.indexOf("to");
+
+    private static final Logger LOG = Logger.getLogger(LinkElement.class.getName());
+
+    /** Mutable field to easily get the data through methods */
+    private ScilabMList data;
+    private BasicPort start;
+    private BasicPort end;
+
+    /** The already decoded block map */
+    private final Map<Integer, BasicBlock> blocks;
+
+    /**
+     * Default constructor
+     *
+     * @param blocks
+     *            the already decoded blocks
+     */
+    public LinkElement(final JavaController controller, Map<Integer, BasicBlock> blocks) {
+        super(controller);
+
+        this.blocks = blocks;
+    }
+
+    /**
+     * Decode the element into the link.
+     *
+     * @param element
+     *            The current Scilab data
+     * @param into
+     *            the target, if null a new instance is allocated and returned.
+     * @return the decoded block.
+     * @throws ScicosFormatException
+     *             when e decoding error occurred.
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    @Override
+    public BasicLink decode(ScilabType element, BasicLink into) throws ScicosFormatException {
+        data = (ScilabMList) element;
+        BasicLink link = into;
+
+        validate();
+
+        if (into == null) {
+            link = allocateLink();
+        }
+
+        link = beforeDecode(element, link);
+
+        searchForPorts(link);
+        List<mxPoint> points = getPoints();
+
+        /*
+         * Fill the data
+         */
+        link.setSource(start);
+        link.setTarget(end);
+
+        mxGeometry geom = link.getGeometry();
+        if (geom == null) {
+            geom = new mxGeometry();
+        }
+        geom.setPoints(points);
+        link.setGeometry(geom);
+
+        link = afterDecode(element, link);
+
+        return link;
+    }
+
+    /**
+     * @return a new typed link
+     */
+    private BasicLink allocateLink() {
+        BasicLink link = null;
+        final int type = (int) ((ScilabDouble) data.get(CT_INDEX)).getRealPart()[0][1];
+
+        try {
+            Class<? extends BasicLink> klass = LinkPortMap.getLinkClass(type);
+            Constructor<? extends BasicLink> cstr = klass.getConstructor(Long.TYPE);
+            link = cstr.newInstance(controller.createObject(Kind.LINK));
+        } catch (ReflectiveOperationException e) {
+            LOG.severe(e.toString());
+        }
+
+        return link;
+    }
+
+    /**
+     * @return the link points
+     */
+    private List<mxPoint> getPoints() {
+        List<mxPoint> points = new ArrayList<mxPoint>();
+
+        final double[][] xAxis = ((ScilabDouble) data.get(XX_INDEX)).getRealPart();
+        final double[][] yAxis = ((ScilabDouble) data.get(YY_INDEX)).getRealPart();
+        final boolean isColumnDominant = data.get(XX_INDEX).getHeight() >= data.get(XX_INDEX).getWidth();
+
+        /*
+         * Pre-condition (start and end should have been set)
+         */
+        if (start == null || end == null) {
+            return points;
+        }
+
+        /*
+         * The first, last and common indexes.
+         */
+        final int min = 1;
+        final int max;
+        final int[] indexes = { 0, 0 };
+        if (isColumnDominant) {
+            max = data.get(1).getHeight() - 1;
+            indexes[0] = min;
+        } else {
+            max = data.get(1).getWidth() - 1;
+            indexes[1] = min;
+        }
+
+        /*
+         * Loop all over the points
+         */
+        for (int i = min; i < max; i++) {
+            double x = xAxis[indexes[0]][indexes[1]];
+            double y = yAxis[indexes[0]][indexes[1]];
+
+            // invert the y-axis value
+            y = -y;
+
+            points.add(new mxPoint(x, y));
+
+            incrementIndexes(indexes, isColumnDominant);
+        }
+
+        return points;
+    }
+
+    /**
+     * Fill the {@link #start} and {@link #end} parameters.
+     *
+     * @param link
+     *            the link instance
+     */
+    // CSOFF: JavaNCSS
+    private void searchForPorts(final BasicLink link) {
+
+        /*
+         * Retrieve data from encoded instance
+         */
+        final ScilabDouble from = (ScilabDouble) data.get(FROM_INDEX);
+        final ScilabDouble to = (ScilabDouble) data.get(TO_INDEX);
+
+        final double[][] fromReal = from.getRealPart();
+        final double[][] toReal = to.getRealPart();
+
+        final int[] indexes = { 0, 0 };
+        final boolean isColumnDominant = from.getHeight() >= from.getWidth();
+
+        final int startBlockIndex = (int) fromReal[indexes[0]][indexes[1]];
+        final int endBlockIndex = (int) toReal[indexes[0]][indexes[1]];
+
+        final BasicBlock startBlock = blocks.get(startBlockIndex - 1);
+        final BasicBlock endBlock = blocks.get(endBlockIndex - 1);
+
+        incrementIndexes(indexes, isColumnDominant);
+
+        final int startPortIndex = (int) fromReal[indexes[0]][indexes[1]];
+        if (startPortIndex == 0) {
+            LOG.severe("Link has an invalid start port");
+            LOG.severe(data.toString());
+            return;
+        }
+        final int endPortIndex = (int) toReal[indexes[0]][indexes[1]];
+        if (endPortIndex == 0) {
+            LOG.severe("Link has an invalid end port");
+            LOG.severe(data.toString());
+            return;
+        }
+
+        incrementIndexes(indexes, isColumnDominant);
+
+        final boolean startPortIsStart;
+        if (canGet(from, indexes)) {
+            startPortIsStart = fromReal[indexes[0]][indexes[1]] == 0.0;
+        } else {
+            // fallback start value
+            startPortIsStart = true;
+        }
+
+        final boolean endPortIsStart;
+        if (canGet(to, indexes)) {
+            endPortIsStart = toReal[indexes[0]][indexes[1]] == 0.0;
+        } else {
+            // fallback end value
+            endPortIsStart = false;
+        }
+
+        final List<BasicPort> startPorts = BasicBlockInfo.getAllPortsAtPosition(startBlock, startPortIndex);
+        final List<BasicPort> endPorts = BasicBlockInfo.getAllPortsAtPosition(endBlock, endPortIndex);
+
+        /*
+         * Get the ordered ports, this is the normal case.
+         */
+        lookForOrderedPorts(link, startPorts, startPortIsStart, endPorts, endPortIsStart);
+
+        /*
+         * Fallback to handle an inverted link.
+         */
+        if (start == null || end == null) {
+            // implicit links can be inverted but this is exceptional so trace
+            // them
+            if (LOG.isLoggable(Level.FINEST)) {
+                final BasicBlock block;
+                final int index;
+                if (start == null) {
+                    block = startBlock;
+                    index = startPortIndex;
+                } else {
+                    block = endBlock;
+                    index = endPortIndex;
+                }
+
+                if (block != null) {
+                    String[] v = new String[1];
+                    controller.getObjectProperty(block.getUID(), block.getKind(), ObjectProperties.SIM_FUNCTION_NAME, v);
+                    LOG.warning("Unable to get " + v[0] + "[" + index + "]" + block.toString());
+                } else {
+                    return;
+                }
+            }
+
+            /*
+             * Look for inverted ports in all cases (check inverted first).
+             */
+            lookForOrderedPorts(link, startPorts, !startPortIsStart, endPorts, !endPortIsStart);
+            if (start != null && end != null) {
+                return;
+            }
+            lookForOrderedPorts(link, startPorts, startPortIsStart, endPorts, !endPortIsStart);
+            if (start != null && end != null) {
+                return;
+            }
+            lookForOrderedPorts(link, startPorts, !startPortIsStart, endPorts, endPortIsStart);
+            if (start != null && end != null) {
+                return;
+            }
+        }
+    }
+
+    /**
+     * Look for the ordered ports.
+     *
+     * This method assume that the startPorts and endPorts are sorted according to {@link BasicBlock#sortChildren()} and have the right ordering.
+     *
+     * @param link
+     *            the link to connect
+     * @param startPorts
+     *            the possible starts
+     * @param startIsStart
+     *            boolean to indicate the link direction (from start ? )
+     * @param endPorts
+     *            the possible ends
+     * @param endIsStart
+     *            boolean to indicate the link direction (from end ? )
+     */
+    private void lookForOrderedPorts(final BasicLink link, final List<BasicPort> startPorts, final boolean startIsStart, final List<BasicPort> endPorts,
+                                     final boolean endIsStart) {
+        Class<? extends BasicPort> startKlass = LinkPortMap.getPortClass(link.getClass(), startIsStart);
+        Class<? extends BasicPort> endKlass = LinkPortMap.getPortClass(link.getClass(), endIsStart);
+
+        /*
+         * Clear the state
+         */
+        start = null;
+        end = null;
+
+        /*
+         * Iterate over start
+         */
+        for (BasicPort p : startPorts) {
+            if (startKlass.isInstance(p)) {
+                // only link the same port once, fallback should be provided by the caller method
+                if (p.getEdgeCount() == 0) {
+                    start = p;
+                }
+                break;
+            }
+        }
+
+        /*
+         * Iterate over end
+         */
+        for (BasicPort p : endPorts) {
+            if (endKlass.isInstance(p)) {
+                // only link the same port once, fallback should be provided by the caller method
+                if (p.getEdgeCount() == 0) {
+                    end = p;
+                }
+                break;
+            }
+        }
+    }
+
+    // CSON: JavaNCSS
+
+    /**
+     * Validate the current data.
+     *
+     * This method doesn't pass the metrics because it perform many test. Therefore all these tests are trivial and the conditioned action only throw an exception.
+     *
+     * @throws ScicosFormatException
+     *             when there is a validation error.
+     */
+    // CSOFF: CyclomaticComplexity
+    // CSOFF: NPathComplexity
+    private void validate() throws ScicosFormatException {
+        if (!canDecode(data)) {
+            throw new WrongElementException();
+        }
+
+        int field = 0;
+
+        // we test if the structure as enough field
+        if (data.size() != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        /*
+         * Checking the MList header
+         */
+
+        // Check the first field
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+        final String[] header = ((ScilabString) data.get(field)).getData()[0];
+
+        // Checking for the field names
+        if (header.length != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+        for (int i = 0; i < header.length; i++) {
+            if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
+                throw new WrongStructureException(DATA_FIELD_NAMES);
+            }
+        }
+
+        // xx
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // yy
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // id
+        field++;
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // thick
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // ct
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // from
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // to
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+    }
+
+    // CSON: CyclomaticComplexity
+    // CSON: NPathComplexity
+
+    /**
+     * Test if the current implementation can be used to decode the element.
+     *
+     * @param element
+     *            the element to test
+     * @return true, when the current implementation is the right one
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabMList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0));
+    }
+}
+// CSON: ClassDataAbstractionCoupling
+// CSON: FanOutComplexity
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/OutputPortElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/OutputPortElement.java
new file mode 100644 (file)
index 0000000..1105520
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import java.util.List;
+
+import org.scilab.modules.graph.utils.StyleMap;
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.Kind;
+import org.scilab.modules.xcos.ObjectProperties;
+import org.scilab.modules.xcos.VectorOfInt;
+import org.scilab.modules.xcos.port.output.ExplicitOutputPort;
+import org.scilab.modules.xcos.port.output.ImplicitOutputPort;
+import org.scilab.modules.xcos.port.output.OutputPort;
+
+/**
+ * Perform an output port transformation between Scicos and Xcos.
+ *
+ * On this element we doesn't validate the Scicos values has they have been
+ * already checked on the {@link BlockElement}.
+ */
+public final class OutputPortElement extends AbstractElement<OutputPort> {
+    protected static final List<String> DATA_FIELD_NAMES = BlockElement.DATA_FIELD_NAMES;
+
+    protected static final List<String> GRAPHICS_DATA_FIELD_NAMES_FULL = BlockGraphicElement.DATA_FIELD_NAMES_FULL;
+    protected static final List<String> MODEL_DATA_FIELD_NAMES = BlockModelElement.DATA_FIELD_NAMES;
+
+    private static final int GRAPHICS_INDEX = DATA_FIELD_NAMES.indexOf("graphics");
+    private static final int MODEL_INDEX = DATA_FIELD_NAMES.indexOf("model");
+
+    private static final int GRAPHICS_POUT_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("pout");
+    private static final int GRAPHICS_OUTIMPL_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("out_implicit");
+    private static final int GRAPHICS_OUTSTYLE_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("out_style");
+    private static final int GRAPHICS_OUTLABEL_INDEX = GRAPHICS_DATA_FIELD_NAMES_FULL.indexOf("out_label");
+
+    private static final int MODEL_OUT_DATALINE_INDEX = MODEL_DATA_FIELD_NAMES.indexOf("out");
+    private static final int MODEL_OUT_DATACOL_INDEX = MODEL_DATA_FIELD_NAMES.indexOf("out2");;
+    private static final int MODEL_OUT_DATATYPE_INDEX = MODEL_DATA_FIELD_NAMES.indexOf("outtyp");;
+
+    private static final String EXPLICIT = "E";
+    private static final String IMPLICIT = "I";
+
+    /** Mutable fields to easily get the data through methods */
+    private ScilabMList data;
+    private final ScilabMList graphics;
+    private final ScilabMList model;
+
+    private int alreadyDecodedCount;
+    private boolean allColumnsAreZeros = true;
+
+    /**
+     * Default constructor
+     *
+     * @param element
+     *            the Scicos block parameters used by this element.
+     */
+    public OutputPortElement(final JavaController controller, ScilabType element) {
+        super(controller);
+
+        data = (ScilabMList) element;
+        graphics = (ScilabMList) data.get(GRAPHICS_INDEX);
+        model = (ScilabMList) data.get(MODEL_INDEX);
+    }
+
+    /**
+     * @return the number of output port for the element.
+     */
+    public int getNumberOfOutputPort() {
+        return model.get(MODEL_OUT_DATALINE_INDEX).getHeight();
+    }
+
+    /**
+     * Decode Scicos element into the block.
+     *
+     * @param element
+     *            the scicos element
+     * @param into
+     *            the previously instantiated block.
+     * @return the modified into block.
+     * @throws ScicosFormatException
+     *             on error.
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType,
+     *      java.lang.Object)
+     */
+    @Override
+    public OutputPort decode(ScilabType element, OutputPort into) throws ScicosFormatException {
+
+        OutputPort port;
+        data = (ScilabMList) element;
+
+        port = allocatePort();
+
+        port = beforeDecode(element, port);
+
+        decodeModel(port);
+        decodeGraphics(port);
+
+        // Update the index counter
+        alreadyDecodedCount++;
+
+        port = afterDecode(element, port);
+
+        return port;
+    }
+
+    /**
+     * Allocate a port according to the explicit/implicit values.
+     *
+     * @return a new typed port
+     */
+    private OutputPort allocatePort() {
+        OutputPort ret;
+
+        /*
+         * backward compatibility, use explicit as default.
+         */
+        if (graphics.size() <= GRAPHICS_OUTIMPL_INDEX) {
+            return new ExplicitOutputPort(controller.createObject(Kind.PORT));
+        }
+        ScilabType outImpl = graphics.get(GRAPHICS_OUTIMPL_INDEX);
+
+        /*
+         * backward compatibility, use explicit as default.
+         */
+        if (isEmptyField(outImpl)) {
+            return new ExplicitOutputPort(controller.createObject(Kind.PORT));
+        }
+
+        final ScilabString outImplicit = (ScilabString) outImpl;
+
+        /*
+         * backward compatibility, use explicit as default.
+         */
+        if (isEmptyField(outImplicit)) {
+            return new ExplicitOutputPort(controller.createObject(Kind.PORT));
+        }
+
+        final boolean isColumnDominant = outImplicit.getHeight() >= outImplicit.getWidth();
+        final int[] indexes = getIndexes(alreadyDecodedCount, isColumnDominant);
+        final String[][] outimpl = outImplicit.getData();
+
+        // can we safely access the indexed data ?
+        final boolean isSet = canGet(outImplicit, indexes);
+
+        /*
+         * when the type is set, create a new port instance; create an explicit
+         * typed port otherwise.
+         */
+        if (isSet && outimpl[indexes[0]][indexes[1]].equals(EXPLICIT)) {
+            ret = new ExplicitOutputPort(controller.createObject(Kind.PORT));
+        } else if (isSet && outimpl[indexes[0]][indexes[1]].equals(IMPLICIT)) {
+            ret = new ImplicitOutputPort(controller.createObject(Kind.PORT));
+        } else {
+            // when not specified, use explicit
+            ret = new ExplicitOutputPort(controller.createObject(Kind.PORT));
+        }
+
+        return ret;
+    }
+
+    /**
+     * Fill the port with the parameters from the model structure.
+     *
+     * @param port
+     *            the target instance
+     */
+    private void decodeModel(OutputPort port) {
+        ScilabDouble dataLines = (ScilabDouble) model.get(MODEL_OUT_DATALINE_INDEX);
+        ScilabDouble dataColumns = (ScilabDouble) model.get(MODEL_OUT_DATACOL_INDEX);
+        ScilabDouble dataType = (ScilabDouble) model.get(MODEL_OUT_DATATYPE_INDEX);
+
+        // The number of row of the port
+        int nbLines;
+        if (dataLines.getRealPart() != null) {
+            nbLines = (int) dataLines.getRealPart()[alreadyDecodedCount][0];
+        } else {
+            nbLines = 1;
+        }
+
+        // The number of column of the port
+        int nbColumns;
+        if (dataColumns.getRealPart() != null) {
+            try {
+                nbColumns = (int) dataColumns.getRealPart()[alreadyDecodedCount][0];
+            } catch (ArrayIndexOutOfBoundsException e) {
+                nbColumns = 1;
+            }
+        } else {
+            nbColumns = 1;
+        }
+
+        // port scilab type
+        int type;
+        if (dataType.getRealPart() != null) {
+            try {
+                type = (int) dataType.getRealPart()[alreadyDecodedCount][0];
+            } catch (ArrayIndexOutOfBoundsException e) {
+                type = 1;
+            }
+        } else {
+            type = 1;
+        }
+
+        VectorOfInt v = new VectorOfInt(3);
+        v.set(0, nbLines);
+        v.set(1, nbColumns);
+        v.set(2, type);
+        controller.setObjectProperty(port.getUID(), port.getKind(), ObjectProperties.DATATYPE, v);
+    }
+
+    /**
+     * Fill the port with the parameters from the graphics structure.
+     *
+     * @param port
+     *            the target instance
+     */
+    private void decodeGraphics(OutputPort port) {
+        // protection against previously stored blocks
+        if (graphics.size() > GRAPHICS_OUTSTYLE_INDEX && !isEmptyField(graphics.get(GRAPHICS_OUTSTYLE_INDEX))) {
+            final ScilabString styles = (ScilabString) graphics.get(GRAPHICS_OUTSTYLE_INDEX);
+
+            boolean isColumnDominant = styles.getHeight() >= styles.getWidth();
+            int[] indexes = getIndexes(alreadyDecodedCount, isColumnDominant);
+
+            if (canGet(styles, indexes)) {
+                final String style;
+
+                style = styles.getData()[indexes[0]][indexes[1]];
+                port.setStyle(new StyleMap(port.getStyle()).putAll(style).toString());
+            }
+        }
+
+        // protection against previously stored blocks
+        if (graphics.size() > GRAPHICS_OUTLABEL_INDEX && !isEmptyField(graphics.get(GRAPHICS_OUTLABEL_INDEX))) {
+            final ScilabString labels = (ScilabString) graphics.get(GRAPHICS_OUTLABEL_INDEX);
+
+            boolean isColumnDominant = labels.getHeight() >= labels.getWidth();
+            int[] indexes = getIndexes(alreadyDecodedCount, isColumnDominant);
+
+            if (canGet(labels, indexes)) {
+                final String label = labels.getData()[indexes[0]][indexes[1]];
+
+                if (label != null) {
+                    port.setValue(label);
+                } else {
+                    port.setValue("");
+                }
+            }
+        }
+    }
+
+    /**
+     * Test if the current instance can be used to decode the element
+     *
+     * @param element
+     *            the current element
+     * @return true, if the element can be decoded, false otherwise
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabMList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0)) && getNumberOfOutputPort() > alreadyDecodedCount;
+    }
+}
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/ScicosParametersElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/ScicosParametersElement.java
new file mode 100644 (file)
index 0000000..5ff7b6e
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2010 - DIGITEO - Clement DAVID
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+package org.scilab.modules.xcos.io.scicos;
+
+import static java.util.Arrays.asList;
+
+import java.beans.PropertyVetoException;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.scilab.modules.types.ScilabDouble;
+import org.scilab.modules.types.ScilabList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabTList;
+import org.scilab.modules.types.ScilabType;
+import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.Kind;
+import org.scilab.modules.xcos.VectorOfDouble;
+import org.scilab.modules.xcos.VectorOfString;
+import org.scilab.modules.xcos.graph.ScicosParameters;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongElementException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
+import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
+
+/**
+ * Default element used to handle Scicos simulation parameters
+ */
+public final class ScicosParametersElement extends AbstractElement<ScicosParameters> {
+    protected static final List<String> DATA_FIELD_NAMES = asList("params", "wpar", "title", "tol", "tf", "context", "void1", "options", "void2", "void3",
+            "doc");
+
+    private static final int TOL_INDEX = DATA_FIELD_NAMES.indexOf("tol");
+    private static final int TF_INDEX = DATA_FIELD_NAMES.indexOf("tf");
+    private static final int CONTEXT_INDEX = DATA_FIELD_NAMES.indexOf("context");
+
+    private static final int TOL_SIZE = 7;
+
+    /**
+     * Mutable field which contains the current working data.
+     *
+     * This field must be modified on each read/write call.
+     */
+    private ScilabTList data;
+
+    /**
+     * Default constructor
+     *
+     * @param controller
+     *            the shared controller
+     */
+    public ScicosParametersElement(final JavaController controller) {
+        super(controller);
+    }
+
+    /**
+     * Decode the element into the instance
+     *
+     * @param element
+     *            the element to be decoded
+     * @param into
+     *            the Xcos associated instance
+     * @return the modified into parameters
+     * @throws ScicosFormatException
+     *             on decode error
+     * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType, java.lang.Object)
+     */
+    @Override
+    public ScicosParameters decode(ScilabType element, ScicosParameters into) throws ScicosFormatException {
+        data = (ScilabTList) element;
+        ScicosParameters local = into;
+
+        // Validate the fields
+        validate();
+
+        local = beforeDecode(element, local);
+
+        /*
+         * fill data, if accessible
+         */
+        if (local.getKind() == Kind.DIAGRAM) {
+            fillWithThirdFields(local);
+
+            try {
+
+                double val = ((ScilabDouble) data.get(TF_INDEX)).getRealPart()[0][0];
+
+                VectorOfDouble v = local.getProperties(controller);
+                v.set(ScicosParameters.FINAL_INTEGRATION_TIME, val);
+                local.setProperties(controller, v);
+            } catch (PropertyVetoException e) {
+                Logger.getLogger(ScicosParametersElement.class.getName()).severe(e.toString());
+            }
+        }
+
+        fillContext(local);
+
+        local = afterDecode(element, local);
+
+        return local;
+    }
+
+    /**
+     * Validate the current data.
+     *
+     * This method doesn't pass the metrics because it perform many test. Therefore all these tests are trivial and the conditioned action only throw an exception.
+     *
+     * @throws ScicosFormatException
+     *             when there is a validation error.
+     */
+    // CSOFF: CyclomaticComplexity
+    // CSOFF: NPathComplexity
+    private void validate() throws ScicosFormatException {
+        if (!canDecode(data)) {
+            throw new WrongElementException();
+        }
+
+        int field = 0;
+
+        // we test if the structure as enough field
+        if (data.size() != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+
+        /*
+         * Checking the TList header
+         */
+
+        // Check the first field
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+        final String[] header = ((ScilabString) data.get(field)).getData()[0];
+
+        // Checking for the field names
+        if (header.length != DATA_FIELD_NAMES.size()) {
+            throw new WrongStructureException(DATA_FIELD_NAMES);
+        }
+        for (int i = 0; i < header.length; i++) {
+            if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
+                throw new WrongStructureException(DATA_FIELD_NAMES);
+            }
+        }
+
+        /*
+         * Checking the data
+         */
+
+        // wpar
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // title
+        field++;
+        if (!(data.get(field) instanceof ScilabString)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // tol
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // tf
+        field++;
+        if (!(data.get(field) instanceof ScilabDouble)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // context
+        field++;
+        if (!(data.get(field) instanceof ScilabString) && !isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // void1
+        field++;
+        if (!isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // options
+        field++;
+        if (!(data.get(field) instanceof ScilabTList)) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // void2
+        field++;
+        if (!isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // void3
+        field++;
+        if (!isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+
+        // doc
+        field++;
+        if (!(data.get(field) instanceof ScilabList) && !isEmptyField(data.get(field))) {
+            throw new WrongTypeException(DATA_FIELD_NAMES, field);
+        }
+    }
+
+    // CSON: CyclomaticComplexity
+    // CSON: NPathComplexity
+
+    /**
+     * Fill the object with the data third field
+     *
+     * @param into
+     *            the current object to put data into.
+     */
+    private void fillWithThirdFields(ScicosParameters into) {
+        final boolean isColumnDominant = data.get(TOL_INDEX).getHeight() >= data.get(TOL_INDEX).getWidth();
+        final double[][] realPart = ((ScilabDouble) data.get(TOL_INDEX)).getRealPart();
+
+        // global index used to get the data
+        int[] indexes = { 0, 0 };
+
+        VectorOfDouble v = into.getProperties(controller);
+
+        v.set(ScicosParameters.INTEGRATOR_ABSOLUTE_TOLERANCE, realPart[indexes[0]][indexes[1]]);
+        incrementIndexes(indexes, isColumnDominant);
+
+        v.set(ScicosParameters.INTEGRATOR_RELATIVE_TOLERANCE, realPart[indexes[0]][indexes[1]]);
+        incrementIndexes(indexes, isColumnDominant);
+
+        v.set(ScicosParameters.TOLERANCE_ON_TIME, realPart[indexes[0]][indexes[1]]);
+        incrementIndexes(indexes, isColumnDominant);
+
+        v.set(ScicosParameters.MAX_INTEGRATION_TIME_INTERVAL, realPart[indexes[0]][indexes[1]]);
+        incrementIndexes(indexes, isColumnDominant);
+
+        v.set(ScicosParameters.REAL_TIME_SCALING, realPart[indexes[0]][indexes[1]]);
+        incrementIndexes(indexes, isColumnDominant);
+
+        v.set(ScicosParameters.SOLVER, realPart[indexes[0]][indexes[1]]);
+        incrementIndexes(indexes, isColumnDominant);
+
+        // Some times the maximum step size may not exist. Catch it.
+        try {
+            v.set(ScicosParameters.MAXIMUM_STEP_SIZE, realPart[indexes[0]][indexes[1]]);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // do nothing as the maximum step size will keep its default value.
+        }
+
+        try {
+            into.setProperties(controller, v);
+        } catch (PropertyVetoException e) {
+            Logger.getLogger(ScicosParametersElement.class.getName()).severe(e.toString());
+        }
+    }
+
+    /**
+     * Fill the object with the context (5th) field
+     *
+     * @param into
+     *            the current object to put data into.
+     */
+    private void fillContext(ScicosParameters into) {
+        final ScilabType contextType = data.get(CONTEXT_INDEX);
+
+        /*
+         * On an empty context the type is ScilabDouble.
+         */
+        if (contextType instanceof ScilabDouble) {
+            // preserve the default value
+            return;
+        }
+
+        /*
+         * Normal case
+         */
+        final boolean isColumnDominant = contextType.getHeight() >= contextType.getWidth();
+        final String[][] str = ((ScilabString) contextType).getData();
+        final int length = contextType.getHeight() + contextType.getWidth() - 1;
+
+        VectorOfString context = new VectorOfString(length);
+
+        int[] indexes = { 0, 0 };
+        for (int i = 0; i < length; i++) {
+            context.set(i, str[indexes[0]][indexes[1]]);
+            incrementIndexes(indexes, isColumnDominant);
+        }
+
+        try {
+            into.setContext(controller, context);
+        } catch (PropertyVetoException e) {
+            Logger.getLogger(ScicosParametersElement.class.getName()).severe(e.toString());
+        }
+    }
+
+    /**
+     * Test if the element can be decoded with this instance implementation.
+     *
+     * @param element
+     *            the element
+     * @return true when the implementation can be used to decode the element.
+     * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
+     */
+    @Override
+    public boolean canDecode(ScilabType element) {
+        data = (ScilabTList) element;
+
+        final String type = ((ScilabString) data.get(0)).getData()[0][0];
+        return type.equals(DATA_FIELD_NAMES.get(0));
+    }
+}
index 064191a..635c32c 100644 (file)
@@ -47,6 +47,7 @@ public class PreLoadedElement extends AbstractElement<PreLoaded> {
      * Default constructor
      */
     public PreLoadedElement() {
+        super(null);
     }
 
     /**
index 82c0eed..bd77f54 100644 (file)
@@ -48,6 +48,7 @@ public class StyleElement extends AbstractElement<mxStylesheet> {
      * Default constructor
      */
     public StyleElement() {
+        super(null);
     }
 
     /**
@@ -234,22 +235,4 @@ public class StyleElement extends AbstractElement<mxStylesheet> {
             throw new WrongTypeException(DATA_FIELD_NAMES, field);
         }
     }
-
-    /**
-     * Not used
-     *
-     * @param from
-     *            Not used
-     * @param element
-     *            Not used
-     * @return null
-     * @see org.scilab.modules.xcos.io.scicos.Element#encode(java.lang.Object,
-     *      org.scilab.modules.types.ScilabType)
-     */
-    @Override
-    @Deprecated
-    public ScilabType encode(mxStylesheet from, ScilabType element) {
-        return null;
-    }
-
 }
index 3f49b9f..0ff9873 100644 (file)
@@ -37,8 +37,7 @@ import com.mxgraph.util.mxStyleUtils;
 public final class BlockPositioning {
 
     /**
-     * The default grid size. This value is used when the grid size isn't
-     * accessible (on the palette).
+     * The default grid size. This value is used when the grid size isn't accessible (on the palette).
      */
     public static final double DEFAULT_GRIDSIZE = Double.MIN_NORMAL;
     /** The rotation step of the clockwise and anticlockwise rotation */
@@ -58,7 +57,7 @@ public final class BlockPositioning {
      * @param ports
      *            The ports we have to move on the side.
      */
-    public static void updateWestPortsPosition(final XcosDiagram diag, BasicBlock block, List <? extends BasicPort > ports) {
+    public static void updateWestPortsPosition(final XcosDiagram diag, BasicBlock block, List<? extends BasicPort> ports) {
 
         double gridSize = diag.getGridSize();
 
@@ -98,8 +97,7 @@ public final class BlockPositioning {
      */
     private static double calculateAlignedPosition(final double gridSize, final double segLength, int i) {
         /*
-         * The base position is the origin of the port geometry. It is the
-         * upper-left corner position.
+         * The base position is the origin of the port geometry. It is the upper-left corner position.
          */
         final double basePosition = (i + 1) * segLength;
 
@@ -109,8 +107,7 @@ public final class BlockPositioning {
         final double alignedBasePosition = basePosition - Math.IEEEremainder(basePosition, gridSize);
 
         /*
-         * The aligned position is the base position translated from origin to
-         * the middle of the port.
+         * The aligned position is the base position translated from origin to the middle of the port.
          */
         final double alignedPosition = alignedBasePosition - (BasicPort.DEFAULT_PORTSIZE / 2.0);
 
@@ -125,7 +122,7 @@ public final class BlockPositioning {
      * @param ports
      *            The ports we have to move on the side.
      */
-    public static void updateNorthPortsPosition(final XcosDiagram diag, BasicBlock block, List <? extends BasicPort > ports) {
+    public static void updateNorthPortsPosition(final XcosDiagram diag, BasicBlock block, List<? extends BasicPort> ports) {
         double gridSize = diag.getGridSize();
 
         final mxGeometry blockGeom = block.getGeometry();
@@ -159,7 +156,7 @@ public final class BlockPositioning {
      * @param ports
      *            The ports we have to move on the side.
      */
-    public static void updateEastPortsPosition(final XcosDiagram diag, BasicBlock block, List <? extends BasicPort > ports) {
+    public static void updateEastPortsPosition(final XcosDiagram diag, BasicBlock block, List<? extends BasicPort> ports) {
         double gridSize = diag.getGridSize();
 
         final mxGeometry blockGeom = block.getGeometry();
@@ -193,7 +190,7 @@ public final class BlockPositioning {
      * @param ports
      *            The ports we have to move on the side.
      */
-    public static void updateSouthPortsPosition(final XcosDiagram diag, BasicBlock block, List <? extends BasicPort > ports) {
+    public static void updateSouthPortsPosition(final XcosDiagram diag, BasicBlock block, List<? extends BasicPort> ports) {
         double gridSize = diag.getGridSize();
 
         final mxGeometry blockGeom = block.getGeometry();
@@ -239,8 +236,7 @@ public final class BlockPositioning {
     }
 
     /**
-     * Update the port position for the specified orientation. This function
-     * manage the flip and mirror properties.
+     * Update the port position for the specified orientation. This function manage the flip and mirror properties.
      *
      * @param block
      *            The block we are working on
@@ -261,10 +257,10 @@ public final class BlockPositioning {
         VectorOfDouble mvcAngle = new VectorOfDouble();
         controller.getObjectProperty(block.getUID(), Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
 
-        double flags = mvcAngle.get(0);
-        final boolean mirrored = flags == 4d;
-        final boolean flipped = flags == 8d;
-        final int angle = ( ((int) Math.round(mvcAngle.get(1))) % 360 + 360) % 360;
+        int flags = (int) mvcAngle.get(0);
+        final boolean mirrored = (flags & 0x0002) != 0;
+        final boolean flipped = (flags & 0x0001) != 0;
+        final int angle = (((int) Math.round(mvcAngle.get(1))) % 360 + 360) % 360;
 
         List<BasicPort> working = ports;
 
@@ -283,8 +279,7 @@ public final class BlockPositioning {
         }
 
         /*
-         * Ugly modification of the iter to update at the right position Works
-         * only for 0 - 90 - 180 - 270 angles.
+         * Ugly modification of the iter to update at the right position Works only for 0 - 90 - 180 - 270 angles.
          */
         Orientation rotated = rotateOrientation(iter, mirrored, flipped);
 
@@ -292,8 +287,7 @@ public final class BlockPositioning {
     }
 
     /**
-     * Ugly modification of the iter to update at the right position. Works only
-     * for 0 - 90 - 180 - 270 angles.
+     * Ugly modification of the iter to update at the right position. Works only for 0 - 90 - 180 - 270 angles.
      *
      * @param iter
      *            the real orientation
@@ -322,8 +316,7 @@ public final class BlockPositioning {
     }
 
     /**
-     * Update the ports positions according to the angle. This function doesn't
-     * handle order inversion.
+     * Update the ports positions according to the angle. This function doesn't handle order inversion.
      *
      * @param block
      *            The block we are working on
@@ -336,8 +329,7 @@ public final class BlockPositioning {
      */
     private static void updatePortsPosition(final XcosDiagram diag, BasicBlock block, Orientation iter, final double angle, List<BasicPort> working) {
         /*
-         * Ugly modification of the iter to update at the right position Works
-         * only for 0 - 90 - 180 - 270 angles.
+         * 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;
@@ -377,8 +369,9 @@ public final class BlockPositioning {
         VectorOfDouble mvcAngle = new VectorOfDouble();
         controller.getObjectProperty(block.getUID(), Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
 
-        final boolean mirrored = mvcAngle.get(0) == 4d;
-        final boolean flipped = mvcAngle.get(0) == 8d;
+        final int mirrorAndFlip = (int) mvcAngle.get(0);
+        final boolean flipped = (mirrorAndFlip & 0x0001) != 0;
+        final boolean mirrored = (mirrorAndFlip & 0x0002) != 0;
         final double angle = mvcAngle.get(1);
 
         final int childrenCount = block.getChildCount();
@@ -394,7 +387,6 @@ public final class BlockPositioning {
                 final String rot = Double.toString(orientation.getRelativeAngle(angle, port.getClass(), flipped, mirrored));
                 mxStyleUtils.setCellStyles(model, new Object[] { port }, XcosConstants.STYLE_ROTATION, rot);
 
-
                 diag.getModel().endUpdate();
             }
         }
@@ -417,11 +409,9 @@ public final class BlockPositioning {
         diag.getModel().endUpdate();
 
         /*
-         * FIXME: #6705; This placement trick doesn't work on the first block
-         * Dnd as the view is not revalidated.
+         * FIXME: #6705; This placement trick doesn't work on the first block Dnd as the view is not revalidated.
          *
-         * On block loading, parentDiagram is null thus placement is not
-         * performed.
+         * On block loading, parentDiagram is null thus placement is not performed.
          */
     }
 
@@ -434,9 +424,15 @@ public final class BlockPositioning {
     public static void toggleFlip(final XcosDiagram diag, BasicBlock block) {
         JavaController controller = new JavaController();
         VectorOfDouble mvcAngle = new VectorOfDouble();
-        controller.getObjectProperty(block.getUID(), Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
+        controller.getObjectProperty(block.getUID(), block.getKind(), ObjectProperties.ANGLE, mvcAngle);
+
+        // retrieve then mask the value
+        int mirrorAndFlip = (int) mvcAngle.get(0);
+        mirrorAndFlip ^= 0x0001;
+
+        mvcAngle.set(0, mirrorAndFlip);
+        controller.setObjectProperty(block.getUID(), block.getKind(), ObjectProperties.ANGLE, mvcAngle);
 
-        mvcAngle.set(0, mvcAngle.get(0) + 8d);
         updateBlockView(diag, block);
     }
 
@@ -449,9 +445,15 @@ public final class BlockPositioning {
     public static void toggleMirror(final XcosDiagram diag, BasicBlock block) {
         JavaController controller = new JavaController();
         VectorOfDouble mvcAngle = new VectorOfDouble();
-        controller.getObjectProperty(block.getUID(), Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
+        controller.getObjectProperty(block.getUID(), block.getKind(), ObjectProperties.ANGLE, mvcAngle);
+
+        // retrieve then mask the value
+        int mirrorAndFlip = (int) mvcAngle.get(0);
+        mirrorAndFlip ^= 0x0002;
+
+        mvcAngle.set(0, mirrorAndFlip);
+        controller.setObjectProperty(block.getUID(), block.getKind(), ObjectProperties.ANGLE, mvcAngle);
 
-        mvcAngle.set(0, mvcAngle.get(0) + 16d);
         updateBlockView(diag, block);
     }
 
index 98436eb..bd72fc5 100644 (file)
@@ -94,6 +94,17 @@ namespace std {
                     self->erase(it);
                 return true;
             }
+            void* asByteBuffer(int i, int capacity) {
+                (void) capacity;
+                void* buffer = nullptr;
+                int size = int(self->size()) ;
+                if (i>=0 && i<size) {
+                    buffer = ((char*) self->data()) + i;
+                } else {
+                    throw std::out_of_range("vector index out of range");
+                }
+                return buffer;
+            }
         }
     };
 
@@ -209,6 +220,27 @@ namespace std {
 %apply std::string &OUTPUT { std::string &v };
 
 /*
+ * Custom typemap to retrieve a view of the memory as a ByteBuffer
+ */
+%typemap(jni)     void* "jobject"
+%typemap(jtype)   void* "java.nio.ByteBuffer"
+%typemap(jstype)  void* "java.nio.ByteBuffer"
+
+%typemap(out) void* {
+    if (arg3 <= 0) {
+        arg3 = arg1->size() - arg2;
+    } else if (arg1->size() < arg3) {
+        throw std::out_of_range("vector index out of range");
+    }
+    $result = JCALL2(NewDirectByteBuffer, jenv, $1, arg3 * sizeof(decltype(arg1->back())));
+}
+%typemap(javaout) void* {
+    java.nio.ByteBuffer buffer = $jnicall;
+    buffer.order(java.nio.ByteOrder.nativeOrder());
+    return buffer;
+  }
+
+/*
  * Generate the View interface
  */
 %feature("director", assumeoverride=0) org_scilab_modules_scicos::View;
index c951759..efff679 100644 (file)
@@ -713,6 +713,17 @@ SWIGINTERN bool std_vector_Sl_int_Sg__remove(std::vector< int > *self,std::vecto
                     self->erase(it);
                 return true;
             }
+SWIGINTERN void *std_vector_Sl_int_Sg__asByteBuffer(std::vector< int > *self,int i,int capacity){
+                (void) capacity;
+                void* buffer = nullptr;
+                int size = int(self->size()) ;
+                if (i>=0 && i<size) {
+                    buffer = ((char*) self->data()) + i;
+                } else {
+                    throw std::out_of_range("vector index out of range");
+                }
+                return buffer;
+            }
 SWIGINTERN bool std_vector_Sl_bool_Sg__get(std::vector< bool > *self,int i){
                 int size = int(self->size());
                 if (i>=0 && i<size)
@@ -781,6 +792,17 @@ SWIGINTERN bool std_vector_Sl_double_Sg__remove(std::vector< double > *self,std:
                     self->erase(it);
                 return true;
             }
+SWIGINTERN void *std_vector_Sl_double_Sg__asByteBuffer(std::vector< double > *self,int i,int capacity){
+                (void) capacity;
+                void* buffer = nullptr;
+                int size = int(self->size()) ;
+                if (i>=0 && i<size) {
+                    buffer = ((char*) self->data()) + i;
+                } else {
+                    throw std::out_of_range("vector index out of range");
+                }
+                return buffer;
+            }
 SWIGINTERN bool std_vector_Sl_std_string_Sg__contains(std::vector< std::string > *self,std::string const &o){
                return std::find(self->begin(), self->end(), o) != self->end();
             }
@@ -820,6 +842,17 @@ SWIGINTERN bool std_vector_Sl_std_string_Sg__remove(std::vector< std::string > *
                     self->erase(it);
                 return true;
             }
+SWIGINTERN void *std_vector_Sl_std_string_Sg__asByteBuffer(std::vector< std::string > *self,int i,int capacity){
+                (void) capacity;
+                void* buffer = nullptr;
+                int size = int(self->size()) ;
+                if (i>=0 && i<size) {
+                    buffer = ((char*) self->data()) + i;
+                } else {
+                    throw std::out_of_range("vector index out of range");
+                }
+                return buffer;
+            }
 SWIGINTERN bool std_vector_Sl_ScicosID_Sg__contains(std::vector< ScicosID > *self,long long const &o){
                return std::find(self->begin(), self->end(), o) != self->end();
             }
@@ -859,6 +892,17 @@ SWIGINTERN bool std_vector_Sl_ScicosID_Sg__remove(std::vector< ScicosID > *self,
                     self->erase(it);
                 return true;
             }
+SWIGINTERN void *std_vector_Sl_ScicosID_Sg__asByteBuffer(std::vector< ScicosID > *self,int i,int capacity){
+                (void) capacity;
+                void* buffer = nullptr;
+                int size = int(self->size()) ;
+                if (i>=0 && i<size) {
+                    buffer = ((char*) self->data()) + i;
+                } else {
+                    throw std::out_of_range("vector index out of range");
+                }
+                return buffer;
+            }
 
 static void register_view(const std::string& name, org_scilab_modules_scicos::View* view) {
   org_scilab_modules_scicos::Controller::register_view(name, view);
@@ -2236,6 +2280,32 @@ SWIGEXPORT jboolean JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_Vecto
 }
 
 
+SWIGEXPORT jobject JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_VectorOfInt_1asByteBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
+  jobject jresult = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  int arg2 ;
+  int arg3 ;
+  void *result = 0 ;
+  
+  (void)jenv;
+  (void)jcls;
+  (void)jarg1_;
+  arg1 = *(std::vector< int > **)&jarg1; 
+  arg2 = (int)jarg2; 
+  arg3 = (int)jarg3; 
+  result = (void *)std_vector_Sl_int_Sg__asByteBuffer(arg1,arg2,arg3);
+  {
+    if (arg3 <= 0) {
+      arg3 = arg1->size() - arg2;
+    } else if (arg1->size() < arg3) {
+      throw std::out_of_range("vector index out of range");
+    }
+    jresult = jenv->NewDirectByteBuffer(result, arg3 * sizeof(decltype(arg1->back())));
+  }
+  return jresult;
+}
+
+
 SWIGEXPORT void JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_delete_1VectorOfInt(JNIEnv *jenv, jclass jcls, jlong jarg1) {
   std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   
@@ -2692,6 +2762,32 @@ SWIGEXPORT jboolean JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_Vecto
 }
 
 
+SWIGEXPORT jobject JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_VectorOfDouble_1asByteBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
+  jobject jresult = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  int arg2 ;
+  int arg3 ;
+  void *result = 0 ;
+  
+  (void)jenv;
+  (void)jcls;
+  (void)jarg1_;
+  arg1 = *(std::vector< double > **)&jarg1; 
+  arg2 = (int)jarg2; 
+  arg3 = (int)jarg3; 
+  result = (void *)std_vector_Sl_double_Sg__asByteBuffer(arg1,arg2,arg3);
+  {
+    if (arg3 <= 0) {
+      arg3 = arg1->size() - arg2;
+    } else if (arg1->size() < arg3) {
+      throw std::out_of_range("vector index out of range");
+    }
+    jresult = jenv->NewDirectByteBuffer(result, arg3 * sizeof(decltype(arg1->back())));
+  }
+  return jresult;
+}
+
+
 SWIGEXPORT void JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_delete_1VectorOfDouble(JNIEnv *jenv, jclass jcls, jlong jarg1) {
   std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   
@@ -2975,6 +3071,32 @@ SWIGEXPORT jboolean JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_Vecto
 }
 
 
+SWIGEXPORT jobject JNICALL Java_org_scilab_modules_xcos_JavaControllerJNI_VectorOfString_1asByteBuffer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
+  jobject jresult = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  int arg2 ;
+  int arg3 ;
+  void *result = 0 ;
+  
+  (void)jenv;
+  (void)jcls;
+  (void)jarg1_;
+  arg1 = *(std::vector< std::string > **)&jarg1; 
+  arg2 =&nb