Xcos MVC: list insertion in diagram, 'xx', 'yy' and 'odstate' properties and split... 47/15247/10
Paul Bignier [Thu, 18 Sep 2014 14:58:41 +0000 (16:58 +0200)]
 * can now augment or reduce 'xx' and 'yy' fields
 * odstate is now allowed to be an empty matrix (but still returns an empty list
 * Link split blocks can be connected to either implicit or explicit blocks,
so their 'from' and 'to' related properties don't matter
 * A link now stores 'from' and 'to' in its Adapter until it is added to an actual Diagram. Only then does it update the model
 * LinkAdapter new defines its own cloner, to transfer the data saved in the Adapter (not only the model).

--> loadXcosLibs();
--> importScicosDiagram("SCI/test/xcos/samphold.cosf")

Change-Id: I4a2b173cb9cc2aeae8097006f4279a576805b132

scilab/modules/scicos/macros/scicos_scicos/%l_i_diagram.sci [new file with mode: 0644]
scilab/modules/scicos/src/cpp/view_scilab/BaseAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/DiagramAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/LinkAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/LinkAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp
scilab/modules/scicos/tests/unit_tests/model/Diagram.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Diagram.tst
scilab/modules/scicos/tests/unit_tests/model/Link.dia.ref

diff --git a/scilab/modules/scicos/macros/scicos_scicos/%l_i_diagram.sci b/scilab/modules/scicos/macros/scicos_scicos/%l_i_diagram.sci
new file mode 100644 (file)
index 0000000..4a0827e
--- /dev/null
@@ -0,0 +1,24 @@
+//  Scicos
+//
+//  Copyright (C) 2014 - Scilab Enterprises - Paul Bignier
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// See the file ../license.txt
+//
+
+function d=%l_i_diagram(i,l,d)
+    scicos_setfield(i,l,d)
+endfunction
index 67200b2..15b1233 100644 (file)
@@ -236,7 +236,7 @@ public:
 
 private:
 
-    types::InternalType* clone()
+    virtual types::InternalType* clone()
     {
         Controller controller = Controller();
         ScicosID clone = controller.cloneObject(getAdaptee()->id());
@@ -345,6 +345,10 @@ private:
         return true;
     }
 
+    bool getOwn()
+    {
+        return ownAdaptee;
+    };
 
 private:
     const bool ownAdaptee;
index 59103c9..d1b7749 100644 (file)
@@ -117,7 +117,11 @@ struct objs
         model::Diagram* adaptee = adaptor.getAdaptee();
 
         types::List* list = v->getAs<types::List>();
-        std::vector<ScicosID> diagramChildren (list->getSize());
+
+        // Clear the children list before the loop to reset the diagram children
+        std::vector<ScicosID> diagramChildren;
+        controller.setObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
+
         for (int i = 0; i < list->getSize(); ++i)
         {
             if (list->get(i)->getType() != types::InternalType::ScilabUserType)
@@ -138,8 +142,12 @@ struct objs
                     BlockAdapter* modelElement = list->get(i)->getAs<BlockAdapter>();
                     model::Block* subAdaptee = modelElement->getAdaptee();
 
-                    controller.setObjectProperty(id, subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
                     id = subAdaptee->id();
+
+                    controller.setObjectProperty(id, subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
+                    controller.getObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
+                    diagramChildren.push_back(id);
+                    controller.setObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
                     break;
                 }
                 case Adapters::LINK_ADAPTER:
@@ -147,8 +155,25 @@ struct objs
                     LinkAdapter* modelElement = list->get(i)->getAs<LinkAdapter>();
                     model::Link* subAdaptee = modelElement->getAdaptee();
 
-                    controller.setObjectProperty(subAdaptee->id(), subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
                     id = subAdaptee->id();
+
+                    controller.setObjectProperty(id, subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
+
+                    // Trigger 'from' and 'to' properties to be stored at model-level
+                    std::vector<double> from_content = modelElement->getFrom();
+                    if (!modelElement->setFrom(id, from_content, controller))
+                    {
+                        return false;
+                    }
+                    std::vector<double> to_content = modelElement->getTo();
+                    if (!modelElement->setTo(id, to_content, controller))
+                    {
+                        return false;
+                    }
+
+                    controller.getObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
+                    diagramChildren.push_back(id);
+                    controller.setObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
                     break;
                 }
                 case Adapters::TEXT_ADAPTER:
@@ -156,18 +181,19 @@ struct objs
                     TextAdapter* modelElement = list->get(i)->getAs<TextAdapter>();
                     model::Annotation* subAdaptee = modelElement->getAdaptee();
 
-                    controller.setObjectProperty(subAdaptee->id(), subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
                     id = subAdaptee->id();
+
+                    controller.setObjectProperty(id, subAdaptee->kind(), PARENT_DIAGRAM, adaptee->id());
+                    controller.getObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
+                    diagramChildren.push_back(id);
+                    controller.setObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
                     break;
                 }
                 default:
                     return false;
             }
-
-            diagramChildren[i] = id;
         }
 
-        controller.setObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, diagramChildren);
         return true;
     }
 };
index a38174f..2f3c7f8 100644 (file)
@@ -23,8 +23,8 @@
 
 #include "Controller.hxx"
 #include "LinkAdapter.hxx"
-#include "model/Port.hxx"
 #include "model/Link.hxx"
+#include "model/Port.hxx"
 
 extern "C" {
 #include "sci_malloc.h"
@@ -38,6 +38,10 @@ namespace view_scilab
 namespace
 {
 
+const std::string split ("split");
+const std::string lsplit ("lsplit");
+const std::string limpsplit ("limpsplit");
+
 struct xx
 {
 
@@ -74,14 +78,32 @@ struct xx
         std::vector<double> controlPoints;
         controller.getObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
 
-        if (current->getSize() != static_cast<int>(controlPoints.size() / 2))
+        int newXSize = current->getSize();
+        int oldXSize = static_cast<int>(controlPoints.size() / 2);
+        std::vector<double> newControlPoints (controlPoints);
+
+        if (newXSize == oldXSize)
         {
-            return false;
+#ifdef _MSC_VER
+            std::copy(current->getReal(), current->getReal() + newXSize, stdext::checked_array_iterator<double*>( newControlPoints.begin(), newXSize ));
+#else
+            std::copy(current->getReal(), current->getReal() + newXSize, newControlPoints.begin());
+#endif
         }
+        else
+        {
+            newControlPoints.resize(2 * current->getSize(), 0);
 
-        std::copy(current->getReal(), current->getReal() + current->getSize(), controlPoints.begin());
-        controller.setObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
+#ifdef _MSC_VER
+            std::copy(current->getReal(), current->getReal() + newXSize, stdext::checked_array_iterator<double*>( newControlPoints.begin(), newXSize ));
+            std::copy(controlPoints.begin() + oldXSize, controlPoints.begin() + oldXSize + std::min(newXSize, oldXSize), stdext::checked_array_iterator<double*>( newControlPoints.begin() + newXSize, std::min(newXSize, oldXSize) ));
+#else
+            std::copy(current->getReal(), current->getReal() + newXSize, newControlPoints.begin());
+            std::copy(controlPoints.begin() + oldXSize, controlPoints.begin() + oldXSize + std::min(newXSize, oldXSize), newControlPoints.begin() + newXSize);
+#endif
+        }
 
+        controller.setObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, newControlPoints);
         return true;
     }
 };
@@ -122,14 +144,34 @@ struct yy
         std::vector<double> controlPoints;
         controller.getObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
 
-        if (current->getSize() != static_cast<int>(controlPoints.size() / 2))
+        int newYSize = current->getSize();
+        int oldYSize = static_cast<int>(controlPoints.size() / 2);
+        std::vector<double> newControlPoints (controlPoints);
+
+        if (newYSize == oldYSize)
         {
-            return false;
+#ifdef _MSC_VER
+            std::copy(current->getReal(), current->getReal() + newYSize, stdext::checked_array_iterator<double*>( newControlPoints.begin() + newYSize, newYSize ));
+#else
+            std::copy(current->getReal(), current->getReal() + newYSize, newControlPoints.begin() + newYSize);
+#endif
         }
+        else
+        {
+            newControlPoints.resize(2 * current->getSize());
 
-        std::copy(current->getReal(), current->getReal() + current->getSize(), controlPoints.begin() + controlPoints.size() / 2);
-        controller.setObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
+#ifdef _MSC_VER
+            std::copy(current->getReal(), current->getReal() + newYSize, stdext::checked_array_iterator<double*>( newControlPoints.begin() + newYSize, newYSize ));
+#else
+            std::copy(current->getReal(), current->getReal() + newYSize, newControlPoints.begin() + newYSize);
+#endif
+            if (newYSize > oldYSize)
+            {
+                std::fill(newControlPoints.begin() + oldYSize, newControlPoints.begin() + oldYSize + newYSize, 0);
+            }
+        }
 
+        controller.setObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, newControlPoints);
         return true;
     }
 };
@@ -293,19 +335,34 @@ static types::Double* getLinkEnd(const LinkAdapter& adaptor, const Controller& c
         controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
         data[0] = static_cast<double>(std::distance(children.begin(), std::find(children.begin(), children.end(), sourceBlock)) + 1);
 
+        // To find the port index from its 'endID' ID, search through all the block's ports lists
         std::vector<ScicosID> sourceBlockPorts;
-        switch (end)
+        controller.getObjectProperty(sourceBlock, BLOCK, INPUTS, sourceBlockPorts);
+
+        std::vector<ScicosID>::iterator found = std::find(sourceBlockPorts.begin(), sourceBlockPorts.end(), endID);
+        if (found == sourceBlockPorts.end()) // Not found in the data inputs
         {
-            case SOURCE_PORT:
-                controller.getObjectProperty(sourceBlock, BLOCK, OUTPUTS, sourceBlockPorts);
-                break;
-            case DESTINATION_PORT:
-                controller.getObjectProperty(sourceBlock, BLOCK, INPUTS, sourceBlockPorts);
-                break;
-            default:
-                return 0;
+            sourceBlockPorts.clear();
+            controller.getObjectProperty(sourceBlock, BLOCK, OUTPUTS, sourceBlockPorts);
+            found = std::find(sourceBlockPorts.begin(), sourceBlockPorts.end(), endID);
+            if (found == sourceBlockPorts.end()) // Not found in the data outputs
+            {
+                sourceBlockPorts.clear();
+                controller.getObjectProperty(sourceBlock, BLOCK, EVENT_INPUTS, sourceBlockPorts);
+                found = std::find(sourceBlockPorts.begin(), sourceBlockPorts.end(), endID);
+                if (found == sourceBlockPorts.end()) // Not found in the event inputs
+                {
+                    sourceBlockPorts.clear();
+                    controller.getObjectProperty(sourceBlock, BLOCK, EVENT_OUTPUTS, sourceBlockPorts);
+                    found = std::find(sourceBlockPorts.begin(), sourceBlockPorts.end(), endID);
+                    if (found == sourceBlockPorts.end()) // Not found in the event outputs
+                    {
+                        return 0;
+                    }
+                }
+            }
         }
-        data[1] = static_cast<double>(std::distance(sourceBlockPorts.begin(), std::find(sourceBlockPorts.begin(), sourceBlockPorts.end(), endID)) + 1);
+        data[1] = static_cast<double>(std::distance(sourceBlockPorts.begin(), found) + 1);
 
         bool isImplicit;
         controller.getObjectProperty(endID, PORT, IMPLICIT, isImplicit);
@@ -330,26 +387,42 @@ enum startOrEnd
     End = 1
 };
 
-static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_properties_t end, types::InternalType* v)
+/*
+ * Connectivity is ensured if 'port' is of the desired type or if either of the concerned blocks is a split block,
+ * because they are connectable to anything
+ */
+static bool checkConnectivity(const int neededType, const ScicosID port, const ScicosID blk1, Controller& controller)
 {
-    model::Link* adaptee = adaptor.getAdaptee();
+    int portKind;
+    controller.getObjectProperty(port, PORT, PORT_KIND, portKind);
 
-    if (v->getType() != types::InternalType::ScilabDouble)
+    if (portKind != neededType)
     {
-        return false;
+        // Last chance if one of the connecting blocks is just a split block
+        std::string name1;
+        controller.getObjectProperty(blk1, BLOCK, SIM_FUNCTION_NAME, name1);
+        if (name1 != split && name1 != lsplit && name1 != limpsplit)
+        {
+            ScicosID blk2;
+            controller.getObjectProperty(port, PORT, SOURCE_BLOCK, blk2);
+            std::string name2;
+            controller.getObjectProperty(blk2, BLOCK, SIM_FUNCTION_NAME, name2);
+            if (name2 != split && name2 != lsplit && name2 != limpsplit)
+            {
+                return false;
+            }
+        }
     }
+    return true;
+}
 
-    types::Double* current = v->getAs<types::Double>();
-
-    if ((current->getRows() != 1 || current->getCols() != 3) && current->getSize() != 0)
-    {
-        return false; // Must be [] or [x y z]
-    }
+static bool setLinkEnd(ScicosID id, Controller& controller, object_properties_t end, std::vector<double> v)
+{
 
     ScicosID from;
-    controller.getObjectProperty(adaptee->id(), adaptee->kind(), SOURCE_PORT, from);
+    controller.getObjectProperty(id, LINK, SOURCE_PORT, from);
     ScicosID to;
-    controller.getObjectProperty(adaptee->id(), adaptee->kind(), DESTINATION_PORT, to);
+    controller.getObjectProperty(id, LINK, DESTINATION_PORT, to);
     ScicosID concernedPort;
     ScicosID otherPort;
     object_properties_t otherEnd;
@@ -370,38 +443,35 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
     }
     ScicosID unconnected = 0;
 
-    if (current->getSize() == 0 || (current->get(0) == 0 || current->get(1) == 0))
+    if (v.size() == 0 || (v[0] == 0 || v[1] == 0))
     {
         // We want to set an empty link
         if (concernedPort == 0)
         {
             // In this case, the link was already empty, do a dummy call to display the console status.
-            controller.setObjectProperty(adaptee->id(), adaptee->kind(), end, concernedPort);
+            controller.setObjectProperty(id, LINK, end, concernedPort);
         }
         else
         {
-            // Untie the old link on both ends and set the 2 concerned ports as unconnected
-            controller.setObjectProperty(from, PORT, CONNECTED_SIGNALS, unconnected);
-            controller.setObjectProperty(to, PORT, CONNECTED_SIGNALS, unconnected);
-
-            controller.setObjectProperty(adaptee->id(), adaptee->kind(), SOURCE_PORT, unconnected);
-            controller.setObjectProperty(adaptee->id(), adaptee->kind(), DESTINATION_PORT, unconnected);
+            // Untie the old link on the concerned end and set its port as unconnected
+            controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
+            controller.setObjectProperty(id, LINK, end, unconnected);
         }
         return true;
     }
 
-    if (current->get(2) != 0 && current->get(2) != 1)
+    if (v[2] != 0 && v[2] != 1)
     {
         return false;
     }
 
-    if (floor(current->get(0)) != current->get(0) || floor(current->get(1)) != current->get(1))
+    if (floor(v[0]) != v[0] || floor(v[1]) != v[1])
     {
         return false; // Must be an integer value
     }
 
     ScicosID parentDiagram;
-    controller.getObjectProperty(adaptee->id(), BLOCK, PARENT_DIAGRAM, parentDiagram);
+    controller.getObjectProperty(id, LINK, PARENT_DIAGRAM, parentDiagram);
     std::vector<ScicosID> children;
     if (parentDiagram != 0)
     {
@@ -409,9 +479,9 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
     }
 
     // Connect the new one
-    int blk  = static_cast<int>(current->get(0));
-    int port = static_cast<int>(current->get(1));
-    int kind = static_cast<int>(current->get(2));
+    int blk  = static_cast<int>(v[0]);
+    int port = static_cast<int>(v[1]);
+    int kind = static_cast<int>(v[2]);
     if (kind != Start && kind != End)
     {
         return false;
@@ -430,7 +500,7 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
     bool newPortIsImplicit = false;
     int newPortKind = static_cast<int>(model::UNDEF);
     int linkType;
-    controller.getObjectProperty(adaptee->id(), adaptee->kind(), KIND, linkType);
+    controller.getObjectProperty(id, LINK, KIND, linkType);
     if (linkType == model::activation)
     {
         std::vector<ScicosID> evtin;
@@ -442,10 +512,7 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
         {
             if (otherPort != 0)
             {
-                // The other end must be an input
-                int otherPortKind;
-                controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
-                if (otherPortKind != model::EIN)
+                if (!checkConnectivity(model::EIN, otherPort, blkID, controller))
                 {
                     return false;
                 }
@@ -457,10 +524,7 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
         {
             if (otherPort != 0)
             {
-                // The other end must be an output
-                int otherPortKind;
-                controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
-                if (otherPortKind != model::EOUT)
+                if (!checkConnectivity(model::EOUT, otherPort, blkID, controller))
                 {
                     return false;
                 }
@@ -483,10 +547,7 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
             {
                 if (otherPort != 0)
                 {
-                    // The other end must be an input
-                    int otherPortKind;
-                    controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
-                    if (otherPortKind != model::IN)
+                    if (!checkConnectivity(model::IN, otherPort, blkID, controller))
                     {
                         return false;
                     }
@@ -498,10 +559,7 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
             {
                 if (otherPort != 0)
                 {
-                    // The other end must be an output
-                    int otherPortKind = 1;
-                    controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
-                    if (otherPortKind != model::OUT)
+                    if (!checkConnectivity(model::OUT, otherPort, blkID, controller))
                     {
                         return false;
                     }
@@ -612,8 +670,8 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
     }
 
     // Connect the new source and destination ports together
-    controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, adaptee->id());
-    controller.setObjectProperty(adaptee->id(), adaptee->kind(), end, concernedPort);
+    controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, id);
+    controller.setObjectProperty(id, LINK, end, concernedPort);
     return true;
 }
 
@@ -622,12 +680,41 @@ struct from
 
     static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
     {
-        return getLinkEnd(adaptor, controller, SOURCE_PORT);
+        std::vector<double> from_content;
+        from_content = adaptor.getFrom();
+        double* data;
+        types::Double* o = new types::Double(1, 3, &data);
+
+        data[0] = from_content[0];
+        data[1] = from_content[1];
+        data[2] = from_content[2];
+        return o;
     }
 
     static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return setLinkEnd(adaptor, controller, SOURCE_PORT, v);
+        model::Link* adaptee = adaptor.getAdaptee();
+
+        if (v->getType() != types::InternalType::ScilabDouble)
+        {
+            return false;
+        }
+
+        types::Double* current = v->getAs<types::Double>();
+
+        if (current->getSize() != 0 && current->getSize() != 3)
+        {
+            return false;
+        }
+        std::vector<double> from_content (3, 0);
+        if (current->getSize() == 3)
+        {
+            from_content[0] = current->get(0);
+            from_content[1] = current->get(1);
+            from_content[2] = current->get(2);
+        }
+
+        return adaptor.setFrom(adaptee->id(), from_content, controller);
     }
 };
 
@@ -636,12 +723,41 @@ struct to
 
     static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
     {
-        return getLinkEnd(adaptor, controller, DESTINATION_PORT);
+        std::vector<double> to_content;
+        to_content = adaptor.getTo();
+        double* data;
+        types::Double* o = new types::Double(1, 3, &data);
+
+        data[0] = to_content[0];
+        data[1] = to_content[1];
+        data[2] = to_content[2];
+        return o;
     }
 
     static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return setLinkEnd(adaptor, controller, DESTINATION_PORT, v);
+        model::Link* adaptee = adaptor.getAdaptee();
+
+        if (v->getType() != types::InternalType::ScilabDouble)
+        {
+            return false;
+        }
+
+        types::Double* current = v->getAs<types::Double>();
+
+        if (current->getSize() != 0 && current->getSize() != 3)
+        {
+            return false;
+        }
+        std::vector<double> to_content (3, 0);
+        if (current->getSize() == 3)
+        {
+            to_content[0] = current->get(0);
+            to_content[1] = current->get(1);
+            to_content[2] = current->get(2);
+        }
+
+        return adaptor.setTo(adaptee->id(), to_content, controller);
     }
 };
 
@@ -663,6 +779,20 @@ LinkAdapter::LinkAdapter(bool ownAdaptee, org_scilab_modules_scicos::model::Link
         property<LinkAdapter>::add_property(L"from", &from::get, &from::set);
         property<LinkAdapter>::add_property(L"to", &to::get, &to::set);
     }
+
+    from_content = std::vector<double> (3);
+    to_content   = std::vector<double> (3);
+
+    // If the Link has been added to a diagram, the following lines will dig up its information at model-level
+    Controller controller = Controller();
+    types::Double* modelFrom = getLinkEnd(*this, controller, SOURCE_PORT);
+    types::Double* modelTo   = getLinkEnd(*this, controller, DESTINATION_PORT);
+    from_content[0] = modelFrom->get(0);
+    from_content[1] = modelFrom->get(1);
+    from_content[2] = modelFrom->get(2);
+    to_content[0]   = modelTo->get(0);
+    to_content[1]   = modelTo->get(1);
+    to_content[2]   = modelTo->get(2);
 }
 
 LinkAdapter::~LinkAdapter()
@@ -678,5 +808,58 @@ std::wstring LinkAdapter::getShortTypeStr()
     return getSharedTypeStr();
 }
 
+std::vector<double> LinkAdapter::getFrom() const
+{
+    return from_content;
+}
+
+bool LinkAdapter::setFrom(ScicosID id, const std::vector<double>& v, Controller& controller)
+{
+    from_content = v;
+
+    ScicosID parentDiagram;
+    controller.getObjectProperty(id, LINK, PARENT_DIAGRAM, parentDiagram);
+
+    if (parentDiagram != 0)
+    {
+        // If the Link has been added to a diagram, do the linking at model-level
+        return setLinkEnd(id, controller, SOURCE_PORT, from_content);
+    }
+    return true;
+}
+
+std::vector<double> LinkAdapter::getTo() const
+{
+    return to_content;
+}
+
+bool LinkAdapter::setTo(ScicosID id, const std::vector<double>& v, Controller& controller)
+{
+    to_content = v;
+
+    ScicosID parentDiagram;
+    controller.getObjectProperty(id, LINK, PARENT_DIAGRAM, parentDiagram);
+
+    if (parentDiagram != 0)
+    {
+        // If the Link has been added to a diagram, do the linking at model-level
+        return setLinkEnd(id, controller, DESTINATION_PORT, to_content);
+    }
+    return true;
+}
+
+types::InternalType* LinkAdapter::clone()
+{
+    Controller controller = Controller();
+    ScicosID clone = controller.cloneObject(getAdaptee()->id());
+    LinkAdapter* ret = new LinkAdapter(false, static_cast<org_scilab_modules_scicos::model::Link*>(controller.getObject(clone)));
+
+    // When cloning a LinkAdapter, clone its 'from' and 'to' information as well.
+    // setFrom() will propagate the information at model-level if necessary.
+    ret->setFrom(clone, this->getFrom(), controller);
+    ret->setTo(clone, this->getTo(), controller);
+    return ret;
+}
+
 } /* namespace view_scilab */
 } /* namespace org_scilab_modules_scicos */
index b25c006..8a542d0 100644 (file)
@@ -37,6 +37,15 @@ public:
 
     std::wstring getTypeStr();
     std::wstring getShortTypeStr();
+    types::InternalType* clone();
+
+    std::vector<double> getFrom() const;
+    bool setFrom(ScicosID id, const std::vector<double>& v, Controller& controller);
+    std::vector<double> getTo() const;
+    bool setTo(ScicosID id, const std::vector<double>& v, Controller& controller);
+private:
+    std::vector<double> from_content;
+    std::vector<double> to_content;
 };
 
 } /* namespace view_scilab */
index f841545..78e0c14 100644 (file)
 #include <algorithm>
 #include <sstream>
 
-#include "list.hxx"
-#include "mlist.hxx"
 #include "double.hxx"
 #include "string.hxx"
+#include "list.hxx"
+#include "user.hxx"
 
 #include "Controller.hxx"
 #include "Adapters.hxx"
@@ -355,25 +355,48 @@ struct odstate
 
     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        if (v->getType() != types::InternalType::ScilabList)
+        // For the moment, odstate can only either be an empty matrix or list
+
+        if (v->getType() == types::InternalType::ScilabList)
         {
-            return false;
-        }
+            types::List* current = v->getAs<types::List>();
 
-        types::List* current = v->getAs<types::List>();
+            if (current->getSize() == 0)
+            {
+                return true;
+            }
+            else
+            {
+                // silent unused parameter warnings
+                (void) adaptor;
+                (void) v;
+                (void) controller;
 
-        if (current->getSize() == 0)
+                // FIXME: implement as a scicos encoded list of values
+                return false;
+            }
+        }
+        else if (v->getType() == types::InternalType::ScilabDouble)
         {
-            return true;
+            types::Double* current = v->getAs<types::Double>();
+
+            if (current->getSize() == 0)
+            {
+                return true;
+            }
+            else
+            {
+                // silent unused parameter warnings
+                (void) adaptor;
+                (void) v;
+                (void) controller;
+
+                // FIXME: implement as a scicos encoded list of values
+                return false;
+            }
         }
         else
         {
-            // silent unused parameter warnings
-            (void) adaptor;
-            (void) v;
-            (void) controller;
-
-            // FIXME: implement as a scicos encoded list of values
             return false;
         }
     }
@@ -711,6 +734,7 @@ struct nzcross
 
     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
+        model::Block* adaptee = adaptor.getAdaptee();
 
         if (v->getType() != types::InternalType::ScilabDouble)
         {
@@ -718,18 +742,21 @@ struct nzcross
         }
 
         types::Double* current = v->getAs<types::Double>();
-        if (current->getSize() != 1)
-        {
-            return false;
-        }
-        if (floor(current->get(0)) != current->get(0))
-        {
-            return false;
-        }
 
-        model::Block* adaptee = adaptor.getAdaptee();
+        int nzcross = 0; // Default value
+        if (current->getSize() != 0)
+        {
+            if (current->getSize() != 1)
+            {
+                return false;
+            }
+            if (floor(current->get(0)) != current->get(0))
+            {
+                return false;
+            }
 
-        int nzcross = static_cast<int>(current->get(0));
+            nzcross = static_cast<int>(current->get(0));
+        }
 
         controller.setObjectProperty(adaptee->id(), adaptee->kind(), NZCROSS, nzcross);
         return true;
@@ -753,6 +780,7 @@ struct nmode
 
     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
+        model::Block* adaptee = adaptor.getAdaptee();
 
         if (v->getType() != types::InternalType::ScilabDouble)
         {
@@ -760,18 +788,21 @@ struct nmode
         }
 
         types::Double* current = v->getAs<types::Double>();
-        if (current->getSize() != 1)
-        {
-            return false;
-        }
-        if (floor(current->get(0)) != current->get(0))
-        {
-            return false;
-        }
 
-        model::Block* adaptee = adaptor.getAdaptee();
+        int nmode = 0; // Default value
+        if (current->getSize() != 0)
+        {
+            if (current->getSize() != 1)
+            {
+                return false;
+            }
+            if (floor(current->get(0)) != current->get(0))
+            {
+                return false;
+            }
 
-        int nmode = static_cast<int>(current->get(0));
+            nmode = static_cast<int>(current->get(0));
+        }
 
         controller.setObjectProperty(adaptee->id(), adaptee->kind(), NMODE, nmode);
         return true;
index be4e4d3..bfe84c9 100644 (file)
@@ -168,8 +168,6 @@ propertyUpdated( 12 , LINK , LABEL ) : NO_CHANGES
 propertyUpdated( 12 , LINK , THICK ) : NO_CHANGES
 propertyUpdated( 12 , LINK , COLOR ) : NO_CHANGES
 propertyUpdated( 12 , LINK , KIND ) : NO_CHANGES
-propertyUpdated( 12 , LINK , SOURCE_PORT ) : NO_CHANGES
-propertyUpdated( 12 , LINK , DESTINATION_PORT ) : NO_CHANGES
 lnk2   = scicos_link(ct=[1,-1]); // Activation link
 objectCreated( 13 , LINK )
 propertyUpdated( 13 , LINK , CONTROL_POINTS ) : NO_CHANGES
@@ -178,8 +176,6 @@ propertyUpdated( 13 , LINK , LABEL ) : NO_CHANGES
 propertyUpdated( 13 , LINK , THICK ) : NO_CHANGES
 propertyUpdated( 13 , LINK , COLOR ) : NO_CHANGES
 propertyUpdated( 13 , LINK , KIND ) : SUCCESS
-propertyUpdated( 13 , LINK , SOURCE_PORT ) : NO_CHANGES
-propertyUpdated( 13 , LINK , DESTINATION_PORT ) : NO_CHANGES
 scs_m = scicos_diagram( objs=list(Sum,Scope1,Scope2,lnk1,lnk2) )
 objectCreated( 14 , BLOCK )
 propertyUpdated( 14 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
@@ -343,11 +339,20 @@ propertyUpdated( 26 , DIAGRAM , PATH ) : NO_CHANGES
 propertyUpdated( 26 , DIAGRAM , PROPERTIES ) : NO_CHANGES
 propertyUpdated( 26 , DIAGRAM , PROPERTIES ) : NO_CHANGES
 propertyUpdated( 26 , DIAGRAM , CONTEXT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : NO_CHANGES
 propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
 propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
 propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
 propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
 propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
 propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
 propertyUpdated( 26 , DIAGRAM , VERSION_NUMBER ) : NO_CHANGES
 objectDeleted( 1 )
@@ -396,33 +401,68 @@ scicos_Link type :
   from
   to
 // Link output port #1 of block #1 with input port #1 of block #2 thanks to lnk1
-l = scs_m.objs;
-l(4).from = [1 1 0]; // Link block #1
+scs_m.objs(4).from = [1 1 0]; // Link block #1
 propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
 propertyUpdated( 24 , LINK , SOURCE_PORT ) : SUCCESS
-l(1).graphics.pout   // Check that block #1 is connected to lnk1
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs(1).graphics.pout   // Check that block #1 is connected to lnk1
  ans  =
     4.
-l(1).model.out       // "
+scs_m.objs(1).model.out       // "
  ans  =
   - 1.
-l(4).to = [2 1 1];   // Link block #2
+scs_m.objs(4).to = [2 1 1];   // Link block #2
 propertyUpdated( 19 , PORT , CONNECTED_SIGNALS ) : SUCCESS
 propertyUpdated( 24 , LINK , DESTINATION_PORT ) : SUCCESS
-l(4).from
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 19 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 19 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs(4).from
  ans  =
     1.    1.    0.
-l(4).to
+scs_m.objs(4).to
  ans  =
     2.    1.    1.
-l(2).graphics.pin    // Check that block #2 is connected to lnk1
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk1
  ans  =
     4.
-l(2).model.in        // "
+scs_m.objs(2).model.in        // "
  ans  =
   - 1.
 // Change the end of the link to input port #2 of block #2
-l(4).to = [2 2 1];
+scs_m.objs(4).to = [2 2 1];
 propertyUpdated( 19 , PORT , CONNECTED_SIGNALS ) : SUCCESS
 objectCreated( 27 , PORT )
 propertyUpdated( 27 , PORT , IMPLICIT ) : NO_CHANGES
@@ -433,44 +473,118 @@ propertyUpdated( 27 , PORT , DATATYPE ) : SUCCESS
 propertyUpdated( 18 , BLOCK , INPUTS ) : SUCCESS
 propertyUpdated( 27 , PORT , CONNECTED_SIGNALS ) : SUCCESS
 propertyUpdated( 24 , LINK , DESTINATION_PORT ) : SUCCESS
-l(4).from
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 27 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 27 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs(4).from
  ans  =
     1.    1.    0.
-l(4).to
+scs_m.objs(4).to
  ans  =
     2.    2.    1.
-l(2).graphics.pin    // Check that block #2 is connected to lnk1
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk1
  ans  =
     0.
     4.
-l(2).model.in        // "
+scs_m.objs(2).model.in        // "
  ans  =
   - 1.
   - 1.
-// Disconnect the source, the destination is also disconnected
-l(4).from = [0 0 0];
+// Disconnect the source
+scs_m.objs(4).from = [0 0 0];
 propertyUpdated( 17 , PORT , CONNECTED_SIGNALS ) : SUCCESS
-propertyUpdated( 27 , PORT , CONNECTED_SIGNALS ) : SUCCESS
 propertyUpdated( 24 , LINK , SOURCE_PORT ) : SUCCESS
-propertyUpdated( 24 , LINK , DESTINATION_PORT ) : SUCCESS
-l(4).from
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 27 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 27 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs(4).from
  ans  =
     0.    0.    0.
-l(4).to
+scs_m.objs(4).to
  ans  =
-    0.    0.    0.
-l(1).graphics.pout   // Check that both blocks are unconnected
+    2.    2.    1.
+scs_m.objs(1).graphics.pout   // Check that block #1 is not connected
  ans  =
     0.
-l(2).graphics.pin    // "
+scs_m.objs(2).graphics.pin    // But block #2 is still connected to the link
+ ans  =
+    0.
+    4.
+// Disconnect the destination
+scs_m.objs(4).to = [0 0 0];
+propertyUpdated( 27 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : SUCCESS
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs(2).graphics.pin    // Check that block #2 is not connected
  ans  =
     0.
     0.
 // Now link the two Scope blocks together by adding an event output port to block #3 thanks to lnk2
-l(5).from = [2 1 1]; // Link the input of block #2
+scs_m.objs(5).from = [2 1 1]; // Link the input of block #2
 propertyUpdated( 20 , PORT , CONNECTED_SIGNALS ) : SUCCESS
 propertyUpdated( 25 , LINK , SOURCE_PORT ) : SUCCESS
-l(5).to = [3 1 0];   // Add an event output to block #3 and link it to the previous
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 20 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 20 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs(5).to = [3 1 0];   // Add an event output to block #3 and link it to the previous
 objectCreated( 28 , PORT )
 propertyUpdated( 28 , PORT , IMPLICIT ) : NO_CHANGES
 propertyUpdated( 28 , PORT , PORT_KIND ) : SUCCESS
@@ -480,24 +594,414 @@ propertyUpdated( 28 , PORT , DATATYPE ) : SUCCESS
 propertyUpdated( 21 , BLOCK , EVENT_OUTPUTS ) : SUCCESS
 propertyUpdated( 28 , PORT , CONNECTED_SIGNALS ) : SUCCESS
 propertyUpdated( 25 , LINK , DESTINATION_PORT ) : SUCCESS
-l(5).from
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 20 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 20 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 25 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 28 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 28 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 25 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs(5).from
  ans  =
     2.    1.    1.
-l(5).to
+scs_m.objs(5).to
  ans  =
-    3.    2.    0.
-l(2).graphics.pein   // Check that block #2 is connected to lnk2
+    3.    1.    0.
+scs_m.objs(2).graphics.pein   // Check that block #2 is connected to lnk2
  ans  =
     5.
-l(2).model.evtin     // "
+scs_m.objs(2).model.evtin     // "
  ans  =
     1.
-l(3).graphics.peout  // Check that block #3 is connected to lnk2
+scs_m.objs(3).graphics.peout  // Check that block #3 is connected to lnk2
  ans  =
     5.
-l(3).model.evtout    // "
+scs_m.objs(3).model.evtout    // "
  ans  =
   - 1.
 // Verify that it is impossible to link two inputs or two outputs together
-l(5).from = [2 1 0]; // Two outputs
-l(5).to = [3 1 1];   // Two inputs
+scs_m.objs(5).from = [2 1 0]; // Two outputs
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 25 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+scs_m.objs(5).to = [3 1 1];   // Two inputs
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 14 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 21 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 24 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 24 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 24 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 26 , DIAGRAM , CHILDREN ) : SUCCESS
+//===================================================================================================
+// Test predefined link at diagram creation
+clear scs_m;
+objectDeleted( 26 )
+lnk   = scicos_link( from=[1 1 0],to=[2 1 1] );
+objectCreated( 29 , LINK )
+propertyUpdated( 29 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 29 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 29 , LINK , LABEL ) : NO_CHANGES
+propertyUpdated( 29 , LINK , THICK ) : NO_CHANGES
+propertyUpdated( 29 , LINK , COLOR ) : NO_CHANGES
+propertyUpdated( 29 , LINK , KIND ) : NO_CHANGES
+scs_m = scicos_diagram( objs=list(Sum,Scope1,lnk) );
+objectCreated( 30 , BLOCK )
+propertyUpdated( 30 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
+propertyUpdated( 30 , BLOCK , NZCROSS ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , NMODE ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
+propertyUpdated( 30 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
+propertyUpdated( 30 , BLOCK , SIM_BLOCKTYPE ) : SUCCESS
+propertyUpdated( 30 , BLOCK , UID ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , STYLE ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , LABEL ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , GEOMETRY ) : SUCCESS
+propertyUpdated( 30 , BLOCK , ANGLE ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , STATE ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , DSTATE ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , RPAR ) : SUCCESS
+propertyUpdated( 30 , BLOCK , SIM_DEP_UT ) : SUCCESS
+propertyUpdated( 30 , BLOCK , IPAR ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , EXPRS ) : SUCCESS
+propertyUpdated( 30 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+objectCreated( 31 , PORT )
+propertyUpdated( 31 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 31 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 31 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 31 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 31 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 31 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 31 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 31 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+objectCreated( 32 , PORT )
+propertyUpdated( 32 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 32 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 32 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 32 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 32 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 32 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 32 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 32 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , INPUTS ) : SUCCESS
+objectCreated( 33 , PORT )
+propertyUpdated( 33 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 33 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 33 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 33 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 33 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 33 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 33 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 33 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , OUTPUTS ) : SUCCESS
+propertyUpdated( 30 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , CHILDREN ) : NO_CHANGES
+objectCreated( 34 , BLOCK )
+propertyUpdated( 34 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
+propertyUpdated( 34 , BLOCK , NZCROSS ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , NMODE ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
+propertyUpdated( 34 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
+propertyUpdated( 34 , BLOCK , SIM_BLOCKTYPE ) : SUCCESS
+propertyUpdated( 34 , BLOCK , UID ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , STYLE ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , LABEL ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , GEOMETRY ) : SUCCESS
+propertyUpdated( 34 , BLOCK , ANGLE ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , STATE ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , DSTATE ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , RPAR ) : SUCCESS
+propertyUpdated( 34 , BLOCK , SIM_DEP_UT ) : SUCCESS
+propertyUpdated( 34 , BLOCK , IPAR ) : SUCCESS
+propertyUpdated( 34 , BLOCK , EXPRS ) : SUCCESS
+propertyUpdated( 34 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+objectCreated( 35 , PORT )
+propertyUpdated( 35 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 35 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 35 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 35 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 35 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 35 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 35 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 35 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , INPUTS ) : SUCCESS
+propertyUpdated( 34 , BLOCK , OUTPUTS ) : NO_CHANGES
+objectCreated( 36 , PORT )
+propertyUpdated( 36 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 36 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 36 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 36 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 36 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 36 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 36 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 36 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , EVENT_INPUTS ) : SUCCESS
+propertyUpdated( 34 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
+propertyUpdated( 34 , BLOCK , CHILDREN ) : NO_CHANGES
+objectCreated( 37 , LINK )
+propertyUpdated( 37 , LINK , COLOR ) : NO_CHANGES
+propertyUpdated( 37 , LINK , KIND ) : NO_CHANGES
+propertyUpdated( 37 , LINK , LABEL ) : NO_CHANGES
+propertyUpdated( 37 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 37 , LINK , THICK ) : NO_CHANGES
+propertyUpdated( 37 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 37 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 37 , LINK , DESTINATION_PORT ) : NO_CHANGES
+objectCreated( 38 , DIAGRAM )
+propertyUpdated( 38 , DIAGRAM , TITLE ) : NO_CHANGES
+propertyUpdated( 38 , DIAGRAM , PATH ) : NO_CHANGES
+propertyUpdated( 38 , DIAGRAM , PROPERTIES ) : NO_CHANGES
+propertyUpdated( 38 , DIAGRAM , PROPERTIES ) : NO_CHANGES
+propertyUpdated( 38 , DIAGRAM , CONTEXT ) : NO_CHANGES
+propertyUpdated( 38 , DIAGRAM , CHILDREN ) : NO_CHANGES
+propertyUpdated( 30 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 38 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 34 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 38 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 37 , LINK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 33 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 37 , LINK , SOURCE_PORT ) : SUCCESS
+propertyUpdated( 35 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 37 , LINK , DESTINATION_PORT ) : SUCCESS
+propertyUpdated( 38 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 38 , DIAGRAM , VERSION_NUMBER ) : NO_CHANGES
+scs_m.objs(3).from
+ ans  =
+    1.    1.    0.
+scs_m.objs(3).to
+ ans  =
+    2.    1.    1.
+scs_m.objs(1).graphics.pout   // Check that block #1 is connected to lnk
+ ans  =
+    3.
+scs_m.objs(1).model.out       // "
+ ans  =
+  - 1.
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk
+ ans  =
+    3.
+scs_m.objs(2).model.in        // "
+ ans  =
+  - 1.
+//===================================================================================================
+// Test predefined link insertion
+clear scs_m;
+objectDeleted( 38 )
+lnk   = scicos_link( from=[1 1 0],to=[2 1 1] );
+objectCreated( 39 , LINK )
+propertyUpdated( 39 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 39 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 39 , LINK , LABEL ) : NO_CHANGES
+propertyUpdated( 39 , LINK , THICK ) : NO_CHANGES
+propertyUpdated( 39 , LINK , COLOR ) : NO_CHANGES
+propertyUpdated( 39 , LINK , KIND ) : NO_CHANGES
+objectDeleted( 29 )
+scs_m = scicos_diagram( objs=list(Sum,Scope1) );
+objectCreated( 40 , BLOCK )
+propertyUpdated( 40 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
+propertyUpdated( 40 , BLOCK , NZCROSS ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , NMODE ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
+propertyUpdated( 40 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
+propertyUpdated( 40 , BLOCK , SIM_BLOCKTYPE ) : SUCCESS
+propertyUpdated( 40 , BLOCK , UID ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , STYLE ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , LABEL ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , GEOMETRY ) : SUCCESS
+propertyUpdated( 40 , BLOCK , ANGLE ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , STATE ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , DSTATE ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , RPAR ) : SUCCESS
+propertyUpdated( 40 , BLOCK , SIM_DEP_UT ) : SUCCESS
+propertyUpdated( 40 , BLOCK , IPAR ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , EXPRS ) : SUCCESS
+propertyUpdated( 40 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+objectCreated( 41 , PORT )
+propertyUpdated( 41 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 41 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 41 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 41 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 41 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 41 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 41 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 41 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+objectCreated( 42 , PORT )
+propertyUpdated( 42 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 42 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 42 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 42 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 42 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 42 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 42 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 42 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , INPUTS ) : SUCCESS
+objectCreated( 43 , PORT )
+propertyUpdated( 43 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 43 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 43 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 43 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 43 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 43 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 43 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 43 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , OUTPUTS ) : SUCCESS
+propertyUpdated( 40 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , CHILDREN ) : NO_CHANGES
+objectCreated( 44 , BLOCK )
+propertyUpdated( 44 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
+propertyUpdated( 44 , BLOCK , NZCROSS ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , NMODE ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
+propertyUpdated( 44 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
+propertyUpdated( 44 , BLOCK , SIM_BLOCKTYPE ) : SUCCESS
+propertyUpdated( 44 , BLOCK , UID ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , STYLE ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , LABEL ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , GEOMETRY ) : SUCCESS
+propertyUpdated( 44 , BLOCK , ANGLE ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , STATE ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , DSTATE ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , RPAR ) : SUCCESS
+propertyUpdated( 44 , BLOCK , SIM_DEP_UT ) : SUCCESS
+propertyUpdated( 44 , BLOCK , IPAR ) : SUCCESS
+propertyUpdated( 44 , BLOCK , EXPRS ) : SUCCESS
+propertyUpdated( 44 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+objectCreated( 45 , PORT )
+propertyUpdated( 45 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 45 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 45 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 45 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 45 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 45 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 45 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 45 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , INPUTS ) : SUCCESS
+propertyUpdated( 44 , BLOCK , OUTPUTS ) : NO_CHANGES
+objectCreated( 46 , PORT )
+propertyUpdated( 46 , PORT , FIRING ) : NO_CHANGES
+propertyUpdated( 46 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 46 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 46 , PORT , STYLE ) : NO_CHANGES
+propertyUpdated( 46 , PORT , LABEL ) : NO_CHANGES
+propertyUpdated( 46 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 46 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 46 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , EVENT_INPUTS ) : SUCCESS
+propertyUpdated( 44 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
+propertyUpdated( 44 , BLOCK , CHILDREN ) : NO_CHANGES
+objectCreated( 47 , DIAGRAM )
+propertyUpdated( 47 , DIAGRAM , TITLE ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , PATH ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , PROPERTIES ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , PROPERTIES ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , CONTEXT ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , CHILDREN ) : NO_CHANGES
+propertyUpdated( 40 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 47 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 44 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 47 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 47 , DIAGRAM , VERSION_NUMBER ) : NO_CHANGES
+scs_m.objs(1).graphics.pout   // Check that block #1 is not connected
+ ans  =
+    0.
+scs_m.objs(1).model.out       // "
+ ans  =
+  - 1.
+scs_m.objs(2).graphics.pin    // Check that block #2 is not connected
+ ans  =
+    0.
+scs_m.objs(2).model.in        // "
+ ans  =
+  - 1.
+scs_m.objs(3) = lnk;          // Add the predefined Link
+objectCreated( 48 , LINK )
+propertyUpdated( 48 , LINK , COLOR ) : NO_CHANGES
+propertyUpdated( 48 , LINK , KIND ) : NO_CHANGES
+propertyUpdated( 48 , LINK , LABEL ) : NO_CHANGES
+propertyUpdated( 48 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 48 , LINK , THICK ) : NO_CHANGES
+propertyUpdated( 48 , LINK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 48 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 48 , LINK , DESTINATION_PORT ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 40 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 44 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
+propertyUpdated( 47 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 48 , LINK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 43 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 48 , LINK , SOURCE_PORT ) : SUCCESS
+propertyUpdated( 45 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 48 , LINK , DESTINATION_PORT ) : SUCCESS
+propertyUpdated( 47 , DIAGRAM , CHILDREN ) : SUCCESS
+scs_m.objs
+ ans  =
+     (1)
+scicos_Block type :
+  graphics
+  model
+  gui
+  doc
+     (2)
+scicos_Block type :
+  graphics
+  model
+  gui
+  doc
+     (3)
+scicos_Link type :
+  xx
+  yy
+  id
+  thick
+  ct
+  from
+  to
+scs_m.objs(3).from
+ ans  =
+    1.    1.    0.
+scs_m.objs(3).to
+ ans  =
+    2.    1.    1.
+scs_m.objs(1).graphics.pout   // Check that block #1 is connected to lnk
+ ans  =
+    3.
+scs_m.objs(1).model.out       // "
+ ans  =
+  - 1.
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk
+ ans  =
+    3.
+scs_m.objs(2).model.in        // "
+ ans  =
+  - 1.
index 31d807c..72c3186 100644 (file)
@@ -25,40 +25,81 @@ scs_m = scicos_diagram( objs=list(Sum,Scope1,Scope2,lnk1,lnk2) )
 scs_m.objs
 
 // Link output port #1 of block #1 with input port #1 of block #2 thanks to lnk1
-l = scs_m.objs;
-l(4).from = [1 1 0]; // Link block #1
-l(1).graphics.pout   // Check that block #1 is connected to lnk1
-l(1).model.out       // "
-l(4).to = [2 1 1];   // Link block #2
-l(4).from
-l(4).to
-l(2).graphics.pin    // Check that block #2 is connected to lnk1
-l(2).model.in        // "
+scs_m.objs(4).from = [1 1 0]; // Link block #1
+scs_m.objs(1).graphics.pout   // Check that block #1 is connected to lnk1
+scs_m.objs(1).model.out       // "
+scs_m.objs(4).to = [2 1 1];   // Link block #2
+scs_m.objs(4).from
+scs_m.objs(4).to
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk1
+scs_m.objs(2).model.in        // "
 
 // Change the end of the link to input port #2 of block #2
-l(4).to = [2 2 1];
-l(4).from
-l(4).to
-l(2).graphics.pin    // Check that block #2 is connected to lnk1
-l(2).model.in        // "
-
-// Disconnect the source, the destination is also disconnected
-l(4).from = [0 0 0];
-l(4).from
-l(4).to
-l(1).graphics.pout   // Check that both blocks are unconnected
-l(2).graphics.pin    // "
+scs_m.objs(4).to = [2 2 1];
+scs_m.objs(4).from
+scs_m.objs(4).to
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk1
+scs_m.objs(2).model.in        // "
+
+// Disconnect the source
+scs_m.objs(4).from = [0 0 0];
+scs_m.objs(4).from
+scs_m.objs(4).to
+scs_m.objs(1).graphics.pout   // Check that block #1 is not connected
+scs_m.objs(2).graphics.pin    // But block #2 is still connected to the link
+
+// Disconnect the destination
+scs_m.objs(4).to = [0 0 0];
+scs_m.objs(2).graphics.pin    // Check that block #2 is not connected
 
 // Now link the two Scope blocks together by adding an event output port to block #3 thanks to lnk2
-l(5).from = [2 1 1]; // Link the input of block #2
-l(5).to = [3 1 0];   // Add an event output to block #3 and link it to the previous
-l(5).from
-l(5).to
-l(2).graphics.pein   // Check that block #2 is connected to lnk2
-l(2).model.evtin     // "
-l(3).graphics.peout  // Check that block #3 is connected to lnk2
-l(3).model.evtout    // "
+scs_m.objs(5).from = [2 1 1]; // Link the input of block #2
+scs_m.objs(5).to = [3 1 0];   // Add an event output to block #3 and link it to the previous
+scs_m.objs(5).from
+scs_m.objs(5).to
+scs_m.objs(2).graphics.pein   // Check that block #2 is connected to lnk2
+scs_m.objs(2).model.evtin     // "
+scs_m.objs(3).graphics.peout  // Check that block #3 is connected to lnk2
+scs_m.objs(3).model.evtout    // "
 
 // Verify that it is impossible to link two inputs or two outputs together
-l(5).from = [2 1 0]; // Two outputs
-l(5).to = [3 1 1];   // Two inputs
+scs_m.objs(5).from = [2 1 0]; // Two outputs
+scs_m.objs(5).to = [3 1 1];   // Two inputs
+
+
+//===================================================================================================
+// Test predefined link at diagram creation
+clear scs_m;
+
+lnk   = scicos_link( from=[1 1 0],to=[2 1 1] );
+scs_m = scicos_diagram( objs=list(Sum,Scope1,lnk) );
+
+scs_m.objs(3).from
+scs_m.objs(3).to
+scs_m.objs(1).graphics.pout   // Check that block #1 is connected to lnk
+scs_m.objs(1).model.out       // "
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk
+scs_m.objs(2).model.in        // "
+
+
+//===================================================================================================
+// Test predefined link insertion
+clear scs_m;
+
+lnk   = scicos_link( from=[1 1 0],to=[2 1 1] );
+scs_m = scicos_diagram( objs=list(Sum,Scope1) );
+
+scs_m.objs(1).graphics.pout   // Check that block #1 is not connected
+scs_m.objs(1).model.out       // "
+scs_m.objs(2).graphics.pin    // Check that block #2 is not connected
+scs_m.objs(2).model.in        // "
+
+scs_m.objs(3) = lnk;          // Add the predefined Link
+
+scs_m.objs
+scs_m.objs(3).from
+scs_m.objs(3).to
+scs_m.objs(1).graphics.pout   // Check that block #1 is connected to lnk
+scs_m.objs(1).model.out       // "
+scs_m.objs(2).graphics.pin    // Check that block #2 is connected to lnk
+scs_m.objs(2).model.in        // "
index 464266b..e899800 100644 (file)
@@ -14,8 +14,6 @@ propertyUpdated( 1 , LINK , LABEL ) : NO_CHANGES
 propertyUpdated( 1 , LINK , THICK ) : NO_CHANGES
 propertyUpdated( 1 , LINK , COLOR ) : NO_CHANGES
 propertyUpdated( 1 , LINK , KIND ) : NO_CHANGES
-propertyUpdated( 1 , LINK , SOURCE_PORT ) : NO_CHANGES
-propertyUpdated( 1 , LINK , DESTINATION_PORT ) : NO_CHANGES
 lnk  = 
 scicos_Link type :
   xx