Xcos: remove block default values
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / block / BasicBlock.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4  * 
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at    
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.block;
14
15 import static org.scilab.modules.xcos.utils.FileUtils.delete;
16
17 import java.awt.MouseInfo;
18 import java.awt.event.ActionEvent;
19 import java.awt.event.ActionListener;
20 import java.beans.PropertyChangeEvent;
21 import java.beans.PropertyChangeListener;
22 import java.beans.PropertyChangeSupport;
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.Serializable;
26 import java.util.Arrays;
27 import java.util.Deque;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34
35 import ncsa.hdf.hdf5lib.exceptions.HDF5Exception;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
40 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
41 import org.scilab.modules.graph.ScilabGraph;
42 import org.scilab.modules.graph.ScilabGraphUniqueObject;
43 import org.scilab.modules.graph.actions.CopyAction;
44 import org.scilab.modules.graph.actions.CutAction;
45 import org.scilab.modules.graph.actions.DeleteAction;
46 import org.scilab.modules.graph.actions.base.DefaultAction;
47 import org.scilab.modules.graph.utils.StyleMap;
48 import org.scilab.modules.gui.bridge.contextmenu.SwingScilabContextMenu;
49 import org.scilab.modules.gui.contextmenu.ContextMenu;
50 import org.scilab.modules.gui.contextmenu.ScilabContextMenu;
51 import org.scilab.modules.gui.events.callback.CallBack;
52 import org.scilab.modules.gui.menu.Menu;
53 import org.scilab.modules.gui.menu.ScilabMenu;
54 import org.scilab.modules.gui.menuitem.MenuItem;
55 import org.scilab.modules.gui.menuitem.ScilabMenuItem;
56 import org.scilab.modules.hdf5.write.H5Write;
57 import org.scilab.modules.types.scilabTypes.ScilabDouble;
58 import org.scilab.modules.types.scilabTypes.ScilabList;
59 import org.scilab.modules.types.scilabTypes.ScilabString;
60 import org.scilab.modules.types.scilabTypes.ScilabType;
61 import org.scilab.modules.xcos.Xcos;
62 import org.scilab.modules.xcos.XcosTab;
63 import org.scilab.modules.xcos.actions.ShowHideShadowAction;
64 import org.scilab.modules.xcos.block.actions.BlockDocumentationAction;
65 import org.scilab.modules.xcos.block.actions.BlockParametersAction;
66 import org.scilab.modules.xcos.block.actions.BorderColorAction;
67 import org.scilab.modules.xcos.block.actions.EditBlockFormatAction;
68 import org.scilab.modules.xcos.block.actions.FilledColorAction;
69 import org.scilab.modules.xcos.block.actions.FlipAction;
70 import org.scilab.modules.xcos.block.actions.MirrorAction;
71 import org.scilab.modules.xcos.block.actions.RegionToSuperblockAction;
72 import org.scilab.modules.xcos.block.actions.RotateAction;
73 import org.scilab.modules.xcos.block.actions.ViewDetailsAction;
74 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockAction;
75 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionBottom;
76 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionCenter;
77 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionLeft;
78 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionMiddle;
79 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionRight;
80 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionTop;
81 import org.scilab.modules.xcos.graph.PaletteDiagram;
82 import org.scilab.modules.xcos.graph.SuperBlockDiagram;
83 import org.scilab.modules.xcos.graph.XcosDiagram;
84 import org.scilab.modules.xcos.io.scicos.BasicBlockInfo;
85 import org.scilab.modules.xcos.io.scicos.H5RWHandler;
86 import org.scilab.modules.xcos.port.BasicPort;
87 import org.scilab.modules.xcos.port.command.CommandPort;
88 import org.scilab.modules.xcos.port.control.ControlPort;
89 import org.scilab.modules.xcos.port.input.InputPort;
90 import org.scilab.modules.xcos.port.output.OutputPort;
91 import org.scilab.modules.xcos.utils.BlockPositioning;
92 import org.scilab.modules.xcos.utils.FileUtils;
93 import org.scilab.modules.xcos.utils.XcosConstants;
94 import org.scilab.modules.xcos.utils.XcosEvent;
95 import org.scilab.modules.xcos.utils.XcosMessages;
96
97 import com.mxgraph.model.mxGeometry;
98 import com.mxgraph.model.mxICell;
99 import com.mxgraph.util.mxEventObject;
100 import com.mxgraph.util.mxUtils;
101
102 public class BasicBlock extends ScilabGraphUniqueObject implements Serializable {
103         private static final double DEFAULT_POSITION_X = 10.0;
104         private static final double DEFAULT_POSITION_Y = 10.0;
105         private static final double DEFAULT_WIDTH = 40.0;
106         private static final double DEFAULT_HEIGHT = 40.0;
107         
108         private static final PropertyChangeListener styleUpdater = new UpdateStyleFromInterfunction();
109         private static final Log LOG = LogFactory.getLog(BasicBlock.class);
110         
111         /**
112          * Manage events for block parameters.
113          * 
114          * The property name is the field name, is one of:
115          *     - "interfaceFunctionName"
116          *     - "simulationFunctionName"
117          *     - "simulationFunctionType"
118          *     - "exprs"
119          *     - "realParameters"
120          *     - "integerParameters"
121          *     - "objectsParameters"
122          *     - "nbZerosCrossing"
123          *     - "nmode"
124          *     - "state"
125          *     - "dState"
126          *     - "oDState"
127          *     - "equations"
128          *     - "dependsOnU"
129          *     - "dependsOnT"
130          *     - "blockType"
131          *     - "ordering"
132          */
133         protected PropertyChangeSupport parametersPCS = new PropertyChangeSupport(this);
134         
135     private String interfaceFunctionName = "xcos_block";
136     private String simulationFunctionName = "xcos_simulate";
137     private SimulationFunctionType simulationFunctionType = SimulationFunctionType.DEFAULT;
138     private transient XcosDiagram parentDiagram;   
139     
140     private int angle;
141     private boolean isFlipped;
142     private boolean isMirrored;
143     
144
145     // TODO : Must make this types evolve, but for now keep a strong link to Scilab
146     // !! WARNING !!
147     // exprs = [] ; rpar = [] ; ipar = [] ; opar = list()
148
149     //private List<String> exprs = new ArrayList<String>();
150     private ScilabType exprs;
151     //private List<Double> realParameters = new ArrayList<Double>();
152     private ScilabType realParameters;
153     //private List<Integer> integerParameters = new ArrayList<Integer>();
154     private ScilabType integerParameters;
155     //private List objectsParameters = new ArrayList();
156     private ScilabType objectsParameters;
157
158     private ScilabType nbZerosCrossing = new ScilabDouble();
159
160     private ScilabType nmode = new ScilabDouble();
161
162     private ScilabType state = new ScilabDouble();
163     private ScilabType dState = new ScilabDouble();
164     private ScilabType oDState = new ScilabDouble();
165
166     private ScilabType equations;
167
168     private boolean dependsOnU;
169     private boolean dependsOnT;
170
171     private String blockType = "c";
172
173     private int ordering;
174     private boolean locked;
175
176         /**
177          * Represent a simulation function type compatible with Scilab/Scicos
178          * function type descriptors.
179          */
180         public static enum SimulationFunctionType {
181                 ESELECT(-2.0), IFTHENELSE(-1.0), DEFAULT(0.0), TYPE_1(1.0), TYPE_2(2.0),
182                     TYPE_3(3.0), C_OR_FORTRAN(4.0), SCILAB(5.0), MODELICA(30004.0), UNKNOWN(5.0), OLDBLOCKS(10001.0), IMPLICIT_C_OR_FORTRAN(10004.0);
183
184                 private double value;
185
186                 /**
187                  * Default constructor
188                  * 
189                  * @param scilabValue
190                  *            Scilab/Scicos function type descriptor
191                  */
192                 private SimulationFunctionType(double scilabValue) {
193                         value = scilabValue;
194                 }
195
196                 /**
197                  * Get the Java descriptor from the Scilab descriptor.
198                  * 
199                  * @param scilabValue
200                  *            Scilab/Scicos function type descriptor
201                  * @return The corresponding java descriptor
202                  */
203                 public static SimulationFunctionType convertScilabValue(int scilabValue) {
204                         for (SimulationFunctionType iter : SimulationFunctionType.values()) {
205                                 if (iter.getAsDouble() == scilabValue) {
206                                         return iter;
207                                 }
208                         }
209                         return UNKNOWN;
210                 }
211
212                 /**
213                  * Get the Scilab Descriptor from the Java Descriptor
214                  * 
215                  * @return The corresponding Scilab/Scicos descriptor
216                  */
217                 public double getAsDouble() {
218                         return this.value;
219                 }
220         };
221
222         /**
223          * Update the source block when the interfunction change. 
224          */
225         private static class UpdateStyleFromInterfunction implements PropertyChangeListener, Serializable {
226
227                 /**
228                  * Update the label on interfunction change.
229                  * 
230                  * @param evt the property change event.
231                  * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
232                  */
233                 @Override
234                 public void propertyChange(PropertyChangeEvent evt) {
235                         BasicBlock source = (BasicBlock) evt.getSource();
236                         
237                         StyleMap style = new StyleMap(source.getStyle());
238                         style.remove(evt.getOldValue());
239                         style.put((String) evt.getNewValue(), null);
240                         source.setStyle(style.toString());
241                 }
242                 
243         }
244         
245         private static class TraceParametersListener implements PropertyChangeListener, Serializable {
246                 private static TraceParametersListener instance;
247                 
248                 private TraceParametersListener() {
249                         super();
250                 }
251                 
252                 /**
253                  * @return the instance
254                  */
255                 public static TraceParametersListener getInstance() {
256                         if (instance == null) {
257                                 instance = new TraceParametersListener();
258                         }
259                         return instance;
260                 }
261                 
262                 @Override
263                 public void propertyChange(PropertyChangeEvent evt) {
264                         LOG.trace(evt.getPropertyName() + ": " + evt.getOldValue() + ", " + evt.getNewValue());
265                 }
266         }
267         
268         /**
269          * 
270          */
271         public BasicBlock() {
272                 super();
273                 setDefaultValues();
274                 setVisible(true);
275                 setVertex(true);
276                 
277                 if (getStyle().isEmpty() && !getInterfaceFunctionName().isEmpty()) {
278                         setStyle(getInterfaceFunctionName());
279                 }
280                 
281                 parametersPCS.addPropertyChangeListener("interfaceFunctionName",
282                                 styleUpdater);
283                 
284                 /*
285                  * Trace block parameters change if applicable.
286                  */
287                 if (LOG.isTraceEnabled()) {
288                         parametersPCS.addPropertyChangeListener(TraceParametersListener.getInstance());
289                 }
290         }
291
292         /**
293          * @param label block label
294          */
295         protected BasicBlock(String label) {
296                 this();
297                 setDefaultValues();
298         }
299
300         /**
301          * @param label block label
302          * @param style initial style
303          */
304         protected BasicBlock(String label, String style) {
305                 this(label);
306                 setStyle(style);
307         }
308
309         /**
310          * Initialize the block with the default values
311          */
312         protected void setDefaultValues() {
313                 setVisible(true);
314                 setVertex(true);
315                 setConnectable(false);
316                 setGeometry(new mxGeometry(DEFAULT_POSITION_X, DEFAULT_POSITION_Y,
317                                 DEFAULT_WIDTH, DEFAULT_HEIGHT));
318                 setValue("");
319                 setStyle("");
320         }
321
322     /**
323      * @return parent diagram
324      */
325     public XcosDiagram getParentDiagram() {
326         return parentDiagram;
327     }
328
329     /**
330      * @param parentDiagram parent diagram
331      */
332     public void setParentDiagram(XcosDiagram parentDiagram) {
333         this.parentDiagram = parentDiagram;
334     }
335
336     
337     /**
338      * @return interface function name
339      */
340     public String getInterfaceFunctionName() {
341         return interfaceFunctionName;
342     }
343
344     /**
345      * @param interfaceFunctionName interface function name
346      */
347     public void setInterfaceFunctionName(String interfaceFunctionName) {
348                 if ((this.interfaceFunctionName == null && interfaceFunctionName != null)
349                                 || !this.interfaceFunctionName.equals(interfaceFunctionName)) {
350                         
351                         final String oldValue = this.interfaceFunctionName;
352                         this.interfaceFunctionName = interfaceFunctionName;
353                         parametersPCS.firePropertyChange("interfaceFunctionName", oldValue,
354                                         interfaceFunctionName);
355                 }
356     }
357
358     /**
359      * @param simulationFunctionName sumulation function name
360      */
361     public void setSimulationFunctionName(String simulationFunctionName) {
362                 if ((this.simulationFunctionName == null && simulationFunctionName != null)
363                                 || !this.simulationFunctionName.equals(simulationFunctionName)) {
364                         
365                 final String oldValue = this.simulationFunctionName;
366                 this.simulationFunctionName = simulationFunctionName;
367                 parametersPCS.firePropertyChange("simulationFunctionName", oldValue, simulationFunctionName);
368         }
369     }
370
371     /**
372      * @return sumulation function name
373      */
374     public String getSimulationFunctionName() {
375         return simulationFunctionName;
376     }
377
378     /**
379      * @param scilabValue simulation function type
380      */
381     public void setSimulationFunctionType(int scilabValue) {
382                 SimulationFunctionType simulationFunctionType = SimulationFunctionType.convertScilabValue(scilabValue);
383                 setSimulationFunctionType(simulationFunctionType);
384     }
385
386     /**
387      * @param simulationFunctionType simulation function type
388      */
389         public void setSimulationFunctionType(SimulationFunctionType simulationFunctionType) {
390                 if ((this.simulationFunctionType == null && simulationFunctionType != null)
391                                 || !this.simulationFunctionType.equals(simulationFunctionType)) {
392                         
393                         final SimulationFunctionType oldValue = this.simulationFunctionType;
394                         this.simulationFunctionType = simulationFunctionType;
395                         parametersPCS.firePropertyChange("simulationFunctionType", oldValue,
396                                         simulationFunctionType);
397                 }
398         }
399
400     /**
401      * @return simulation function type
402      */
403     public SimulationFunctionType getSimulationFunctionType() {
404         return simulationFunctionType;
405     }
406
407     /**
408      * @return real parameter ( rpar )
409      */
410     public ScilabType getRealParameters() {
411         return realParameters;
412     }
413
414     /**
415      * @param realParameters reaL parameter ( rpar )
416      */
417     public void setRealParameters(ScilabType realParameters) {
418                 if ((this.realParameters == null && realParameters != null)
419                                 || !this.realParameters.equals(realParameters)) {
420                         
421                         final ScilabType oldValue = this.realParameters;
422                         this.realParameters = realParameters;
423                         parametersPCS.firePropertyChange("realParameters", oldValue, realParameters);
424                 }
425     } 
426
427     /**
428      * @return integer parameter ( ipar )
429      */
430     public ScilabType getIntegerParameters() {
431         return integerParameters;
432     }
433
434     /**
435      * @param integerParameters integer parameter ( ipar )
436      */
437     public void setIntegerParameters(ScilabType integerParameters) {
438                 if ((this.integerParameters == null && integerParameters != null)
439                                 || !this.integerParameters.equals(integerParameters)) {
440                         
441                         final ScilabType oldValue = this.integerParameters;
442                         this.integerParameters = integerParameters;
443                         parametersPCS.firePropertyChange("integerParameters", oldValue, integerParameters);
444                 }
445     }
446
447     /**
448      * @return object parameter ( opar )
449      */
450     public ScilabType getObjectsParameters() {
451         return objectsParameters;
452     }
453
454     /**
455      * @param objectsParameters object parameter ( opar )
456      */
457     public void setObjectsParameters(ScilabType objectsParameters) {
458                 if ((this.objectsParameters == null && objectsParameters != null)
459                                 || !this.objectsParameters.equals(objectsParameters)) {
460                         
461                         final ScilabType oldValue = this.objectsParameters;
462                         this.objectsParameters = objectsParameters;
463                         parametersPCS.firePropertyChange("objectsParameters", oldValue, objectsParameters);
464                 }
465     }
466
467     /**
468      * @param dependsOnU ?
469      */
470     public void setDependsOnU(boolean dependsOnU) {
471                 if (this.dependsOnU != dependsOnU) {
472                         
473                         final boolean oldValue = this.dependsOnU;
474                         this.dependsOnU = dependsOnU;
475                         parametersPCS.firePropertyChange("dependsOnU", oldValue, dependsOnU);
476                 }
477     }
478
479     /**
480      * @return ?
481      */
482     public boolean isDependsOnU() {
483         return dependsOnU;
484     }
485
486     /**
487      * @param dependsOnT ?
488      */
489     public void setDependsOnT(boolean dependsOnT) {
490                 if (this.dependsOnT != dependsOnT) {
491                         
492                         final boolean oldValue = this.dependsOnT;
493                         this.dependsOnT = dependsOnT;
494                         parametersPCS.firePropertyChange("dependsOnT", oldValue, dependsOnT);
495                 }
496     }
497
498     /**
499      * @return ?
500      */
501     public boolean isDependsOnT() {
502         return dependsOnT;
503     }
504
505     /**
506      * @param blockType block type
507      */
508     public void setBlockType(String blockType) {
509                 if ((this.blockType == null && blockType != null)
510                                 || !this.blockType.equals(blockType)) {
511                         
512                         final String oldValue = this.blockType;
513                         this.blockType = blockType;
514                         parametersPCS.firePropertyChange("blockType", oldValue, blockType);
515                 }
516     }
517
518     /**
519      * @return block type
520      */
521     public String getBlockType() {
522         return blockType;
523     }
524
525     /**
526      * @param ordering order value
527      */
528     public void setOrdering(int ordering) {
529                 if (this.ordering != ordering) {
530                         
531                         final int oldValue = this.ordering;
532                         this.ordering = ordering;
533                         parametersPCS.firePropertyChange("ordering", oldValue, ordering);
534                 }
535     }
536
537     /**
538      * @return order value
539      */
540     public int getOrdering() {
541         return ordering;
542     }
543
544     /**
545      * @param exprs expression
546      */
547     public void setExprs(ScilabType exprs) {
548                 if ((this.exprs == null && exprs != null)
549                                 || !this.exprs.equals(exprs)) {
550                         
551                         final ScilabType oldValue = this.exprs;
552                         this.exprs = exprs;
553                         parametersPCS.firePropertyChange("exprs", oldValue, exprs);
554                 }
555     }
556
557     /**
558      * @return expression
559      */
560     public ScilabType getExprs() {
561         return exprs;
562     }
563
564     /**
565      * @return zero crossing value
566      */
567     public ScilabType getNbZerosCrossing() {
568         return nbZerosCrossing;
569     }
570
571     /**
572      * @param nbZerosCrossing zero crossing value
573      */
574     public void setNbZerosCrossing(ScilabType nbZerosCrossing) {
575                 if ((this.nbZerosCrossing == null && nbZerosCrossing != null)
576                                 || !this.nbZerosCrossing.equals(nbZerosCrossing)) {
577                         
578                         final ScilabType oldValue = this.nbZerosCrossing;
579                         this.nbZerosCrossing = nbZerosCrossing;
580                         parametersPCS.firePropertyChange("nbZerosCrossing", oldValue, nbZerosCrossing);
581                 }
582     }
583
584     /**
585      * @return nmode
586      */
587     public ScilabType getNmode() {
588         return nmode;
589     }
590
591     /**
592      * @param nmode nmode
593      */
594     public void setNmode(ScilabType nmode) {
595                 if ((this.nmode == null && nmode != null)
596                                 || !this.nmode.equals(nmode)) {
597                         
598                         final ScilabType oldValue = this.nmode;
599                         this.nmode = nmode;
600                         parametersPCS.firePropertyChange("nmode", oldValue, nmode);
601                 }
602     }
603
604     /**
605      * @return current state
606      */
607     public ScilabType getState() {
608         return state;
609     }
610
611     /**
612      * @param state new state
613      */
614     public void setState(ScilabType state) {
615                 if ((this.state == null && state != null)
616                                 || !this.state.equals(state)) {
617                         
618                         final ScilabType oldValue = this.state;
619                         this.state = state;
620                         parametersPCS.firePropertyChange("state", oldValue, state);
621                 }
622     }
623
624     /**
625      * @return current dstate
626      */
627     public ScilabType getDState() {
628         return dState;
629     }
630
631     /**
632      * @param state new dstate
633      */
634     public void setDState(ScilabType dState) {
635                 if ((this.dState == null && dState != null)
636                                 || !this.dState.equals(dState)) {
637                         
638                         final ScilabType oldValue = this.dState;
639                         this.dState = dState;
640                         parametersPCS.firePropertyChange("dState", oldValue, dState);
641                 }
642     }
643
644     /**
645      * @return current ostate
646      */
647     public ScilabType getODState() {
648         return oDState;
649     }
650
651     /**
652      * @param state new ostate
653      */
654     public void setODState(ScilabType oDState) {
655                 if ((this.oDState == null && oDState != null)
656                                 || !this.oDState.equals(oDState)) {
657                         
658                         final ScilabType oldValue = this.oDState;
659                         this.oDState = oDState;
660                         parametersPCS.firePropertyChange("oDState", oldValue, oDState);
661                 }
662     }
663
664     /**
665      * @return equations
666      */
667     public ScilabType getEquations() {
668         return equations;
669     }
670
671     /**
672      * @param equations equations
673      */
674     public void setEquations(ScilabType equations) {
675                 if ((this.equations == null && equations != null)
676                                 || !this.equations.equals(equations)) {
677                         
678                         final ScilabType oldValue = this.equations;
679                         this.equations = equations;
680                         parametersPCS.firePropertyChange("equations", oldValue, equations);
681                 }
682     }
683
684     /**
685      * @return locked status
686      */
687     public synchronized boolean isLocked() {
688         return locked;
689     }
690
691     /**
692      * @param locked change locked status
693      */
694     public synchronized void setLocked(boolean locked) {
695         this.locked = locked;
696     }
697
698     /**
699      * @param port to remove
700      */
701     public void removePort(BasicPort port) {
702         if (port.getEdgeCount() != 0) {
703             getParentDiagram().removeCells(new Object[]{port.getEdgeAt(0)});
704         }
705         remove(port);
706     }
707     
708     /**
709      * Add a port on the block.
710      * @param port The port to be added to the block
711      */
712     public void addPort(BasicPort port) {
713         insert(port);
714         BlockPositioning.updateBlockView(this);
715         port.setOrdering(BasicBlockInfo.getAllTypedPorts(this, false, port.getClass()).size());
716     }
717
718         /**
719          * @return command ports initial state
720          */
721         public ScilabDouble getAllCommandPortsInitialStates() {
722                 final List<CommandPort> cmdPorts = BasicBlockInfo.getAllTypedPorts(
723                                 this, false, CommandPort.class);
724                 if (cmdPorts.isEmpty()) {
725                         return new ScilabDouble();
726                 }
727
728                 double[][] data = new double[cmdPorts.size()][1];
729                 for (int i = 0; i < cmdPorts.size(); ++i) {
730                         data[i][0] = cmdPorts.get(i).getInitialState();
731                 }
732
733                 return new ScilabDouble(data);
734         }
735
736     /**
737      * @return name and type of the simulation function
738      */
739     public ScilabType getSimulationFunctionNameAndType() {
740         if (getSimulationFunctionType() == SimulationFunctionType.DEFAULT) {
741             return new ScilabString(getSimulationFunctionName());
742         }
743         ScilabList data = new ScilabList();
744
745         data.add(new ScilabString(getSimulationFunctionName()));
746         data.add(new ScilabDouble(getSimulationFunctionType().getAsDouble()));
747
748         return data;
749     }
750
751     /**
752      * Does the block update and register on the undo manager 
753      * @param modifiedBlock the new settings
754      */
755     public void updateBlockSettings(BasicBlock modifiedBlock) {
756         /*
757                  * Update the block settings
758                  */
759                 updateFields(modifiedBlock);
760
761                 /*
762                  * Update the children ports
763                  */
764                 updateChildren(modifiedBlock);
765
766                 /*
767                  * If the block is in a superblock then update it.
768                  */
769                 if (getParentDiagram() instanceof SuperBlockDiagram) {
770                         SuperBlock parentBlock = ((SuperBlockDiagram) getParentDiagram())
771                                         .getContainer();
772                         parentBlock.getParentDiagram().fireEvent(
773                                         new mxEventObject(XcosEvent.SUPER_BLOCK_UPDATED,
774                                                         XcosConstants.EVENT_BLOCK_UPDATED, parentBlock));
775                 }
776     }
777
778         /**
779          * Update the instance field.
780          * 
781          * @param modifiedBlock the modified instance
782          */
783         private void updateFields(BasicBlock modifiedBlock) {
784                 setDependsOnT(modifiedBlock.isDependsOnT());
785                 setDependsOnU(modifiedBlock.isDependsOnU());
786                 setExprs(modifiedBlock.getExprs());
787
788                 setRealParameters(modifiedBlock.getRealParameters());
789                 setIntegerParameters(modifiedBlock.getIntegerParameters());
790                 setObjectsParameters(modifiedBlock.getObjectsParameters());
791
792                 setState(modifiedBlock.getState());
793                 setDState(modifiedBlock.getDState());
794                 setODState(modifiedBlock.getODState());
795
796                 setEquations(modifiedBlock.getEquations());
797         }
798
799         /**
800          * Update the children of the block.
801          * 
802          * @param modifiedBlock the new block instance
803          */
804         private void updateChildren(BasicBlock modifiedBlock) {
805                 Set<Class<? extends mxICell>> types = new HashSet<Class<? extends mxICell>>(
806                                 Arrays.asList(InputPort.class, OutputPort.class,
807                                                 ControlPort.class, CommandPort.class));
808
809                 Map<Class<? extends mxICell>, Deque<mxICell>> annotatedOlds = getTypedChildren(types);
810                 Map<Class<? extends mxICell>, Deque<mxICell>> annotatedNews = modifiedBlock
811                                 .getTypedChildren(types);
812
813                 getParentDiagram().getModel().beginUpdate();
814                 try {
815                         for (Class<? extends mxICell> klass : types) {
816                                 final Deque<mxICell> olds = annotatedOlds.get(klass);
817                                 final Deque<mxICell> news = annotatedNews.get(klass);
818
819                                 // updated ports
820                                 while (!olds.isEmpty() && !news.isEmpty()) {
821                                         mxICell previous = olds.poll();
822                                         mxICell modified = news.poll();
823
824                                         final int previousIndex = children.indexOf(previous);
825
826                                         // relink
827                                         if (previous.getEdgeCount() != 0) {
828                                                 final mxICell edge = previous.getEdgeAt(0);
829                                                 final boolean isOutgoing = previous == edge
830                                                                 .getTerminal(true);
831                                                 previous.removeEdge(edge, isOutgoing);
832                                                 modified.insertEdge(edge, isOutgoing);
833                                         }
834
835                                         getParentDiagram().removeCells(new Object[] { previous },
836                                                         false);
837                                         getParentDiagram().addCells(new Object[] { modified },
838                                                         this, previousIndex);
839                                 }
840
841                                 // removed ports
842                                 if (!olds.isEmpty()) {
843                                         getParentDiagram().removeCells(olds.toArray(), true);
844                                 }
845
846                                 // added ports
847                                 if (!news.isEmpty()) {
848                                         getParentDiagram().addCells(news.toArray(), this);
849                                 }
850                         }
851                 } finally {
852                         getParentDiagram().getModel().endUpdate();
853                 }
854         }
855         
856         /**
857          * Format the children as a typed map for the given class set.
858          * 
859          * @param types the classes to search for.
860          * @return a map which linked foreach type the corresponding cell list. 
861          */
862         private Map<Class<? extends mxICell>, Deque<mxICell>> getTypedChildren(Set<Class<? extends mxICell>> types) {
863                 Map<Class<? extends mxICell>, Deque<mxICell>> oldPorts = new HashMap<Class<? extends mxICell>, Deque<mxICell>>();
864                 
865                 // Allocate all types set
866                 for (Class<? extends mxICell> type : types) {
867                         oldPorts.put(type, new LinkedList<mxICell>());
868                 }
869                 
870                 // children lookup
871                 for (Object cell : children) {
872                         
873                         Class<? extends Object> klass = cell.getClass();
874                         while (klass != null) {
875                                 if (types.contains(klass)) {
876                                         break;
877                                 }
878                                 klass = klass.getSuperclass();
879                         }
880                         
881                         final Deque<mxICell> current = oldPorts.get(klass);
882                         current.add((mxICell) cell);
883                 }
884                 
885                 return oldPorts;
886         }
887
888     /**
889      * @param context parent diagram context
890      */
891     public void openBlockSettings(String[] context) {
892         
893         if (getParentDiagram() instanceof PaletteDiagram) {
894             return;
895         }
896         
897         //prevent to open twice
898         if (isLocked()) {
899             return;
900         }
901         
902         final File tempOutput;
903         final File tempInput;
904         final File tempContext;
905         final BasicBlock currentBlock = this;
906         
907         try {
908             tempInput = FileUtils.createTempFile();
909
910             // Write scs_m
911             tempOutput = exportBlockStruct();
912             // Write context
913             tempContext = exportContext(context);
914             
915             final ActionListener action = new ActionListener() {
916                         @Override
917                         public void actionPerformed(ActionEvent e) {
918                                 if (tempInput.exists()) {
919                                         LOG.trace("Updating data.");
920                                         
921                                 // Now read new Block
922                             BasicBlock modifiedBlock = new H5RWHandler(tempInput).readBlock();
923                             updateBlockSettings(modifiedBlock);
924                             
925                             getParentDiagram().fireEvent(new mxEventObject(XcosEvent.ADD_PORTS, XcosConstants.EVENT_BLOCK_UPDATED, 
926                                     currentBlock));
927                             delete(tempInput);
928                                 } else {
929                                         LOG.trace("No needs to update data.");
930                                 }
931                                 
932                             setLocked(false);
933                             delete(tempOutput);
934                             delete(tempContext);
935                         }
936                 };
937                 
938             try {
939                         ScilabInterpreterManagement.asynchronousScilabExec(action, 
940                                 "xcosBlockInterface", 
941                                 tempOutput.getAbsolutePath(),
942                                 tempInput.getAbsolutePath(),
943                                 getInterfaceFunctionName().toCharArray(),
944                                 "set",
945                                 tempContext.getAbsolutePath());
946                 } catch (InterpreterException e) {
947                         LOG.error(e);
948                 }
949             setLocked(true);
950
951         } catch (IOException e) {
952             LOG.error(e);
953         }
954     }
955
956     /**
957      * @return exported file
958      */
959     protected File exportBlockStruct() {
960
961         // Write scs_m
962         File tempOutput;
963         try {
964             tempOutput = FileUtils.createTempFile();
965             tempOutput.deleteOnExit();
966             
967             new H5RWHandler(tempOutput).writeBlock(this);
968             return tempOutput;
969         } catch (IOException e) {
970             e.printStackTrace();
971         }
972         return null;
973     }
974     
975     /**
976      * @param context parent diagram context
977      * @return exported file
978      */
979     protected File exportContext(String[] context) {
980
981         // Write context
982         try {
983             File tempContext = FileUtils.createTempFile();
984             tempContext.deleteOnExit();
985             int contextFileId = H5Write.createFile(tempContext.getAbsolutePath());
986             H5Write.writeInDataSet(contextFileId, "context", new ScilabString(context));
987             H5Write.closeFile(contextFileId);
988             return tempContext;
989         } catch (IOException e) {
990             e.printStackTrace();
991         } catch (HDF5Exception e) {
992             e.printStackTrace();
993         }
994         return null;
995     }
996     
997     /**
998      * @return tooltip text
999      */
1000     public String getToolTipText() {
1001         StringBuilder result = new StringBuilder();
1002         result.append(XcosConstants.HTML_BEGIN);
1003         result.append("Block Name : " + getInterfaceFunctionName() + XcosConstants.HTML_NEWLINE);
1004         result.append("Simulation : " + getSimulationFunctionName() + XcosConstants.HTML_NEWLINE);
1005
1006         if (getParentDiagram() instanceof PaletteDiagram) {
1007             if (getIntegerParameters() != null) {
1008                 result.append("Integer parameters : " + getIntegerParameters() + XcosConstants.HTML_NEWLINE);
1009             }
1010             
1011             if (getRealParameters() != null && getRealParameters().getHeight() != 0 && getRealParameters().getWidth() != 0) {
1012                 result.append("Real parameters : " + getRealParameters() + XcosConstants.HTML_NEWLINE);
1013             }
1014             
1015             if (getObjectsParameters() != null) {
1016                 result.append("Object parameters : " + getObjectsParameters() + XcosConstants.HTML_NEWLINE);
1017             }
1018         } else {
1019             result.append("UID : " + getId() + XcosConstants.HTML_NEWLINE);
1020                 final int length = getStyle().length();
1021                 result.append("Style : ");
1022                 if (length > XcosConstants.MAX_CHAR_IN_STYLE) {
1023                         result.append(getStyle().substring(0, XcosConstants.MAX_CHAR_IN_STYLE));
1024                         result.append(XcosMessages.DOTS);
1025                 } else {
1026                         result.append(getStyle());
1027                 }
1028                 result.append(XcosConstants.HTML_NEWLINE);
1029             result.append("Flip : " + getFlip() + XcosConstants.HTML_NEWLINE);
1030             result.append("Mirror : " + getMirror() + XcosConstants.HTML_NEWLINE);
1031             result.append("Input ports : " + BasicBlockInfo.getAllTypedPorts(this, false, InputPort.class).size() + XcosConstants.HTML_NEWLINE);
1032             result.append("Output ports : " + BasicBlockInfo.getAllTypedPorts(this, false, OutputPort.class).size() + XcosConstants.HTML_NEWLINE);
1033             result.append("Control ports : " + BasicBlockInfo.getAllTypedPorts(this, false, ControlPort.class).size() + XcosConstants.HTML_NEWLINE);
1034             result.append("Command ports : " + BasicBlockInfo.getAllTypedPorts(this, false, CommandPort.class).size() + XcosConstants.HTML_NEWLINE);
1035         }
1036
1037         result.append("x : " + getGeometry().getX() + XcosConstants.HTML_NEWLINE);
1038         result.append("y : " + getGeometry().getY() + XcosConstants.HTML_NEWLINE);
1039         result.append("w : " + getGeometry().getWidth() + XcosConstants.HTML_NEWLINE);
1040         result.append("h : " + getGeometry().getHeight() + XcosConstants.HTML_NEWLINE);
1041         result.append(XcosConstants.HTML_END);
1042         return result.toString();
1043     }
1044
1045     /**
1046      * @param graph parent graph
1047      */
1048     public void openContextMenu(ScilabGraph graph) {
1049         ContextMenu menu = null;
1050         if (getParentDiagram() instanceof PaletteDiagram) {
1051             menu = createPaletteContextMenu(graph);
1052         } else {
1053             menu = createContextMenu(graph);
1054         }
1055         menu.setVisible(true);
1056     }
1057
1058     /**
1059      * @param graph parent graph
1060      * @return context menu
1061      */
1062     public ContextMenu createPaletteContextMenu(ScilabGraph graph) {
1063         ContextMenu menu = ScilabContextMenu.createContextMenu();
1064
1065         final List<XcosDiagram> allDiagrams = Xcos.getInstance().getDiagrams();
1066
1067         if (allDiagrams.size() == 0) {
1068             // No diagram opened: should never happen if Xcos opens an empty diagram when it is launched
1069             MenuItem addTo = ScilabMenuItem.createMenuItem();
1070
1071             addTo.setText(XcosMessages.ADDTO_NEW_DIAGRAM);
1072             addTo.setCallback(new CallBack(XcosMessages.ADDTO_NEW_DIAGRAM) {
1073                 @Override
1074                 public void callBack() {
1075                         
1076                     XcosDiagram theDiagram = new XcosDiagram();
1077                     BasicBlock block = (BasicBlock) BlockFactory.createClone(BasicBlock.this);
1078                     theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
1079                     mxGeometry geom = BasicBlock.this.getGeometry();
1080                     setDefaultPosition(geom);
1081                     theDiagram.getModel().setGeometry(block, geom);
1082                     
1083                     new XcosTab(theDiagram).setVisible(true);
1084                     BlockPositioning.updateBlockView(block);
1085                 }
1086             });
1087
1088             menu.add(addTo);
1089
1090         } else if (allDiagrams.size() == 1) {
1091             // A single diagram opened: add to this diagram
1092             MenuItem addTo = ScilabMenuItem.createMenuItem();
1093
1094             addTo.setText(XcosMessages.ADDTO + " " + allDiagrams.get(0).getParentTab().getName());
1095             final XcosDiagram theDiagram = allDiagrams.get(0);
1096             addTo.setCallback(new CallBack(theDiagram.getTitle()) {
1097                 private static final long serialVersionUID = -99601763227525686L;
1098
1099                 @Override
1100                 public void callBack() {
1101                     BasicBlock block = (BasicBlock) BlockFactory.createClone(BasicBlock.this);
1102                     theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
1103                     mxGeometry geom = BasicBlock.this.getGeometry();
1104                     setDefaultPosition(geom);
1105                     theDiagram.getModel().setGeometry(block, geom);
1106                     BlockPositioning.updateBlockView(block);
1107                     block.setParentDiagram(theDiagram);
1108                 }
1109             });
1110
1111             menu.add(addTo);
1112
1113         } else {
1114             // The user has to choose
1115             Menu addTo = ScilabMenu.createMenu();
1116
1117             addTo.setText(XcosMessages.ADDTO);
1118
1119             for (int i = 0; i < allDiagrams.size(); i++) {
1120                 MenuItem diagram = ScilabMenuItem.createMenuItem();
1121                 final XcosDiagram theDiagram = allDiagrams.get(i);
1122                 diagram.setText(allDiagrams.get(i).getParentTab().getName());
1123                 diagram.setCallback(new CallBack(theDiagram.getTitle()) {
1124                     private static final long serialVersionUID = 3345416658377835057L;
1125
1126                         @Override
1127                     public void callBack() {
1128                         BasicBlock block = (BasicBlock) BlockFactory.createClone(BasicBlock.this);
1129                         theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
1130                         mxGeometry geom = BasicBlock.this.getGeometry();
1131                     setDefaultPosition(geom);
1132                         theDiagram.getModel().setGeometry(block, geom);
1133                         BlockPositioning.updateBlockView(block);
1134                     }
1135                 });
1136                 addTo.add(diagram);
1137             }
1138
1139             menu.add(addTo);
1140         }
1141
1142
1143         menu.getAsSimpleContextMenu().addSeparator();
1144
1145         MenuItem help = ScilabMenuItem.createMenuItem();
1146         help.setText(XcosMessages.BLOCK_DOCUMENTATION);
1147         help.setCallback(new CallBack(XcosMessages.BLOCK_DOCUMENTATION) {
1148             private static final long serialVersionUID = -1480947262397441951L;
1149
1150                 @Override
1151             public void callBack() {
1152                 ScilabInterpreterManagement.requestScilabExec("help " + getInterfaceFunctionName());
1153             }
1154         });
1155         menu.add(help);
1156
1157         menu.setVisible(true);
1158
1159         ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(
1160                 MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo().getLocation().y);
1161         
1162         return menu;
1163     }
1164
1165     /**
1166      * @param graph parent graph
1167      * @return context menu
1168      */
1169     public ContextMenu createContextMenu(ScilabGraph graph) {
1170                 ContextMenu menu = ScilabContextMenu.createContextMenu();
1171                 Map<Class< ? extends DefaultAction>, Menu> menuList = new HashMap<Class< ? extends DefaultAction>, Menu>();
1172                 
1173                 MenuItem value = BlockParametersAction.createMenu(graph);
1174                 menuList.put(BlockParametersAction.class, value);
1175                 menu.add(value);
1176                 /*--- */
1177                 menu.getAsSimpleContextMenu().addSeparator();
1178                 /*--- */
1179                 value = CutAction.cutMenu(graph);
1180                 menuList.put(CutAction.class, value);
1181                 menu.add(value);
1182                 value = CopyAction.copyMenu(graph);
1183                 menuList.put(CopyAction.class, value);
1184                 menu.add(value);
1185                 value = DeleteAction.createMenu(graph);
1186                 menuList.put(DeleteAction.class, value);
1187                 menu.add(value);
1188                 /*--- */
1189                 menu.getAsSimpleContextMenu().addSeparator();
1190                 /*--- */
1191                 value = RegionToSuperblockAction.createMenu(graph);
1192                 menuList.put(RegionToSuperblockAction.class, value);
1193                 menu.add(value);
1194                 /*--- */
1195                 menu.getAsSimpleContextMenu().addSeparator();
1196                 /*--- */
1197                 Menu format = ScilabMenu.createMenu();
1198                 format.setText(XcosMessages.FORMAT);
1199                 menu.add(format);
1200                 value = RotateAction.createMenu(graph);
1201                 menuList.put(RotateAction.class, value);
1202                 format.add(value);
1203                 value = MirrorAction.createMenu(graph);
1204                 menuList.put(MirrorAction.class, value);
1205                 format.add(value);
1206                 value = FlipAction.createMenu(graph);
1207                 menuList.put(FlipAction.class, value);
1208                 format.add(value);
1209                 value = ShowHideShadowAction.createMenu(graph);
1210                 menuList.put(ShowHideShadowAction.class, value);
1211                 format.add(value);
1212                 /*--- */
1213                 format.addSeparator();
1214                 /*--- */
1215                 Menu alignMenu = ScilabMenu.createMenu();
1216                 alignMenu.setText(XcosMessages.ALIGN_BLOCKS);
1217                 alignMenu.add(AlignBlockActionLeft.createMenu(graph));
1218                 alignMenu.add(AlignBlockActionCenter.createMenu(graph));
1219                 alignMenu.add(AlignBlockActionRight.createMenu(graph));
1220                 alignMenu.addSeparator();
1221                 alignMenu.add(AlignBlockActionTop.createMenu(graph));
1222                 alignMenu.add(AlignBlockActionMiddle.createMenu(graph));
1223                 alignMenu.add(AlignBlockActionBottom.createMenu(graph));
1224                 menuList.put(AlignBlockAction.class, alignMenu);
1225                 format.add(alignMenu);
1226                 /*--- */
1227                 format.addSeparator();
1228                 /*--- */
1229                 if (graph.getSelectionCells().length > 1) {
1230                         format.add(BorderColorAction.createMenu(graph));
1231                         format.add(FilledColorAction.createMenu(graph));
1232                 } else {
1233                         format.add(EditBlockFormatAction.createMenu(graph));
1234                 }
1235                 /*--- */
1236                 menu.getAsSimpleContextMenu().addSeparator();
1237                 /*--- */
1238                 menu.add(ViewDetailsAction.createMenu(graph));
1239                 /*--- */
1240                 menu.getAsSimpleContextMenu().addSeparator();
1241                 /*--- */
1242                 menu.add(BlockDocumentationAction.createMenu(graph));
1243
1244                 ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x, 
1245                         MouseInfo.getPointerInfo().getLocation().y);
1246                 
1247                 customizeMenu(menuList);
1248                 
1249                 return menu;
1250     }
1251     
1252     /**
1253      * @param flip value
1254      */
1255     public void setFlip(boolean flip) {
1256         if (getParentDiagram() != null) {
1257             isFlipped = flip;
1258             if (flip) {
1259                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_FLIP, Boolean.TRUE.toString());
1260             } else {
1261                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_FLIP, Boolean.FALSE.toString());
1262             }
1263         }
1264     }
1265
1266     /**
1267      * Override this to customize contextual menu
1268      * @param menuList list of menu
1269      */
1270     protected void customizeMenu(Map<Class< ? extends DefaultAction>, Menu> menuList) {
1271         // To be overridden by sub-classes
1272     }
1273     
1274
1275     /**
1276      * @return mirror value
1277      */
1278     public boolean getMirror() {
1279         return isMirrored;
1280     }
1281     
1282     /**
1283      * @param mirror new mirror value
1284      */
1285     public void setMirror(boolean mirror) {
1286         if (getParentDiagram() != null) {
1287             isMirrored = mirror;
1288             if (mirror) {
1289                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_MIRROR, "true");
1290             } else {
1291                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_MIRROR, "false");
1292             }
1293         }
1294     }
1295
1296     /**
1297      * @return flip status
1298      */
1299     public boolean getFlip() {
1300         return isFlipped;
1301     }
1302
1303     /**
1304      * invert flip status
1305      */
1306     public void toggleFlip() {
1307         BlockPositioning.toggleFlip(this);
1308     }
1309
1310     /**
1311      * invert mirror value
1312      */
1313     public void toggleMirror() {
1314         BlockPositioning.toggleMirror(this);
1315     }
1316
1317     /**
1318      * 
1319      */
1320     public void toggleAntiClockwiseRotation() {
1321         BlockPositioning.toggleAntiClockwiseRotation(this);
1322
1323     }
1324
1325     /**
1326      * @return current angle
1327      */
1328     public int getAngle() {
1329         return angle;
1330     }
1331
1332     /**
1333      * @param angle new block angle
1334      */
1335     public void setAngle(int angle) {
1336         this.angle = angle;
1337         
1338         if (getParentDiagram() != null) {
1339             mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_ROTATION, Integer.toString(angle));
1340         }
1341     }
1342
1343     /**
1344      * Useful when we need to update local properties with mxCell style properties 
1345      */
1346         public void updateFieldsFromStyle() {
1347                 StyleMap map = new StyleMap(getStyle());
1348
1349                 if (map.get(XcosConstants.STYLE_ROTATION) != null) {
1350                         angle = Integer.parseInt(map.get(XcosConstants.STYLE_ROTATION));
1351                 } else {
1352                         angle = 0;
1353                 }
1354                 
1355                 isFlipped = Boolean.parseBoolean(map.get(XcosConstants.STYLE_FLIP));
1356                 isMirrored = Boolean.parseBoolean(map.get(XcosConstants.STYLE_MIRROR));
1357         }
1358
1359         /**
1360          * Set the default block position on the geom
1361          * @param geom the current geom
1362          */
1363         private void setDefaultPosition(mxGeometry geom) {
1364                 geom.setX(DEFAULT_POSITION_X);
1365                 geom.setY(DEFAULT_POSITION_Y);
1366         }
1367         
1368         /**
1369          * Get the parameters change support.
1370          * 
1371          * The property name for each event is the field name, so one of:
1372          *     - "interfaceFunctionName"
1373          *     - "simulationFunctionName"
1374          *     - "simulationFunctionType"
1375          *     - "exprs"
1376          *     - "realParameters"
1377          *     - "integerParameters"
1378          *     - "objectsParameters"
1379          *     - "nbZerosCrossing"
1380          *     - "nmode"
1381          *     - "state"
1382          *     - "dState"
1383          *     - "oDState"
1384          *     - "equations"
1385          *     - "dependsOnU"
1386          *     - "dependsOnT"
1387          *     - "blockType"
1388          *     - "ordering"
1389          * 
1390          * @return the associated {@link PropertyChangeSupport} instance
1391          */
1392         public PropertyChangeSupport getParametersPCS() {
1393                 return parametersPCS;
1394         }
1395         
1396         /**
1397          * Re-associate fields with the new instance.
1398          * 
1399          * @return a new clone instance
1400          * @throws CloneNotSupportedException never
1401          * @see com.mxgraph.model.mxCell#clone()
1402          */
1403         @Override
1404         public Object clone() throws CloneNotSupportedException {
1405                 BasicBlock clone = (BasicBlock) super.clone();
1406                 
1407                 /* Reinstall the PropertyChangeSupport and all of it listeners */
1408                 clone.parametersPCS = new PropertyChangeSupport(clone);
1409                 PropertyChangeSupport pcs = getParametersPCS();
1410                 for (PropertyChangeListener iter : pcs.getPropertyChangeListeners()) {
1411                         clone.parametersPCS.addPropertyChangeListener(iter);
1412                 }
1413                 
1414                 return clone;
1415         }
1416         
1417         /**
1418          * Overriden to correct jgraphx bug fixed in 1.4.0.4
1419          * 
1420          * @param child the child to insert
1421          * @return the previous child
1422          * @see com.mxgraph.model.mxCell#insert(com.mxgraph.model.mxICell)
1423          * @see http://www.jgraphsupport.co.uk/bugzilla/show_bug.cgi?id=39
1424          * @deprecated Will be left after the switch to jgraphx >= 1.4.0.4
1425          */
1426         @Deprecated
1427         @Override
1428         public mxICell insert(mxICell child) {
1429                 int index = getChildCount();
1430                 
1431                 if (child.getParent() == this) {
1432                         index--;
1433                 }
1434                 
1435                 return insert(child, index);
1436         }
1437 }