Xcos: fix bugs when loading XCOS or ZCOS files 75/17375/2
Clément DAVID [Thu, 22 Oct 2015 07:57:47 +0000 (09:57 +0200)]
* Add an UID for Annotation, Link and Port
* decode link's inner ports
* manage duplicated id element (are invalid xml) PARTIAL FIX
* Render blocks well (size and flip)

Change-Id: I416782be9c73744fe082d2932ca396bf543018d2

21 files changed:
scilab/modules/scicos/src/cpp/Model_getObjectProperties.cpp
scilab/modules/scicos/src/cpp/Model_setObjectProperties.cpp
scilab/modules/scicos/src/cpp/model/Annotation.hxx
scilab/modules/scicos/src/cpp/model/Block.hxx
scilab/modules/scicos/src/cpp/model/Link.hxx
scilab/modules/scicos/src/cpp/model/Port.hxx
scilab/modules/scicos/src/cpp/view_scilab/GraphicsAdapter.cpp
scilab/modules/xcos/src/java/org/scilab/modules/xcos/UpdateStyleFromInterfunctionAdapter.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/actions/RotateAction.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
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/XcosFileType.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/BlockHandler.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/LinkHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/PortHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/RawDataHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/SAXHandler.java

index 529cd19..4c7d480 100644 (file)
@@ -227,6 +227,9 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
             case STYLE:
                 o->getStyle(v);
                 return true;
+            case UID:
+                o->getUID(v);
+                return true;
             default:
                 break;
         }
@@ -284,6 +287,9 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
             case LABEL:
                 o->getLabel(v);
                 return true;
+            case UID:
+                o->getUID(v);
+                return true;
             default:
                 break;
         }
@@ -299,6 +305,9 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
             case LABEL:
                 o->getLabel(v);
                 return true;
+            case UID:
+                o->getUID(v);
+                return true;
             default:
                 break;
         }
index 1678ca3..34b84f4 100644 (file)
@@ -294,6 +294,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
                 return o->setFontSize(v);
             case STYLE:
                 return o->setStyle(v);
+            case UID:
+                return o->setUID(v);
             default:
                 break;
         }
@@ -341,6 +343,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         {
             case LABEL:
                 return o->setLabel(v);
+            case UID:
+                return o->setUID(v);
             default:
                 break;
         }
@@ -354,6 +358,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
                 return o->setStyle(v);
             case LABEL:
                 return o->setLabel(v);
+            case UID:
+                return o->setUID(v);
             default:
                 break;
         }
index d042b0c..47749bf 100644 (file)
@@ -29,12 +29,12 @@ class Annotation: public BaseObject
 {
 public:
     Annotation(): BaseObject(ANNOTATION), m_parentDiagram(ScicosID()), m_parentBlock(ScicosID()),
-        m_description("Text"), m_font("2"), m_font_size("1"), m_style(""), m_relatedTo(ScicosID())
+        m_description("Text"), m_font("2"), m_font_size("1"), m_style(""), m_relatedTo(ScicosID()), m_uid()
     {
         m_geometry = {0, 0, 2, 1};
     };
     Annotation(const Annotation& o) : BaseObject(ANNOTATION), m_parentDiagram(o.m_parentDiagram), m_parentBlock(o.m_parentBlock), m_geometry(o.m_geometry),
-        m_description(o.m_description), m_font(o.m_font), m_font_size(o.m_font_size), m_style(o.m_style), m_relatedTo(o.m_relatedTo) {};
+        m_description(o.m_description), m_font(o.m_font), m_font_size(o.m_font_size), m_style(o.m_style), m_relatedTo(o.m_relatedTo), m_uid(o.m_uid) {};
     ~Annotation() = default;
 
 private:
@@ -174,6 +174,22 @@ private:
         return SUCCESS;
     }
 
+    void getUID(std::string& data) const
+    {
+        data = m_uid;
+    }
+
+    update_status_t setUID(const std::string& data)
+    {
+        if (data == m_uid)
+        {
+            return NO_CHANGES;
+        }
+
+        m_uid = data;
+        return SUCCESS;
+    }
+
 private:
     ScicosID m_parentDiagram;
     ScicosID m_parentBlock;
@@ -184,6 +200,7 @@ private:
     std::string m_font_size;
     std::string m_style;
     ScicosID m_relatedTo;
+    std::string m_uid;
 };
 
 } /* namespace model */
index 4297f32..21a0632 100644 (file)
@@ -97,7 +97,7 @@ struct Angle
     bool mirror;
     double theta;
 
-    Angle() : flip(true), mirror(false), theta(0) {};
+    Angle() : flip(false), mirror(false), theta(0) {};
     Angle(const Angle& a) : flip(a.flip), mirror(a.mirror), theta(a.theta) {};
     Angle(const std::vector<double>& a) :
         flip(  ((static_cast<int>(a[0]) & 0x0001) == 0) ? false : true),
index 327f6eb..3bb9317 100644 (file)
@@ -38,9 +38,9 @@ enum link_kind_t
 class Link: public BaseObject
 {
 public:
-    Link() : BaseObject(LINK), m_parentDiagram(ScicosID()), m_parentBlock(ScicosID()), m_sourcePort(ScicosID()), m_destinationPort(ScicosID()), m_controlPoints(),
+    Link() : BaseObject(LINK), m_parentDiagram(ScicosID()), m_parentBlock(ScicosID()), m_sourcePort(ScicosID()), m_destinationPort(ScicosID()), m_uid(), m_controlPoints(),
         m_label(), m_thick(2), m_color(1), m_linkKind(regular) {};
-    Link(const Link& o) : BaseObject(LINK), m_parentDiagram(o.m_parentDiagram), m_parentBlock(o.m_parentBlock), m_sourcePort(o.m_sourcePort), m_destinationPort(o.m_destinationPort),
+    Link(const Link& o) : BaseObject(LINK), m_parentDiagram(o.m_parentDiagram), m_parentBlock(o.m_parentBlock), m_sourcePort(o.m_sourcePort), m_destinationPort(o.m_destinationPort),  m_uid(o.m_uid),
         m_controlPoints(o.m_controlPoints), m_label(o.m_label), m_thick(o.m_thick), m_color(o.m_color), m_linkKind(o.m_linkKind) {};
     ~Link() = default;
 
@@ -210,6 +210,22 @@ private:
         return SUCCESS;
     }
 
+    void getUID(std::string& data) const
+    {
+        data = m_uid;
+    }
+
+    update_status_t setUID(const std::string& data)
+    {
+        if (data == m_uid)
+        {
+            return NO_CHANGES;
+        }
+
+        m_uid = data;
+        return SUCCESS;
+    }
+
 private:
     ScicosID m_parentDiagram;
     ScicosID m_parentBlock;
@@ -217,6 +233,7 @@ private:
     ScicosID m_sourcePort;
     ScicosID m_destinationPort;
 
+    std::string m_uid;
     // used to store, user-defined control points
     std::vector<double> m_controlPoints;
 
index 3336cdc..209d472 100644 (file)
@@ -28,18 +28,34 @@ namespace model
 class Port: public BaseObject
 {
 public:
-    Port() : BaseObject(PORT), m_dataType(0), m_sourceBlock(ScicosID()), m_kind(PORT_UNDEF), m_implicit(false),
+    Port() : BaseObject(PORT), m_uid(), m_dataType(0), m_sourceBlock(ScicosID()), m_kind(PORT_UNDEF), m_implicit(false),
         m_style(), m_label(), m_firing(0)
     {
         m_connectedSignals = {ScicosID()};
     }
-    Port(const Port& o) : BaseObject(PORT), m_dataType(o.m_dataType), m_sourceBlock(o.m_sourceBlock), m_kind(o.m_kind), m_implicit(o.m_implicit),
+    Port(const Port& o) : BaseObject(PORT), m_uid(o.m_uid), m_dataType(o.m_dataType), m_sourceBlock(o.m_sourceBlock), m_kind(o.m_kind), m_implicit(o.m_implicit),
         m_style(o.m_style), m_label(o.m_label), m_firing(0), m_connectedSignals(o.m_connectedSignals) {};
     ~Port() = default;
 
 private:
     friend class ::org_scilab_modules_scicos::Model;
 
+    void getUID(std::string& data) const
+    {
+        data = m_uid;
+    }
+
+    update_status_t setUID(const std::string& data)
+    {
+        if (data == m_uid)
+        {
+            return NO_CHANGES;
+        }
+
+        m_uid = data;
+        return SUCCESS;
+    }
+
     const std::vector<ScicosID>& getConnectedSignals() const
     {
         return m_connectedSignals;
@@ -191,6 +207,7 @@ private:
     }
 
 private:
+    std::string m_uid;
     Datatype* m_dataType;
     ScicosID m_sourceBlock;
     portKind m_kind;
index 5219277..98a314e 100644 (file)
@@ -156,7 +156,10 @@ struct flip
         std::vector<double> angle;
         controller.getObjectProperty(adaptee, BLOCK, ANGLE, angle);
 
-        data[0] = static_cast<int>(angle[0]);
+        int mirrorAndFlip = angle[0];
+        mirrorAndFlip ^= 1 << 0;
+
+        data[0] = mirrorAndFlip;
         return o;
     }
 
@@ -169,7 +172,7 @@ struct flip
         }
 
         types::Bool* current = v->getAs<types::Bool>();
-        if (current->isScalar() != true)
+        if (!current->isScalar())
         {
             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s: %d-by-%d expected.\n"), "graphics", "flip", 1, 1);
             return false;
@@ -179,7 +182,9 @@ struct flip
         std::vector<double> angle;
         controller.getObjectProperty(adaptee, BLOCK, ANGLE, angle);
 
-        angle[0] = (current->get(0) == false) ? 0 : 1;
+        int mirrorAndFlip = static_cast<int>(angle[0]);
+        current->get(0) ? mirrorAndFlip &= ~(1 << 0) : mirrorAndFlip |= 1 << 0;
+        angle[0] = mirrorAndFlip;
 
         controller.setObjectProperty(adaptee, BLOCK, ANGLE, angle);
         return true;
index 805ae46..6ec6349 100644 (file)
@@ -30,7 +30,7 @@ public final class UpdateStyleFromInterfunctionAdapter extends XcosViewListener
      */
     @Override
     public void propertyUpdated(long uid, Kind kind, ObjectProperties property, UpdateStatus status) {
-        if (status != UpdateStatus.SUCCESS) {
+        if (status != UpdateStatus.SUCCESS || kind != Kind.BLOCK) {
             return;
         }
 
index de23a02..f841602 100644 (file)
@@ -20,12 +20,9 @@ import java.awt.event.KeyEvent;
 import org.scilab.modules.graph.ScilabGraph;
 import org.scilab.modules.graph.actions.base.VertexSelectionDependantAction;
 import org.scilab.modules.gui.menuitem.MenuItem;
-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.block.BasicBlock;
 import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.utils.BlockPositioning;
 import org.scilab.modules.xcos.utils.XcosMessages;
 
 /**
@@ -74,24 +71,17 @@ public class FlipAction extends VertexSelectionDependantAction {
 
             Object[] allCells = ((XcosDiagram) getGraph(null)).getSelectionCells();
 
-            JavaController controller = new JavaController();
-            VectorOfDouble mvcAngle = new VectorOfDouble();
+            try {
+                getGraph(null).getModel().beginUpdate();
 
-            getGraph(null).getModel().beginUpdate();
-            for (int i = 0; i < allCells.length; ++i) {
-                if (allCells[i] instanceof BasicBlock) {
-                    long uid = ((BasicBlock) allCells[i]).getUID();
-                    controller.getObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
-
-                    // 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);
+                for (int i = 0; i < allCells.length; ++i) {
+                    if (allCells[i] instanceof BasicBlock) {
+                        BlockPositioning.toggleFlip((XcosDiagram) getGraph(null), (BasicBlock) allCells[i]);
+                    }
                 }
+            } finally {
+                getGraph(null).getModel().endUpdate();
             }
-            getGraph(null).getModel().endUpdate();
         }
     }
 
index 7e82fa9..d9e8157 100644 (file)
@@ -19,12 +19,9 @@ import java.awt.event.KeyEvent;
 import org.scilab.modules.graph.ScilabGraph;
 import org.scilab.modules.graph.actions.base.VertexSelectionDependantAction;
 import org.scilab.modules.gui.menuitem.MenuItem;
-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.block.BasicBlock;
 import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.utils.BlockPositioning;
 import org.scilab.modules.xcos.utils.XcosMessages;
 
 /**
@@ -73,24 +70,17 @@ public class MirrorAction extends VertexSelectionDependantAction {
 
             Object[] allCells = ((XcosDiagram) getGraph(null)).getSelectionCells();
 
-            JavaController controller = new JavaController();
-            VectorOfDouble mvcAngle = new VectorOfDouble();
+            try {
+                getGraph(null).getModel().beginUpdate();
 
-            getGraph(null).getModel().beginUpdate();
-            for (int i = 0; i < allCells.length; ++i) {
-                if (allCells[i] instanceof BasicBlock) {
-                    long uid = ((BasicBlock) allCells[i]).getUID();
-                    controller.getObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
-
-                    // 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);
+                for (int i = 0; i < allCells.length; ++i) {
+                    if (allCells[i] instanceof BasicBlock) {
+                        BlockPositioning.toggleMirror((XcosDiagram) getGraph(null), (BasicBlock) allCells[i]);
+                    }
                 }
+            } finally {
+                getGraph(null).getModel().endUpdate();
             }
-            getGraph(null).getModel().endUpdate();
         }
     }
 
index b8614eb..670483c 100644 (file)
@@ -20,12 +20,9 @@ import java.awt.event.KeyEvent;
 import org.scilab.modules.graph.ScilabGraph;
 import org.scilab.modules.graph.actions.base.VertexSelectionDependantAction;
 import org.scilab.modules.gui.menuitem.MenuItem;
-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.block.BasicBlock;
 import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.utils.BlockPositioning;
 import org.scilab.modules.xcos.utils.XcosMessages;
 
 /**
@@ -72,23 +69,19 @@ public class RotateAction extends VertexSelectionDependantAction {
     @Override
     public void actionPerformed(ActionEvent e) {
         if (((XcosDiagram) getGraph(null)).getSelectionCells().length != 0) {
+            Object[] allCells = ((XcosDiagram) getGraph(null)).getSelectionCells();
 
-            Object[] allCells = ((XcosDiagram) getGraph(null))
-                                .getSelectionCells();
+            try {
+                getGraph(null).getModel().beginUpdate();
 
-            JavaController controller = new JavaController();
-            VectorOfDouble mvcAngle = new VectorOfDouble();
-
-            getGraph(null).getModel().beginUpdate();
-            for (int i = 0; i < allCells.length; ++i) {
-                if (allCells[i] instanceof BasicBlock) {
-                    long uid = ((BasicBlock) allCells[i]).getUID();
-                    controller.getObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
-                    mvcAngle.set(1, mvcAngle.get(1) + 90d);
-                    controller.setObjectProperty(uid, Kind.BLOCK, ObjectProperties.ANGLE, mvcAngle);
+                for (int i = 0; i < allCells.length; ++i) {
+                    if (allCells[i] instanceof BasicBlock) {
+                        BlockPositioning.rotateAllPorts((XcosDiagram) getGraph(null), (BasicBlock) allCells[i]);
+                    }
                 }
+            } finally {
+                getGraph(null).getModel().endUpdate();
             }
-            getGraph(null).getModel().endUpdate();
         }
     }
 }
index 315234f..fe55796 100644 (file)
@@ -111,14 +111,8 @@ public class XcosCell extends ScilabGraphUniqueObject {
         JavaController controller = new JavaController();
         switch (getKind()) {
             case ANNOTATION:
-                controller.setObjectProperty(getUID(), getKind(), ObjectProperties.UID, id);
-                break;
             case BLOCK:
-                controller.setObjectProperty(getUID(), getKind(), ObjectProperties.UID, id);
-                break;
             case LINK:
-                controller.setObjectProperty(getUID(), getKind(), ObjectProperties.UID, id);
-                break;
             case PORT:
                 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.UID, id);
                 break;
index 892b4f9..37e33ba 100644 (file)
@@ -18,9 +18,8 @@ import static org.scilab.modules.action_binding.highlevel.ScilabInterpreterManag
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.EnumSet;
+import java.util.HashMap;
 import java.util.Optional;
 
 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
@@ -49,7 +48,6 @@ import org.scilab.modules.xcos.utils.BlockPositioning;
 
 import com.mxgraph.model.mxCell;
 import com.mxgraph.model.mxGeometry;
-import com.mxgraph.model.mxICell;
 import com.mxgraph.util.mxPoint;
 
 /**
@@ -57,6 +55,9 @@ import com.mxgraph.util.mxPoint;
  */
 public final class XcosCellFactory {
 
+    /** Size compatibility for user defined blocks */
+    private static final double DEFAULT_SIZE_FACTOR = 20.0;
+
     /** Default singleton constructor */
     private XcosCellFactory() {
         // This class is a static singleton
@@ -135,7 +136,7 @@ public final class XcosCellFactory {
          * Allocation some pre-sized stash data
          */
         final ArrayList<BasicLink> links = new ArrayList<>(childrenLen / 2);
-        final ArrayList<BasicPort> ports = new ArrayList<>(childrenLen);
+        final HashMap<Long, BasicPort> ports = new HashMap<>(childrenLen);
 
         /*
          * Create the XcosCell objects and store some of them for later use
@@ -151,8 +152,11 @@ 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)
+                    .map(c -> (BasicPort) c)
+                    .forEach(c -> ports.put(c.getUID(), c));
                     break;
                 case LINK:
                     BasicLink l = createLink(controller, uid, kind);
@@ -167,8 +171,6 @@ public final class XcosCellFactory {
         /*
          * Relink the links on the XcosCell part
          */
-        Comparator<XcosCell> compare = (c1, c2) -> (int) (c1.getUID() - c2.getUID());
-        Collections.sort(ports, compare);
         for (BasicLink l : links) {
             long[] src = new long[1];
             controller.getObjectProperty(l.getUID(), l.getKind(), ObjectProperties.SOURCE_PORT, src);
@@ -176,17 +178,19 @@ public final class XcosCellFactory {
             long[] dest = new long[1];
             controller.getObjectProperty(l.getUID(), l.getKind(), ObjectProperties.DESTINATION_PORT, dest);
 
-            int srcIndex = Collections.binarySearch(ports, new XcosCell(src[0], Kind.PORT), compare);
-            if (srcIndex >= 0) {
-                l.setSource(ports.get(srcIndex));
+            BasicPort srcPort = ports.get(src[0]);
+            if (srcPort != null) {
+                l.setSource(srcPort);
             } else {
+                //               FIXME Commented for the alpha release
                 throw new IllegalStateException();
             }
 
-            int destIndex = Collections.binarySearch(ports, new XcosCell(dest[0], Kind.PORT), compare);
-            if (destIndex >= 0) {
-                l.setTarget(ports.get(destIndex));
+            BasicPort destPort = ports.get(dest[0]);;
+            if (destPort != null) {
+                l.setTarget(destPort);
             } else {
+                //               FIXME Commented for the alpha release
                 throw new IllegalStateException();
             }
         }
@@ -316,6 +320,12 @@ public final class XcosCellFactory {
          */
         insertPortChildren(controller, block);
 
+        String[] strUID = new String[1];
+        controller.getObjectProperty(block.getUID(), block.getKind(), ObjectProperties.UID, strUID);
+        if (!strUID[0].isEmpty()) {
+            block.setId(strUID[0]);
+        }
+
         String[] style = new String[1];
         controller.getObjectProperty(block.getUID(), block.getKind(), ObjectProperties.STYLE, style);
         if (style[0].isEmpty()) {
@@ -326,9 +336,22 @@ public final class XcosCellFactory {
 
         VectorOfDouble geom = new VectorOfDouble(4);
         controller.getObjectProperty(block.getUID(), block.getKind(), ObjectProperties.GEOMETRY, geom);
-        block.setGeometry(new mxGeometry(geom.get(0), geom.get(1), geom.get(2), geom.get(3)));
 
-        // FIXME find a way to reuse the Scicos compat handler from org.scilab.modules.xcos.io.scicos
+        /*
+         * Compatibility to ease user definition
+         */
+        double x = geom.get(0);
+        double y = geom.get(1);
+        double w = geom.get(2) * DEFAULT_SIZE_FACTOR;
+        double h = geom.get(3) * DEFAULT_SIZE_FACTOR;
+
+        /*
+         * Invert the y-axis value and translate it.
+         */
+        y = -y - h;
+
+
+        block.setGeometry(new mxGeometry(x, y, w, h));
 
         return block;
     }
@@ -401,9 +424,10 @@ public final class XcosCellFactory {
         VectorOfScicosID modelChildren = new VectorOfScicosID();
         controller.getObjectProperty(parent.getUID(), parent.getKind(), property, modelChildren);
 
-        mxICell[] children = new mxICell[modelChildren.size()];
+        XcosCell[] children = new XcosCell[modelChildren.size()];
         for (int i = 0; i < children.length; i++) {
-            children[i] = createPort(controller, modelChildren.get(i), property);
+            XcosCell child = createPort(controller, modelChildren.get(i), property);
+            children[i] = child;
         }
         Arrays.stream(children).forEach(c -> parent.insert(c));
     }
@@ -425,30 +449,47 @@ public final class XcosCellFactory {
      * @return a newly allocated port
      */
     private static final BasicPort createPort(final JavaController controller, long uid, final ObjectProperties property) {
+        BasicPort port;
         boolean[] isImplicit = { false };
 
         switch (property) {
             case INPUTS:
                 controller.getObjectProperty(uid, Kind.PORT, ObjectProperties.IMPLICIT, isImplicit);
                 if (isImplicit[0]) {
-                    return new ImplicitInputPort(uid);
+                    port = new ImplicitInputPort(uid);
                 } else {
-                    return new ExplicitInputPort(uid);
+                    port = new ExplicitInputPort(uid);
                 }
+                break;
             case OUTPUTS:
                 controller.getObjectProperty(uid, Kind.PORT, ObjectProperties.IMPLICIT, isImplicit);
                 if (isImplicit[0]) {
-                    return new ImplicitOutputPort(uid);
+                    port = new ImplicitOutputPort(uid);
                 } else {
-                    return new ExplicitOutputPort(uid);
+                    port = new ExplicitOutputPort(uid);
                 }
+                break;
             case EVENT_INPUTS:
-                return new ControlPort(uid);
+                port = new ControlPort(uid);
+                break;
             case EVENT_OUTPUTS:
-                return new CommandPort(uid);
+                port = new CommandPort(uid);
+                break;
             default:
                 return null;
         }
+
+        /*
+         * Setup JGraphX properties
+         */
+
+        String[] childUID = new String[1];
+        controller.getObjectProperty(port.getUID(), port.getKind(), ObjectProperties.UID, childUID);
+        if (!childUID[0].isEmpty()) {
+            port.setId(childUID[0]);
+        }
+
+        return port;
     }
 
     /*
@@ -477,6 +518,13 @@ public final class XcosCellFactory {
         /*
          * Synchronize model information back to the JGraphX data
          */
+
+        String[] strUID = new String[1];
+        controller.getObjectProperty(uid, kind, ObjectProperties.UID, strUID);
+        if (!strUID[0].isEmpty()) {
+            link.setId(strUID[0]);
+        }
+
         VectorOfDouble controlPoints = new VectorOfDouble();
         controller.getObjectProperty(uid, kind, ObjectProperties.CONTROL_POINTS, controlPoints);
         final int pointsLen = controlPoints.size() / 2;
index 5f23f9c..b1f1e60 100644 (file)
@@ -42,59 +42,6 @@ import org.scilab.modules.xcos.VectorOfDouble;
  */
 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;
@@ -108,26 +55,7 @@ public class ScilabTypeCoder {
     /** 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);
-        }
     }
 
     /*
@@ -168,13 +96,13 @@ public class ScilabTypeCoder {
                 encode((ScilabString) var, vec);
                 break;
             case sci_list:
-                encode((ArrayList<ScilabType>) var, vec);
+                encode((ArrayList<ScilabType>) var, vec, var.getType());
                 break;
             case sci_mlist:
-                encode((ArrayList<ScilabType>) var, vec);
+                encode((ArrayList<ScilabType>) var, vec, var.getType());
                 break;
             case sci_tlist:
-                encode((ArrayList<ScilabType>) var, vec);
+                encode((ArrayList<ScilabType>) var, vec, var.getType());
                 break;
             default:
                 break;
@@ -193,7 +121,7 @@ public class ScilabTypeCoder {
      */
     private void encode(ScilabDouble var, VectorOfDouble vec) {
         // Header
-        encodeHeader(var, vec, NativeScilabType.ScilabDouble);
+        encodeHeader(var, vec, ScilabTypeEnum.sci_matrix);
 
         // specific flag for managing the complex case
         if (var.isReal()) {
@@ -217,37 +145,6 @@ public class ScilabTypeCoder {
     }
 
     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;
@@ -280,7 +177,7 @@ public class ScilabTypeCoder {
         }
 
         // Header
-        encodeHeader(var, vec, detected);
+        encodeHeader(var, vec, ScilabTypeEnum.sci_ints);
 
         // push the data on a pre-allocated space
         final int requiredBytes = sizeof * var.getHeight() * var.getWidth();
@@ -315,7 +212,7 @@ public class ScilabTypeCoder {
 
     private void encode(ScilabBoolean var, VectorOfDouble vec) {
         // header
-        encodeHeader(var, vec, NativeScilabType.ScilabBool);
+        encodeHeader(var, vec, ScilabTypeEnum.sci_boolean);
 
         // put all the boolean as int accordingly to Scilab 6 implementation
         final int requiredBytes = Integer.BYTES * var.getHeight() * var.getWidth();
@@ -334,7 +231,7 @@ public class ScilabTypeCoder {
 
     private void encode(ScilabString var, VectorOfDouble vec) {
         // header
-        encodeHeader(var, vec, NativeScilabType.ScilabString);
+        encodeHeader(var, vec, ScilabTypeEnum.sci_strings);
 
         // add the offset table which contains the offset of each UTF-8 encoded strings
         int offsetTableStart = vec.size();
@@ -360,9 +257,9 @@ public class ScilabTypeCoder {
         }
     }
 
-    private void encode(ArrayList<ScilabType> var, VectorOfDouble vec) {
+    private void encode(ArrayList<ScilabType> var, VectorOfDouble vec, ScilabTypeEnum as) {
         // header
-        encodeHeader(var, vec, NativeScilabType.ScilabList);
+        encodeHeader(var, vec, as);
 
         // encode list content
         for (ScilabType localVar : var) {
@@ -377,52 +274,43 @@ public class ScilabTypeCoder {
      *            the scilab matrix type to encode
      * @param vec
      *            the raw encoded data container
+     * @param as
+     *            the type to encode
      * @param detected
      *            the detected type
      */
     @SuppressWarnings({ "unchecked", "fallthrough" })
-    private void encodeHeader(Object var, VectorOfDouble vec, final NativeScilabType detected) {
+    private void encodeHeader(Object var, VectorOfDouble vec, final ScilabTypeEnum as) {
         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:
+        switch (as) {
+            case sci_boolean:
+            case sci_ints:
+            case sci_matrix:
+            case sci_strings:
                 matrix = (ScilabType) var;
                 break;
-            case ScilabList:
-            case ScilabMList:
-            case ScilabTList:
+            case sci_list:
+            case sci_mlist:
+            case sci_tlist:
                 list = (ArrayList<ScilabType>) var;
                 break;
-
-            case ScilabStruct:
-                map = (Map<String, ScilabType>) var;
-                break;
             default:
                 throw new IllegalArgumentException();
         }
 
-        vec.add(detected.ordinal());
+        vec.add(as.swigValue());
+        if (matrix instanceof ScilabInteger) {
+            vec.add(((ScilabInteger) matrix).getPrec().swigValue());
+        }
         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();
         }
@@ -612,6 +500,9 @@ public class ScilabTypeCoder {
     private ScilabType decodeHeader(VectorOfDouble vec) {
         int nativeScilabType = (int) vec.get(position++);
 
+        // specific integer sub-type
+        int precision = 0;
+
         // for data[][]-based type
         int height = 0;
         int width = 0;
@@ -619,11 +510,13 @@ public class ScilabTypeCoder {
         // for ArrayList-based type
         int listLen = 0;
 
-        final JavaScilabType type = typeMap.get(nativeScilabType);
-        switch (type.type) {
+        final ScilabTypeEnum type = ScilabTypeEnum.swigToEnum(nativeScilabType);
+        switch (type) {
+            case sci_ints:
+                // special case for integer precision
+                precision = (int) vec.get(position++);
             case sci_matrix:
             case sci_boolean:
-            case sci_ints:
             case sci_strings:
                 height = (int) vec.get(position++);
                 width = (int) vec.get(position++);
@@ -639,7 +532,7 @@ public class ScilabTypeCoder {
 
         // special case for complex double matrix
         double[][] imagData = null;
-        if (type.type == ScilabTypeEnum.sci_matrix) {
+        if (type == ScilabTypeEnum.sci_matrix) {
             boolean isComplex = vec.get(position++) != 0;
 
             if (isComplex) {
@@ -648,13 +541,13 @@ public class ScilabTypeCoder {
         }
 
         // allocate the right type with the decoded properties
-        switch (type.type) {
+        switch (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) {
+                switch (ScilabIntegerTypeEnum.swigToEnum(precision)) {
                     case sci_int8:
                         return new ScilabInteger(new byte[height][width], false);
                     case sci_int16:
index 8e92a93..93dff59 100644 (file)
@@ -40,6 +40,9 @@ import javax.xml.transform.stream.StreamSource;
 import org.scilab.modules.commons.xml.ScilabTransformerFactory;
 import org.scilab.modules.types.ScilabList;
 import org.scilab.modules.xcos.JavaController;
+import org.scilab.modules.xcos.View;
+import org.scilab.modules.xcos.Xcos;
+import org.scilab.modules.xcos.XcosView;
 import org.scilab.modules.xcos.graph.XcosDiagram;
 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
 import org.scilab.modules.xcos.io.codec.XcosCodec;
@@ -64,9 +67,16 @@ public enum XcosFileType {
             ParserConfigurationException {
             LOG.entering("XcosFileType.ZCOS", "load");
 
-            XcosPackage p = new XcosPackage(new File(file));
-            p.setContent(into);
-            p.load();
+            View xcosView = JavaController.lookup_view(Xcos.class.getName());
+            try {
+                JavaController.unregister_view(xcosView);
+
+                XcosPackage p = new XcosPackage(new File(file));
+                p.setContent(into);
+                p.load();
+            } finally {
+                JavaController.register_view(Xcos.class.getName(), xcosView);
+            }
 
             LOG.exiting("XcosFileType.ZCOS", "load");
         }
@@ -89,8 +99,10 @@ public enum XcosFileType {
         @Override
         public void load(String file, XcosDiagram into)
         throws TransformerException {
-
+            View xcosView = JavaController.lookup_view(Xcos.class.getName());
             try {
+                JavaController.unregister_view(xcosView);
+
                 final TransformerFactory tranFactory = ScilabTransformerFactory.newInstance();
                 final Transformer aTransformer = tranFactory.newTransformer();
 
@@ -108,6 +120,8 @@ public enum XcosFileType {
                 Logger.getLogger(ContentEntry.class.getName()).severe(e.getMessageAndLocation());
             } catch (Exception e) {
                 e.printStackTrace();
+            } finally {
+                JavaController.register_view(Xcos.class.getName(), xcosView);
             }
         }
 
index d9fae8a..adad6cc 100644 (file)
@@ -126,8 +126,8 @@ class BlockHandler implements ScilabHandler {
          */
         v = atts.getValue("id");
         if (v != null) {
+            block.setId(v);
             saxHandler.allChildren.peek().put(v, uid);
-            saxHandler.controller.setObjectProperty(uid, Kind.BLOCK, ObjectProperties.UID, v);
         }
 
         v = atts.getValue("interfaceFunctionName");
index 44b4b66..c015e70 100644 (file)
@@ -192,7 +192,7 @@ class CustomHandler implements ScilabHandler {
                 long uid = uidObject.longValue();
 
                 for (UnresolvedReference unresolvedReference : entry.getValue()) {
-                    unresolvedReference.resolve(saxHandler.controller, uid);
+                    unresolvedReference.resolve(saxHandler.controller, uid, saxHandler.controller.getKind(uid));
                 }
             }
         }
index 9d144ae..a9a10fd 100644 (file)
@@ -30,7 +30,7 @@ class LinkHandler implements ScilabHandler {
 
     /**
      * Default constructor
-     * 
+     *
      * @param saxHandler
      *            the shared sax handler
      */
@@ -45,20 +45,20 @@ class LinkHandler implements ScilabHandler {
         final long uid = saxHandler.controller.createObject(Kind.LINK);
 
         switch (found) {
-        case CommandControlLink:
-            link = new CommandControlLink(uid);
-            saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.KIND, -1);
-            break;
-        case ExplicitLink:
-            link = new ExplicitLink(uid);
-            saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.KIND, 1);
-            break;
-        case ImplicitLink:
-            link = new ImplicitLink(uid);
-            saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.KIND, 2);
-            break;
-        default:
-            throw new IllegalArgumentException();
+            case CommandControlLink:
+                link = new CommandControlLink(uid);
+                saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.KIND, -1);
+                break;
+            case ExplicitLink:
+                link = new ExplicitLink(uid);
+                saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.KIND, 1);
+                break;
+            case ImplicitLink:
+                link = new ImplicitLink(uid);
+                saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.KIND, 2);
+                break;
+            default:
+                throw new IllegalArgumentException();
         }
 
         /*
@@ -66,8 +66,8 @@ class LinkHandler implements ScilabHandler {
          */
         v = atts.getValue("id");
         if (v != null) {
+            link.setId(v);
             saxHandler.allChildren.peek().put(v, uid);
-            saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.UID, v);
         }
 
         v = atts.getValue("source");
@@ -77,6 +77,7 @@ class LinkHandler implements ScilabHandler {
                 // if the attribute is present then the connected port is already
                 // decoded and present in the map
                 saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.SOURCE_PORT, src.longValue());
+                saxHandler.controller.setObjectProperty(src.longValue(), Kind.PORT, ObjectProperties.CONNECTED_SIGNALS, uid);
             } else {
                 // if not present then it will be resolved later
                 ArrayList<UnresolvedReference> refList = saxHandler.unresolvedReferences.get(v);
@@ -84,7 +85,7 @@ class LinkHandler implements ScilabHandler {
                     refList = new ArrayList<>();
                     saxHandler.unresolvedReferences.put(v, refList);
                 }
-                refList.add(new UnresolvedReference(new ScicosObjectOwner(uid, Kind.LINK), ObjectProperties.SOURCE_PORT, null, 0));
+                refList.add(new UnresolvedReference(new ScicosObjectOwner(uid, Kind.LINK), ObjectProperties.SOURCE_PORT, ObjectProperties.CONNECTED_SIGNALS, 0));
             }
         }
 
@@ -95,6 +96,7 @@ class LinkHandler implements ScilabHandler {
                 // if the attribute is present then the connected port is already
                 // decoded and present in the map
                 saxHandler.controller.setObjectProperty(uid, Kind.LINK, ObjectProperties.DESTINATION_PORT, dst.longValue());
+                saxHandler.controller.setObjectProperty(dst.longValue(), Kind.PORT, ObjectProperties.CONNECTED_SIGNALS, uid);
             } else {
                 // if not present then it will be resolved later
                 ArrayList<UnresolvedReference> refList = saxHandler.unresolvedReferences.get(v);
@@ -102,7 +104,7 @@ class LinkHandler implements ScilabHandler {
                     refList = new ArrayList<>();
                     saxHandler.unresolvedReferences.put(v, refList);
                 }
-                refList.add(new UnresolvedReference(new ScicosObjectOwner(uid, Kind.LINK), ObjectProperties.DESTINATION_PORT, null, 0));
+                refList.add(new UnresolvedReference(new ScicosObjectOwner(uid, Kind.LINK), ObjectProperties.DESTINATION_PORT, ObjectProperties.CONNECTED_SIGNALS, 0));
             }
         }
 
index 9c7c0e1..68ef046 100644 (file)
 
 package org.scilab.modules.xcos.io.sax;
 
+import java.util.ArrayList;
+
 import org.scilab.modules.xcos.Kind;
 import org.scilab.modules.xcos.ObjectProperties;
 import org.scilab.modules.xcos.VectorOfInt;
 import org.scilab.modules.xcos.VectorOfScicosID;
+import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
+import org.scilab.modules.xcos.graph.model.XcosCell;
+import org.scilab.modules.xcos.io.sax.SAXHandler.UnresolvedReference;
 import org.scilab.modules.xcos.port.BasicPort;
 import org.scilab.modules.xcos.port.command.CommandPort;
 import org.scilab.modules.xcos.port.control.ControlPort;
@@ -82,6 +87,7 @@ class PortHandler implements ScilabHandler {
 
         v = atts.getValue("id");
         if (v != null) {
+            port.setId(v);
             saxHandler.allChildren.peek().put(v, uid);
         }
 
@@ -114,11 +120,11 @@ class PortHandler implements ScilabHandler {
         }
 
         /*
-         * Associate to the parent block
+         * Associate to the parent block : now or later
          */
 
         int ordering = 0;
-        long parent = 0l;
+        Long parent = 0l;
 
         v = atts.getValue("ordering");
         if (v != null) {
@@ -128,17 +134,47 @@ class PortHandler implements ScilabHandler {
         v = atts.getValue("parent");
         if (v != null) {
             parent = saxHandler.allChildren.peek().get(v);
-        }
 
-        VectorOfScicosID associatedPorts = new VectorOfScicosID();
-        saxHandler.controller.getObjectProperty(parent, Kind.BLOCK, relatedProperty, associatedPorts);
-
-        associatedPorts.resize(ordering + 1);
-        associatedPorts.set(ordering, uid);
-        saxHandler.controller.referenceObject(uid);
+            // if we can resolve the parent, then connect it directly
+            if (parent != null) {
+                VectorOfScicosID associatedPorts = new VectorOfScicosID();
+                saxHandler.controller.getObjectProperty(parent, Kind.BLOCK, relatedProperty, associatedPorts);
+
+                associatedPorts.resize(ordering + 1);
+                associatedPorts.set(ordering, uid);
+                saxHandler.controller.referenceObject(uid);
+
+                saxHandler.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.SOURCE_BLOCK, parent);
+                saxHandler.controller.setObjectProperty(parent, Kind.BLOCK, relatedProperty, associatedPorts);
+            } else {
+                // resolve the parent later
+                ArrayList<UnresolvedReference> refList = saxHandler.unresolvedReferences.get(v);
+                if (refList == null) {
+                    refList = new ArrayList<>();
+                    saxHandler.unresolvedReferences.put(v, refList);
+                }
+                refList.add(new UnresolvedReference(new ScicosObjectOwner(uid, Kind.PORT), ObjectProperties.SOURCE_BLOCK, ObjectProperties.CHILDREN, ordering));
+            }
+        }
 
-        saxHandler.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.SOURCE_BLOCK, parent);
-        saxHandler.controller.setObjectProperty(parent, Kind.BLOCK, relatedProperty, associatedPorts);
+        /*
+         * Associate to the link if possible (reverse linking)
+         */
+        v = atts.getValue("as");
+        if (v != null) {
+            ObjectProperties opposite = null;
+            if ("source".equals(v)) {
+                opposite = ObjectProperties.SOURCE_PORT;
+            } else if ("target".equals(v)) {
+                opposite = ObjectProperties.DESTINATION_PORT;
+            }
+
+            XcosCell cell = saxHandler.lookupForParentXcosCellElement();
+            if (cell.getKind() == Kind.LINK) {
+                saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), opposite, port.getUID());
+                saxHandler.controller.setObjectProperty(port.getUID(), port.getKind(), ObjectProperties.CONNECTED_SIGNALS, cell.getUID());
+            }
+        }
 
         return port;
     }
index a2d2ded..85014e0 100644 (file)
@@ -428,7 +428,7 @@ class RawDataHandler implements ScilabHandler {
                             vec.set(i, value.getRealElement(i, 0));
                         }
 
-                        saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), ObjectProperties.RPAR, vec);
+                        saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), fieldValue.as, vec);
                         break;
                     }
                     case EXPRS:
index a183595..d3f242c 100644 (file)
@@ -28,6 +28,7 @@ import org.scilab.modules.xcos.VectorOfScicosID;
 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.sax.SAXHandler.UnresolvedReference;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
@@ -53,17 +54,17 @@ public class SAXHandler extends DefaultHandler {
             this.associatedPropertyIndex = associatedPropertyIndex;
         }
 
-        public void resolve(JavaController controller, long v) {
+        public void resolve(JavaController controller, long v, Kind kind) {
             controller.setObjectProperty(owner.getUID(), owner.getKind(), property, v);
 
             if (associatedProperty != null) {
                 VectorOfScicosID associated = new VectorOfScicosID();
-                controller.getObjectProperty(owner.getUID(), owner.getKind(), associatedProperty, associated);
+                controller.getObjectProperty(v, kind, associatedProperty, associated);
 
                 associated.resize(associatedPropertyIndex + 1);
                 associated.set(associatedPropertyIndex, v);
 
-                controller.setObjectProperty(owner.getUID(), owner.getKind(), associatedProperty, associated);
+                controller.setObjectProperty(v, kind, associatedProperty, associated);
             }
         }
     }