2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4 * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
17 package org.scilab.modules.xcos.block;
19 import java.awt.MouseInfo;
20 import java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.Deque;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.LinkedList;
28 import java.util.List;
32 import org.scilab.modules.action_binding.InterpreterManagement;
33 import org.scilab.modules.graph.ScilabGraph;
34 import org.scilab.modules.graph.actions.CopyAction;
35 import org.scilab.modules.graph.actions.CutAction;
36 import org.scilab.modules.graph.actions.DeleteAction;
37 import org.scilab.modules.graph.actions.base.DefaultAction;
38 import org.scilab.modules.gui.bridge.contextmenu.SwingScilabContextMenu;
39 import org.scilab.modules.gui.contextmenu.ContextMenu;
40 import org.scilab.modules.gui.contextmenu.ScilabContextMenu;
41 import org.scilab.modules.gui.events.callback.CommonCallBack;
42 import org.scilab.modules.gui.menu.Menu;
43 import org.scilab.modules.gui.menu.ScilabMenu;
44 import org.scilab.modules.gui.menuitem.MenuItem;
45 import org.scilab.modules.gui.menuitem.ScilabMenuItem;
46 import org.scilab.modules.xcos.JavaController;
47 import org.scilab.modules.xcos.Kind;
48 import org.scilab.modules.xcos.ObjectProperties;
49 import org.scilab.modules.xcos.VectorOfDouble;
50 import org.scilab.modules.xcos.VectorOfInt;
51 import org.scilab.modules.xcos.VectorOfScicosID;
52 import org.scilab.modules.xcos.VectorOfString;
53 import org.scilab.modules.xcos.Xcos;
54 import org.scilab.modules.xcos.XcosTab;
55 import org.scilab.modules.xcos.actions.EditFormatAction;
56 import org.scilab.modules.xcos.actions.ShowHideShadowAction;
57 import org.scilab.modules.xcos.block.actions.AutoPositionSplitBlockAction;
58 import org.scilab.modules.xcos.block.actions.BlockDocumentationAction;
59 import org.scilab.modules.xcos.block.actions.BlockParametersAction;
60 import org.scilab.modules.xcos.block.actions.BorderColorAction;
61 import org.scilab.modules.xcos.block.actions.FilledColorAction;
62 import org.scilab.modules.xcos.block.actions.FlipAction;
63 import org.scilab.modules.xcos.block.actions.MirrorAction;
64 import org.scilab.modules.xcos.block.actions.RegionToSuperblockAction;
65 import org.scilab.modules.xcos.block.actions.RotateAction;
66 import org.scilab.modules.xcos.block.actions.ViewDetailsAction;
67 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockAction;
68 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionBottom;
69 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionCenter;
70 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionLeft;
71 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionMiddle;
72 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionRight;
73 import org.scilab.modules.xcos.block.actions.alignement.AlignBlockActionTop;
74 import org.scilab.modules.xcos.graph.XcosDiagram;
75 import org.scilab.modules.xcos.graph.model.XcosCell;
76 import org.scilab.modules.xcos.port.command.CommandPort;
77 import org.scilab.modules.xcos.port.control.ControlPort;
78 import org.scilab.modules.xcos.port.input.InputPort;
79 import org.scilab.modules.xcos.port.output.OutputPort;
80 import org.scilab.modules.xcos.utils.BlockPositioning;
81 import org.scilab.modules.xcos.utils.XcosMessages;
83 import com.mxgraph.model.mxGeometry;
84 import com.mxgraph.model.mxICell;
87 * A block on the diagram
89 @SuppressWarnings(value = { "serial" })
90 public class BasicBlock extends XcosCell implements Serializable {
92 * Sorted kind of input, useful to sort them by kind
94 private static final Class<?>[] sortedChildrenClass = { InputPort.class, OutputPort.class, ControlPort.class, CommandPort.class, Object.class };
101 * Default interface function name
103 public static final String DEFAULT_INTERFACE_FUNCTION = "xcos_block";
105 * Default simulation function name
107 public static final String DEFAULT_SIMULATION_FUNCTION = "xcos_simulate";
113 protected static final double DEFAULT_POSITION_X = 10.0;
114 protected static final double DEFAULT_POSITION_Y = 10.0;
115 private static final double DEFAULT_WIDTH = 40.0;
116 private static final double DEFAULT_HEIGHT = 40.0;
119 * Internal method to get a base index to compare with depending on the cell type.
123 * @return the base index
125 private static int compareByChildClass(final Object o1, final Object o2) {
129 for (int i = 0; i < sortedChildrenClass.length; i++) {
130 final Class<?> klass = sortedChildrenClass[i];
132 if (klass.isInstance(o1)) {
137 for (int i = 0; i < sortedChildrenClass.length; i++) {
138 final Class<?> klass = sortedChildrenClass[i];
140 if (klass.isInstance(o2)) {
146 final int base = o1Index - o2Index;
147 return base * (Integer.MAX_VALUE / sortedChildrenClass.length);
150 private boolean locked;
153 * Hook used to implement specifix behavior after any parameter update and before re-layouting the block
155 public void updateBlockView() {
159 * Represent a simulation function type compatible with Scilab/Scicos function type descriptors.
161 public static enum SimulationFunctionType {
162 /** event select; reduced at compilation */
163 ESELECT(-2), /** if then else; reduced at compilation */
164 IFTHENELSE(-1), /** first common block */
165 DEFAULT(0), /** first native block */
166 TYPE_1(1), /** second native block */
167 TYPE_2(2), /** third native block */
168 TYPE_3(3), /** forth native block */
169 C_OR_FORTRAN(4), /** Scilab blocks */
170 SCILAB(5), /** Debug blocks */
171 DEBUG(99), /** dynamic {@link #TYPE_1} Fortran blocks (fortran_block.sci) */
172 DYNAMIC_FORTRAN_1(1001), /** dynamic {@link #TYPE_1} C blocks (c_block.sci) */
173 DYNAMIC_C_1(2001), /** Explicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
174 DYNAMIC_EXPLICIT_4(2004), /** Implicit {@link #TYPE_1} Fortran blocks (DIFF_f.sci) */
175 OLDBLOCKS(10001), /** Implicit {@link #C_OR_FORTRAN} blocks */
176 IMPLICIT_C_OR_FORTRAN(10004), /** Implicit dynamic {@link #TYPE_4} blocks (CBLOCK.sci) */
177 DYNAMIC_IMPLICIT_4(12004), /** Modelica {@link #C_OR_FORTRAN} blocks */
178 MODELICA(30004), /** Magic types */
181 private final int value;
184 * Default constructor
187 * Scilab/Scicos function type descriptor
189 private SimulationFunctionType(int scilabValue) {
194 * Get the Java descriptor from the Scilab descriptor.
197 * Scilab/Scicos function type descriptor
198 * @return The corresponding java descriptor
200 public static SimulationFunctionType convertScilabValue(int scilabValue) {
201 for (SimulationFunctionType iter : SimulationFunctionType.values()) {
202 if (iter.getValue() == scilabValue) {
210 * Get the Scilab Descriptor from the Java Descriptor
212 * @return The corresponding Scilab/Scicos descriptor
214 public int getValue() {
220 * Constructor that setup some properties and pass all its arguments this its {@link XcosCell} parent.
223 * @param controller The shared controller instance
224 * @param uid the uid of the MVC object
225 * @param kind {@link Kind#BLOCK} or {@link Kind#ANNOTATION}
226 * @param value the value of the block
227 * @param geometry the geometry to apply to this JGraphX object
228 * @param style the style to apply to this JGraphX object
229 * @param id the id to apply to this JGraphX object
231 public BasicBlock(final JavaController controller, long uid, Kind kind, Object value, mxGeometry geometry, String style, String id) {
232 super(controller, uid, kind, value, geometry, style, id);
235 * Default JGraphX properties for blocks
239 this.connectable = false;
243 * @return locked status
245 public synchronized boolean isLocked() {
251 * change locked status
253 public synchronized void setLocked(boolean locked) {
254 this.locked = locked;
258 * Does the block update and register on the undo manager
259 * @param controller the shared controller
260 * @param parent the parent diagram or superblock diagram
261 * @param modifiedBlock the new settings
263 public void updateBlockSettings(JavaController controller, XcosDiagram parent, BasicBlock modifiedBlock) {
264 if (modifiedBlock == null) {
269 * Update the block settings
271 updateFields(controller, parent, modifiedBlock);
274 * Update the children ports
276 updateChildren(controller, parent, modifiedBlock);
280 * Update the instance field and the model values
282 * @param modifiedBlock
283 * the modified instance
285 private void updateFields(JavaController controller, XcosDiagram parent, BasicBlock modifiedBlock) {
286 if (modifiedBlock == null) {
290 // TODO these copies are not managed by undo/redo ; fix that
292 int[] integer = new int[1];
294 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_FUNCTION_API, integer);
295 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_FUNCTION_API, integer[0]);
297 String[] str = new String[1];
299 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.INTERFACE_FUNCTION, str);
300 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.INTERFACE_FUNCTION, str[0]);
302 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_FUNCTION_NAME, str);
303 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_FUNCTION_NAME, str[0]);
305 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_BLOCKTYPE, str);
306 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_BLOCKTYPE, str[0]);
308 VectorOfDouble vDouble = new VectorOfDouble();
310 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.EXPRS, vDouble);
311 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.EXPRS, vDouble);
313 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.STATE, vDouble);
314 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.STATE, vDouble);
316 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.DSTATE, vDouble);
317 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DSTATE, vDouble);
319 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.ODSTATE, vDouble);
320 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.ODSTATE, vDouble);
322 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.RPAR, vDouble);
323 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.RPAR, vDouble);
325 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.OPAR, vDouble);
326 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.OPAR, vDouble);
328 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.EQUATIONS, vDouble);
329 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.EQUATIONS, vDouble);
331 VectorOfInt vInt = new VectorOfInt();
333 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.SIM_DEP_UT, vInt);
334 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SIM_DEP_UT, vInt);
336 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.NZCROSS, vInt);
337 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.NZCROSS, vInt);
339 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.NMODE, vInt);
340 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.NMODE, vInt);
342 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.IPAR, vInt);
343 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.IPAR, vInt);
345 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.COLOR, vInt);
346 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.COLOR, vInt);
348 VectorOfString vStr = new VectorOfString();
350 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.DIAGRAM_CONTEXT, vStr);
351 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DIAGRAM_CONTEXT, vStr);
353 VectorOfScicosID localChildren = new VectorOfScicosID();
355 controller.getObjectProperty(modifiedBlock.getUID(), modifiedBlock.getKind(), ObjectProperties.CHILDREN, localChildren);
356 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, localChildren);
359 * JGraphX mapped properties
361 parent.getModel().setStyle(this, modifiedBlock.getStyle());
362 parent.getModel().setValue(this, modifiedBlock.getValue());
366 * Update the children of the block.
368 * @param modifiedBlock
369 * the new block instance
371 private void updateChildren(JavaController controller, XcosDiagram parent, BasicBlock modifiedBlock) {
372 if (modifiedBlock == null) {
377 * Checked as port classes only
379 Set < Class <? extends mxICell >> types = new HashSet < > (Arrays.asList(InputPort.class, OutputPort.class, ControlPort.class, CommandPort.class));
381 Map < Class <? extends mxICell > , Deque<mxICell >> annotatedOlds = getTypedChildren(types);
382 Map < Class <? extends mxICell > , Deque<mxICell >> annotatedNews = modifiedBlock.getTypedChildren(types);
384 parent.getModel().beginUpdate();
386 for (Class <? extends mxICell > klass : types) {
387 final Deque<mxICell> olds = annotatedOlds.get(klass);
388 final Deque<mxICell> news = annotatedNews.get(klass);
391 while (!olds.isEmpty() && !news.isEmpty()) {
392 mxICell previous = olds.poll();
393 mxICell modified = news.poll();
395 final int previousIndex = children.indexOf(previous);
398 if (previous.getEdgeCount() != 0) {
399 final mxICell relinked = previous.getEdgeAt(0);
400 final boolean isOutgoing = previous == relinked.getTerminal(true);
401 previous.removeEdge(relinked, isOutgoing);
402 modified.insertEdge(relinked, isOutgoing);
405 parent.removeCells(new Object[] { previous }, false);
406 parent.addCells(new Object[] { modified }, this, previousIndex);
408 // Clone the geometry to avoid empty geometry on new cells.
409 parent.getModel().setGeometry(modified, (mxGeometry) previous.getGeometry().clone());
414 if (!olds.isEmpty()) {
415 parent.removeCells(olds.toArray(), true);
419 if (!news.isEmpty()) {
420 parent.addCells(news.toArray(), this);
424 parent.getModel().endUpdate();
429 * Format the children as a typed map for the given class set.
432 * the classes to search for.
433 * @return a map which linked foreach type the corresponding cell list.
435 private Map < Class <? extends mxICell > , Deque<mxICell >> getTypedChildren(Set < Class <? extends mxICell >> types) {
436 Map < Class <? extends mxICell > , Deque<mxICell >> oldPorts = new HashMap < > ();
438 // Allocate all types set
439 for (Class <? extends mxICell > type : types) {
440 oldPorts.put(type, new LinkedList<>());
443 if (getChildCount() <= 0) {
448 for (Object cell : children) {
450 Class <? extends Object > klass = cell.getClass();
451 while (klass != null) {
452 if (types.contains(klass)) {
455 klass = klass.getSuperclass();
458 final Deque<mxICell> current = oldPorts.get(klass);
459 if (current != null) {
460 current.add((mxICell) cell);
468 * Format the children as a typed map index for the given class set.
471 * the classes to search for.
472 * @return a map which linked foreach type the corresponding cell index in the children.
474 private Map<Class<? extends mxICell>, ArrayList<Integer>> getTypedChildrenIndexes(Set<Class<? extends mxICell>> types) {
475 Map<Class<? extends mxICell>, ArrayList<Integer>> oldPorts = new HashMap<Class<? extends mxICell>, ArrayList<Integer>>();
477 // Allocate all types set
478 for (Class<? extends mxICell> type : types) {
479 oldPorts.put(type, new ArrayList<>());
482 if (getChildCount() <= 0) {
487 for (int i = 0; i < children.size(); i++) {
488 final Object cell = children.get(i);
490 Class<? extends Object> klass = cell.getClass();
491 while (klass != null) {
492 if (types.contains(klass)) {
495 klass = klass.getSuperclass();
498 final ArrayList<Integer> current = oldPorts.get(klass);
499 if (current != null) {
507 public ArrayList<Integer> getTypedChildrenIndexes(Class<? extends mxICell> type) {
508 return getTypedChildrenIndexes(Collections.singleton(type)).get(type);
511 public Map<Class<? extends mxICell>, ArrayList<Long>> getTypedChildrenUIDs(Set<Class<? extends mxICell>> types) {
512 Map<Class<? extends mxICell>, ArrayList<Long>> ports = new HashMap<>();
514 // Allocate all types set
515 types.stream().forEach(t -> ports.put(t, new ArrayList<>()));
517 if (getChildCount() <= 0) {
522 for (int i = 0; i < children.size(); i++) {
523 final Object cell = children.get(i);
525 Class<? extends Object> klass = cell.getClass();
526 while (klass != null) {
527 if (types.contains(klass)) {
530 klass = klass.getSuperclass();
533 final ArrayList<Long> current = ports.get(klass);
534 if (current != null) {
535 if (cell instanceof XcosCell) {
536 current.add(((XcosCell) cell).getUID());
546 public ArrayList<Long> getTypedChildrenUIDs(Class<? extends mxICell> type) {
547 return getTypedChildrenUIDs(Collections.singleton(type)).get(type);
554 public void openContextMenu(ScilabGraph graph) {
555 ContextMenu menu = null;
556 // if (getParentDiagram() instanceof PaletteDiagram) {
557 // menu = createPaletteContextMenu(graph);
559 menu = createContextMenu(graph);
561 menu.setVisible(true);
567 * @return context menu
570 public ContextMenu createPaletteContextMenu(ScilabGraph graph) {
571 ContextMenu menu = ScilabContextMenu.createContextMenu();
573 final List<XcosDiagram> allDiagrams = Xcos.getInstance().openedDiagrams();
575 if (allDiagrams.size() == 0) {
576 // No diagram opened: should never happen if Xcos opens an empty
577 // diagram when it is launched
578 MenuItem addTo = ScilabMenuItem.createMenuItem();
580 addTo.setText(XcosMessages.ADDTO_NEW_DIAGRAM);
581 addTo.setCallback(new CommonCallBack(XcosMessages.ADDTO_NEW_DIAGRAM) {
583 public void callBack() {
584 JavaController controller = new JavaController();
585 BasicBlock block = null;
587 block = (BasicBlock) BasicBlock.this.clone();
588 } catch (CloneNotSupportedException e) {
592 XcosDiagram theDiagram = new XcosDiagram(controller, controller.createObject(Kind.DIAGRAM), Kind.DIAGRAM, "");
593 theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
594 mxGeometry geom = BasicBlock.this.getGeometry();
595 setDefaultPosition(geom);
596 theDiagram.getModel().setGeometry(block, geom);
598 XcosTab.get(theDiagram).setVisible(true);
599 BlockPositioning.updateBlockView(theDiagram, block);
605 } else if (allDiagrams.size() == 1) {
606 // A single diagram opened: add to this diagram
607 MenuItem addTo = ScilabMenuItem.createMenuItem();
609 addTo.setText(XcosMessages.ADDTO + " " + XcosTab.get(allDiagrams.get(0)).getName());
610 final XcosDiagram theDiagram = allDiagrams.get(0);
611 addTo.setCallback(new CommonCallBack(theDiagram.getTitle()) {
612 private static final long serialVersionUID = -99601763227525686L;
615 public void callBack() {
616 BasicBlock block = null;
618 block = (BasicBlock) BasicBlock.this.clone();
619 } catch (CloneNotSupportedException e) {
622 theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
623 mxGeometry geom = BasicBlock.this.getGeometry();
624 setDefaultPosition(geom);
625 theDiagram.getModel().setGeometry(block, geom);
626 BlockPositioning.updateBlockView(theDiagram, block);
633 // The user has to choose
634 Menu addTo = ScilabMenu.createMenu();
636 addTo.setText(XcosMessages.ADDTO);
638 for (int i = 0; i < allDiagrams.size(); i++) {
639 MenuItem diagram = ScilabMenuItem.createMenuItem();
640 final XcosDiagram theDiagram = allDiagrams.get(i);
641 diagram.setText(XcosTab.get(allDiagrams.get(i)).getName());
642 diagram.setCallback(new CommonCallBack(theDiagram.getTitle()) {
643 private static final long serialVersionUID = 3345416658377835057L;
646 public void callBack() {
647 BasicBlock block = null;
649 block = (BasicBlock) BasicBlock.this.clone();
650 } catch (CloneNotSupportedException e) {
653 theDiagram.getModel().add(theDiagram.getDefaultParent(), block, 0);
654 mxGeometry geom = BasicBlock.this.getGeometry();
655 setDefaultPosition(geom);
656 theDiagram.getModel().setGeometry(block, geom);
657 BlockPositioning.updateBlockView(theDiagram, block);
666 menu.getAsSimpleContextMenu().addSeparator();
668 MenuItem help = ScilabMenuItem.createMenuItem();
669 help.setText(XcosMessages.BLOCK_DOCUMENTATION);
670 help.setCallback(new CommonCallBack(XcosMessages.BLOCK_DOCUMENTATION) {
671 private static final long serialVersionUID = -1480947262397441951L;
674 public void callBack() {
675 JavaController controller = new JavaController();
676 String[] interfaceFunctionName = new String[1];
677 controller.getObjectProperty(getUID(), Kind.BLOCK, ObjectProperties.INTERFACE_FUNCTION, interfaceFunctionName);
679 InterpreterManagement.requestScilabExec("help " + interfaceFunctionName[0]);
684 menu.setVisible(true);
686 ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x,
687 MouseInfo.getPointerInfo().getLocation().y);
697 * @return context menu
700 public ContextMenu createContextMenu(ScilabGraph graph) {
701 ContextMenu menu = ScilabContextMenu.createContextMenu();
702 Map<Class<? extends DefaultAction>, Menu> menuList = new HashMap<>();
704 MenuItem value = BlockParametersAction.createMenu(graph);
705 menuList.put(BlockParametersAction.class, value);
708 menu.getAsSimpleContextMenu().addSeparator();
710 value = CutAction.cutMenu(graph);
711 menuList.put(CutAction.class, value);
713 value = CopyAction.copyMenu(graph);
714 menuList.put(CopyAction.class, value);
716 value = DeleteAction.createMenu(graph);
717 menuList.put(DeleteAction.class, value);
720 menu.getAsSimpleContextMenu().addSeparator();
722 value = RegionToSuperblockAction.createMenu(graph);
723 menuList.put(RegionToSuperblockAction.class, value);
726 menu.getAsSimpleContextMenu().addSeparator();
728 Menu format = ScilabMenu.createMenu();
729 format.setText(XcosMessages.FORMAT);
731 value = RotateAction.createMenu(graph);
732 menuList.put(RotateAction.class, value);
734 value = MirrorAction.createMenu(graph);
735 menuList.put(MirrorAction.class, value);
737 value = FlipAction.createMenu(graph);
738 menuList.put(FlipAction.class, value);
740 value = ShowHideShadowAction.createMenu(graph);
741 menuList.put(ShowHideShadowAction.class, value);
744 format.addSeparator();
746 Menu alignMenu = ScilabMenu.createMenu();
747 alignMenu.setText(XcosMessages.ALIGN_BLOCKS);
748 alignMenu.add(AlignBlockActionLeft.createMenu(graph));
749 alignMenu.add(AlignBlockActionCenter.createMenu(graph));
750 alignMenu.add(AlignBlockActionRight.createMenu(graph));
751 alignMenu.addSeparator();
752 alignMenu.add(AlignBlockActionTop.createMenu(graph));
753 alignMenu.add(AlignBlockActionMiddle.createMenu(graph));
754 alignMenu.add(AlignBlockActionBottom.createMenu(graph));
755 menuList.put(AlignBlockAction.class, alignMenu);
756 format.add(alignMenu);
758 format.addSeparator();
760 MenuItem sbapMenuItem = AutoPositionSplitBlockAction.createMenu(graph);
761 sbapMenuItem.setText(XcosMessages.BLOCK_AUTO_POSITION_SPLIT_BLOCK_CONTEXTUAL);
762 sbapMenuItem.setEnabled(false);
763 menuList.put(AutoPositionSplitBlockAction.class, sbapMenuItem);
764 format.add(sbapMenuItem);
766 format.addSeparator();
768 if (graph.getSelectionCells().length > 1) {
769 format.add(BorderColorAction.createMenu(graph));
770 format.add(FilledColorAction.createMenu(graph));
772 format.add(EditFormatAction.createMenu(graph));
775 menu.getAsSimpleContextMenu().addSeparator();
777 menu.add(ViewDetailsAction.createMenu(graph));
779 menu.getAsSimpleContextMenu().addSeparator();
781 menu.add(BlockDocumentationAction.createMenu(graph));
783 ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(MouseInfo.getPointerInfo().getLocation().x,
784 MouseInfo.getPointerInfo().getLocation().y);
786 customizeMenu(menuList);
792 * Override this to customize contextual menu
797 protected void customizeMenu(Map<Class<? extends DefaultAction>, Menu> menuList) {
798 // To be overridden by sub-classes
802 * Set the default block position on the geom
807 private void setDefaultPosition(mxGeometry geom) {
808 geom.setX(DEFAULT_POSITION_X);
809 geom.setY(DEFAULT_POSITION_Y);
813 * Overriden methods from jgraphx
817 * @return always false
818 * @see com.mxgraph.model.mxCell#isConnectable()
821 public boolean isConnectable() {
828 * Sync the specific child {@link EditFormatAction#HASH_IDENTIFIER}
831 public mxICell insert(mxICell child, int index) {
833 * Update the id if this is an identifier cell (herited identifier)
835 if (child.getId().endsWith(XcosDiagram.HASH_IDENTIFIER)) {
836 child.setId(getId() + XcosDiagram.HASH_IDENTIFIER);
839 return super.insert(child, index);