56955f5cce3bf95f038a3c30fe0281d8b49017d2
[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
16 import java.awt.MouseInfo;
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import ncsa.hdf.hdf5lib.exceptions.HDF5Exception;
24
25 import org.scilab.modules.action_binding.InterpreterManagement;
26 import org.scilab.modules.graph.ScilabGraph;
27 import org.scilab.modules.graph.actions.CopyAction;
28 import org.scilab.modules.graph.actions.CutAction;
29 import org.scilab.modules.graph.actions.DefaultAction;
30 import org.scilab.modules.graph.actions.DeleteAction;
31 import org.scilab.modules.gui.bridge.contextmenu.SwingScilabContextMenu;
32 import org.scilab.modules.gui.contextmenu.ContextMenu;
33 import org.scilab.modules.gui.contextmenu.ScilabContextMenu;
34 import org.scilab.modules.gui.menu.Menu;
35 import org.scilab.modules.gui.menu.ScilabMenu;
36 import org.scilab.modules.gui.menuitem.MenuItem;
37 import org.scilab.modules.hdf5.scilabTypes.ScilabDouble;
38 import org.scilab.modules.hdf5.scilabTypes.ScilabList;
39 import org.scilab.modules.hdf5.scilabTypes.ScilabString;
40 import org.scilab.modules.hdf5.scilabTypes.ScilabType;
41 import org.scilab.modules.hdf5.write.H5Write;
42 import org.scilab.modules.xcos.XcosDiagram;
43 import org.scilab.modules.xcos.XcosUIDObject;
44 import org.scilab.modules.xcos.actions.AlignBlockAction;
45 import org.scilab.modules.xcos.actions.BlockDocumentationAction;
46 import org.scilab.modules.xcos.actions.BlockParametersAction;
47 import org.scilab.modules.xcos.actions.ColorAction;
48 import org.scilab.modules.xcos.actions.FlipAction;
49 import org.scilab.modules.xcos.actions.MirrorAction;
50 import org.scilab.modules.xcos.actions.RegionToSuperblockAction;
51 import org.scilab.modules.xcos.actions.RotateAction;
52 import org.scilab.modules.xcos.actions.ShowHideShadowAction;
53 import org.scilab.modules.xcos.actions.ViewDetailsAction;
54 import org.scilab.modules.xcos.io.BasicBlockInfo;
55 import org.scilab.modules.xcos.io.BlockReader;
56 import org.scilab.modules.xcos.port.BasicPort;
57 import org.scilab.modules.xcos.port.command.CommandPort;
58 import org.scilab.modules.xcos.port.control.ControlPort;
59 import org.scilab.modules.xcos.port.input.InputPort;
60 import org.scilab.modules.xcos.port.output.OutputPort;
61 import org.scilab.modules.xcos.utils.BlockPositioning;
62 import org.scilab.modules.xcos.utils.Signal;
63 import org.scilab.modules.xcos.utils.XcosConstants;
64 import org.scilab.modules.xcos.utils.XcosEvent;
65 import org.scilab.modules.xcos.utils.XcosMessages;
66
67 import com.mxgraph.model.mxGeometry;
68 import com.mxgraph.util.mxConstants;
69 import com.mxgraph.util.mxEventObject;
70 import com.mxgraph.util.mxUtils;
71 import com.mxgraph.view.mxCellState;
72
73 public class BasicBlock extends XcosUIDObject {
74
75     private static final long serialVersionUID = 2189690915516168262L;
76     private String interfaceFunctionName = "xcos_block";
77     private String simulationFunctionName = "xcos_simulate";
78     private SimulationFunctionType simulationFunctionType = SimulationFunctionType.DEFAULT;
79     private transient XcosDiagram parentDiagram = null;
80
81     // TODO :
82     // Must make this types evolve, but for now keep a strong link to Scilab
83     // !! WARNING !!
84     // exprs = [] ; rpar = [] ; ipar = [] ; opar = list()
85
86     //private List<String> exprs = new ArrayList<String>();
87     private ScilabType exprs = null;
88     //private List<Double> realParameters = new ArrayList<Double>();
89     private ScilabType realParameters = null;
90     //private List<Integer> integerParameters = new ArrayList<Integer>();
91     private ScilabType integerParameters = null;
92     //private List objectsParameters = new ArrayList();
93     private ScilabType objectsParameters = null;
94
95     private ScilabType nbZerosCrossing = new ScilabDouble();
96
97     private ScilabType nmode = new ScilabDouble();
98
99     private ScilabType state = new ScilabDouble();
100     private ScilabType dState = new ScilabDouble();
101     private ScilabType oDState = new ScilabDouble();
102
103     private ScilabType equations = null;
104
105     private boolean dependsOnU = false;
106     private boolean dependsOnT = false;
107
108     private String blockType = "c";
109
110     private int ordering = 0;
111     private boolean locked = false;
112
113     public enum SimulationFunctionType {
114         DEFAULT,
115         TYPE_1,
116         TYPE_2,
117         TYPE_3,
118         C_OR_FORTRAN,
119         SCILAB,
120         UNKNOWN;
121
122         public static SimulationFunctionType convertScilabValue(int scilabValue) {
123             switch (scilabValue) {
124             case 0:
125                 return DEFAULT;
126             case 1:
127                 return TYPE_1;
128             case 2:
129                 return TYPE_2;
130             case 3:
131                 return TYPE_3;
132             case 4:
133                 return C_OR_FORTRAN;
134             case 5:
135                 return SCILAB;
136             default:
137                 return UNKNOWN;
138             }
139         }
140
141         public double getAsDouble() {
142             switch (this) {
143             case DEFAULT:
144                 return 0.0;
145             case TYPE_1:
146                 return 1.0;
147             case TYPE_2 :
148                 return 2.0;
149             case TYPE_3 :
150                 return 3.0;
151             case C_OR_FORTRAN:
152                 return 4.0;
153             case SCILAB:
154                 return 5.0;
155             default:
156                 return -1;
157             }
158         }
159     };
160
161     public static BasicBlock createBlock(String label) {
162         if(label.compareTo("TEXT_f") == 0) { return new TextBlock(label); }
163         if(label.compareTo("SUPER_f") == 0) { return new SuperBlock(label); }
164         if(label.compareTo("CONST_m") == 0
165                 || label.compareTo("CONST") == 0
166                 || label.compareTo("CONST_f") == 0) {
167             return new ConstBlock(label);
168         }
169         if(label.compareTo("AFFICH_m") == 0
170                 || label.compareTo("AFFICH_f") == 0) {
171             return new AfficheBlock(label); 
172         }
173         if(label.compareTo("GAINBLK_f") == 0
174                 || label.compareTo("GAINBLK") == 0
175                 || label.compareTo("GAIN_f") == 0) {
176             return new GainBlock(label);
177         }
178         if(label.compareTo("IN_f") == 0) { return new ExplicitInBlock(label); }
179         if(label.compareTo("OUT_f") == 0) { return new ExplicitOutBlock(label); }
180         if(label.compareTo("INIMPL_f") == 0) { return new ImplicitInBlock(label); }
181         if(label.compareTo("OUTIMPL_f") == 0) { return new ImplicitOutBlock(label); }
182         if(label.compareTo("CLKINV_f") == 0) { return new EventInBlock(label); }
183         if(label.compareTo("CLKOUTV_f") == 0) { return new EventOutBlock(label); }
184         if(label.compareTo("SPLIT_f") == 0 || 
185                 label.compareTo("IMPSPLIT_f") == 0 ||
186                 label.compareTo("CLKSPLIT_f") == 0) {
187             return new SplitBlock(label);
188         }
189         else { 
190                 return new BasicBlock(label); 
191         }
192     }
193
194     public BasicBlock() {
195         super();
196         setVertex(false);
197         setVisible(false);
198     }
199
200     protected BasicBlock(String label) {
201         super();
202         setValue(label);
203         setStyle("");
204         setVertex(true);
205         setConnectable(false);
206         setGeometry(new mxGeometry(0,0,40,40));
207     }
208
209     protected BasicBlock(String label, String style) {
210         super();
211         setValue(label);
212         setStyle(style);
213         setVertex(true);
214         setConnectable(false);
215         setGeometry(new mxGeometry(0,0,40,40));
216     }
217
218     public XcosDiagram getParentDiagram() {
219         return parentDiagram;
220     }
221
222     public void setParentDiagram(XcosDiagram parentDiagram) {
223         this.parentDiagram = parentDiagram;
224     }
225
226     
227     public String getInterfaceFunctionName() {
228         return interfaceFunctionName;
229     }
230
231     public void setInterfaceFunctionName(String interfaceFunctionName) {
232         this.interfaceFunctionName = interfaceFunctionName;
233     }
234
235     public void setSimulationFunctionName(String simulationFunctionName) {
236         this.simulationFunctionName = simulationFunctionName;
237     }
238
239     public String getSimulationFunctionName() {
240         return simulationFunctionName;
241     }
242
243     public void setSimulationFunctionType(int scilabValue) {
244         this.simulationFunctionType = SimulationFunctionType.convertScilabValue(scilabValue);
245     }
246
247     public void setSimulationFunctionType(SimulationFunctionType simulationFunctionType) {
248         this.simulationFunctionType = simulationFunctionType;
249     }
250
251     public SimulationFunctionType getSimulationFunctionType() {
252         return simulationFunctionType;
253     }
254
255     public ScilabType getRealParameters() {
256         return realParameters;
257     }
258
259     public void setRealParameters(ScilabType realParameters) {
260         this.realParameters = realParameters;
261     } 
262
263     public ScilabType getIntegerParameters() {
264         return integerParameters;
265     }
266
267     public void setIntegerParameters(ScilabType integerParameters) {
268         this.integerParameters = integerParameters;
269     }
270
271     public ScilabType getObjectsParameters() {
272         return objectsParameters;
273     }
274
275     public void setObjectsParameters(ScilabType objectsParameters) {
276         this.objectsParameters = objectsParameters;
277     }
278
279     public void setDependsOnU(boolean dependsOnU) {
280         this.dependsOnU = dependsOnU;
281     }
282
283     public boolean isDependsOnU() {
284         return this.dependsOnU;
285        }
286     
287     public boolean dependsOnU() {
288         return dependsOnU;
289     }
290
291     public void setDependsOnT(boolean dependsOnT) {
292         this.dependsOnT = dependsOnT;
293     }
294
295     public boolean isDependsOnT() {
296         return this.dependsOnT;
297        }
298     public boolean dependsOnT() {
299         return dependsOnT;
300     }
301
302     public void setBlockType(String blockType) {
303         this.blockType = blockType;
304     }
305
306     public String getBlockType() {
307         return blockType;
308     }
309
310     public void setOrdering(int ordering) {
311         this.ordering = ordering;
312     }
313
314     public int getOrdering() {
315         return ordering;
316     }
317
318     public void setExprs(ScilabType exprs) {
319         this.exprs = exprs;
320     }
321
322     public ScilabType getExprs() {
323         return exprs;
324     }
325
326     public ScilabType getNbZerosCrossing() {
327         return nbZerosCrossing;
328     }
329
330     public void setNbZerosCrossing(ScilabType nbZerosCrossing) {
331         this.nbZerosCrossing = nbZerosCrossing;
332     }
333
334     public ScilabType getNmode() {
335         return nmode;
336     }
337
338     public void setNmode(ScilabType nmode) {
339         this.nmode = nmode;
340     }
341
342     public ScilabType getState() {
343         return state;
344     }
345
346     public void setState(ScilabType state) {
347         this.state = state;
348     }
349
350     public ScilabType getDState() {
351         return dState;
352     }
353
354     public void setDState(ScilabType state) {
355         dState = state;
356     }
357
358     public ScilabType getODState() {
359         return oDState;
360     }
361
362     public void setODState(ScilabType state) {
363         oDState = state;
364     }
365
366     public ScilabType getEquations() {
367         return equations;
368     }
369
370     public void setEquations(ScilabType equations) {
371         this.equations = equations;
372     }
373
374     public boolean isLocked() {
375         return locked;
376     }
377
378     public void setLocked(boolean locked) {
379         this.locked = locked;
380     }
381
382     public void removePort(BasicPort port){
383         if(port.getEdgeCount() != 0) {
384             getParentDiagram().removeCells(new Object[]{port.getEdgeAt(0)});
385         }
386         remove(port);
387     }
388     
389     public void addPort(InputPort port) {
390         insert(port);
391         BlockPositioning.updatePortsPosition(this);
392         port.setOrdering(BasicBlockInfo.getAllInputPorts(this, false).size());
393     }
394
395     public void addPort(OutputPort port) {
396         insert(port);
397         BlockPositioning.updatePortsPosition(this);
398         port.setOrdering(BasicBlockInfo.getAllOutputPorts(this, false).size());
399     }
400
401     public void addPort(CommandPort port) {
402         insert(port);
403         BlockPositioning.updatePortsPosition(this);
404         port.setOrdering(BasicBlockInfo.getAllCommandPorts(this, false).size());
405     }
406
407     public void addPort(ControlPort port) {
408         insert(port);
409         BlockPositioning.updatePortsPosition(this);
410         port.setOrdering(BasicBlockInfo.getAllControlPorts(this, false).size());
411     }
412
413     public ScilabDouble getAllCommandPortsInitialStates() {
414         if (BasicBlockInfo.getAllCommandPorts(this, false).isEmpty()) {
415             return new ScilabDouble();
416         }
417
418         double[][] data = new double[BasicBlockInfo.getAllCommandPorts(this, false).size()][1];
419         for (int i = 0 ; i < BasicBlockInfo.getAllCommandPorts(this, false).size() ; ++i) {
420             data[i][0] = BasicBlockInfo.getAllCommandPorts(this, false).get(i).getInitialState();
421         }
422
423         return new ScilabDouble(data);
424     }
425
426     public ScilabType getSimulationFunctionNameAndType() {
427         if (getSimulationFunctionType() == SimulationFunctionType.DEFAULT) {
428             return new ScilabString(getSimulationFunctionName());
429         }
430         ScilabList data = new ScilabList();
431
432         data.add(new ScilabString(getSimulationFunctionName()));
433         data.add(new ScilabDouble(getSimulationFunctionType().getAsDouble()));
434
435         return data;
436     }
437
438
439     public void updateBlockSettings(BasicBlock modifiedBlock) {
440
441         setDependsOnT(modifiedBlock.dependsOnT());
442         setDependsOnU(modifiedBlock.dependsOnU());
443         setExprs(modifiedBlock.getExprs());
444
445         setRealParameters(modifiedBlock.getRealParameters());
446         setIntegerParameters(modifiedBlock.getIntegerParameters());
447         setObjectsParameters(modifiedBlock.getObjectsParameters());
448
449         setState(modifiedBlock.getState());
450         setDState(modifiedBlock.getDState());
451         setODState(modifiedBlock.getODState());
452
453         setEquations(modifiedBlock.getEquations());
454
455
456         List modifiedPorts = null;
457         List ports = null;
458         
459         // Check if new input port have been added
460         if ((modifiedPorts = BasicBlockInfo.getAllInputPorts(modifiedBlock, false)).size() > (ports = BasicBlockInfo.getAllInputPorts(this, false)).size()) {
461             while((ports = BasicBlockInfo.getAllInputPorts(this, false)).size() < modifiedPorts.size()) {
462                 addPort((InputPort)modifiedPorts.get(ports.size()));
463             }
464         }
465         // Check if input ports have been removed
466         else if ((modifiedPorts = BasicBlockInfo.getAllInputPorts(modifiedBlock, false)).size() < (ports = BasicBlockInfo.getAllInputPorts(this, false)).size()) {
467             while((ports = BasicBlockInfo.getAllInputPorts(this, false)).size() > modifiedPorts.size()) {
468                 removePort((BasicPort)ports.get(ports.size() - 1));
469             }
470         }
471
472         // Check if new output port have been added
473         if ((modifiedPorts = BasicBlockInfo.getAllOutputPorts(modifiedBlock, false)).size() > (ports = BasicBlockInfo.getAllOutputPorts(this, false)).size()) {
474             while((ports = BasicBlockInfo.getAllOutputPorts(this, false)).size() < modifiedPorts.size()) {
475                 addPort((OutputPort)modifiedPorts.get(ports.size()));
476             }
477         }
478         // Check if output ports have been removed
479         else if ((modifiedPorts = BasicBlockInfo.getAllOutputPorts(modifiedBlock, false)).size() < (ports = BasicBlockInfo.getAllOutputPorts(this, false)).size()) {
480             while((ports = BasicBlockInfo.getAllOutputPorts(this, false)).size() > modifiedPorts.size()) {
481                 removePort((BasicPort)ports.get(ports.size() - 1));
482             }
483         }
484
485
486         // Check if new command port have been added
487         if ((modifiedPorts = BasicBlockInfo.getAllCommandPorts(modifiedBlock, false)).size() > (ports = BasicBlockInfo.getAllCommandPorts(this, false)).size()) {
488             while((ports = BasicBlockInfo.getAllCommandPorts(this, false)).size() < modifiedPorts.size()) {
489                 addPort((CommandPort)modifiedPorts.get(ports.size()));
490             }
491         }
492         // Check if command ports have been removed
493         else if ((modifiedPorts = BasicBlockInfo.getAllCommandPorts(modifiedBlock, false)).size() < (ports = BasicBlockInfo.getAllCommandPorts(this, false)).size()) {
494             while((ports = BasicBlockInfo.getAllCommandPorts(this, false)).size() > modifiedPorts.size()) {
495                 removePort((BasicPort)ports.get(ports.size() - 1));
496             }
497         }
498
499         // Check if new control port have been added
500         if ((modifiedPorts = BasicBlockInfo.getAllControlPorts(modifiedBlock, false)).size() > (ports = BasicBlockInfo.getAllControlPorts(this, false)).size()) {
501             while((ports = BasicBlockInfo.getAllControlPorts(this, false)).size() < modifiedPorts.size()) {
502                 addPort((ControlPort)modifiedPorts.get(ports.size()));
503             }
504         }
505         // Check if control ports have been removed
506         else if ((modifiedPorts = BasicBlockInfo.getAllControlPorts(modifiedBlock, false)).size() < (ports = BasicBlockInfo.getAllControlPorts(this, false)).size()) {
507             while((ports = BasicBlockInfo.getAllControlPorts(this, false)).size() > modifiedPorts.size()) {
508                 removePort((BasicPort)ports.get(ports.size() - 1));
509             }
510         }
511
512         /*
513          * If the block is in a superblock then update it.
514          */
515         if (getParentDiagram() instanceof SuperBlockDiagram) {
516             SuperBlock parentBlock = ((SuperBlockDiagram) getParentDiagram()).getContainer();
517             parentBlock.getParentDiagram().fireEvent(XcosEvent.SUPER_BLOCK_UPDATED,new mxEventObject(new Object[] { parentBlock }));
518         }
519     }
520
521     public void openBlockSettings(String context[]) {
522         
523         //prevent to open twice
524         if(isLocked()) {
525             return;
526         }
527         
528         final File tempOutput;
529         final File tempInput;
530         final File tempContext;
531         try {
532             tempInput = File.createTempFile("xcos",".h5");
533             tempInput.deleteOnExit();
534
535             // Write scs_m
536             tempOutput = exportBlockStruct();
537             // Write context
538             tempContext = exportContext(context);
539
540             String cmd;
541             
542             cmd = "xcosBlockInterface(\""+tempOutput.getAbsolutePath()+"\"";
543             cmd += ", \""+tempInput.getAbsolutePath()+"\"";
544             cmd += ", "+getInterfaceFunctionName();
545             cmd += ", \"set\"";
546             cmd += ", \""+tempContext.getAbsolutePath()+"\");";
547             
548             InterpreterManagement.putCommandInScilabQueue(cmd);
549             final BasicBlock currentBlock = this;
550             Thread launchMe = new Thread() {
551                 public void run() {
552                     Signal.wait(tempInput.getAbsolutePath());
553                     // Now read new Block
554                     BasicBlock modifiedBlock = BlockReader.readBlockFromFile(tempInput.getAbsolutePath());
555                     updateBlockSettings(modifiedBlock);
556                     getParentDiagram().fireEvent(XcosEvent.ADD_PORTS, new mxEventObject(new Object[] {currentBlock}));
557                     setLocked(false);
558                 }
559             };
560             launchMe.start();
561             setLocked(true);
562
563         } catch (IOException e) {
564             e.printStackTrace();
565         }
566     }
567
568     protected File exportBlockStruct() {
569
570         // Write scs_m
571         File tempOutput;
572         try {
573             tempOutput = File.createTempFile("xcos",".h5");
574             tempOutput.deleteOnExit();
575             int file_id = H5Write.createFile(tempOutput.getAbsolutePath());
576             H5Write.writeInDataSet(file_id, "scs_m", BasicBlockInfo.getAsScilabObj(this));
577             H5Write.closeFile(file_id);
578             return tempOutput;
579         } catch (IOException e) {
580             e.printStackTrace();
581         } catch (HDF5Exception e) {
582             e.printStackTrace();
583         }
584         return null;
585     }
586     
587     protected File exportContext(String[] context) {
588
589         // Write context
590         try {
591             File tempContext = File.createTempFile("xcos",".h5");
592             tempContext.deleteOnExit();
593             int context_file_id = H5Write.createFile(tempContext.getAbsolutePath());
594             H5Write.writeInDataSet(context_file_id, "context", new ScilabString(context));
595             H5Write.closeFile(context_file_id);
596             return tempContext;
597         } catch (IOException e) {
598             e.printStackTrace();
599         } catch (HDF5Exception e) {
600             e.printStackTrace();
601         }
602         return null;
603     }
604     
605     public String getToolTipText() {
606         StringBuffer result = new StringBuffer();
607         result.append("<html>");
608         //result.append("Block Address : " + this + "<br>");
609         result.append("Block Name : "+ getInterfaceFunctionName() + "<br>");
610         result.append("Simulation : "+ getSimulationFunctionName() + "<br>");
611         result.append("UID : "+ getId() + "<br>");
612         result.append("Block Style : " + getStyle() + "<br>");
613         result.append("Flip : " + getFlip() + "<br>");
614         result.append("Mirror : " + getMirror() + "<br>");
615         result.append("Input ports : " + BasicBlockInfo.getAllInputPorts(this, false).size() + "<br>");
616         result.append("Output ports : " + BasicBlockInfo.getAllOutputPorts(this, false).size() + "<br>");
617         result.append("Control ports : " + BasicBlockInfo.getAllControlPorts(this, false).size() + "<br>");
618         result.append("Command ports : " + BasicBlockInfo.getAllCommandPorts(this, false).size() + "<br>");
619 //      result.append("Diagram : " + getParentDiagram() + "<br>");
620 //      //exprs
621 //      if (getExprs() != null) {
622 //          result.append("Exprs : "+getExprs().toString()+"<br>");
623 //      }
624 //      else {
625 //          result.append("Exprs : (null)<br>");
626 //      }
627 //      //ipar
628 //      if (getIntegerParameters() != null ) {
629 //          result.append("Ipar : "+getIntegerParameters().toString()+"<br>");
630 //      }
631 //      else {
632 //          result.append("Ipar : (null)<br>");
633 //      }
634 //      //rpar
635 //      if (getRealParameters() != null) {
636 //          result.append("Rpar : "+getRealParameters().toString()+"<br>");
637 //      }
638 //      else {
639 //          result.append("Rpar : (null)<br>");
640 //      }
641 //      //opar
642 //      if (getObjectsParameters() != null) {
643 //          result.append("Opar : "+getObjectsParameters().toString()+"<br>");
644 //      }
645 //      else {
646 //          result.append("Opar : (null)<br>");
647 //      }
648         
649         result.append("</html>");
650         return result.toString();
651     }
652
653     public void openContextMenu(ScilabGraph graph) {
654         ContextMenu menu = createContextMenu(graph);
655         menu.setVisible(true);
656     }
657
658     public ContextMenu createContextMenu(ScilabGraph graph) {
659                 ContextMenu menu = ScilabContextMenu.createContextMenu();
660                 Map<Class<? extends DefaultAction>, MenuItem> menuList = new HashMap<Class<? extends DefaultAction>, MenuItem>();
661                 
662                 MenuItem value = BlockParametersAction.createMenu(graph);
663                 menuList.put(BlockParametersAction.class, value);
664                 menu.add(value);
665                 /*--- */
666                 menu.getAsSimpleContextMenu().addSeparator();
667                 /*--- */
668                 value = CutAction.cutMenu(graph);
669                 menuList.put(CutAction.class, value);
670                 menu.add(value);
671                 value = CopyAction.copyMenu(graph);
672                 menuList.put(CopyAction.class, value);
673                 menu.add(value);
674                 value = DeleteAction.createMenu(graph);
675                 menuList.put(DeleteAction.class, value);
676                 menu.add(value);
677                 /*--- */
678                 menu.getAsSimpleContextMenu().addSeparator();
679                 /*--- */
680                 value = RegionToSuperblockAction.createMenu(graph);
681                 menuList.put(RegionToSuperblockAction.class, value);
682                 menu.add(value);
683 //              Menu mask = ScilabMenu.createMenu();
684 //              mask.setText(XcosMessages.SUPERBLOCK_MASK);
685 //              menu.add(mask);
686 //              mask.add(SuperblockMaskCreateAction.createMenu(graph));
687 //              mask.add(SuperblockMaskRemoveAction.createMenu(graph));
688                 /*--- */
689                 menu.getAsSimpleContextMenu().addSeparator();
690                 /*--- */
691                 Menu format = ScilabMenu.createMenu();
692                 format.setText(XcosMessages.FORMAT);
693                 menu.add(format);
694                 value = RotateAction.createMenu(graph);
695                 menuList.put(RotateAction.class, value);
696                 format.add(value);
697                 value = MirrorAction.createMenu(graph);
698                 menuList.put(MirrorAction.class, value);
699                 format.add(value);
700                 value = FlipAction.createMenu(graph);
701                 menuList.put(FlipAction.class, value);
702                 format.add(value);
703                 value = ShowHideShadowAction.createMenu(graph);
704                 menuList.put(ShowHideShadowAction.class, value);
705                 format.add(value);
706                 /*--- */
707                 format.addSeparator();
708                 /*--- */
709                 Menu alignMenu = ScilabMenu.createMenu();
710                 alignMenu.setText(XcosMessages.ALIGN_BLOCKS);
711                 alignMenu.add(AlignBlockAction.createMenu(graph, XcosMessages.ALIGN_LEFT, mxConstants.ALIGN_LEFT));
712                 alignMenu.add(AlignBlockAction.createMenu(graph, XcosMessages.ALIGN_CENTER, mxConstants.ALIGN_CENTER));
713                 alignMenu.add(AlignBlockAction.createMenu(graph, XcosMessages.ALIGN_RIGHT, mxConstants.ALIGN_RIGHT));
714                 alignMenu.addSeparator();
715                 alignMenu.add(AlignBlockAction.createMenu(graph, XcosMessages.ALIGN_TOP, mxConstants.ALIGN_TOP));
716                 alignMenu.add(AlignBlockAction.createMenu(graph, XcosMessages.ALIGN_MIDDLE, mxConstants.ALIGN_MIDDLE));
717                 alignMenu.add(AlignBlockAction.createMenu(graph, XcosMessages.ALIGN_BOTTOM, mxConstants.ALIGN_BOTTOM));
718                 format.add(alignMenu);
719                 /*--- */
720                 format.addSeparator();
721                 /*--- */
722                 format.add(ColorAction.createMenu(graph, XcosMessages.BORDER_COLOR, mxConstants.STYLE_STROKECOLOR));
723                 format.add(ColorAction.createMenu(graph, XcosMessages.FILL_COLOR, mxConstants.STYLE_FILLCOLOR));
724                 /*--- */
725                 menu.getAsSimpleContextMenu().addSeparator();
726                 /*--- */
727                 menu.add(ViewDetailsAction.createMenu(graph));
728                 /*--- */
729                 menu.getAsSimpleContextMenu().addSeparator();
730                 /*--- */
731                 menu.add(BlockDocumentationAction.createMenu(graph));
732
733                 ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo().getLocation().y);
734                 
735                 customizeMenu(menuList);
736                 
737                 return menu;
738     }
739     
740     public void setFlip(boolean flip) {
741         if(getParentDiagram() != null) {
742             if(flip == true) {
743                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_FLIP, "true");
744             } else {
745                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_FLIP, "false");
746             }
747         }
748     }
749
750     /**
751      * Override this to customize contextual menu
752      * @param menuList
753      */
754     protected void customizeMenu(Map<Class<? extends DefaultAction>, MenuItem> menuList) {
755         // To be overridden by sub-classes
756     }
757     
758
759     public boolean getMirror(){
760         if(getParentDiagram() != null) {
761             mxCellState state = getParentDiagram().getView().getState(this);
762             if(state != null) {
763                 String  currentMirror = mxUtils.getString(state.getStyle(), XcosConstants.STYLE_MIRROR, "false");
764                 if(currentMirror.compareTo("true") == 0) {
765                     return true;
766                 } else {
767                     return false;
768                 }
769             }
770         }
771         return false;
772     }
773     public void setMirror(boolean mirror) {
774         if(getParentDiagram() != null) {
775             if(mirror == true) {
776                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_MIRROR, "true");
777             } else {
778                 mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_MIRROR, "false");
779             }
780         }
781     }
782
783     public boolean getFlip(){
784         if(getParentDiagram() != null) {
785             mxCellState state = getParentDiagram().getView().getState(this);
786             if(state != null) {
787                 String  currentFlip = mxUtils.getString(state.getStyle(), XcosConstants.STYLE_FLIP, "false");
788                 if(currentFlip.compareTo("true") == 0) {
789                     return true;
790                 } else {
791                     return false;
792                 }
793             }
794         }
795         return false;
796     }
797
798     public void toggleFlip() {
799         BlockPositioning.toggleFlip(this);
800     }
801
802     public void toggleMirror() {
803         BlockPositioning.toggleMirror(this);
804     }
805
806     public void toggleAntiClockwiseRotation() {
807         BlockPositioning.toggleAntiClockwiseRotation(this);
808
809     }
810     /**
811      * Create a clone for block added by context menu in palette
812      * @return the clone
813      */
814     public Object createClone() {
815         try {
816             BasicBlock clone = (BasicBlock) clone();
817
818             /* Clone children */
819             for (int i = 0; i < getChildCount(); i++) {
820                 if (getChildAt(i) instanceof InputPort) {
821                     clone.addPort((InputPort) getChildAt(i).clone());
822                 } else if (getChildAt(i) instanceof OutputPort) {
823                     clone.addPort((OutputPort) getChildAt(i).clone());
824                 } else if (getChildAt(i) instanceof CommandPort) {
825                     clone.addPort((CommandPort) getChildAt(i).clone());
826                 } else if (getChildAt(i) instanceof ControlPort) {
827                     clone.addPort((ControlPort) getChildAt(i).clone());
828                 }
829             }
830
831             return clone;
832         } catch (CloneNotSupportedException e) {
833             e.printStackTrace();
834             return null;
835         }
836     }
837
838     public int getAngle() {
839         if(getParentDiagram() != null) {
840             mxCellState state = getParentDiagram().getView().getState(this);
841             if(state != null) {
842                 String  currentAngle = mxUtils.getString(state.getStyle(), XcosConstants.STYLE_ROTATION, "0");
843                 return Integer.parseInt(currentAngle);
844             }
845         }
846         return 0;
847     }
848
849     public void setAngle(int angle) {
850         if(getParentDiagram() != null) {
851             mxUtils.setCellStyles(getParentDiagram().getModel(), new Object[] {this}, XcosConstants.STYLE_ROTATION, new Integer(angle).toString());
852         }
853     }
854 }