Xcos: fix recent diagrams management 40/18940/3
Clément DAVID [Tue, 24 Jan 2017 13:54:30 +0000 (14:54 +0100)]
Change-Id: Idd2f76ad1d608fc3f48a2cb087eb37c60935f077

scilab/modules/graph/src/java/org/scilab/modules/graph/ScilabGraph.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/Xcos.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/XcosTab.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/actions/ExportAllAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/actions/RegionToSuperblockAction.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/configuration/ConfigurationManager.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/ScicosObjectOwner.java

index 67660b3..2690921 100644 (file)
@@ -300,25 +300,6 @@ public class ScilabGraph extends mxGraph {
     }
 
     /**
-     * The instance can be not visible but used (when using SuperBlock). The
-     * openned flag is true in this case and also when the Window/Tab is
-     * visible.
-     *
-     * @param opened
-     *            Openned state
-     */
-    public void setOpened(boolean opened) {
-        this.opened = opened;
-    }
-
-    /**
-     * @return Openned state
-     */
-    public boolean isOpened() {
-        return opened;
-    }
-
-    /**
      * A read-only state will disable all actions in the graph.
      *
      * @param readOnly
index 885bec0..a017e9c 100644 (file)
@@ -2,7 +2,7 @@
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
  * Copyright (C) 2010 - DIGITEO - Clement DAVID
- * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
+ * Copyright (C) 2011-2017 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -74,6 +74,7 @@ import com.mxgraph.model.mxICell;
 import com.mxgraph.util.mxEvent;
 import com.mxgraph.util.mxEventObject;
 import com.mxgraph.view.mxStylesheet;
+import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
 
 /**
  * Xcos entry point class
@@ -123,7 +124,7 @@ public final class Xcos {
     /*
      * Instance data
      */
-    private final Map<Long, List<XcosDiagram>> diagrams;
+    private final Map<ScicosObjectOwner, List<XcosDiagram>> diagrams;
     private XcosView view;
     private BrowserView browser;
     private boolean onDiagramIteration = false;
@@ -306,10 +307,10 @@ public final class Xcos {
      * @return the opened diagrams list
      */
     public List<XcosDiagram> openedDiagrams() {
-        final List<XcosDiagram> opened = new ArrayList<XcosDiagram>();
-        for (Long l : diagrams.keySet()) {
-            opened.addAll(openedDiagrams(l));
-        }
+        final List<XcosDiagram> opened = new ArrayList<>();
+        diagrams.entrySet().forEach((e) -> {
+            opened.addAll(e.getValue());
+        });
 
         return opened;
     }
@@ -317,32 +318,25 @@ public final class Xcos {
     /**
      * Opened diagrams
      *
-     * @param l
-     *            the root diagram uid
+     * @param root
+     *            the root diagram
      * @return the opened diagrams list
      */
-    public List<XcosDiagram> openedDiagrams(Long l) {
-        final List<XcosDiagram> opened = new ArrayList<>();
-        for (XcosDiagram d : diagrams.get(l)) {
-            if (d.isOpened()) {
-                opened.add(d);
-            }
-        }
-
-        return opened;
+    public List<XcosDiagram> openedDiagrams(ScicosObjectOwner root) {
+        return diagrams.get(root);
     }
 
-    public Long openedDiagramUID(File f) {
-        Long opened = 0l;
+    public long openedDiagramUID(File f) {
+        long opened = 0l;
         if (f == null) {
             return opened;
         }
 
-        for (Long diagUID : diagrams.keySet()) {
-            List<XcosDiagram> diags = diagrams.getOrDefault(diagUID, Collections.emptyList());
+        for (ScicosObjectOwner root : diagrams.keySet()) {
+            List<XcosDiagram> diags = diagrams.getOrDefault(root, Collections.emptyList());
 
             if (!diags.isEmpty() && f.equals(diags.get(0).getSavedFile())) {
-                opened = diagUID;
+                opened = root.getUID();
                 break;
             }
         }
@@ -353,12 +347,12 @@ public final class Xcos {
     /**
      * Check if the in memory file representation is modified
      *
-     * @param l
-     *            the root diagram UID
+     * @param root
+     *            the root diagram
      * @return is modified
      */
-    public boolean isModified(Long l) {
-        for (XcosDiagram d : diagrams.get(l)) {
+    public boolean isModified(ScicosObjectOwner root) {
+        for (XcosDiagram d : diagrams.get(root)) {
             if (d.isModified()) {
                 return true;
             }
@@ -445,24 +439,21 @@ public final class Xcos {
             diag = null;
         }
 
-       // looking for an empty, unsaved diagram to use if opening a new file
+        // looking for an empty, unsaved diagram to use if opening a new file
         // if not found an already open instance of the file
-        if(diag == null)
-        {
-       // traverse through the key set of all the opened diagrams
-        for(long key : diagrams.keySet())
-       {
-       List<XcosDiagram> diagramsWithKey = diagrams.get(key);
-       XcosDiagram diagramWithKey = diagramsWithKey.get(0); // get the diagram that maps to that key
-       int childCount = diagramWithKey.countChildren(); //count the number of children in the diagram
-       // if empty, unsaved and unused
-               if(childCount == 0 && diagramWithKey.getSavedFile() == null && !diagramWithKey.isModified())
-               {
-               // use that open diagram
-               diag = diagramWithKey;
-               diag.transformAndLoadFile(controller, file);
-               }
-        }
+        if (diag == null) {
+            // traverse through the key set of all the opened diagrams
+            for (Map.Entry<ScicosObjectOwner, List<XcosDiagram>> entry : diagrams.entrySet()) {
+                List<XcosDiagram> diagramsWithKey = entry.getValue();
+                XcosDiagram diagramWithKey = diagramsWithKey.get(0); // get the diagram that maps to that key
+                int childCount = diagramWithKey.countChildren(); //count the number of children in the diagram
+                // if empty, unsaved and unused
+                if (childCount == 0 && diagramWithKey.getSavedFile() == null && !diagramWithKey.isModified()) {
+                    // use that open diagram
+                    diag = diagramWithKey;
+                    diag.transformAndLoadFile(controller, file);
+                }
+            }
         }
         // if reuse then request focus
         if (diag != null) {
@@ -524,7 +515,7 @@ public final class Xcos {
              */
             diag.transformAndLoadFile(controller, file);
 
-            addDiagram(diag.getUID(), diag);
+            addDiagram(new ScicosObjectOwner(controller, diag.getUID(), Kind.DIAGRAM), diag);
         }
     }
 
@@ -569,12 +560,12 @@ public final class Xcos {
     /**
      * Get an unmodifiable view of the diagrams for an UID
      *
-     * @param l
-     *            the root diagram UID
+     * @param root
+     *            the root diagram
      * @return the diagram collection
      */
-    public Collection<XcosDiagram> getDiagrams(final long l) {
-        final Collection<XcosDiagram> diags = diagrams.get(l);
+    public Collection<XcosDiagram> getDiagrams(final ScicosObjectOwner root) {
+        final Collection<XcosDiagram> diags = diagrams.get(root);
         if (diags == null) {
             return null;
         }
@@ -584,26 +575,26 @@ public final class Xcos {
     /**
      * Add a diagram to the diagram list for a file. Be sure to set the right opened status on the diagram before calling this method.
      *
-     * @param l
-     *            the root diagram UID
+     * @param root
+     *            the root diagram
      * @param diag
      *            the diag
      */
-    public void addDiagram(final long l, final XcosDiagram diag) {
+    public void addDiagram(final ScicosObjectOwner root, final XcosDiagram diag) {
         if (onDiagramIteration) {
             throw new RuntimeException();
         }
-        if (l == 0l) {
+        if (root == null) {
             throw new IllegalArgumentException();
         }
 
         /*
          * Create the collection if it does not exist
          */
-        List<XcosDiagram> diags = diagrams.get(l);
+        List<XcosDiagram> diags = diagrams.get(root);
         if (diags == null) {
             diags = createDiagramCollection();
-            diagrams.put(l, diags);
+            diagrams.put(root, diags);
         }
 
         // insert the diagram
@@ -617,19 +608,10 @@ public final class Xcos {
      * @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);
-        }
-
+        ScicosObjectOwner root = findRoot(diag);
+        addDiagram(root, diag);
     }
 
-
-
     /**
      * Create a diagram collections (sorted List)
      *
@@ -664,15 +646,10 @@ public final class Xcos {
     public boolean canClose(final XcosDiagram graph) {
         boolean canClose = false;
 
-        JavaController controller = new JavaController();
-        long[] rootDiagram = new long[1];
-        controller.getObjectProperty(graph.getUID(), graph.getKind(), ObjectProperties.PARENT_DIAGRAM, rootDiagram);
-        if (rootDiagram[0] == 0l) {
-            rootDiagram[0] = graph.getUID();
-        }
+        ScicosObjectOwner root = findRoot(graph);
 
-        final boolean wasLastOpened = openedDiagrams(rootDiagram[0]).size() <= 1;
-        final boolean isModified = isModified(rootDiagram[0]);
+        final boolean wasLastOpened = openedDiagrams(root).size() <= 1;
+        final boolean isModified = isModified(root);
         if (!(wasLastOpened && isModified)) {
             canClose = true;
         }
@@ -683,7 +660,7 @@ public final class Xcos {
 
             switch (ans) {
                 case YES_OPTION:
-                    canClose = diagrams.get(rootDiagram[0]).iterator().next().saveDiagram();
+                    canClose = diagrams.get(root).iterator().next().saveDiagram();
                     break;
                 case NO_OPTION:
                     canClose = true; // can close
@@ -713,18 +690,13 @@ public final class Xcos {
      *            the diagram to close
      */
     public void destroy(XcosDiagram graph) {
-        JavaController controller = new JavaController();
-        long[] rootDiagram = new long[1];
-        controller.getObjectProperty(graph.getUID(), graph.getKind(), ObjectProperties.PARENT_DIAGRAM, rootDiagram);
-        if (rootDiagram[0] == 0l) {
-            rootDiagram[0] = graph.getUID();
-        }
+        ScicosObjectOwner root = findRoot(graph);
 
-        final boolean wasLastOpenedForFile = openedDiagrams(rootDiagram[0]).size() <= 1;
+        final boolean wasLastOpenedForFile = openedDiagrams(root).size() <= 1;
         if (wasLastOpenedForFile) {
-            diagrams.remove(rootDiagram[0]);
+            diagrams.remove(root);
         } else {
-            diagrams.get(rootDiagram[0]).remove(graph);
+            diagrams.get(root).remove(graph);
         }
 
         if (openedDiagrams().size() <= 0) {
@@ -820,7 +792,7 @@ public final class Xcos {
         // clear states
         if (status) {
             /* reset the shared instance state */
-            instance.diagrams.keySet().clear();
+            instance.diagrams.clear();
 
             /* terminate any remaining simulation */
             JavaController.end_simulation();
@@ -1103,6 +1075,35 @@ public final class Xcos {
         return null;
     }
 
+    /**
+     * Look for the root object of the whole graph hierarchy
+     * @param graph the graph
+     * @return the root MVC object with Kind.DIAGRAM
+     */
+    public static ScicosObjectOwner findRoot(XcosDiagram graph) {
+        return findRoot(new JavaController(), graph);
+    }
+
+    /**
+     * Look for the root object of the whole graph hierarchy
+     * @param  controller the shared controller
+     * @param graph the graph
+     * @return the root MVC object with Kind.DIAGRAM
+     */
+    public static ScicosObjectOwner findRoot(JavaController controller, XcosDiagram graph) {
+        ScicosObjectOwner root;
+        if (graph.getKind() == Kind.DIAGRAM) {
+            root = new ScicosObjectOwner(controller, graph.getUID(), graph.getKind());
+        } else {
+            long[] rootDiagram = new long[1];
+            controller.getObjectProperty(graph.getUID(), graph.getKind(), ObjectProperties.PARENT_DIAGRAM, rootDiagram);
+            root = new ScicosObjectOwner(controller, rootDiagram[0], Kind.DIAGRAM);
+        }
+
+        return root;
+
+    }
+
     /*
      * @see org.scilab.modules.gui.tabfactory.AbstractScilabTabFactory
      */
index a22ef7d..31c6bea 100644 (file)
@@ -194,7 +194,6 @@ public class XcosTab extends SwingScilabDockablePanel implements SimpleTab {
             }
 
             Xcos.getInstance().destroy(diag);
-            diag.setOpened(false);
         }
 
         @Override
@@ -330,7 +329,6 @@ public class XcosTab extends SwingScilabDockablePanel implements SimpleTab {
         final XcosTab tab = new XcosTab(graph, uuid);
         ScilabTabFactory.getInstance().addToCache(tab);
 
-        graph.setOpened(true);
         if (visible) {
             tab.createDefaultWindow().setVisible(true);
 
index 45558de..f967bb3 100644 (file)
@@ -115,7 +115,7 @@ public final class ExportAllAction extends DefaultAction {
         Collection<String> imageFormats = Arrays.asList(ImageIO.getWriterFileSuffixes());
 
         // The mask ordered collection
-        Set<String> mask = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+        Set<String> mask = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
 
         mask.add(SVG);
         mask.add(HTML);
@@ -156,9 +156,6 @@ public final class ExportAllAction extends DefaultAction {
             ArrayList<XcosDiagram> diagrams = new ArrayList<>();
             diagrams.add(graph);
 
-            // append the already allocated diagram
-            diagrams.addAll(Xcos.getInstance().getDiagrams(graph.getUID()));
-
             ArrayList<Long> stash = new ArrayList<>();
             allocateDiagrams(controller, diagrams, stash, graph.getUID(), Kind.DIAGRAM);
             while (!stash.isEmpty()) {
index d9a818a..9b28084 100644 (file)
@@ -734,7 +734,7 @@ public class RegionToSuperblockAction extends VertexSelectionDependantAction {
         if (parentGraph.getKind() == Kind.DIAGRAM) {
             parentDiagram = parentGraph.getUID();
         } else {
-            parentDiagram = parentGraph.getRootDiagram().getUID();
+            parentDiagram = parentGraph.getRootDiagramUID(controller);
         }
 
         cellsToCopy.stream().forEach(c -> {
index bec3e29..0f64a8d 100644 (file)
@@ -57,6 +57,7 @@ import org.scilab.modules.xcos.configuration.model.ObjectFactory;
 import org.scilab.modules.xcos.configuration.model.SettingType;
 import org.scilab.modules.xcos.configuration.utils.ConfigurationConstants;
 import org.scilab.modules.xcos.graph.XcosDiagram;
+import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
 import org.scilab.modules.xcos.io.XcosFileType;
 import org.scilab.modules.xcos.preferences.XcosOptions;
 import org.scilab.modules.xcos.utils.FileUtils;
@@ -415,7 +416,7 @@ public final class ConfigurationManager {
                 filetype.load(filename, graph);
                 graph.postLoad(f);
             }
-            Xcos.getInstance().addDiagram(graph.getUID(), graph);
+            Xcos.getInstance().addDiagram(new ScicosObjectOwner(graph.getUID(), Kind.DIAGRAM), graph);
 
             graph = loadPath(doc, graph);
 
index 110be57..7fc1317 100644 (file)
@@ -2,7 +2,7 @@
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2009-2009 - DIGITEO - Bruno JOFRET
  * Copyright (C) 2009-2010 - DIGITEO - Clement DAVID
- * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
+ * Copyright (C) 2011-2017 - Scilab Enterprises - Clement DAVID
  * Copyright (C) 2015 - Marcos Cardinot
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
@@ -115,6 +115,7 @@ import com.mxgraph.view.mxMultiplicity;
 import java.lang.reflect.Constructor;
 import java.rmi.server.UID;
 import java.util.Hashtable;
+import java.util.Optional;
 import org.scilab.modules.xcos.io.ScilabTypeCoder;
 
 /**
@@ -124,7 +125,6 @@ public class XcosDiagram extends ScilabGraph {
 
     private static final Logger LOG = Logger.getLogger(XcosDiagram.class.getName());
 
-    private static final String MODIFIED = "modified";
     private static final String CELLS = "cells";
     public static final String IN = "in";
     public static final String OUT = "out";
@@ -1923,14 +1923,41 @@ public class XcosDiagram extends ScilabGraph {
         }
 
         JavaController controller = new JavaController();
-        long[] parent = new long[1];
-        controller.getObjectProperty(getUID(), getKind(), ObjectProperties.PARENT_DIAGRAM, parent);
 
-        Collection<XcosDiagram> diagrams = Xcos.getInstance().getDiagrams(parent[0]);
-        return diagrams.stream().filter(d -> d.getUID() == parent[0]).findFirst().get();
+        ScicosObjectOwner root = Xcos.findRoot(controller, this);
+        Collection<XcosDiagram> diagrams = Xcos.getInstance().getDiagrams(root);
+        Optional<XcosDiagram> found = diagrams.stream().filter(d -> d.getUID() == root.getUID()).findFirst();
+        if (found.isPresent()) {
+            return found.get();
+        } else {
+            // create a temporary hidden root diagram
+            String[] uid = {""};
+            controller.getObjectProperty(root.getUID(), Kind.DIAGRAM, ObjectProperties.UID, uid);
+            return new XcosDiagram(controller, root.getUID(), Kind.DIAGRAM, uid[0]);
+        }
+
+
     }
 
     /**
+     * Getting the root diagram UID of a decomposed diagram
+     *
+     * @param controller the current JavaController
+     * @return Root parent of the whole parent
+     */
+    public long getRootDiagramUID(JavaController controller) {
+        if (getKind() == Kind.DIAGRAM) {
+            return getUID();
+        }
+
+        long[] uid = new long[1];
+        controller.getObjectProperty(getUID(), getKind(), ObjectProperties.PARENT_DIAGRAM, uid);
+
+        return uid[0];
+    }
+
+
+    /**
      * Returns the tooltip to be used for the given cell.
      *
      * @param cell block
index 350329b..6a23292 100644 (file)
@@ -55,9 +55,35 @@ public class ScicosObjectOwner {
     }
 
     @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 67 * hash + (int) (this.uid ^ (this.uid >>> 32));
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ScicosObjectOwner other = (ScicosObjectOwner) obj;
+        if (this.uid != other.uid) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
     protected void finalize() throws Throwable {
         JavaController controller = new JavaController();
 
         controller.deleteObject(uid);
     }
+
 }
\ No newline at end of file