2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
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.1-en.txt
13 package org.scilab.modules.xcos.block;
15 import java.awt.MouseInfo;
16 import java.awt.event.ActionEvent;
17 import java.awt.event.ActionListener;
18 import java.beans.PropertyChangeEvent;
19 import java.beans.PropertyChangeListener;
20 import java.beans.PropertyChangeSupport;
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.Deque;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.LinkedList;
30 import java.util.List;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
36 import org.scilab.modules.action_binding.InterpreterManagement;
37 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
38 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
39 import org.scilab.modules.graph.ScilabGraph;
40 import org.scilab.modules.graph.ScilabGraphUniqueObject;
41 import org.scilab.modules.graph.actions.CopyAction;
42 import org.scilab.modules.graph.actions.CutAction;
43 import org.scilab.modules.graph.actions.DeleteAction;
44 import org.scilab.modules.graph.actions.base.DefaultAction;
45 import org.scilab.modules.graph.utils.ScilabGraphConstants;
46 import org.scilab.modules.graph.utils.StyleMap;
47 import org.scilab.modules.gui.bridge.contextmenu.SwingScilabContextMenu;
48 import org.scilab.modules.gui.contextmenu.ContextMenu;
49 import org.scilab.modules.gui.contextmenu.ScilabContextMenu;
50 import org.scilab.modules.gui.events.callback.CommonCallBack;
51 import org.scilab.modules.gui.menu.Menu;
52 import org.scilab.modules.gui.menu.ScilabMenu;
53 import org.scilab.modules.gui.menuitem.MenuItem;
54 import org.scilab.modules.gui.menuitem.ScilabMenuItem;
55 import org.scilab.modules.types.ScilabDouble;
56 import org.scilab.modules.types.ScilabList;
57 import org.scilab.modules.types.ScilabMList;
58 import org.scilab.modules.types.ScilabString;
59 import org.scilab.modules.types.ScilabType;
60 import org.scilab.modules.xcos.Xcos;
61 import org.scilab.modules.xcos.XcosTab;
62 import org.scilab.modules.xcos.actions.EditFormatAction;
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.FilledColorAction;
68 import org.scilab.modules.xcos.block.actions.FlipAction;
69 import org.scilab.modules.xcos.block.actions.MirrorAction;
70 import org.scilab.modules.xcos.block.actions.RegionToSuperblockAction;
71 import org.scilab.modules.xcos.block.actions.RotateAction;
72 import org.scilab.modules.xcos.block.actions.ViewDetailsAction;
73 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockAction;
74 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionBottom;
75 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionCenter;
76 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionLeft;
77 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionMiddle;
78 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionRight;
79 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionTop;
80 import org.scilab.modules.xcos.graph.PaletteDiagram;
81 import org.scilab.modules.xcos.graph.SuperBlockDiagram;
82 import org.scilab.modules.xcos.graph.XcosDiagram;
83 import org.scilab.modules.xcos.io.scicos.BasicBlockInfo;
84 import org.scilab.modules.xcos.io.scicos.DiagramElement;
85 import org.scilab.modules.xcos.io.scicos.ScicosFormatException;
86 import org.scilab.modules.xcos.io.scicos.ScilabDirectHandler;
87 import org.scilab.modules.xcos.port.BasicPort;
88 import org.scilab.modules.xcos.port.command.CommandPort;
89 import org.scilab.modules.xcos.port.control.ControlPort;
90 import org.scilab.modules.xcos.port.input.InputPort;
91 import org.scilab.modules.xcos.port.output.OutputPort;
92 import org.scilab.modules.xcos.utils.BlockPositioning;
93 import org.scilab.modules.xcos.utils.XcosConstants;
94 import org.scilab.modules.xcos.utils.XcosEvent;
95 import org.scilab.modules.xcos.utils.XcosMessages;
97 import com.mxgraph.model.mxGeometry;
98 import com.mxgraph.model.mxICell;
99 import com.mxgraph.model.mxIGraphModel;
100 import com.mxgraph.util.mxConstants;
101 import com.mxgraph.util.mxEventObject;
102 import com.mxgraph.util.mxUtils;
105 * A block on the diagram
107 // CSOFF: ClassDataAbstractionCoupling
108 // CSOFF: ClassFanOutComplexity
109 @SuppressWarnings(value = { "serial" })
110 public class BasicBlock extends ScilabGraphUniqueObject implements Serializable {
112 * Sorted kind of input, useful to sort them by kind
114 private static final Class<?>[] sortedChildrenClass = {InputPort.class, OutputPort.class, ControlPort.class, CommandPort.class, Object.class};
121 * Property name of interfaceFunctionName
123 public static final String INTERFACE_FUNCTION_NAME = "interfaceFunctionName";
125 * Property name of simulationFunctionName
127 public static final String SIMULATION_FUNCTION_NAME = "simulationFunctionName";
129 * Property name of simulationFunctionType
131 public static final String SIMULATION_FUNCTION_TYPE = "simulationFunctionType";
133 * Property name of realParameters
135 public static final String REAL_PARAMETERS = "realParameters";
137 * Property name of integerParameters
139 public static final String INTEGER_PARAMETERS = "integerParameters";
141 * Property name of objectsParameters
143 public static final String OBJECTS_PARAMETERS = "objectsParameters";
145 * Property name of dependsOnU
147 public static final String DEPENDS_ON_U = "dependsOnU";
149 * Property name of dependsOnT
151 public static final String DEPENDS_ON_T = "dependsOnT";
153 * Property name of blockType
155 public static final String BLOCK_TYPE = "blockType";
157 * Property name of ordering
159 public static final String ORDERING = "ordering";
161 * Property name of exprs
163 public static final String EXPRS = "exprs";
165 * Property name of nbZerosCrossing
167 public static final String NB_ZEROS_CROSSING = "nbZerosCrossing";
169 * Property name of nmode
171 public static final String NMODE = "nmode";
173 * Property name of state
175 public static final String STATE = "state";
177 * Property name of dState
179 public static final String D_STATE = "dState";
181 * Property name of oDState
183 public static final String O_D_STATE = "oDState";
185 * Property name of equations
187 public static final String EQUATIONS = "equations";
194 * Default interface function name
196 public static final String DEFAULT_INTERFACE_FUNCTION = "xcos_block";
198 * Default simulation function name
200 public static final String DEFAULT_SIMULATION_FUNCTION = "xcos_simulate";
206 private static final String PARENT_DIAGRAM_WAS_NULL = "Parent diagram was null";
207 private static final double DEFAULT_POSITION_X = 10.0;
208 private static final double DEFAULT_POSITION_Y = 10.0;
209 private static final double DEFAULT_WIDTH = 40.0;
210 private static final double DEFAULT_HEIGHT = 40.0;
212 private static final PropertyChangeListener STYLE_UPDATER = new UpdateStyleFromInterfunction();
213 private static final Logger LOG = Logger.getLogger(BasicBlock.class.getName());
216 * Sort the children list in place.
218 * The sort put inputs then outputs the control then command ports. The
219 * local port order is preserved.The sort is performed in place and do not
224 * the children to sort
226 public static final void sort(List<?> children) {
227 final List<Object> reference = new ArrayList<Object>(children);
229 Collections.sort(children, new Comparator<Object>() {
231 public int compare(Object o1, Object o2) {
232 // diff is the major sorting by kind
233 int diff = compareByChildClass(o1, o2);
235 if (o1 instanceof BasicPort && o2 instanceof BasicPort) {
236 // first sort with the port list index
237 final int diffIndexOf = Integer.signum(reference.indexOf(o1) - reference.indexOf(o2));
238 // then sort with the ordering value
239 final int diffOrdering = Integer.signum(((BasicPort) o1).getOrdering() - ((BasicPort) o2).getOrdering());
240 // then sort with the port position value
241 final mxGeometry o1Geom = ((BasicPort) o1).getGeometry();
242 final mxGeometry o2Geom = ((BasicPort) o2).getGeometry();
243 final int diffPosition = Integer.signum((int) (o2Geom.getX() - o1Geom.getX() - o2Geom.getY() + o1Geom.getY()));
245 // voting is performed with these equivalent 3 selector
246 diff = diff + diffIndexOf + diffOrdering + diffPosition;
255 * Internal method to get a base index to compare with depending on the cell
260 * @return the base index
262 private static final int compareByChildClass(final Object o1, final Object o2) {
266 for (int i = 0; i < sortedChildrenClass.length; i++) {
267 final Class<?> klass = sortedChildrenClass[i];
269 if (klass.isInstance(o1)) {
274 for (int i = 0; i < sortedChildrenClass.length; i++) {
275 final Class<?> klass = sortedChildrenClass[i];
277 if (klass.isInstance(o2)) {
283 final int base = o1Index - o2Index;
284 return base * (Integer.MAX_VALUE / sortedChildrenClass.length);
288 * Manage events for block parameters.
290 * The property name is the field name, is one of:
292 * <li>"interfaceFunctionName"
293 * <li>"simulationFunctionName"
294 * <li>"simulationFunctionType"
296 * <li>"realParameters"
297 * <li>"integerParameters"
298 * <li>"objectsParameters"
299 * <li>"nbZerosCrossing"
311 * you can easily access to then by using property name constants.
313 private PropertyChangeSupport parametersPCS = new PropertyChangeSupport(this);
315 private String interfaceFunctionName = DEFAULT_INTERFACE_FUNCTION;
316 private String simulationFunctionName = DEFAULT_SIMULATION_FUNCTION;
317 private SimulationFunctionType simulationFunctionType = SimulationFunctionType.DEFAULT;
318 private transient XcosDiagram parentDiagram;
321 private boolean isFlipped;
322 private boolean isMirrored;
324 // TODO : Must make this types evolve, but for now keep a strong link to
327 // exprs = [] ; rpar = [] ; ipar = [] ; opar = list()
329 // private List<String> exprs = new ArrayList<String>();
330 private ScilabType exprs;
331 // private List<Double> realParameters = new ArrayList<Double>();
332 private ScilabType realParameters;
334 * Update status on the rpar mlist, if true then a re-encode has to be performed on the getter.
336 protected boolean hasAValidRpar = false;
337 // private List<Integer> integerParameters = new ArrayList<Integer>();
338 private ScilabType integerParameters;
339 // private List objectsParameters = new ArrayList();
340 private ScilabType objectsParameters;
342 private ScilabType nbZerosCrossing = new ScilabDouble();
344 private ScilabType nmode = new ScilabDouble();
346 private ScilabType state = new ScilabDouble();
347 private ScilabType dState = new ScilabDouble();
348 private ScilabType oDState = new ScilabDouble();
350 private ScilabType equations;
352 private boolean dependsOnU;
353 private boolean dependsOnT;
355 private String blockType = "c";
357 private int ordering;
358 private boolean locked;
361 * Represent a simulation function type compatible with Scilab/Scicos
362 * function type descriptors.
364 public static enum SimulationFunctionType {
365 /** event select; reduced at compilation */
367 /** if then else; reduced at compilation */
369 /** first common block */
371 /** first native block */
373 /** second native block */
375 /** third native block */
377 /** forth native block */
383 /** dynamic {@link #TYPE_1} Fortran blocks (fortran_block.sci) */
384 DYNAMIC_FORTRAN_1(1001.0),
385 /** dynamic {@link #TYPE_1} C blocks (c_block.sci) */
387 /** Explicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
388 DYNAMIC_EXPLICIT_4(2004.0),
389 /** Implicit {@link #TYPE_1} Fortran blocks (DIFF_f.sci) */
391 /** Implicit {@link #C_OR_FORTRAN} blocks */
392 IMPLICIT_C_OR_FORTRAN(10004.0),
393 /** Implicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
394 DYNAMIC_IMPLICIT_4(12004.0),
395 /** Modelica {@link #C_OR_FORTRAN} blocks */
400 private double value;
403 * Default constructor
406 * Scilab/Scicos function type descriptor
408 private SimulationFunctionType(double scilabValue) {
413 * Get the Java descriptor from the Scilab descriptor.
416 * Scilab/Scicos function type descriptor
417 * @return The corresponding java descriptor
419 public static SimulationFunctionType convertScilabValue(int scilabValue) {
420 for (SimulationFunctionType iter : SimulationFunctionType.values()) {
421 if (iter.getAsDouble() == scilabValue) {
429 * Get the Scilab Descriptor from the Java Descriptor
431 * @return The corresponding Scilab/Scicos descriptor
433 public double getAsDouble() {
439 * Update the source block when the interfunction change.
441 private static final class UpdateStyleFromInterfunction implements PropertyChangeListener, Serializable {
444 * Default constructor.
446 public UpdateStyleFromInterfunction() {
450 * Update the label on interfunction change.
453 * the property change event.
454 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
457 public void propertyChange(PropertyChangeEvent evt) {
458 final BasicBlock source = (BasicBlock) evt.getSource();
461 * Put the interfunction at the start of the style map to preserve
462 * style modification.
464 * oldStyle="SUPER_f;fillColor=red" newStyle="DSUPER;fillColor=red"
466 * and not newStyle="fillColor=red;DSUPER"
468 final StyleMap style = new StyleMap((String) evt.getNewValue());
469 style.putAll(source.getStyle());
470 style.remove(evt.getOldValue());
472 source.setStyle(style.toString());
478 * Trace the parameters change on the {@link Logger}.
480 * This listener is only installed if the trace is enable.
482 private static final class TraceParametersListener implements PropertyChangeListener, Serializable {
483 private static TraceParametersListener instance;
486 * Default constructor.
488 private TraceParametersListener() {
493 * @return the instance
495 public static TraceParametersListener getInstance() {
496 if (instance == null) {
497 instance = new TraceParametersListener();
507 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
510 public void propertyChange(PropertyChangeEvent evt) {
511 if (LOG.isLoggable(Level.FINEST)) {
512 LOG.finest(evt.getPropertyName() + ": " + evt.getOldValue() + ", " + evt.getNewValue());
518 * Default constructor.
520 public BasicBlock() {
526 if (getStyle().isEmpty() && !getInterfaceFunctionName().isEmpty()) {
527 setStyle(getInterfaceFunctionName());
530 parametersPCS.addPropertyChangeListener(INTERFACE_FUNCTION_NAME, STYLE_UPDATER);
533 * Trace block parameters change if applicable.
535 if (LOG.isLoggable(Level.FINEST)) {
536 parametersPCS.addPropertyChangeListener(TraceParametersListener.getInstance());
544 protected BasicBlock(String label) {
555 protected BasicBlock(String label, String style) {
561 * Initialize the block with the default values
563 protected void setDefaultValues() {
566 setConnectable(false);
567 setGeometry(new mxGeometry(DEFAULT_POSITION_X, DEFAULT_POSITION_Y, DEFAULT_WIDTH, DEFAULT_HEIGHT));
573 * @return parent diagram
575 public XcosDiagram getParentDiagram() {
576 return parentDiagram;
580 * @param parentDiagram
583 public void setParentDiagram(XcosDiagram parentDiagram) {
584 this.parentDiagram = parentDiagram;
588 * @return interface function name
590 public String getInterfaceFunctionName() {
591 return interfaceFunctionName;
595 * @param interfaceFunctionName
596 * interface function name
598 public void setInterfaceFunctionName(String interfaceFunctionName) {
599 if ((this.interfaceFunctionName == null && interfaceFunctionName != null) || !this.interfaceFunctionName.equals(interfaceFunctionName)) {
601 final String oldValue = this.interfaceFunctionName;
602 this.interfaceFunctionName = interfaceFunctionName;
603 parametersPCS.firePropertyChange(INTERFACE_FUNCTION_NAME, oldValue, interfaceFunctionName);
608 * @param simulationFunctionName
609 * sumulation function name
611 public void setSimulationFunctionName(String simulationFunctionName) {
612 if ((this.simulationFunctionName == null && simulationFunctionName != null) || !this.simulationFunctionName.equals(simulationFunctionName)) {
614 final String oldValue = this.simulationFunctionName;
615 this.simulationFunctionName = simulationFunctionName;
616 parametersPCS.firePropertyChange(SIMULATION_FUNCTION_NAME, oldValue, simulationFunctionName);
621 * @return sumulation function name
623 public String getSimulationFunctionName() {
624 return simulationFunctionName;
629 * simulation function type
631 public void setSimulationFunctionType(int scilabValue) {
632 SimulationFunctionType simFunctionType = SimulationFunctionType.convertScilabValue(scilabValue);
633 setSimulationFunctionType(simFunctionType);
637 * @param simulationFunctionType
638 * simulation function type
640 public void setSimulationFunctionType(SimulationFunctionType simulationFunctionType) {
641 if ((this.simulationFunctionType == null && simulationFunctionType != null) || !this.simulationFunctionType.equals(simulationFunctionType)) {
643 final SimulationFunctionType oldValue = this.simulationFunctionType;
644 this.simulationFunctionType = simulationFunctionType;
645 parametersPCS.firePropertyChange(SIMULATION_FUNCTION_TYPE, oldValue, simulationFunctionType);
650 * @return simulation function type
652 public SimulationFunctionType getSimulationFunctionType() {
653 return simulationFunctionType;
657 * @return real parameter ( rpar )
659 public ScilabType getRealParameters() {
660 if (!hasAValidRpar && realParameters instanceof ScilabMList) {
662 final DiagramElement elem = new DiagramElement();
663 final XcosDiagram d = elem.decode(realParameters, new XcosDiagram(false));
664 realParameters = elem.encode(d, null);
665 } catch (ScicosFormatException e) {
666 // do nothing on error (no assignation)
670 return realParameters;
674 * @param realParameters
675 * reaL parameter ( rpar )
677 public void setRealParameters(ScilabType realParameters) {
678 if ((this.realParameters == null && realParameters != null) || !this.realParameters.equals(realParameters)) {
680 final ScilabType oldValue = this.realParameters;
681 this.realParameters = realParameters;
682 parametersPCS.firePropertyChange(REAL_PARAMETERS, oldValue, realParameters);
687 * Invalide the rpar, a new child diagram encoding will be performed on
690 public void invalidateRpar() {
691 hasAValidRpar = false;
695 * @return integer parameter ( ipar )
697 public ScilabType getIntegerParameters() {
698 return integerParameters;
702 * @param integerParameters
703 * integer parameter ( ipar )
705 public void setIntegerParameters(ScilabType integerParameters) {
706 if ((this.integerParameters == null && integerParameters != null) || !this.integerParameters.equals(integerParameters)) {
708 final ScilabType oldValue = this.integerParameters;
709 this.integerParameters = integerParameters;
710 parametersPCS.firePropertyChange(INTEGER_PARAMETERS, oldValue, integerParameters);
715 * @return object parameter ( opar )
717 public ScilabType getObjectsParameters() {
718 return objectsParameters;
722 * @param objectsParameters
723 * object parameter ( opar )
725 public void setObjectsParameters(ScilabType objectsParameters) {
726 if ((this.objectsParameters == null && objectsParameters != null) || !this.objectsParameters.equals(objectsParameters)) {
728 final ScilabType oldValue = this.objectsParameters;
729 this.objectsParameters = objectsParameters;
730 parametersPCS.firePropertyChange(OBJECTS_PARAMETERS, oldValue, objectsParameters);
738 public void setDependsOnU(boolean dependsOnU) {
739 if (this.dependsOnU != dependsOnU) {
741 final boolean oldValue = this.dependsOnU;
742 this.dependsOnU = dependsOnU;
743 parametersPCS.firePropertyChange(DEPENDS_ON_U, oldValue, dependsOnU);
750 public boolean isDependsOnU() {
758 public void setDependsOnT(boolean dependsOnT) {
759 if (this.dependsOnT != dependsOnT) {
761 final boolean oldValue = this.dependsOnT;
762 this.dependsOnT = dependsOnT;
763 parametersPCS.firePropertyChange(DEPENDS_ON_T, oldValue, dependsOnT);
770 public boolean isDependsOnT() {
778 public void setBlockType(String blockType) {
779 if ((this.blockType == null && blockType != null) || !this.blockType.equals(blockType)) {
781 final String oldValue = this.blockType;
782 this.blockType = blockType;
783 parametersPCS.firePropertyChange(BLOCK_TYPE, oldValue, blockType);
790 public String getBlockType() {
798 public void setOrdering(int ordering) {
799 if (this.ordering != ordering) {
801 final int oldValue = this.ordering;
802 this.ordering = ordering;
803 parametersPCS.firePropertyChange(ORDERING, oldValue, ordering);
808 * @return order value
810 public int getOrdering() {
818 public void setExprs(ScilabType exprs) {
819 if ((this.exprs == null && exprs != null) || !this.exprs.equals(exprs)) {
821 final ScilabType oldValue = this.exprs;
823 parametersPCS.firePropertyChange(EXPRS, oldValue, exprs);
830 public ScilabType getExprs() {
835 * @return the expression as an object array
837 public Object[] getExprsFormat() {
838 // evaluate emptiness
839 if (getExprs() == null || getExprs().isEmpty() || getExprs().getHeight() == 0 || getExprs().getWidth() == 0) {
840 return new String[0];
843 List<String[]> stack = getString(null, getExprs());
846 for (Object[] strings : stack) {
847 len += strings.length;
850 final Object[] array = new Object[len];
852 for (Object[] strings : stack) {
853 System.arraycopy(strings, 0, array, start, strings.length);
854 start += strings.length;
861 * Append the data recursively to the stack
863 * @param currentStack
869 private List<String[]> getString(List<String[]> currentStack, ScilabType data) {
870 final List<String[]> stack;
872 if (currentStack == null) {
873 stack = new LinkedList<String[]>();
875 stack = currentStack;
878 if (data instanceof List) {
880 * Container case (ScilabList, ScilabMList, ScilabTList)
883 @SuppressWarnings("unchecked")
884 final List<ScilabType> list = (List<ScilabType>) data;
886 for (final ScilabType scilabType : list) {
887 getString(stack, scilabType);
889 } else if (data instanceof ScilabString) {
891 * native case (only ScilabString supported)
894 final String[][] scilabData = ((ScilabString) data).getData();
895 final int height = data.getHeight();
896 final int width = data.getWidth();
898 final String[] array = new String[height * width];
899 for (int i = 0; i < height; ++i) {
900 System.arraycopy(scilabData[i], 0, array, i * width, width);
910 * @return zero crossing value
912 public ScilabType getNbZerosCrossing() {
913 return nbZerosCrossing;
917 * @param nbZerosCrossing
918 * zero crossing value
920 public void setNbZerosCrossing(ScilabType nbZerosCrossing) {
921 if ((this.nbZerosCrossing == null && nbZerosCrossing != null) || !this.nbZerosCrossing.equals(nbZerosCrossing)) {
923 final ScilabType oldValue = this.nbZerosCrossing;
924 this.nbZerosCrossing = nbZerosCrossing;
925 parametersPCS.firePropertyChange(NB_ZEROS_CROSSING, oldValue, nbZerosCrossing);
932 public ScilabType getNmode() {
940 public void setNmode(ScilabType nmode) {
941 if ((this.nmode == null && nmode != null) || !this.nmode.equals(nmode)) {
943 final ScilabType oldValue = this.nmode;
945 parametersPCS.firePropertyChange(NMODE, oldValue, nmode);
950 * @return current state
952 public ScilabType getState() {
960 public void setState(ScilabType state) {
961 if ((this.state == null && state != null) || !this.state.equals(state)) {
963 final ScilabType oldValue = this.state;
965 parametersPCS.firePropertyChange(STATE, oldValue, state);
970 * @return current dstate
972 public ScilabType getDState() {
980 public void setDState(ScilabType dState) {
981 if ((this.dState == null && dState != null) || !this.dState.equals(dState)) {
983 final ScilabType oldValue = this.dState;
984 this.dState = dState;
985 parametersPCS.firePropertyChange(D_STATE, oldValue, dState);
990 * @return current ostate
992 public ScilabType getODState() {
1000 public void setODState(ScilabType oDState) {
1001 if ((this.oDState == null && oDState != null) || !this.oDState.equals(oDState)) {
1003 final ScilabType oldValue = this.oDState;
1004 this.oDState = oDState;
1005 parametersPCS.firePropertyChange(O_D_STATE, oldValue, oDState);
1012 public ScilabType getEquations() {
1020 public void setEquations(ScilabType equations) {
1021 if ((this.equations == null && equations != null) || !this.equations.equals(equations)) {
1023 final ScilabType oldValue = this.equations;
1024 this.equations = equations;
1025 parametersPCS.firePropertyChange(EQUATIONS, oldValue, equations);
1030 * @return locked status
1032 public synchronized boolean isLocked() {
1038 * change locked status
1040 public synchronized void setLocked(boolean locked) {
1041 this.locked = locked;
1048 public void removePort(BasicPort port) {
1049 if (port.getEdgeCount() != 0 && getParentDiagram() != null) {
1050 getParentDiagram().removeCells(new Object[] { port.getEdgeAt(0) });
1056 * Add a port on the block.
1058 * This call should only be used when a port reordering operation must be
1062 * The port to be added to the block
1064 public void addPort(BasicPort port) {
1066 port.setOrdering(BasicBlockInfo.getAllTypedPorts(this, false, port.getClass()).size());
1067 BlockPositioning.updateBlockView(this);
1071 * @return command ports initial state
1073 public ScilabDouble getAllCommandPortsInitialStates() {
1074 final List<CommandPort> cmdPorts = BasicBlockInfo.getAllTypedPorts(this, false, CommandPort.class);
1075 if (cmdPorts.isEmpty()) {
1076 return new ScilabDouble();
1079 double[][] data = new double[cmdPorts.size()][1];
1080 for (int i = 0; i < cmdPorts.size(); ++i) {
1081 data[i][0] = cmdPorts.get(i).getInitialState();
1084 return new ScilabDouble(data);
1088 * @return name and type of the simulation function
1090 public ScilabType getSimulationFunctionNameAndType() {
1091 if (getSimulationFunctionType() == SimulationFunctionType.DEFAULT) {
1092 return new ScilabString(getSimulationFunctionName());
1094 ScilabList data = new ScilabList();
1096 data.add(new ScilabString(getSimulationFunctionName()));
1097 data.add(new ScilabDouble(getSimulationFunctionType().getAsDouble()));
1103 * Does the block update and register on the undo manager
1105 * @param modifiedBlock
1108 public void updateBlockSettings(BasicBlock modifiedBlock) {
1109 if (modifiedBlock == null) {
1114 * Update the block settings
1116 updateFields(modifiedBlock);
1119 * Update the children ports
1121 updateChildren(modifiedBlock);
1124 * If the block is in a superblock then update it.
1126 if (getParentDiagram() instanceof SuperBlockDiagram) {
1127 SuperBlock block = ((SuperBlockDiagram) getParentDiagram()).getContainer();
1129 XcosDiagram graph = block.getParentDiagram();
1130 if (graph == null) {
1131 setParentDiagram(Xcos.findParent(block));
1132 graph = block.getParentDiagram();
1133 LOG.finest(PARENT_DIAGRAM_WAS_NULL);
1136 graph.fireEvent(new mxEventObject(XcosEvent.SUPER_BLOCK_UPDATED, XcosConstants.EVENT_BLOCK_UPDATED, block));
1141 * Update the instance field.
1143 * @param modifiedBlock
1144 * the modified instance
1146 private void updateFields(BasicBlock modifiedBlock) {
1147 if (modifiedBlock == null) {
1151 setDependsOnT(modifiedBlock.isDependsOnT());
1152 setDependsOnU(modifiedBlock.isDependsOnU());
1153 setExprs(modifiedBlock.getExprs());
1155 setRealParameters(modifiedBlock.getRealParameters());
1156 setIntegerParameters(modifiedBlock.getIntegerParameters());
1157 setObjectsParameters(modifiedBlock.getObjectsParameters());
1159 setState(modifiedBlock.getState());
1160 setDState(modifiedBlock.getDState());
1161 setODState(modifiedBlock.getODState());
1163 setBlockType(modifiedBlock.getBlockType());
1164 setSimulationFunctionName(modifiedBlock.getSimulationFunctionName());
1165 setSimulationFunctionType(modifiedBlock.getSimulationFunctionType());
1167 setNbZerosCrossing(modifiedBlock.getNbZerosCrossing());
1168 setNmode(modifiedBlock.getNmode());
1170 setEquations(modifiedBlock.getEquations());
1171 setStyle(modifiedBlock.getStyle());
1175 * Update the children of the block.
1177 * @param modifiedBlock
1178 * the new block instance
1180 private void updateChildren(BasicBlock modifiedBlock) {
1181 if (modifiedBlock == null) {
1185 XcosDiagram graph = getParentDiagram();
1186 if (graph == null) {
1187 setParentDiagram(Xcos.findParent(this));
1188 graph = getParentDiagram();
1189 LOG.finest(PARENT_DIAGRAM_WAS_NULL);
1193 * Checked as port classes only
1195 @SuppressWarnings("unchecked")
1196 Set < Class <? extends mxICell >> types = new HashSet < Class <? extends mxICell >> (Arrays.asList(InputPort.class, OutputPort.class, ControlPort.class,
1197 CommandPort.class));
1199 Map < Class <? extends mxICell > , Deque<mxICell >> annotatedOlds = getTypedChildren(types);
1200 Map < Class <? extends mxICell > , Deque<mxICell >> annotatedNews = modifiedBlock.getTypedChildren(types);
1202 getParentDiagram().getModel().beginUpdate();
1204 for (Class <? extends mxICell > klass : types) {
1205 final Deque<mxICell> olds = annotatedOlds.get(klass);
1206 final Deque<mxICell> news = annotatedNews.get(klass);
1209 while (!olds.isEmpty() && !news.isEmpty()) {
1210 mxICell previous = olds.poll();
1211 mxICell modified = news.poll();
1213 final int previousIndex = children.indexOf(previous);
1216 if (previous.getEdgeCount() != 0) {
1217 final mxICell edge = previous.getEdgeAt(0);
1218 final boolean isOutgoing = previous == edge.getTerminal(true);
1219 previous.removeEdge(edge, isOutgoing);
1220 modified.insertEdge(edge, isOutgoing);
1223 getParentDiagram().removeCells(new Object[] { previous }, false);
1224 getParentDiagram().addCells(new Object[] { modified }, this, previousIndex);
1226 // Clone the geometry to avoid empty geometry on new cells.
1227 getParentDiagram().getModel().setGeometry(modified, (mxGeometry) previous.getGeometry().clone());
1232 if (!olds.isEmpty()) {
1233 getParentDiagram().removeCells(olds.toArray(), true);
1237 if (!news.isEmpty()) {
1238 getParentDiagram().addCells(news.toArray(), this);
1242 getParentDiagram().getModel().endUpdate();
1247 * Format the children as a typed map for the given class set.
1250 * the classes to search for.
1251 * @return a map which linked foreach type the corresponding cell list.
1253 private Map < Class <? extends mxICell > , Deque<mxICell >> getTypedChildren(Set < Class <? extends mxICell >> types) {
1254 Map < Class <? extends mxICell > , Deque<mxICell >> oldPorts = new HashMap < Class <? extends mxICell > , Deque<mxICell >> ();
1256 // Allocate all types set
1257 for (Class <? extends mxICell > type : types) {
1258 oldPorts.put(type, new LinkedList<mxICell>());
1261 if (getChildCount() <= 0) {
1265 // sort children according to the ordering parameter (useful on
1266 // scilab-5.2.x diagrams)
1270 for (Object cell : children) {
1272 Class <? extends Object > klass = cell.getClass();
1273 while (klass != null) {
1274 if (types.contains(klass)) {
1277 klass = klass.getSuperclass();
1280 final Deque<mxICell> current = oldPorts.get(klass);
1281 if (current != null) {
1282 current.add((mxICell) cell);
1290 * Sort the children list in place.
1292 * The sort put inputs then outputs the control then command ports. The
1293 * local port order is preserved.The sort is performed in place and do not
1296 public void sortChildren() {
1297 if (getChildCount() <= 0) {
1306 * parent diagram context
1308 public void openBlockSettings(String[] context) {
1309 final XcosDiagram graph;
1310 if (getParentDiagram() == null) {
1311 setParentDiagram(Xcos.findParent(this));
1312 graph = getParentDiagram();
1313 LOG.finest(PARENT_DIAGRAM_WAS_NULL);
1315 graph = getParentDiagram();
1317 if (graph instanceof PaletteDiagram) {
1321 if (context == null) {
1322 throw new IllegalArgumentException();
1325 // prevent to open twice
1330 // sort children according to the ordering parameter (useful on
1331 // scilab-5.2.x diagrams)
1334 final ScilabDirectHandler handler = ScilabDirectHandler.acquire();
1335 if (handler == null) {
1341 handler.writeBlock(this);
1343 handler.writeContext(context);
1345 final ActionListener action = new ActionListener() {
1347 public void actionPerformed(ActionEvent e) {
1348 LOG.finest("Updating data.");
1350 graph.getView().clear(this, true, true);
1352 // Now read new Block
1353 graph.getModel().beginUpdate();
1355 final BasicBlock modifiedBlock = handler.readBlock();
1356 updateBlockSettings(modifiedBlock);
1358 graph.fireEvent(new mxEventObject(XcosEvent.ADD_PORTS, XcosConstants.EVENT_BLOCK_UPDATED, BasicBlock.this));
1359 } catch (ScicosFormatException ex) {
1360 LOG.severe(ex.toString());
1362 graph.getModel().endUpdate();
1371 ScilabInterpreterManagement.asynchronousScilabExec(action, "blk = xcosBlockInterface", getInterfaceFunctionName().toCharArray(), "set",
1372 ScilabDirectHandler.BLK.toCharArray(), ScilabDirectHandler.CONTEXT.toCharArray());
1373 } catch (InterpreterException e) {
1374 LOG.severe(e.toString());
1382 * @return tooltip text
1384 public String getToolTipText() {
1385 StringBuilder result = new StringBuilder();
1386 result.append(ScilabGraphConstants.HTML_BEGIN);
1387 result.append("Block Name : " + getInterfaceFunctionName() + ScilabGraphConstants.HTML_NEWLINE);
1388 result.append("Simulation : " + getSimulationFunctionName() + ScilabGraphConstants.HTML_NEWLINE);
1390 if (getParentDiagram() instanceof PaletteDiagram) {
1391 if (getIntegerParameters() != null) {
1392 result.append("Integer parameters : " + getIntegerParameters() + ScilabGraphConstants.HTML_NEWLINE);
1395 if (getRealParameters() != null && getRealParameters().getHeight() != 0 && getRealParameters().getWidth() != 0) {
1396 result.append("Real parameters : " + getRealParameters() + ScilabGraphConstants.HTML_NEWLINE);
1399 if (getObjectsParameters() != null) {
1400 result.append("Object parameters : " + getObjectsParameters() + ScilabGraphConstants.HTML_NEWLINE);
1403 result.append("UID : " + getId() + ScilabGraphConstants.HTML_NEWLINE);
1404 final int length = getStyle().length();
1405 result.append("Style : ");
1406 if (length > XcosConstants.MAX_CHAR_IN_STYLE) {
1407 result.append(getStyle().substring(0, XcosConstants.MAX_CHAR_IN_STYLE));
1408 result.append(XcosMessages.DOTS);
1410 result.append(getStyle());
1412 result.append(ScilabGraphConstants.HTML_NEWLINE);
1413 result.append("Flip : " + getFlip() + ScilabGraphConstants.HTML_NEWLINE);
1414 result.append("Mirror : " + getMirror() + ScilabGraphConstants.HTML_NEWLINE);
1415 result.append("Input ports : " + BasicBlockInfo.getAllTypedPorts(this, false, InputPort.class).size() + ScilabGraphConstants.HTML_NEWLINE);
1416 result.append("Output ports : " + BasicBlockInfo.getAllTypedPorts(this, false, OutputPort.class).size() + ScilabGraphConstants.HTML_NEWLINE);
1417 result.append("Control ports : " + BasicBlockInfo.getAllTypedPorts(this, false, ControlPort.class).size() + ScilabGraphConstants.HTML_NEWLINE);
1418 result.append("Command ports : " + BasicBlockInfo.getAllTypedPorts(this, false, CommandPort.class).size() + ScilabGraphConstants.HTML_NEWLINE);
1421 result.append("x : " + getGeometry().getX() + ScilabGraphConstants.HTML_NEWLINE);
1422 result.append("y : " + getGeometry().getY() + ScilabGraphConstants.HTML_NEWLINE);
1423 result.append("w : " + getGeometry().getWidth() + ScilabGraphConstants.HTML_NEWLINE);
1424 result.append("h : " + getGeometry().getHeight() + ScilabGraphConstants.HTML_NEWLINE);
1425 result.append(ScilabGraphConstants.HTML_END);
1426 return result.toString();
1433 public void openContextMenu(ScilabGraph graph) {
1434 ContextMenu menu = null;
1435 if (getParentDiagram() instanceof PaletteDiagram) {
1436 menu = createPaletteContextMenu(graph);
1438 menu = createContextMenu(graph);
1440 menu.setVisible(true);
1446 * @return context menu
1449 public ContextMenu createPaletteContextMenu(ScilabGraph graph) {
1450 ContextMenu menu = ScilabContextMenu.createContextMenu();
1452 final List<XcosDiagram> allDiagrams = Xcos.getInstance().openedDiagrams();
1454 if (allDiagrams.size() == 0) {
1455 // No diagram opened: should never happen if Xcos opens an empty
1456 // diagram when it is launched
1457 MenuItem addTo = ScilabMenuItem.createMenuItem();
1459 addTo.setText(XcosMessages.ADDTO_NEW_DIAGRAM);
1460 addTo.setCallback(new CommonCallBack(XcosMessages.ADDTO_NEW_DIAGRAM) {
1462 public void callBack() {
1464 XcosDiagram theDiagram = new XcosDiagram();
1465 BasicBlock block = (BasicBlock) BlockFactory.createClone(BasicBlock.this);
1466 theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
1467 mxGeometry geom = BasicBlock.this.getGeometry();
1468 setDefaultPosition(geom);
1469 theDiagram.getModel().setGeometry(block, geom);
1471 XcosTab.get(theDiagram).setVisible(true);
1472 BlockPositioning.updateBlockView(block);
1478 } else if (allDiagrams.size() == 1) {
1479 // A single diagram opened: add to this diagram
1480 MenuItem addTo = ScilabMenuItem.createMenuItem();
1482 addTo.setText(XcosMessages.ADDTO + " " + XcosTab.get(allDiagrams.get(0)).getName());
1483 final XcosDiagram theDiagram = allDiagrams.get(0);
1484 addTo.setCallback(new CommonCallBack(theDiagram.getTitle()) {
1485 private static final long serialVersionUID = -99601763227525686L;
1488 public void callBack() {
1489 BasicBlock block = (BasicBlock) BlockFactory.createClone(BasicBlock.this);
1490 theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
1491 mxGeometry geom = BasicBlock.this.getGeometry();
1492 setDefaultPosition(geom);
1493 theDiagram.getModel().setGeometry(block, geom);
1494 BlockPositioning.updateBlockView(block);
1495 block.setParentDiagram(theDiagram);
1502 // The user has to choose
1503 Menu addTo = ScilabMenu.createMenu();
1505 addTo.setText(XcosMessages.ADDTO);
1507 for (int i = 0; i < allDiagrams.size(); i++) {
1508 MenuItem diagram = ScilabMenuItem.createMenuItem();
1509 final XcosDiagram theDiagram = allDiagrams.get(i);
1510 diagram.setText(XcosTab.get(allDiagrams.get(i)).getName());
1511 diagram.setCallback(new CommonCallBack(theDiagram.getTitle()) {
1512 private static final long serialVersionUID = 3345416658377835057L;
1515 public void callBack() {
1516 BasicBlock block = (BasicBlock) BlockFactory.createClone(BasicBlock.this);
1517 theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
1518 mxGeometry geom = BasicBlock.this.getGeometry();
1519 setDefaultPosition(geom);
1520 theDiagram.getModel().setGeometry(block, geom);
1521 BlockPositioning.updateBlockView(block);
1530 menu.getAsSimpleContextMenu().addSeparator();
1532 MenuItem help = ScilabMenuItem.createMenuItem();
1533 help.setText(XcosMessages.BLOCK_DOCUMENTATION);
1534 help.setCallback(new CommonCallBack(XcosMessages.BLOCK_DOCUMENTATION) {
1535 private static final long serialVersionUID = -1480947262397441951L;
1538 public void callBack() {
1539 InterpreterManagement.requestScilabExec("help " + getInterfaceFunctionName());
1544 menu.setVisible(true);
1546 ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo()
1557 * @return context menu
1560 public ContextMenu createContextMenu(ScilabGraph graph) {
1561 ContextMenu menu = ScilabContextMenu.createContextMenu();
1562 Map < Class <? extends DefaultAction > , Menu > menuList = new HashMap < Class <? extends DefaultAction > , Menu > ();
1564 MenuItem value = BlockParametersAction.createMenu(graph);
1565 menuList.put(BlockParametersAction.class, value);
1568 menu.getAsSimpleContextMenu().addSeparator();
1570 value = CutAction.cutMenu(graph);
1571 menuList.put(CutAction.class, value);
1573 value = CopyAction.copyMenu(graph);
1574 menuList.put(CopyAction.class, value);
1576 value = DeleteAction.createMenu(graph);
1577 menuList.put(DeleteAction.class, value);
1580 menu.getAsSimpleContextMenu().addSeparator();
1582 value = RegionToSuperblockAction.createMenu(graph);
1583 menuList.put(RegionToSuperblockAction.class, value);
1586 menu.getAsSimpleContextMenu().addSeparator();
1588 Menu format = ScilabMenu.createMenu();
1589 format.setText(XcosMessages.FORMAT);
1591 value = RotateAction.createMenu(graph);
1592 menuList.put(RotateAction.class, value);
1594 value = MirrorAction.createMenu(graph);
1595 menuList.put(MirrorAction.class, value);
1597 value = FlipAction.createMenu(graph);
1598 menuList.put(FlipAction.class, value);
1600 value = ShowHideShadowAction.createMenu(graph);
1601 menuList.put(ShowHideShadowAction.class, value);
1604 format.addSeparator();
1606 Menu alignMenu = ScilabMenu.createMenu();
1607 alignMenu.setText(XcosMessages.ALIGN_BLOCKS);
1608 alignMenu.add(AlignBlockActionLeft.createMenu(graph));
1609 alignMenu.add(AlignBlockActionCenter.createMenu(graph));
1610 alignMenu.add(AlignBlockActionRight.createMenu(graph));
1611 alignMenu.addSeparator();
1612 alignMenu.add(AlignBlockActionTop.createMenu(graph));
1613 alignMenu.add(AlignBlockActionMiddle.createMenu(graph));
1614 alignMenu.add(AlignBlockActionBottom.createMenu(graph));
1615 menuList.put(AlignBlockAction.class, alignMenu);
1616 format.add(alignMenu);
1618 format.addSeparator();
1620 if (graph.getSelectionCells().length > 1) {
1621 format.add(BorderColorAction.createMenu(graph));
1622 format.add(FilledColorAction.createMenu(graph));
1624 format.add(EditFormatAction.createMenu(graph));
1627 menu.getAsSimpleContextMenu().addSeparator();
1629 menu.add(ViewDetailsAction.createMenu(graph));
1631 menu.getAsSimpleContextMenu().addSeparator();
1633 menu.add(BlockDocumentationAction.createMenu(graph));
1635 ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo()
1638 customizeMenu(menuList);
1649 public void setFlip(boolean flip) {
1651 if (getParentDiagram() != null) {
1652 final mxIGraphModel model = getParentDiagram().getModel();
1653 mxUtils.setCellStyles(model, new Object[] { this }, ScilabGraphConstants.STYLE_FLIP, Boolean.toString(flip));
1658 * Override this to customize contextual menu
1663 protected void customizeMenu(Map < Class <? extends DefaultAction > , Menu > menuList) {
1664 // To be overridden by sub-classes
1668 * @return mirror value
1670 public boolean getMirror() {
1678 public void setMirror(boolean mirror) {
1679 isMirrored = mirror;
1680 if (getParentDiagram() != null) {
1681 final mxIGraphModel model = getParentDiagram().getModel();
1682 mxUtils.setCellStyles(model, new Object[] { this }, ScilabGraphConstants.STYLE_MIRROR, Boolean.toString(mirror));
1687 * @return flip status
1689 public boolean getFlip() {
1694 * invert flip status
1696 public void toggleFlip() {
1697 BlockPositioning.toggleFlip(this);
1701 * invert mirror value
1703 public void toggleMirror() {
1704 BlockPositioning.toggleMirror(this);
1710 public void toggleAntiClockwiseRotation() {
1711 BlockPositioning.toggleAntiClockwiseRotation(this);
1716 * @return current angle
1718 public int getAngle() {
1726 public void setAngle(int angle) {
1729 if (getParentDiagram() != null) {
1730 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] { this }, mxConstants.STYLE_ROTATION, Integer.toString(angle));
1735 * Useful when we need to update local properties with mxCell style
1738 public void updateFieldsFromStyle() {
1739 StyleMap map = new StyleMap(getStyle());
1741 if (map.get(mxConstants.STYLE_ROTATION) != null) {
1742 angle = Integer.parseInt(map.get(mxConstants.STYLE_ROTATION));
1747 isFlipped = Boolean.parseBoolean(map.get(ScilabGraphConstants.STYLE_FLIP));
1748 isMirrored = Boolean.parseBoolean(map.get(ScilabGraphConstants.STYLE_MIRROR));
1752 * Set the default block position on the geom
1757 private void setDefaultPosition(mxGeometry geom) {
1758 geom.setX(DEFAULT_POSITION_X);
1759 geom.setY(DEFAULT_POSITION_Y);
1763 * Get the parameters change support.
1765 * The property name for each event is the field name, so one of: -
1766 * "interfaceFunctionName" - "simulationFunctionName" -
1767 * "simulationFunctionType" - "exprs" - "realParameters" -
1768 * "integerParameters" - "objectsParameters" - "nbZerosCrossing" - "nmode" -
1769 * "state" - "dState" - "oDState" - "equations" - "dependsOnU" -
1770 * "dependsOnT" - "blockType" - "ordering"
1772 * @return the associated {@link PropertyChangeSupport} instance
1774 protected PropertyChangeSupport getParametersPCS() {
1775 return parametersPCS;
1779 * Overriden methods from jgraphx
1783 * @return always false
1784 * @see com.mxgraph.model.mxCell#isConnectable()
1787 public boolean isConnectable() {
1792 * Re-associate fields with the new instance.
1794 * @return a new clone instance
1795 * @throws CloneNotSupportedException
1797 * @see com.mxgraph.model.mxCell#clone()
1800 public Object clone() throws CloneNotSupportedException {
1801 BasicBlock clone = (BasicBlock) super.clone();
1803 /* Reinstall the PropertyChangeSupport and all of it listeners */
1804 clone.parametersPCS = new PropertyChangeSupport(clone);
1805 PropertyChangeSupport pcs = getParametersPCS();
1806 for (PropertyChangeListener iter : pcs.getPropertyChangeListeners()) {
1807 clone.parametersPCS.addPropertyChangeListener(iter);
1816 * Sync the specific child {@link EditFormatAction#HASH_IDENTIFIER}
1819 public mxICell insert(mxICell child, int index) {
1821 * Update the id if this is an identifier cell (herited identifier)
1823 if (child.getId().endsWith(XcosDiagram.HASH_IDENTIFIER)) {
1824 child.setId(getId() + XcosDiagram.HASH_IDENTIFIER);
1827 return super.insert(child, index);
1831 public String toString() {
1832 final StringBuilder str = new StringBuilder();
1833 str.append(getInterfaceFunctionName());
1835 for (Object c : children) {
1840 return str.toString();
1843 // CSON: ClassDataAbstractionCoupling
1844 // CSON: ClassFanOutComplexity