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