* Bug #15149 fixed: Files saved as ZCOS were corrupted. 24/19324/11
Clément DAVID [Thu, 6 Jul 2017 08:23:33 +0000 (10:23 +0200)]
Change-Id: I52c2e2c2e3757db04d0ec8706f7a034e41d87a0f

scilab/CHANGES.md
scilab/modules/scicos/macros/scicos_scicos/scicos_flat.sci
scilab/modules/xcos/sci_gateway/cpp/sci_xcosDiagramToScilab.cpp
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/XcosCell.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/XcosCellFactory.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/JGraphXHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/writer/ScilabWriter.java
scilab/modules/xcos/tests/nonreg_tests/bug_15149.tst [new file with mode: 0644]
scilab/modules/xcos/tests/nonreg_tests/bug_15149.zcos [new file with mode: 0644]

index 20a4cde..59104f5 100644 (file)
@@ -461,6 +461,7 @@ the [development mailing list](dev@lists.scilab.org) for a particular toolbox.
 * [#15144](http://bugzilla.scilab.org/show_bug.cgi?id=15144): `mean` and `stdev` could not be overloaded.
 * [#15146](http://bugzilla.scilab.org/show_bug.cgi?id=15146): `lasterror` crashed Scilab when last error message is empty.
 * [#15148](http://bugzilla.scilab.org/show_bug.cgi?id=15148): `link` did not return any error for a wrong flag argument value.
+* [#15149](http://bugzilla.scilab.org/show_bug.cgi?id=15149): Files saved as ZCOS were corrupted.
 * [#15170](http://bugzilla.scilab.org/show_bug.cgi?id=15170): `getd` created and returned a variable `k` that could overwrite a loaded one.
 * [#15183](http://bugzilla.scilab.org/show_bug.cgi?id=15183): `ndgrid(x)` with by default `y=x` was not accepted.
 * [#15184](http://bugzilla.scilab.org/show_bug.cgi?id=15184): `(1+%i) < 2` crashed Scilab.
index 8501c0f..a54acf3 100644 (file)
@@ -352,9 +352,12 @@ function  [cor,corinv,links_table,cur_fictitious,sco_mat,ok, IN, OUT, EIN, EOUT]
     end //end of loop on objects
 
     if ksup==0&nb==0 then
-        messagebox(msprintf(gettext("%s: Empty diagram"), "Xcos"),"modal")
+        if or(flag=="nw") then
+            disp(msprintf(gettext("%s: Empty diagram"), "scicos_flat"));
+        else
+            messagebox(msprintf(gettext("%s: Empty diagram"), "Xcos"),"modal");
+        end
         ok=%f
-        disp(msprintf("%s: Empty diagram", "scicos_flat"));
         return
     end
     //-------------- Analyse  links --------------
index 4459c6a..63e9144 100644 (file)
@@ -35,6 +35,7 @@ extern "C"
 #include "localization.h"
 #include "Scierror.h"
 #include "getScilabJavaVM.h"
+#include "getFullFilename.h"
 }
 /*--------------------------------------------------------------------------*/
 using namespace org_scilab_modules_xcos;
@@ -76,8 +77,10 @@ types::Function::ReturnValue sci_xcosDiagramToScilab(types::typed_list &in, int
         for (int i = 0; i < _iRetCount; i++)
         {
             char* f = wide_string_to_UTF8(files->get(i));
-            out[i] = importFile(f);
+            char* resolvedFile = getFullFilename(f);
             FREE(f);
+            out[i] = importFile(resolvedFile);
+            FREE(resolvedFile);
             if (out[i] == nullptr)
             {
                 return types::Function::Error;
@@ -98,8 +101,10 @@ types::Function::ReturnValue sci_xcosDiagramToScilab(types::typed_list &in, int
         for (int i = 0; i < _iRetCount; i++)
         {
             char* f = wide_string_to_UTF8(files->get(i));
-            bool success = exportFile(1 + i, f, in[1 + i]);
+            char* resolvedFile = getFullFilename(f);
             FREE(f);
+            bool success = exportFile(1 + i, resolvedFile, in[1 + i]);
+            FREE(resolvedFile);
             if (!success)
             {
                 return types::Function::Error;
index c46045b..ac5cbc1 100644 (file)
@@ -243,7 +243,7 @@ public class XcosDiagram extends ScilabGraph {
 
         while (parent[0] != 0l) {
             hierarchy.push(new ScicosObjectOwner(parent[0], Kind.BLOCK));
-            controller.getObjectProperty(local.getUID(), local.getKind(), ObjectProperties.PARENT_BLOCK, parent);
+            controller.getObjectProperty(parent[0], Kind.BLOCK, ObjectProperties.PARENT_BLOCK, parent);
         }
 
         controller.getObjectProperty(local.getUID(), local.getKind(), ObjectProperties.PARENT_DIAGRAM, parent);
index d7bf176..385a682 100644 (file)
@@ -116,11 +116,14 @@ public class XcosCell extends mxCell {
 
         switch (getKind()) {
             case BLOCK:
-                if (!(validCIdentifier.matcher(String.valueOf(value)).matches())) {
+                if (validCIdentifier.matcher(String.valueOf(value)).matches()) {
                     // a block description should be a valid C / Scilab identifier to ease codegeneration
-                    break;
+                    controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DESCRIPTION, String.valueOf(value));
                 }
+                break;
             case ANNOTATION:
+                controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DESCRIPTION, String.valueOf(value));
+                break;
             case LINK:
                 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DESCRIPTION, String.valueOf(value));
                 break;
index 283d1f4..58c9826 100644 (file)
@@ -279,9 +279,6 @@ public final class XcosCellFactory {
 
         // add all the children using the diagram modification tracking features
         diagram.addCells(cells);
-
-        // each cell has been referenced twice (CHILDREN insert and addCells), derefence them all by one
-        Arrays.stream(cells).forEach(c -> controller.deleteObject(c.getUID()));
     }
 
     /*
@@ -570,7 +567,6 @@ public final class XcosCellFactory {
 
         Arrays.stream(children).forEach(c -> {
             parent.insert(c);
-            controller.deleteObject(c.getUID());
         });
 
         return children.length;
index 8c9b92c..2ccc5d8 100644 (file)
@@ -24,7 +24,11 @@ import org.xml.sax.Attributes;
 
 import com.mxgraph.model.mxGeometry;
 import com.mxgraph.util.mxPoint;
+import java.nio.DoubleBuffer;
+import java.nio.LongBuffer;
 import java.util.ArrayList;
+import org.scilab.modules.xcos.VectorOfDouble;
+import org.scilab.modules.xcos.VectorOfScicosID;
 
 class JGraphXHandler implements ScilabHandler {
 
@@ -62,21 +66,39 @@ class JGraphXHandler implements ScilabHandler {
             case mxGeometry: {
                 mxGeometry g = new mxGeometry();
 
-                v = atts.getValue("height");
+                v = atts.getValue("x");
                 if (v != null) {
-                    g.setHeight(Double.valueOf(v));
+                    g.setX(Double.valueOf(v));
+                }
+                v = atts.getValue("y");
+                if (v != null) {
+                    g.setY(Double.valueOf(v));
                 }
                 v = atts.getValue("width");
                 if (v != null) {
                     g.setWidth(Double.valueOf(v));
                 }
-                v = atts.getValue("x");
+                v = atts.getValue("height");
                 if (v != null) {
-                    g.setX(Double.valueOf(v));
+                    g.setHeight(Double.valueOf(v));
                 }
-                v = atts.getValue("y");
-                if (v != null) {
-                    g.setY(Double.valueOf(v));
+
+                /*
+                 * the MVC only store absolute values, resolve the "relative" geometry flag for Scilab 5.5.2 annotation
+                 */
+                v = atts.getValue("relative");
+                if (v != null && v.charAt(0) == '1') {
+                    Object parent = saxHandler.parents.peek();
+                    if (parent instanceof XcosCell) {
+                        XcosCell cell = (XcosCell) parent;
+                        long[] parentUID = {0};
+                        saxHandler.controller.getObjectProperty(cell.getUID(), cell.getKind(), ObjectProperties.RELATED_TO, parentUID);
+
+                        VectorOfDouble parentGeom = new VectorOfDouble(4);
+                        saxHandler.controller.getObjectProperty(parentUID[0], saxHandler.controller.getKind(parentUID[0]), ObjectProperties.GEOMETRY, parentGeom);
+                        g.setX(parentGeom.get(0) + g.getX() * parentGeom.get(2));
+                        g.setY(parentGeom.get(1) + g.getY() * parentGeom.get(3));
+                    }
                 }
 
                 return g;
@@ -93,17 +115,49 @@ class JGraphXHandler implements ScilabHandler {
                     p.setY(Double.valueOf(v));
                 }
 
-                if (saxHandler.parents.peek() instanceof mxGeometry) {
-                    mxGeometry parent = (mxGeometry) saxHandler.parents.peek();
+                Object localParent = saxHandler.parents.peek();
+                if (localParent instanceof mxGeometry) {
+                    mxGeometry parent = (mxGeometry) localParent;
                     v = atts.getValue("as");
                     if ("sourcePoint".equals(v)) {
                         parent.setSourcePoint(p);
                     } else if ("targetPoint".equals(v)) {
                         parent.setTargetPoint(p);
                     }
-                } else if (saxHandler.parents.peek() instanceof RawDataHandler.RawDataDescriptor) {
-                    RawDataHandler.RawDataDescriptor parent = (RawDataHandler.RawDataDescriptor) saxHandler.parents.peek();
+                } else if (localParent instanceof RawDataHandler.RawDataDescriptor) {
+                    RawDataHandler.RawDataDescriptor parent = (RawDataHandler.RawDataDescriptor) localParent;
                     ((ArrayList) parent.value).add(p);
+                } else if (localParent instanceof XcosCell) {
+                    // Diagram origin, translate each children
+                    XcosCell parent = (XcosCell) localParent;
+
+                    VectorOfScicosID children = new VectorOfScicosID();
+                    saxHandler.controller.getObjectProperty(parent.getUID(), parent.getKind(), ObjectProperties.CHILDREN, children);
+
+                    VectorOfDouble geometry = new VectorOfDouble(4);
+                    DoubleBuffer geom = geometry.asByteBuffer(0, 4).asDoubleBuffer();
+
+                    LongBuffer childrenUIDs = children.asByteBuffer(0, children.size()).asLongBuffer();
+                    while (childrenUIDs.hasRemaining()) {
+                        long uid = childrenUIDs.get();
+                        Kind kind = saxHandler.controller.getKind(uid);
+
+                        saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.GEOMETRY, geometry);
+                        geom.put(0, geom.get(0) + p.getX());
+                        geom.put(1, geom.get(1) + p.getY());
+                        saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.GEOMETRY, geometry);
+
+                        // translate the annotation
+                        long[] annotation = { 0 };
+                        saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.LABEL, annotation);
+                        if (annotation[0] != 0) {
+                            saxHandler.controller.getObjectProperty(annotation[0], Kind.ANNOTATION, ObjectProperties.GEOMETRY, geometry);
+                            geom.put(0, geom.get(0) + p.getX());
+                            geom.put(1, geom.get(1) + p.getY());
+                            saxHandler.controller.setObjectProperty(annotation[0], Kind.ANNOTATION, ObjectProperties.GEOMETRY, geometry);
+                        }
+                    }
+
                 }
                 return p;
             }
@@ -151,7 +205,7 @@ class JGraphXHandler implements ScilabHandler {
                 }
                 XcosCell cell = (XcosCell) saxHandler.parents.peek(1);
 
-                cell.setGeometry(g);
+                cell.setGeometry(saxHandler.controller, g);
             }
             break;
             case mxPoint:
index c626b48..a16ef6e 100644 (file)
@@ -60,11 +60,10 @@ abstract class ScilabWriter {
             shared.stream.writeAttribute("style", v[0]);
 
             shared.controller.getObjectProperty(label[0],  Kind.ANNOTATION, ObjectProperties.DESCRIPTION, v);
-            if (!v[0].isEmpty()) {
-                // remove any '\n' character that will not be preserved by the XML Handlers on re-load
-                String escaped = v[0].replace('\n', ' ');
-                shared.stream.writeAttribute("value", escaped);
-            }
+
+            // remove any '\n' character that will not be preserved by the XML Handlers on re-load
+            String escaped = v[0].replace('\n', ' ');
+            shared.stream.writeAttribute("value", escaped);
 
             shared.stream.writeAttribute("vertex", "1");
 
diff --git a/scilab/modules/xcos/tests/nonreg_tests/bug_15149.tst b/scilab/modules/xcos/tests/nonreg_tests/bug_15149.tst
new file mode 100644 (file)
index 0000000..64d19c5
--- /dev/null
@@ -0,0 +1,144 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2017 - ESI Group - Clement DAVID
+//
+// This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- XCOS TEST -->
+// <-- NO CHECK REF -->
+// <-- ENGLISH IMPOSED -->
+//
+// <-- Non-regression test for bug 15149 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=15149
+//
+// <-- Short Description -->
+// Some schema file were corrupted on save and reload
+//
+
+loadXcosLibs();
+
+// load and save
+scs_m1 = xcosDiagramToScilab("SCI/modules/xcos/tests/nonreg_tests/bug_15149.zcos");
+xcosDiagramToScilab("TMPDIR/foo.zcos", scs_m1);
+
+// reload #1
+scs_m2 = xcosDiagramToScilab("TMPDIR/foo.zcos");
+// reload #2
+scs_m3 = xcosDiagramToScilab("TMPDIR/foo.zcos");
+
+// check that objs have the same size
+assert_checkequal(lstsize(scs_m1.objs), lstsize(scs_m2.objs));
+assert_checkequal(lstsize(scs_m1.objs), lstsize(scs_m3.objs));
+
+// check that all blocks are connected
+for i=1:lstsize(scs_m1.objs)
+    o = scs_m1.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+for i=1:lstsize(scs_m2.objs)
+    o = scs_m2.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+for i=1:lstsize(scs_m3.objs)
+    o = scs_m3.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+
+
+// simulate scs_m1 and scs_m2
+// warnings are possible but scs_m2 simulation should pass and should not
+// destroy scs_m1 nor scs_m3 objects
+
+scicos_simulate(scs_m1, "nw");
+
+// check that objs have the same size
+assert_checkequal(lstsize(scs_m1.objs), lstsize(scs_m2.objs));
+assert_checkequal(lstsize(scs_m1.objs), lstsize(scs_m3.objs));
+
+// check that all blocks are connected
+for i=1:lstsize(scs_m1.objs)
+    o = scs_m1.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+for i=1:lstsize(scs_m2.objs)
+    o = scs_m2.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+for i=1:lstsize(scs_m3.objs)
+    o = scs_m3.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+
+
+scicos_simulate(scs_m2, "nw");
+
+// check that objs have the same size
+assert_checkequal(lstsize(scs_m1.objs), lstsize(scs_m2.objs));
+assert_checkequal(lstsize(scs_m1.objs), lstsize(scs_m3.objs));
+
+// check that all blocks are connected
+for i=1:lstsize(scs_m1.objs)
+    o = scs_m1.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+for i=1:lstsize(scs_m2.objs)
+    o = scs_m2.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+for i=1:lstsize(scs_m3.objs)
+    o = scs_m3.objs(i);
+    if typeof(o) == "Block" then
+        assert_checktrue(o.graphics.pin <> 0);
+        assert_checktrue(o.graphics.pout <> 0);
+        assert_checktrue(o.graphics.pein <> 0);
+        assert_checktrue(o.graphics.peout <> 0);
+    end
+end
+
+clear scs_m1
+clear scs_m2
+clear scs_m3
+
diff --git a/scilab/modules/xcos/tests/nonreg_tests/bug_15149.zcos b/scilab/modules/xcos/tests/nonreg_tests/bug_15149.zcos
new file mode 100644 (file)
index 0000000..f239c9f
Binary files /dev/null and b/scilab/modules/xcos/tests/nonreg_tests/bug_15149.zcos differ