* Bug #7350 fixed - The superblock I/O ports numbering was not updated 55/10855/8
Alexandre HERISSE [Fri, 15 Mar 2013 14:13:20 +0000 (15:13 +0100)]
when a new port was dropped.

Change-Id: I714c43f69ac13a92530ef091d552677a9478675a

scilab/CHANGES_5.5.X
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/SuperBlockDiagram.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java

index 4284aa7..d760ead 100644 (file)
@@ -55,6 +55,9 @@ Xcos
 
 * Update Sundials to lastest "2.5.0", keeping our modifications
 
+* Bug #7350 fixed - The superblock I/O ports numbering was not updated
+                    when a new port was dropped.
+
 * Bug #12359 fixed - Xcos files has been converted to zcos to gain some space.
 
 * Bug #12384 fixed - Using a modelica part linked with explicit link to
index 4ffb471..3a56e77 100644 (file)
@@ -15,9 +15,6 @@ package org.scilab.modules.xcos.graph;
 
 import java.io.File;
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.logging.Logger;
@@ -48,11 +45,6 @@ public final class SuperBlockDiagram extends XcosDiagram implements Serializable
     private static final String PARENT_DIAGRAM_WAS_NULL = "Parent diagram was null";
     private static final long serialVersionUID = -402918614723713301L;
 
-    private static final String IN = "in";
-    private static final String OUT = "out";
-    private static final String EIN = "ein";
-    private static final String EOUT = "eout";
-
     private SuperBlock container;
 
     /**
@@ -218,98 +210,6 @@ public final class SuperBlockDiagram extends XcosDiagram implements Serializable
     }
 
     /**
-     * Fill the context with I/O port
-     *
-     * @param context
-     *            the context to fill
-     */
-    @SuppressWarnings("unchecked")
-    private void fillContext(final Hashtable<Object, Object> context) {
-        if (!context.containsKey(IN)) {
-            context.put(IN, iparSort(getAllTypedBlock(new Class[] { ExplicitInBlock.class, ImplicitInBlock.class })));
-        }
-        if (!context.containsKey(OUT)) {
-            context.put(OUT, iparSort(getAllTypedBlock(new Class[] { ExplicitOutBlock.class, ImplicitOutBlock.class })));
-        }
-        if (!context.containsKey(EIN)) {
-            context.put(EIN, iparSort(getAllTypedBlock(EventInBlock.class)));
-        }
-        if (!context.containsKey(EOUT)) {
-            context.put(EOUT, iparSort(getAllTypedBlock(EventOutBlock.class)));
-        }
-    }
-
-    /**
-     * Sort the blocks per first integer parameter value
-     *
-     * @param blocks
-     *            the block list
-     * @return the sorted block list (same instance)
-     */
-    private List <? extends BasicBlock > iparSort(final List <? extends BasicBlock > blocks) {
-        Collections.sort(blocks, new Comparator<BasicBlock>() {
-
-            @Override
-            public int compare(BasicBlock o1, BasicBlock o2) {
-                final ScilabDouble data1 = (ScilabDouble) o1.getIntegerParameters();
-                final ScilabDouble data2 = (ScilabDouble) o2.getIntegerParameters();
-
-                int value1 = 0;
-                int value2 = 0;
-
-                if (data1.getWidth() >= 1 && data1.getHeight() >= 1) {
-                    value1 = (int) data1.getRealPart()[0][0];
-                }
-                if (data2.getWidth() >= 1 && data2.getHeight() >= 1) {
-                    value2 = (int) data2.getRealPart()[0][0];
-                }
-
-                return value1 - value2;
-            }
-        });
-        return blocks;
-    }
-
-    /**
-     * @param <T>
-     *            The type to work on
-     * @param klass
-     *            the class instance to work on
-     * @return list of typed block
-     */
-    @SuppressWarnings("unchecked")
-    private <T extends BasicBlock> List<T> getAllTypedBlock(Class<T> klass) {
-        final List<T> list = new ArrayList<T>();
-
-        int blockCount = getModel().getChildCount(getDefaultParent());
-
-        for (int i = 0; i < blockCount; i++) {
-            Object cell = getModel().getChildAt(getDefaultParent(), i);
-            if (klass.isInstance(cell)) {
-                // According to the test we are sure that the cell is an
-                // instance of T. Thus we can safely cast it.
-                list.add((T) cell);
-            }
-        }
-        return list;
-    }
-
-    /**
-     * @param <T>
-     *            The type to work on
-     * @param klasses
-     *            the class instance list to work on
-     * @return list of typed block
-     */
-    private <T extends BasicBlock> List<T> getAllTypedBlock(Class<T>[] klasses) {
-        final List<T> list = new ArrayList<T>();
-        for (Class<T> klass : klasses) {
-            list.addAll(getAllTypedBlock(klass));
-        }
-        return list;
-    }
-
-    /**
      * Listener for SuperBlock diagram events.
      */
     @SuppressWarnings(value = { "serial" })
index 6427217..282ce7c 100644 (file)
@@ -26,7 +26,9 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.IllegalFormatException;
 import java.util.LinkedList;
 import java.util.List;
@@ -51,7 +53,9 @@ import org.scilab.modules.gui.messagebox.ScilabModalDialog.AnswerOption;
 import org.scilab.modules.gui.messagebox.ScilabModalDialog.ButtonType;
 import org.scilab.modules.gui.messagebox.ScilabModalDialog.IconType;
 import org.scilab.modules.gui.tabfactory.ScilabTabFactory;
+import org.scilab.modules.types.ScilabDouble;
 import org.scilab.modules.types.ScilabMList;
+import org.scilab.modules.types.ScilabString;
 import org.scilab.modules.xcos.Xcos;
 import org.scilab.modules.xcos.XcosTab;
 import org.scilab.modules.xcos.actions.SaveAsAction;
@@ -63,6 +67,12 @@ import org.scilab.modules.xcos.block.SplitBlock;
 import org.scilab.modules.xcos.block.SuperBlock;
 import org.scilab.modules.xcos.block.TextBlock;
 import org.scilab.modules.xcos.block.io.ContextUpdate;
+import org.scilab.modules.xcos.block.io.EventInBlock;
+import org.scilab.modules.xcos.block.io.EventOutBlock;
+import org.scilab.modules.xcos.block.io.ExplicitInBlock;
+import org.scilab.modules.xcos.block.io.ExplicitOutBlock;
+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.swing.GraphComponent;
 import org.scilab.modules.xcos.io.XcosFileType;
@@ -114,6 +124,10 @@ public class XcosDiagram extends ScilabGraph {
 
     private static final String MODIFIED = "modified";
     private static final String CELLS = "cells";
+    protected static final String IN = "in";
+    protected static final String OUT = "out";
+    protected static final String EIN = "ein";
+    protected static final String EOUT = "eout";
 
     /**
      * Prefix used to tag text node.
@@ -224,6 +238,161 @@ public class XcosDiagram extends ScilabGraph {
         });
     }
 
+    /**
+     * Sort the blocks per first integer parameter value
+     *
+     * @param blocks
+     *            the block list
+     * @return the sorted block list (same instance)
+     */
+    private List <? extends BasicBlock > iparSort(final List <? extends BasicBlock > blocks) {
+        Collections.sort(blocks, new Comparator<BasicBlock>() {
+            @Override
+            public int compare(BasicBlock o1, BasicBlock o2) {
+                final ScilabDouble data1 = (ScilabDouble) o1.getIntegerParameters();
+                final ScilabDouble data2 = (ScilabDouble) o2.getIntegerParameters();
+
+                int value1 = 0;
+                int value2 = 0;
+
+                if (data1.getWidth() >= 1 && data1.getHeight() >= 1) {
+                    value1 = (int) data1.getRealPart()[0][0];
+                }
+                if (data2.getWidth() >= 1 && data2.getHeight() >= 1) {
+                    value2 = (int) data2.getRealPart()[0][0];
+                }
+
+                return value1 - value2;
+            }
+        });
+        return blocks;
+    }
+
+    /**
+     * @param <T>
+     *            The type to work on
+     * @param klass
+     *            the class instance to work on
+     * @return list of typed block
+     */
+    @SuppressWarnings("unchecked")
+    private <T extends BasicBlock> List<T> getAllTypedBlock(Class<T> klass) {
+        final List<T> list = new ArrayList<T>();
+
+        int blockCount = getModel().getChildCount(getDefaultParent());
+
+        for (int i = 0; i < blockCount; i++) {
+            Object cell = getModel().getChildAt(getDefaultParent(), i);
+            if (klass.isInstance(cell)) {
+                // According to the test we are sure that the cell is an
+                // instance of T. Thus we can safely cast it.
+                list.add((T) cell);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @param <T>
+     * @param <T>
+     *            The type to work on
+     * @param klasses
+     *            the class instance list to work on
+     * @return list of typed block
+     */
+    private <T extends BasicBlock> List<T> getAllTypedBlock(Class<T>[] klasses) {
+        final List<T> list = new ArrayList<T>();
+        for (Class<T> klass : klasses) {
+            list.addAll(getAllTypedBlock(klass));
+        }
+        return list;
+    }
+
+    /**
+     * Fill the context with I/O port
+     *
+     * @param context
+     *            the context to fill
+     */
+    @SuppressWarnings("unchecked")
+    protected void fillContext(final Hashtable<Object, Object> context) {
+        if (!context.containsKey(IN)) {
+            context.put(IN, iparSort(getAllTypedBlock( new Class [] { ExplicitInBlock.class, ImplicitInBlock.class })));
+        }
+        if (!context.containsKey(OUT)) {
+            context.put(OUT, iparSort(getAllTypedBlock(new Class[] { ExplicitOutBlock.class, ImplicitOutBlock.class })));
+        }
+        if (!context.containsKey(EIN)) {
+            context.put(EIN, iparSort(getAllTypedBlock(new Class[] { EventInBlock.class })));
+        }
+        if (!context.containsKey(EOUT)) {
+            context.put(EOUT, iparSort(getAllTypedBlock(new Class[] { EventOutBlock.class })));
+        }
+    }
+
+    /**
+     * Function to update IO block numbering
+     * @param block
+     * @param ioBlockClass
+     */
+    @SuppressWarnings("unchecked")
+    private void updateIOBlockByType(BasicBlock block, Hashtable<Object, Object> context, String type) {
+        List <ContextUpdate> listOfBlocks = (List <ContextUpdate>) context.get(type);
+        if (listOfBlocks.contains(block)) {
+            int newIndex = 0;
+
+            /*  Get an empty index :
+             *  The list should always have a size greater of equal to one
+             *  since new element with numbering "1" is always added to the list
+             */
+            if (listOfBlocks.size() > 1) {
+                /*
+                 * The new element is the first element of the list
+                 */
+                int index_first = (int) ((ScilabDouble) listOfBlocks.get(1).getIntegerParameters()).getRealPart()[0][0];
+                if (index_first > 1) {
+                    newIndex = 1;
+                } else {
+                    for (int i = 0; i < listOfBlocks.size() - 1; i++) {
+                        int index_next = (int) ((ScilabDouble) listOfBlocks.get(i + 1).getIntegerParameters()).getRealPart()[0][0];
+                        int index_previous = (int) ((ScilabDouble) listOfBlocks.get(i).getIntegerParameters()).getRealPart()[0][0];
+                        if (index_next - index_previous > 1) {
+                            newIndex = i + 1;
+                            break;
+                        }
+                    }
+                    if (newIndex == 0) {
+                        newIndex = (int) ((ScilabDouble) listOfBlocks.get(listOfBlocks.size() - 1).getIntegerParameters()).getRealPart()[0][0] + 1;
+                    }
+                }
+            } else {
+                newIndex = 1;
+            }
+
+            /*
+             * Update the IO block with this new index
+             */
+            block.setIntegerParameters(new ScilabDouble(newIndex));
+            block.setExprs(new ScilabString(Integer.toString(newIndex)));
+            block.setOrdering(newIndex);
+        }
+    }
+
+    /**
+     * If the block is a IO block, update its index to a free index
+     * @param block
+     */
+    private void updateIOBlocks(BasicBlock block) {
+        Hashtable<Object, Object> context = new Hashtable<Object, Object> ();
+
+        fillContext(context);
+
+        updateIOBlockByType(block, context, IN);
+        updateIOBlockByType(block, context, OUT);
+        updateIOBlockByType(block, context, EIN);
+        updateIOBlockByType(block, context, EOUT);
+    }
+
     /*
      * Static diagram listeners
      */
@@ -274,6 +443,9 @@ public class XcosDiagram extends ScilabGraph {
                         if (cell instanceof BasicBlock) {
                             // Update parent on cell addition
                             ((BasicBlock) cell).setParentDiagram(diagram);
+
+                            // update port numbering
+                            diagram.updateIOBlocks((BasicBlock) cell);
                         }
                         return false;
                     }