Xcos: save on the GUI and open block settings 23/17423/7
Clément DAVID [Tue, 3 Nov 2015 10:03:27 +0000 (11:03 +0100)]
Change-Id: Id3468d3d90e5d5f627e8c820bc91f3f934ed70ac

14 files changed:
scilab/modules/action_binding/src/java/org/scilab/modules/action_binding/highlevel/ScilabInterpreterManagement.java
scilab/modules/scicos/sci_gateway/cpp/sci_scicos_new.cpp
scilab/modules/xcos/src/java/org/scilab/modules/xcos/Xcos.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/BasicBlock.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/actions/BlockParametersAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/CompilationEngineStatus.java [deleted file]
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/XcosCellFactory.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/swing/handler/GraphHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/XcosFileType.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/Handler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/ScilabDirectHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/spec/ContentEntry.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/utils/Stack.java

index 4598537..431c295 100644 (file)
@@ -349,7 +349,7 @@ public final class ScilabInterpreterManagement extends InterpreterManagement {
                 b.append(", ");
             }
         }
-        b.append("); ");
+        b.append(")");
 
         return b.toString();
     }
index b8b5945..3c38012 100644 (file)
@@ -11,8 +11,8 @@
  */
 
 #include <string>
+#include <sstream>
 
-#include "../../includes/view_scilab/Adapters.hxx"
 #include "gw_scicos.hxx"
 
 #include "types.hxx"
@@ -23,6 +23,7 @@
 #include "list.hxx"
 #include "function.hxx"
 
+#include "view_scilab/Adapters.hxx"
 #include "view_scilab/BaseAdapter.hxx"
 #include "view_scilab/BlockAdapter.hxx"
 #include "view_scilab/CprAdapter.hxx"
@@ -130,7 +131,7 @@ types::InternalType * alloc_and_set_as_mlist(types::String* type_name, types::ty
     return mlist;
 }
 
-types::Function::ReturnValue allocate(types::typed_list &in, int _iRetCount, types::typed_list &out)
+static types::Function::ReturnValue allocate(types::typed_list &in, int _iRetCount, types::typed_list &out)
 {
     types::InternalType* type = in[0];
 
@@ -234,7 +235,31 @@ types::Function::ReturnValue allocate(types::typed_list &in, int _iRetCount, typ
     return types::Function::OK;
 }
 
-types::Function::ReturnValue get(types::Int64* UIDs, int _iRetCount, types::typed_list &out)
+static ScicosID get(types::GenericType* UIDs, int index)
+{
+    ScicosID ret;
+
+    switch (UIDs->getType())
+    {
+        case types::InternalType::ScilabString:
+        {
+            wchar_t* str = UIDs->getAs<types::String>()->get(index);
+            std::wistringstream iss(str);
+            iss >> ret;
+            break;
+        }
+        case types::InternalType::ScilabInt64:
+            ret = UIDs->getAs<types::Int64>()->get(index);
+            break;
+        default:
+            ret = ScicosID();
+            break;
+    }
+
+    return ret;
+}
+
+static types::Function::ReturnValue get(types::GenericType* UIDs, int _iRetCount, types::typed_list &out)
 {
     if (UIDs->getSize() != _iRetCount)
     {
@@ -247,7 +272,7 @@ types::Function::ReturnValue get(types::Int64* UIDs, int _iRetCount, types::type
     types::Function::ReturnValue retValue = types::Function::OK;
     for (int i = 0; i < _iRetCount; ++i)
     {
-        ScicosID uid = UIDs->get(i);
+        ScicosID uid = get(UIDs, i);
 
         // create the associated object
         model::BaseObject* o = controller.getObject(uid);
@@ -305,7 +330,14 @@ types::Function::ReturnValue sci_scicos_new(types::typed_list &in, int _iRetCoun
     switch (type->getType())
     {
         case types::InternalType::ScilabString:
-            return allocate(in, _iRetCount, out);
+            if (in.size() == 1)
+            {
+                return get(type->getAs<types::String>(), _iRetCount, out);
+            }
+            else
+            {
+                return allocate(in, _iRetCount, out);
+            }
         case types::InternalType::ScilabInt64:
             return get(type->getAs<types::Int64>(), _iRetCount, out);
         default:
index ae4f9fa..d067957 100644 (file)
@@ -502,13 +502,7 @@ public final class Xcos {
              */
             diag.transformAndLoadFile(controller, file);
 
-            if (diag != null) {
-                addDiagram(diag.getUID(), diag);
-            }
-        }
-
-        if (diag != null) {
-            diag.updateTabTitle();
+            addDiagram(diag.getUID(), diag);
         }
     }
 
@@ -595,6 +589,26 @@ public final class Xcos {
     }
 
     /**
+     * Add a diagram to the opened  list
+     *
+     * This method manage both super-block and root diagrams.
+     * @param diag the diagram to add
+     */
+    public void addDiagram(final XcosDiagram diag) {
+        if (diag.getKind() == Kind.DIAGRAM) {
+            addDiagram(diag.getUID(), diag);
+        } else {
+            long[] root = new long[1];
+            new JavaController().getObjectProperty(diag.getUID(), diag.getKind(), ObjectProperties.PARENT_DIAGRAM, root);
+
+            addDiagram(root[0], diag);
+        }
+
+    }
+
+
+
+    /**
      * Create a diagram collections (sorted List)
      *
      * @return the diagram collection
@@ -687,6 +701,8 @@ public final class Xcos {
         final boolean wasLastOpenedForFile = openedDiagrams(rootDiagram[0]).size() <= 1;
         if (wasLastOpenedForFile) {
             diagrams.remove(rootDiagram[0]);
+        } else {
+            diagrams.get(rootDiagram[0]).remove(graph);
         }
 
         if (openedDiagrams().size() <= 0) {
index c6b7b81..9ad5c4b 100644 (file)
@@ -15,8 +15,12 @@ package org.scilab.modules.xcos.block;
 import java.awt.MouseInfo;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -38,6 +42,10 @@ import org.scilab.modules.gui.menuitem.ScilabMenuItem;
 import org.scilab.modules.xcos.JavaController;
 import org.scilab.modules.xcos.Kind;
 import org.scilab.modules.xcos.ObjectProperties;
+import org.scilab.modules.xcos.VectorOfDouble;
+import org.scilab.modules.xcos.VectorOfInt;
+import org.scilab.modules.xcos.VectorOfScicosID;
+import org.scilab.modules.xcos.VectorOfString;
 import org.scilab.modules.xcos.Xcos;
 import org.scilab.modules.xcos.XcosTab;
 import org.scilab.modules.xcos.actions.EditFormatAction;
@@ -232,75 +240,214 @@ public class BasicBlock extends XcosCell implements Serializable {
     }
 
     /**
+     * Does the block update and register on the undo manager
+     * @param controller
+     *
+     * @param modifiedBlock
+     *            the new settings
+     */
+    public void updateBlockSettings(JavaController controller, XcosDiagram parent, BasicBlock modifiedBlock) {
+        if (modifiedBlock == null) {
+            return;
+        }
+
+        /*
+         * Update the block settings
+         */
+        updateFields(controller, parent, modifiedBlock);
+
+        /*
+         * Update the children ports
+         */
+        updateChildren(controller, parent, modifiedBlock);
+    }
+
+    /**
+     * Update the instance field and the model values
+     *
+     * @param modifiedBlock
+     *            the modified instance
+     */
+    private void updateFields(JavaController controller, XcosDiagram parent, BasicBlock modifiedBlock) {
+        if (modifiedBlock == null) {
+            return;
+        }
+
+        // TODO these copies are not managed by undo/redo ; fix that
+
+        int[] integer = new int[1];
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_FUNCTION_API, integer);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_FUNCTION_API, integer[0]);
+
+        String[] str = new String[1];
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.INTERFACE_FUNCTION, str);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.INTERFACE_FUNCTION, str[0]);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_FUNCTION_NAME, str);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_FUNCTION_NAME, str[0]);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_BLOCKTYPE, str);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_BLOCKTYPE, str[0]);
+
+        VectorOfDouble vDouble = new VectorOfDouble();
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.EXPRS, vDouble);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.EXPRS, vDouble);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.STATE, vDouble);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.STATE, vDouble);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.DSTATE, vDouble);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DSTATE, vDouble);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.ODSTATE, vDouble);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.ODSTATE, vDouble);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.RPAR, vDouble);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.RPAR, vDouble);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.OPAR, vDouble);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.OPAR, vDouble);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.EQUATIONS, vDouble);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.EQUATIONS, vDouble);
+
+        VectorOfInt vInt = new VectorOfInt();
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_DEP_UT, vInt);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_DEP_UT, vInt);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.NZCROSS, vInt);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.NZCROSS, vInt);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.NMODE, vInt);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.NMODE, vInt);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.IPAR, vInt);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.IPAR, vInt);
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.COLOR, vInt);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.COLOR, vInt);
+
+        VectorOfString vStr = new VectorOfString();
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.DIAGRAM_CONTEXT, vStr);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DIAGRAM_CONTEXT, vStr);
+
+        VectorOfScicosID children = new VectorOfScicosID();
+
+        controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.CHILDREN, children);
+        controller.setObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
+
+        /*
+         * JGraphX mapped properties
+         */
+        parent.getModel().setStyle(this, modifiedBlock.getStyle());
+        parent.getModel().setValue(this, modifiedBlock.getValue());
+    }
+
+    /**
      * Update the children of the block.
      *
      * @param modifiedBlock
      *            the new block instance
      */
-    private void updateChildren(BasicBlock modifiedBlock) {
-        // if (modifiedBlock == null) {
-        // return;
-        // }
-        //
-        // XcosDiagram graph = getParentDiagram();
-        // if (graph == null) {
-        // setParentDiagram(Xcos.findParent(this));
-        // graph = getParentDiagram();
-        // LOG.finest(PARENT_DIAGRAM_WAS_NULL);
-        // }
-        //
-        // /*
-        // * Checked as port classes only
-        // */
-        // @SuppressWarnings("unchecked")
-        // Set < Class <? extends mxICell >> types = new HashSet < Class <? extends mxICell >> (Arrays.asList(InputPort.class, OutputPort.class, ControlPort.class,
-        // CommandPort.class));
-        //
-        // Map < Class <? extends mxICell > , Deque<mxICell >> annotatedOlds = getTypedChildren(types);
-        // Map < Class <? extends mxICell > , Deque<mxICell >> annotatedNews = modifiedBlock.getTypedChildren(types);
-        //
-        // getParentDiagram().getModel().beginUpdate();
-        // try {
-        // for (Class <? extends mxICell > klass : types) {
-        // final Deque<mxICell> olds = annotatedOlds.get(klass);
-        // final Deque<mxICell> news = annotatedNews.get(klass);
-        //
-        // // updated ports
-        // while (!olds.isEmpty() && !news.isEmpty()) {
-        // mxICell previous = olds.poll();
-        // mxICell modified = news.poll();
-        //
-        // final int previousIndex = children.indexOf(previous);
-        //
-        // // relink
-        // if (previous.getEdgeCount() != 0) {
-        // final mxICell edge = previous.getEdgeAt(0);
-        // final boolean isOutgoing = previous == edge.getTerminal(true);
-        // previous.removeEdge(edge, isOutgoing);
-        // modified.insertEdge(edge, isOutgoing);
-        // }
-        //
-        // getParentDiagram().removeCells(new Object[] { previous }, false);
-        // getParentDiagram().addCells(new Object[] { modified }, this, previousIndex);
-        //
-        // // Clone the geometry to avoid empty geometry on new cells.
-        // getParentDiagram().getModel().setGeometry(modified, (mxGeometry) previous.getGeometry().clone());
-        //
-        // }
-        //
-        // // removed ports
-        // if (!olds.isEmpty()) {
-        // getParentDiagram().removeCells(olds.toArray(), true);
-        // }
-        //
-        // // added ports
-        // if (!news.isEmpty()) {
-        // getParentDiagram().addCells(news.toArray(), this);
-        // }
-        // }
-        // } finally {
-        // getParentDiagram().getModel().endUpdate();
-        // }
+    private void updateChildren(JavaController controller, XcosDiagram parent, BasicBlock modifiedBlock) {
+        if (modifiedBlock == null) {
+            return;
+        }
+
+        /*
+         * Checked as port classes only
+         */
+        Set < Class <? extends mxICell >> types = new HashSet < Class <? extends mxICell >> (Arrays.asList(InputPort.class, OutputPort.class, ControlPort.class, CommandPort.class));
+
+        Map < Class <? extends mxICell > , Deque<mxICell >> annotatedOlds = getTypedChildren(types);
+        Map < Class <? extends mxICell > , Deque<mxICell >> annotatedNews = modifiedBlock.getTypedChildren(types);
+
+        parent.getModel().beginUpdate();
+        try {
+            for (Class <? extends mxICell > klass : types) {
+                final Deque<mxICell> olds = annotatedOlds.get(klass);
+                final Deque<mxICell> news = annotatedNews.get(klass);
+
+                // updated ports
+                while (!olds.isEmpty() && !news.isEmpty()) {
+                    mxICell previous = olds.poll();
+                    mxICell modified = news.poll();
+
+                    final int previousIndex = children.indexOf(previous);
+
+                    // relink
+                    if (previous.getEdgeCount() != 0) {
+                        final mxICell edge = previous.getEdgeAt(0);
+                        final boolean isOutgoing = previous == edge.getTerminal(true);
+                        previous.removeEdge(edge, isOutgoing);
+                        modified.insertEdge(edge, isOutgoing);
+                    }
+
+                    parent.removeCells(new Object[] { previous }, false);
+                    parent.addCells(new Object[] { modified }, this, previousIndex);
+
+                    // Clone the geometry to avoid empty geometry on new cells.
+                    parent.getModel().setGeometry(modified, (mxGeometry) previous.getGeometry().clone());
+
+                }
+
+                // removed ports
+                if (!olds.isEmpty()) {
+                    parent.removeCells(olds.toArray(), true);
+                }
+
+                // added ports
+                if (!news.isEmpty()) {
+                    parent.addCells(news.toArray(), this);
+                }
+            }
+        } finally {
+            parent.getModel().endUpdate();
+        }
+    }
+
+    /**
+     * Format the children as a typed map for the given class set.
+     *
+     * @param types
+     *            the classes to search for.
+     * @return a map which linked foreach type the corresponding cell list.
+     */
+    private Map < Class <? extends mxICell > , Deque<mxICell >> getTypedChildren(Set < Class <? extends mxICell >> types) {
+        Map < Class <? extends mxICell > , Deque<mxICell >> oldPorts = new HashMap < Class <? extends mxICell > , Deque<mxICell >> ();
+
+        // Allocate all types set
+        for (Class <? extends mxICell > type : types) {
+            oldPorts.put(type, new LinkedList<mxICell>());
+        }
+
+        if (getChildCount() <= 0) {
+            return oldPorts;
+        }
+
+        // children lookup
+        for (Object cell : children) {
+
+            Class <? extends Object > klass = cell.getClass();
+            while (klass != null) {
+                if (types.contains(klass)) {
+                    break;
+                }
+                klass = klass.getSuperclass();
+            }
+
+            final Deque<mxICell> current = oldPorts.get(klass);
+            if (current != null) {
+                current.add((mxICell) cell);
+            }
+        }
+
+        return oldPorts;
     }
 
     /**
@@ -310,7 +457,7 @@ public class BasicBlock extends XcosCell implements Serializable {
      *            the classes to search for.
      * @return a map which linked foreach type the corresponding cell index in the children.
      */
-    public Map<Class<? extends mxICell>, ArrayList<Integer>> getTypedChildrenIndexes(Set<Class<? extends mxICell>> types) {
+    private Map<Class<? extends mxICell>, ArrayList<Integer>> getTypedChildrenIndexes(Set<Class<? extends mxICell>> types) {
         Map<Class<? extends mxICell>, ArrayList<Integer>> oldPorts = new HashMap<Class<? extends mxICell>, ArrayList<Integer>>();
 
         // Allocate all types set
@@ -387,93 +534,6 @@ public class BasicBlock extends XcosCell implements Serializable {
     }
 
     /**
-     * @param context
-     *            parent diagram context
-     */
-    public void openBlockSettings() {
-        // FIXME: implement something
-        // final XcosDiagram graph;
-        // if (getParentDiagram() == null) {
-        // setParentDiagram(Xcos.findParent(this));
-        // graph = getParentDiagram();
-        // LOG.finest(PARENT_DIAGRAM_WAS_NULL);
-        // } else {
-        // graph = getParentDiagram();
-        // }
-        // if (graph instanceof PaletteDiagram) {
-        // return;
-        // }
-        //
-        // if (context == null) {
-        // throw new IllegalArgumentException();
-        // }
-        //
-        // // prevent to open twice
-        // if (isLocked()) {
-        // return;
-        // }
-        //
-        // graph.setCellsLocked(true);
-        // graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-        //
-        // // sort children according to the ordering parameter (useful on
-        // // scilab-5.2.x diagrams)
-        // sortChildren();
-        //
-        // final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
-        // if (handler == null) {
-        // return;
-        // }
-        //
-        // try {
-        // // Write scs_m
-        // handler.writeBlock(this);
-        // // Write context
-        // handler.writeContext(context);
-        //
-        // final ActionListener action = new ActionListener() {
-        // @Override
-        // public void actionPerformed(ActionEvent e) {
-        // LOG.finest("Updating data.");
-        //
-        // graph.getView().clear(this, true, true);
-        //
-        // // Now read new Block
-        // graph.getModel().beginUpdate();
-        // try {
-        // final BasicBlock modifiedBlock = handler.readBlock();
-        // updateBlockSettings(modifiedBlock);
-        //
-        // graph.fireEvent(new mxEventObject(XcosEvent.ADD_PORTS, XcosConstants.EVENT_BLOCK_UPDATED, BasicBlock.this));
-        // } catch (ScicosFormatException ex) {
-        // LOG.severe(ex.toString());
-        // } finally {
-        // graph.getModel().endUpdate();
-        // setLocked(false);
-        //
-        // handler.release();
-        //
-        // graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-        // graph.setCellsLocked(false);
-        // }
-        // }
-        // };
-        //
-        // setLocked(true);
-        // ScilabInterpreterManagement.asynchronousScilabExec(action, "blk = xcosBlockInterface", getInterfaceFunctionName().toCharArray(), "set",
-        // ScilabDirectHandler.BLK.toCharArray(), ScilabDirectHandler.CONTEXT.toCharArray());
-        // } catch (InterpreterException e) {
-        // LOG.severe(e.toString());
-        // setLocked(false);
-        //
-        // handler.release();
-        //
-        // graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-        // graph.setCellsLocked(false);
-        // }
-    }
-
-    /**
      * @param graph
      *            parent graph
      */
index 69fb124..171f8f8 100644 (file)
 
 package org.scilab.modules.xcos.block.actions;
 
+import java.awt.Cursor;
 import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 
+import org.scilab.modules.action_binding.InterpreterManagement;
+import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
+import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
 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.VectorOfScicosID;
+import org.scilab.modules.xcos.Xcos;
+import org.scilab.modules.xcos.XcosTab;
+import org.scilab.modules.xcos.block.BasicBlock;
 import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.graph.model.BlockInterFunction;
+import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
+import org.scilab.modules.xcos.graph.model.XcosCell;
+import org.scilab.modules.xcos.graph.model.XcosCellFactory;
+import org.scilab.modules.xcos.io.scicos.ScilabDirectHandler;
+import org.scilab.modules.xcos.utils.BlockPositioning;
 import org.scilab.modules.xcos.utils.XcosMessages;
 
+import static org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.buildCall;
+import static org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.asynchronousScilabExec;
+
 /**
  * Open dialog to set block parameters
  */
@@ -66,13 +87,90 @@ public class BlockParametersAction extends VertexSelectionDependantAction {
      */
     @Override
     public void actionPerformed(ActionEvent e) {
-        if (((XcosDiagram) getGraph(null)).getSelectionCell() != null) {
-            XcosDiagram diagram = (XcosDiagram) getGraph(null);
+        actionPerformed();
+    }
+
+    public void actionPerformed() {
+        XcosDiagram graph = (XcosDiagram) getGraph(null);
+        Object selectedCell = graph.getSelectionCell();
+        if (selectedCell != null && selectedCell instanceof XcosCell) {
+            XcosCell cell = (XcosCell) selectedCell;
+
+            if (cell.getKind() != Kind.BLOCK) {
+                return;
+            }
+
+            final JavaController controller = new JavaController();
+
+            String[] interfaceFunction = new String[1];
+            controller.getObjectProperty(cell.getUID(), cell.getKind(), ObjectProperties.INTERFACE_FUNCTION, interfaceFunction);
+
+            BlockInterFunction func = XcosCellFactory.lookForInterfunction(interfaceFunction[0]);
+            if (func.equals(BlockInterFunction.SUPER_f)) {
+                // this is a super-block, open it
+                XcosDiagram sub = new XcosDiagram(cell.getUID(), cell.getKind());
+                XcosCellFactory.insertChildren(controller, sub);
+
+                XcosTab.restore(sub, true);
+                Xcos.getInstance().addDiagram(sub);
+            } else {
+                BasicBlock block = (BasicBlock) cell;
+                // prevent to open twice
+                if (block.isLocked()) {
+                    return;
+                }
+
+                graph.setCellsLocked(true);
+                graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
 
-            // FIXME implement something using the XcosView
-            //            ((BasicBlock) diagram.getSelectionCell()).openBlockSettings(diagram
-            //                    .getContext());
+                try {
+
+                    final ActionListener action = new ActionListener() {
+                        @Override
+                        public void actionPerformed(ActionEvent e) {
+
+                            graph.getView().clear(this, true, true);
+
+                            // Now read new Block
+                            graph.getModel().beginUpdate();
+                            try {
+                                ScicosObjectOwner last = XcosCellFactory.getLastCreated();
+                                if (last != null && last.getUID() != 0l) {
+                                    BasicBlock modified = XcosCellFactory.createBlock(controller, last);
+                                    if (modified != null) {
+                                        block.updateBlockSettings(controller, graph, modified);
+                                    }
+                                }
+                                BlockPositioning.updateBlockView(graph, block);
+                            } finally {
+                                graph.getModel().endUpdate();
+                                block.setLocked(false);
+
+                                graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                                graph.setCellsLocked(false);
+                            }
+                        }
+                    };
+
+                    ScilabDirectHandler handler = ScilabDirectHandler.acquire();
+                    try {
+                        handler.writeContext(graph.getContext());
+                    } finally {
+                        handler.release();
+                    }
+
+                    block.setLocked(true);
+                    String blk = buildCall("scicos_new", Long.toString(cell.getUID()));
+                    String xcosBlockInterface = buildCall("xcosBlockInterface", interfaceFunction[0].toCharArray(), "set", blk.toCharArray(), ScilabDirectHandler.CONTEXT.toCharArray());
+
+                    asynchronousScilabExec(action, "xcosCellCreated", xcosBlockInterface.toCharArray());
+                } catch (InterpreterException ex) {
+                    block.setLocked(false);
+
+                    graph.getAsComponent().getGraphControl().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+                    graph.setCellsLocked(false);
+                }
+            }
         }
     }
-
 }
diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/CompilationEngineStatus.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/CompilationEngineStatus.java
deleted file mode 100644 (file)
index 70c5873..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2010 - DIGITEO - Clement DAVID
- *
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at
- * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
- *
- */
-
-package org.scilab.modules.xcos.graph;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.logging.Logger;
-
-import com.mxgraph.util.mxEventObject;
-import com.mxgraph.util.mxEventSource.mxIEventListener;
-
-/**
- * Contains the current Scicos engine status.
- */
-public class CompilationEngineStatus implements mxIEventListener, PropertyChangeListener {
-    private static final Logger LOG = Logger.getLogger(CompilationEngineStatus.class.getName());
-
-    private boolean compilationNeeded;
-
-    /**
-     * Default constructor.
-     */
-    public CompilationEngineStatus() {
-        setCompilationNeeded(true);
-    }
-
-    /**
-     * @param status
-     *            true, when the associated diagram need to be compiled, false
-     *            otherwise.
-     */
-    public void setCompilationNeeded(boolean status) {
-        // compilationNeeded = status;
-
-        compilationNeeded = true;
-    }
-
-    /**
-     * @return always true as we don't use scicos internal modification checking
-     */
-    public boolean isCompilationNeeded() {
-        return compilationNeeded;
-    }
-
-    /*
-     * Property change listener
-     */
-
-    /**
-     * Listener used for any interesting diagram change.
-     *
-     * @param sender
-     *            the associated diagram
-     * @param evt
-     *            the current event.
-     * @see com.mxgraph.util.mxEventSource.mxIEventListener#invoke(java.lang.Object,
-     *      com.mxgraph.util.mxEventObject)
-     */
-    @Override
-    public void invoke(Object sender, mxEventObject evt) {
-        setCompilationNeeded(true);
-    }
-
-    /**
-     * Property change listener used to update compilation status when the
-     * context has changed.
-     *
-     * @param evt
-     *            the current event
-     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
-     */
-    @Override
-    public void propertyChange(PropertyChangeEvent evt) {
-        setCompilationNeeded(true);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
-}
index 110facb..dc5bd0a 100644 (file)
@@ -38,6 +38,8 @@ import javax.swing.JOptionPane;
 import javax.swing.SwingWorker;
 import javax.swing.Timer;
 
+import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
+import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
 import org.scilab.modules.graph.ScilabGraph;
 import org.scilab.modules.graph.utils.ScilabGraphConstants;
 import org.scilab.modules.gui.bridge.filechooser.SwingScilabFileChooser;
@@ -52,6 +54,7 @@ import org.scilab.modules.xcos.Kind;
 import org.scilab.modules.xcos.ObjectProperties;
 import org.scilab.modules.xcos.VectorOfDouble;
 import org.scilab.modules.xcos.VectorOfInt;
+import org.scilab.modules.xcos.VectorOfString;
 import org.scilab.modules.xcos.Xcos;
 import org.scilab.modules.xcos.XcosTab;
 import org.scilab.modules.xcos.actions.SaveAsAction;
@@ -67,10 +70,12 @@ import org.scilab.modules.xcos.block.io.ImplicitInBlock;
 import org.scilab.modules.xcos.block.io.ImplicitOutBlock;
 import org.scilab.modules.xcos.configuration.ConfigurationManager;
 import org.scilab.modules.xcos.graph.model.BlockInterFunction;
+import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
 import org.scilab.modules.xcos.graph.model.XcosCell;
 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
 import org.scilab.modules.xcos.graph.swing.GraphComponent;
 import org.scilab.modules.xcos.io.XcosFileType;
+import org.scilab.modules.xcos.io.scicos.ScilabDirectHandler;
 import org.scilab.modules.xcos.link.BasicLink;
 import org.scilab.modules.xcos.link.commandcontrol.CommandControlLink;
 import org.scilab.modules.xcos.link.explicit.ExplicitLink;
@@ -87,6 +92,7 @@ import org.scilab.modules.xcos.port.output.ExplicitOutputPort;
 import org.scilab.modules.xcos.port.output.ImplicitOutputPort;
 import org.scilab.modules.xcos.preferences.XcosOptions;
 import org.scilab.modules.xcos.utils.BlockPositioning;
+import org.scilab.modules.xcos.utils.Stack;
 import org.scilab.modules.xcos.utils.XcosConstants;
 import org.scilab.modules.xcos.utils.XcosDialogs;
 import org.scilab.modules.xcos.utils.XcosMessages;
@@ -204,6 +210,38 @@ public class XcosDiagram extends ScilabGraph {
     }
 
     /**
+     * Fill the hierarchy from the first element up to the root diagram (included)
+     * <p>
+     * Should be used as :
+     * <pre>
+     *  hierarchy = fillHierarchy(new ScicosObjectOwner(getUID(), getKind()))
+     * </pre>
+     * @param hierarchy the collection to fill
+     * @return the filled collection (the root at the end)
+     */
+    public static Stack<ScicosObjectOwner> lookForHierarchy(ScicosObjectOwner current) {
+        ScicosObjectOwner local = current;
+        Stack<ScicosObjectOwner> hierarchy = new Stack<>();
+        JavaController controller = new JavaController();
+
+        long[] parent = new long[] {local.getUID()};
+        if (local.getKind() == Kind.DIAGRAM) {
+            hierarchy.push(local);
+            return hierarchy;
+        }
+
+        while (parent[0] != 0l) {
+            hierarchy.push(new ScicosObjectOwner(parent[0], Kind.BLOCK));
+            controller.getObjectProperty(local.getUID(), local.getKind(), ObjectProperties.PARENT_BLOCK, parent);
+        }
+
+        controller.getObjectProperty(local.getUID(), local.getKind(), ObjectProperties.PARENT_DIAGRAM, parent);
+        hierarchy.push(new ScicosObjectOwner(parent[0], Kind.DIAGRAM));
+
+        return hierarchy;
+    }
+
+    /**
      * Sort the blocks per first integer parameter value
      *
      * @param blocks
@@ -1751,6 +1789,7 @@ public class XcosDiagram extends ScilabGraph {
         }
         setTitle(name.substring(0, name.lastIndexOf('.')));
         setModified(false);
+        updateTabTitle();
 
         fireEvent(new mxEventObject(mxEvent.ROOT));
 
@@ -1902,6 +1941,10 @@ public class XcosDiagram extends ScilabGraph {
      * @return Root parent of the whole parent
      */
     public XcosDiagram getRootDiagram() {
+        if (getKind() == Kind.DIAGRAM) {
+            return this;
+        }
+
         JavaController controller = new JavaController();
         long[] parent = new long[1];
         controller.getObjectProperty(getUID(), getKind(), ObjectProperties.PARENT_DIAGRAM, parent);
@@ -1990,18 +2033,32 @@ public class XcosDiagram extends ScilabGraph {
     }
 
     /**
-     * Set the current diagram in a modified state
-     *
-     * @param modified
-     *            True or False whether the current diagram must be saved or not.
+     * Read the applicable context on this diagram.
+     * <p>
+     * This function retrieve the current diagram's context and all its parent
+     * @return the full context
      */
-    @Override
-    public void setModified(final boolean modified) {
-        super.setModified(modified);
-        // FIXME update the tab title on the caller
-        // updateTabTitle();
+    public String[] getContext() {
+        final ArrayList<String> allContext = new ArrayList<>();
+        final Stack<ScicosObjectOwner> hierarchy = lookForHierarchy(new ScicosObjectOwner(getUID(), getKind()));
+
+        final JavaController controller = new JavaController();
+        final VectorOfString context = new VectorOfString();
+
+        hierarchy.stream().forEach(o -> {
+            controller.getObjectProperty(o.getUID(), o.getKind(), ObjectProperties.DIAGRAM_CONTEXT, context);
+
+            final int length = context.size();
+            for (int i = 0; i < length; i++) {
+                allContext.add(context.get(i));
+            }
+            allContext.add("");
+        });
+
+        return allContext.toArray(new String[allContext.size()]);
     }
 
+
     /**
      * Evaluate the current context
      *
@@ -2009,27 +2066,26 @@ public class XcosDiagram extends ScilabGraph {
      */
     public Map<String, String> evaluateContext() {
         Map<String, String> result = Collections.emptyMap();
-        // FIXME: evaluate the context on scilab 6 ?
-        // final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
-        // if (handler == null) {
-        // return result;
-        // }
-        //
-        // try {
-        // // first write the context strings
-        // handler.writeContext(getContext());
-        //
-        // // evaluate using script2var
-        // ScilabInterpreterManagement.synchronousScilabExec(ScilabDirectHandler.CONTEXT + " = script2var(" + ScilabDirectHandler.CONTEXT + ", struct());");
-        //
-        // // read the structure
-        // result = handler.readContext();
-        // } catch (final InterpreterException e) {
-        // info("Unable to evaluate the contexte");
-        // e.printStackTrace();
-        // } finally {
-        // handler.release();
-        // }
+        final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
+        if (handler == null) {
+            return result;
+        }
+
+        try {
+            // first write the context strings
+            handler.writeContext(getContext());
+
+            // evaluate using script2var
+            ScilabInterpreterManagement.synchronousScilabExec(ScilabDirectHandler.CONTEXT + " = script2var(" + ScilabDirectHandler.CONTEXT + ", struct());");
+
+            // read the structure
+            result = handler.readContext();
+        } catch (final InterpreterException e) {
+            info("Unable to evaluate the contexte");
+            e.printStackTrace();
+        } finally {
+            handler.release();
+        }
 
         return result;
     }
index 61f0753..78704c9 100644 (file)
@@ -21,6 +21,7 @@ import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Optional;
+import java.util.logging.Logger;
 
 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
 import org.scilab.modules.graph.utils.ScilabExported;
@@ -57,6 +58,7 @@ public final class XcosCellFactory {
 
     /** Size compatibility for user defined blocks */
     private static final double DEFAULT_SIZE_FACTOR = 20.0;
+    private static final Logger LOG = Logger.getLogger(XcosCellFactory.class.getName());
 
     /** Default singleton constructor */
     private XcosCellFactory() {
@@ -72,13 +74,23 @@ public final class XcosCellFactory {
      *            the kind of the created object (as an int)
      */
     @ScilabExported(module = "xcos", filename = "XcosCellFactory.giws.xml")
-    public static void created(long uid, int kind) {
+    public static synchronized void created(long uid, int kind) {
         lastCreated = new ScicosObjectOwner(uid, Kind.values()[kind]);
 
     }
 
     private static ScicosObjectOwner lastCreated = null;
 
+    /**
+     * Retrieve and clear the last created object (<pre>xcosCellCreated</pre> call)
+     * @return the last created object
+     */
+    public static synchronized ScicosObjectOwner getLastCreated() {
+        ScicosObjectOwner last = lastCreated;
+        lastCreated = null;
+        return last;
+    }
+
     /*
      * Diagram management
      */
@@ -101,12 +113,12 @@ public final class XcosCellFactory {
         XcosDiagram diagram;
         try {
             synchronousScilabExec(
-                "function f(), " + buildCall("exec", filename, -1) + buildCall("xcosCellCreated", "scs_m".toCharArray()) + "endfunction; f();");
+                "function f(), " + buildCall("exec", filename, -1) + "; " + buildCall("xcosCellCreated", "scs_m".toCharArray()) + "endfunction; f();");
 
-            if (lastCreated.getKind() == Kind.DIAGRAM) {
-                diagram = new XcosDiagram(lastCreated.getUID(), lastCreated.getKind());
+            ScicosObjectOwner last = getLastCreated();
+            if (last.getKind() == Kind.DIAGRAM) {
+                diagram = new XcosDiagram(last.getUID(), last.getKind());
                 insertChildren(controller, diagram);
-                lastCreated = null;
             } else {
                 diagram = null;
             }
@@ -186,16 +198,14 @@ public final class XcosCellFactory {
             if (srcPort != null) {
                 l.setSource(srcPort);
             } else {
-                //               FIXME Commented for the alpha release
-                //                throw new IllegalStateException();
+                LOG.severe("Unable to connect link " + l.getId() + " : invalid source " + src[0]);
             }
 
-            BasicPort destPort = ports.get(dest[0]);;
+            BasicPort destPort = ports.get(dest[0]);
             if (destPort != null) {
                 l.setTarget(destPort);
             } else {
-                //               FIXME Commented for the alpha release
-                //                throw new IllegalStateException();
+                LOG.severe("Unable to connect link " + l.getId() + " : invalid target " + dest[0]);
             }
         }
 
@@ -247,23 +257,25 @@ public final class XcosCellFactory {
     private static BasicBlock createBlock(final JavaController controller, BlockInterFunction func, String interfaceFunction) {
         BasicBlock block;
         try {
+            ScicosObjectOwner last;
+
             if (BlockInterFunction.BASIC_BLOCK.name().equals(interfaceFunction)) {
                 // deliver all the MVC speed for the casual case
-                lastCreated = new ScicosObjectOwner(controller.createObject(Kind.BLOCK), Kind.BLOCK);
+                last = new ScicosObjectOwner(controller.createObject(Kind.BLOCK), Kind.BLOCK);
             } else {
                 // allocate an empty block that will be filled later
                 synchronousScilabExec("xcosCellCreated(" + interfaceFunction + "(\"define\")); ");
+                last = getLastCreated();
             }
 
             // defensive programming
-            if (lastCreated == null) {
+            if (last == null) {
                 System.err.println("XcosCellFactory#createBlock : unable to allocate " + interfaceFunction);
                 return null;
             }
 
-            if (EnumSet.of(Kind.BLOCK, Kind.ANNOTATION).contains(lastCreated.getKind())) {
-                block = createBlock(controller, func, interfaceFunction, lastCreated.getUID());
-                lastCreated = null;
+            if (EnumSet.of(Kind.BLOCK, Kind.ANNOTATION).contains(last.getKind())) {
+                block = createBlock(controller, func, interfaceFunction, last.getUID());
             } else {
                 block = null;
             }
@@ -377,6 +389,24 @@ public final class XcosCellFactory {
         return block;
     }
 
+    /**
+     * Instantiate a new block for an already created MVC object
+     *
+     * @param lastCreated the owned MVC object
+     * @return a block or null
+     */
+    public static BasicBlock createBlock(final JavaController controller, ScicosObjectOwner lastCreated) {
+        // pre-condition
+        if (lastCreated.getKind() != Kind.ANNOTATION && lastCreated.getKind() != Kind.BLOCK) {
+            return null;
+        }
+
+        String[] interfaceFunction = new String[1];
+        BlockInterFunction func = lookForInterfunction(interfaceFunction[0]);
+
+        return createBlock(controller, func, interfaceFunction[0], lastCreated.getUID());
+    }
+
     /*
      * Port management
      */
index f34b491..4e384ee 100644 (file)
@@ -13,6 +13,7 @@
 package org.scilab.modules.xcos.graph.swing.handler;
 
 import java.awt.datatransfer.DataFlavor;
+import java.awt.event.ActionEvent;
 import java.awt.event.MouseEvent;
 import java.util.ArrayList;
 import java.util.List;
@@ -21,8 +22,10 @@ import java.util.logging.Logger;
 import javax.swing.SwingUtilities;
 
 import org.scilab.modules.graph.ScilabGraph;
+import org.scilab.modules.graph.actions.base.GraphActionManager;
 import org.scilab.modules.xcos.block.BasicBlock;
 import org.scilab.modules.xcos.block.TextBlock;
+import org.scilab.modules.xcos.block.actions.BlockParametersAction;
 import org.scilab.modules.xcos.graph.model.BlockInterFunction;
 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
 import org.scilab.modules.xcos.graph.swing.GraphComponent;
@@ -32,6 +35,7 @@ import org.scilab.modules.xcos.utils.XcosMessages;
 
 import com.mxgraph.model.mxGeometry;
 import com.mxgraph.model.mxIGraphModel;
+import com.mxgraph.swing.mxGraphComponent;
 import com.mxgraph.swing.handler.mxGraphHandler;
 import com.mxgraph.swing.util.mxGraphTransferable;
 import com.mxgraph.util.mxPoint;
@@ -96,10 +100,10 @@ public class GraphHandler extends mxGraphHandler {
                 if (cell instanceof BasicLink) {
                     clickOnLink(e, (BasicLink) cell);
                 } else if (cell instanceof BasicBlock) {
-                    openBlock(e, (BasicBlock) cell);
+                    openBlock(graphComponent, e, (BasicBlock) cell);
                 } else if (cell instanceof BasicPort) {
                     // translated to the parent
-                    openBlock(e, (BasicBlock) ((BasicPort) cell).getParent());
+                    openBlock(graphComponent, e, (BasicBlock) ((BasicPort) cell).getParent());
                 } else if (cell == null) {
                     createTextBlock(e);
                 }
@@ -204,14 +208,15 @@ public class GraphHandler extends mxGraphHandler {
     /**
      * Open a block
      *
+     * @param comp the component
      * @param e
      *            the mouse event
      * @param cell
      *            the block
      */
-    private void openBlock(MouseEvent e, BasicBlock cell) {
-        // FIXME: play with the xcos view
-        //        cell.openBlockSettings(((XcosDiagram) graphComponent.getGraph()).getContext());
+    private void openBlock(mxGraphComponent comp, MouseEvent e, BasicBlock cell) {
+        BlockParametersAction action = GraphActionManager.getInstance((ScilabGraph) comp.getGraph(), BlockParametersAction.class);
+        action.actionPerformed();
 
         e.consume();
     }
index 07a1900..dca4c7c 100644 (file)
@@ -134,10 +134,13 @@ public enum XcosFileType {
 
             final XMLOutputFactory factory = ScilabXMLOutputFactory.newInstance();
             final XMLStreamWriter writer = factory.createXMLStreamWriter(result);
-
-            LOG.entering("XMLStreamWriter", "write");
-            new XcosWriter(null, writer).write(from.getUID(), from.getKind());
-            LOG.exiting("XMLStreamWriter", "write");
+            try {
+                LOG.entering("XMLStreamWriter", "write");
+                new XcosWriter(null, writer).write(from.getUID(), from.getKind());
+                LOG.exiting("XMLStreamWriter", "write");
+            } finally {
+                writer.close();
+            }
         }
     },
     /**
index ae5edf6..b80196f 100644 (file)
@@ -14,34 +14,9 @@ package org.scilab.modules.xcos.io.scicos;
 
 import java.util.Map;
 
-import org.scilab.modules.xcos.block.BasicBlock;
-import org.scilab.modules.xcos.graph.XcosDiagram;
-import org.scilab.modules.xcos.io.scicos.ScicosFormatException.VersionMismatchException;
-
 public interface Handler {
 
     /**
-     * Decode an Xcos block
-     *
-     * @return the decoded block
-     * @throws ScicosFormatException
-     *             on decoding error
-     */
-    public abstract BasicBlock readBlock() throws ScicosFormatException;
-
-    /**
-     * Decode an Xcos block into an instance
-     *
-     * @param into
-     *            the instance to update
-     * @return the updated instance.
-     * @throws ScicosFormatException
-     *             on decoding error
-     */
-    public abstract BasicBlock readBlock(BasicBlock into)
-    throws ScicosFormatException;
-
-    /**
      * Decode an evaluated Xcos context
      *
      * @return the decoded context
@@ -49,32 +24,6 @@ public interface Handler {
     public abstract Map<String, String> readContext();
 
     /**
-     * Decode an Xcos diagram from an H5 file
-     *
-     * @return the decoded diagram
-     * @throws VersionMismatchException
-     *             when the diagram version mismatch
-     */
-    public abstract XcosDiagram readDiagram() throws VersionMismatchException;
-
-    /**
-     * Decode an Xcos diagram from an H5 file in place.
-     *
-     * @param instance
-     *            the previously allocated diagram where to decode.
-     * @return the decoded diagram
-     */
-    public abstract XcosDiagram readDiagram(XcosDiagram instance);
-
-    /**
-     * Encode an Xcos block
-     *
-     * @param block
-     *            the block
-     */
-    public abstract void writeBlock(BasicBlock block);
-
-    /**
      * Encode an Xcos context
      *
      * @param context
@@ -82,12 +31,4 @@ public interface Handler {
      */
     public abstract void writeContext(String[] context);
 
-    /**
-     * Encode an Xcos diagram
-     *
-     * @param diagram
-     *            the block
-     */
-    public abstract void writeDiagram(XcosDiagram diagram);
-
 }
\ No newline at end of file
index 33360d5..d102076 100644 (file)
 
 package org.scilab.modules.xcos.io.scicos;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+import org.scilab.modules.javasci.JavasciException;
+import org.scilab.modules.javasci.Scilab;
+import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
+import org.scilab.modules.types.ScilabType;
+
 /**
  * Scilab data direct access.
  */
-public class ScilabDirectHandler {
+public class ScilabDirectHandler implements Handler {
     /**
      * Context Scilab variable name
      */
@@ -28,4 +40,124 @@ public class ScilabDirectHandler {
      * Block Scilab variable name
      */
     public static final String BLK = "blk";
+
+    private static final Logger LOG = Logger.getLogger(ScilabDirectHandler.class.getPackage().getName());
+    private static final ScilabDirectHandler INSTANCE = new ScilabDirectHandler();
+
+    private final Semaphore lock = new Semaphore(1, true);
+
+    private ScilabDirectHandler() {
+    }
+
+    /*
+     * Lock management to avoid multiple actions
+     */
+
+    /**
+     * Get the current instance of a ScilabDirectHandler.
+     *
+     * Please note that after calling {@link #acquire()} and performing action,
+     * you should release the instance using {@link #release()}.
+     *
+     * <p>
+     * It is recommended practice to <em>always</em> immediately follow a call
+     * to {@code getInstance()} with a {@code try} block, most typically in a
+     * before/after construction such as:
+     *
+     * <pre>
+     * class X {
+     *
+     *     // ...
+     *
+     *     public void m() {
+     *         final ScilabDirectHandler handler = ScilabDirectHandler.getInstance();
+     *         try {
+     *             // ... method body
+     *         } finally {
+     *             handler.release();
+     *         }
+     *     }
+     * }
+     * </pre>
+     *
+     * @see #release()
+     * @return the instance or null if another operation is in progress
+     */
+    public static ScilabDirectHandler acquire() {
+        LOG.finest("lock request");
+
+        try {
+            final boolean status = INSTANCE.lock.tryAcquire(0, TimeUnit.SECONDS);
+            if (!status) {
+                return null;
+            }
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        LOG.finest("lock acquired");
+
+        return INSTANCE;
+    }
+
+    /**
+     * Release the instance
+     */
+    public void release() {
+        LOG.finest("lock release");
+
+        INSTANCE.lock.release();
+    }
+
+    /*
+     * Handler implementation
+     */
+
+    @Override
+    public synchronized Map<String, String> readContext() {
+        LOG.entering("ScilabDirectHandler", "readContext");
+        final ScilabMList list;
+        final Map<String, String> result = new LinkedHashMap<String, String>();
+
+        final ScilabType data;
+        try {
+            data = Scilab.getInCurrentScilabSession(CONTEXT);
+        } catch (JavasciException e) {
+            throw new RuntimeException(e);
+        }
+        if (data instanceof ScilabMList) {
+            list = (ScilabMList) data;
+            LOG.finer("data available");
+        } else {
+            list = new ScilabMList();
+            LOG.finer("data unavailable");
+        }
+
+        // We are starting at 2 because a struct is composed of
+        // - the fields names (ScilabString)
+        // - the dimension
+        // - variables values...
+        for (int index = 2; index < list.size(); index++) {
+            String key = ((ScilabString) list.get(0)).getData()[0][index];
+            String value = list.get(index).toString();
+
+            result.put(key, value);
+        }
+
+        LOG.exiting("ScilabDirectHandler", "readContext");
+        return result;
+    }
+
+    @Override
+    public void writeContext(final String[] context) {
+        LOG.entering("ScilabDirectHandler", "writeContext");
+
+        try {
+            Scilab.putInCurrentScilabSession(CONTEXT, new ScilabString(context));
+        } catch (JavasciException e) {
+            throw new RuntimeException(e);
+        }
+
+        LOG.exiting("ScilabDirectHandler", "writeContext");
+    }
 }
index 67a5ba0..74fbbfc 100644 (file)
@@ -99,6 +99,7 @@ public class ContentEntry implements Entry {
 
             LOG.entering("XMLStreamWriter", "write");
             new XcosWriter(pack.getDictionary(), writer).write(content.getUID(), content.getKind());
+            writer.close();
             LOG.exiting("XMLStreamWriter", "write");
 
             /*
@@ -110,6 +111,8 @@ public class ContentEntry implements Entry {
             pack.getManifest().getFirstChild().appendChild(e);
         } catch (XMLStreamException e) {
             Logger.getLogger(ContentEntry.class.getName()).severe(e.getMessage());
+        } finally {
+            stream.closeEntry();
         }
     }
 }
\ No newline at end of file
index 29cbaf3..6a5b8b6 100644 (file)
@@ -47,8 +47,11 @@ public class Stack<E> {
         return stack.size();
     }
 
+    /**
+     * Stream in a reversed order (traditional stack usage)
+     * @return a stream object
+     */
     public Stream<E> stream() {
-        // stream in a reversed order (traditional stack usage)
         return IntStream.range(0, stack.size()).mapToObj(i -> stack.get(stack.size() - 1 - i));
     }