2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
13 package org.scilab.modules.xcos.block;
15 import java.util.ArrayList;
16 import java.util.List;
18 import org.scilab.modules.graph.ScilabGraph;
19 import org.scilab.modules.gui.contextmenu.ContextMenu;
20 import org.scilab.modules.gui.menu.Menu;
21 import org.scilab.modules.gui.menu.ScilabMenu;
22 import org.scilab.modules.gui.utils.UIElementMapper;
23 import org.scilab.modules.gui.window.ScilabWindow;
24 import org.scilab.modules.hdf5.scilabTypes.ScilabDouble;
25 import org.scilab.modules.hdf5.scilabTypes.ScilabList;
26 import org.scilab.modules.hdf5.scilabTypes.ScilabMList;
27 import org.scilab.modules.xcos.XcosTab;
28 import org.scilab.modules.xcos.actions.CodeGenerationAction;
29 import org.scilab.modules.xcos.block.actions.SuperblockMaskCreateAction;
30 import org.scilab.modules.xcos.block.actions.SuperblockMaskCustomizeAction;
31 import org.scilab.modules.xcos.block.actions.SuperblockMaskRemoveAction;
32 import org.scilab.modules.xcos.graph.PaletteDiagram;
33 import org.scilab.modules.xcos.graph.SuperBlockDiagram;
34 import org.scilab.modules.xcos.io.BasicBlockInfo;
35 import org.scilab.modules.xcos.io.BlockReader;
36 import org.scilab.modules.xcos.io.BlockWriter;
37 import org.scilab.modules.xcos.port.command.CommandPort;
38 import org.scilab.modules.xcos.port.control.ControlPort;
39 import org.scilab.modules.xcos.port.input.ExplicitInputPort;
40 import org.scilab.modules.xcos.port.input.ImplicitInputPort;
41 import org.scilab.modules.xcos.port.output.ExplicitOutputPort;
42 import org.scilab.modules.xcos.port.output.ImplicitOutputPort;
43 import org.scilab.modules.xcos.utils.XcosEvent;
44 import org.scilab.modules.xcos.utils.XcosMessages;
46 import com.mxgraph.model.mxCell;
47 import com.mxgraph.util.mxEventObject;
49 public final class SuperBlock extends BasicBlock {
51 private static final long serialVersionUID = 3005281208417373333L;
52 private SuperBlockDiagram child = null;
58 protected SuperBlock(String label) {
64 protected SuperBlock(boolean masked) {
71 protected SuperBlock(String label, boolean masked) {
79 * Initialize the block with the default values
82 protected void setDefaultValues() {
83 super.setDefaultValues();
84 setInterfaceFunctionName("SUPER_f");
85 setSimulationFunctionName("super");
86 setRealParameters(new ScilabDouble());
87 setIntegerParameters(new ScilabDouble());
88 setObjectsParameters(new ScilabList());
89 setExprs(new ScilabDouble());
91 setNbZerosCrossing(new ScilabDouble(0));
92 setNmode(new ScilabDouble(0));
96 * openBlockSettings this method is called when a double click occured on a
99 * @see BasicBlock.openBlockSettings
102 public void openBlockSettings(String[] context) {
103 if (getParentDiagram() instanceof PaletteDiagram) {
107 if (getChild() == null
108 && getSimulationFunctionType().compareTo(
109 SimulationFunctionType.DEFAULT) != 0) {
110 // This means we have a SuperBlock and we generated C code for it.
111 this.setLocked(false);
116 super.openBlockSettings(context);
118 if (createChildDiagram() == true) {
119 getChild().setModifiedNonRecursively(false);
120 XcosTab.createTabFromDiagram(getChild());
121 XcosTab.showTabFromDiagram(getChild());
123 getChild().setVisible(true);
126 getChild().updateCellsContext();
130 public void closeBlockSettings() {
132 // Do not ask the user, the diagram is saved and closed
133 if (getChild().isModified()) {
134 setRealParameters(BlockWriter.convertDiagramToMList(getChild()));
135 getChild().setModified(true);
136 getChild().setModifiedNonRecursively(false);
139 if (getChild().canClose() == false) {
140 getChild().setVisible(false);
144 if (getChild().getParentTab() != null) {
145 ScilabWindow xcosWindow = (ScilabWindow) UIElementMapper
146 .getCorrespondingUIElement(getChild().getParentTab()
147 .getParentWindowId());
148 xcosWindow.removeTab(getChild().getParentTab());
149 getChild().getViewPort().close();
150 getChild().setOpened(false);
151 XcosTab.closeDiagram(getChild());
152 if (getParentDiagram().isOpened()
153 && getParentDiagram().isVisible() == false) {
154 getParentDiagram().closeDiagram();
158 child.removeListener(null);
163 public void openContextMenu(ScilabGraph graph) {
164 ContextMenu menu = null;
166 if (getParentDiagram() instanceof PaletteDiagram) {
167 menu = createPaletteContextMenu(graph);
169 menu = createContextMenu(graph);
170 menu.getAsSimpleContextMenu().addSeparator();
171 menu.add(CodeGenerationAction.createMenu(graph));
174 * FIXME: It is not possible to use Mask. So remove any possibility.
175 * Mask removing only option is not applicable : if remove the mask
176 * you have no way to edit the values anymore.
178 Menu maskMenu = ScilabMenu.createMenu();
179 maskMenu.setText(XcosMessages.SUPERBLOCK_MASK);
182 maskMenu.add(SuperblockMaskRemoveAction.createMenu(graph));
185 maskMenu.add(SuperblockMaskCreateAction.createMenu(graph));
187 maskMenu.add(SuperblockMaskCustomizeAction.createMenu(graph));
191 menu.setVisible(true);
194 public boolean createChildDiagram() {
195 return createChildDiagram(false);
198 public boolean createChildDiagram(boolean generatedUID) {
200 child = new SuperBlockDiagram(this);
201 child.installListeners();
202 child.loadDiagram(BlockReader.convertMListToDiagram(
203 (ScilabMList) getRealParameters(), false));
204 child.installSuperBlockListeners();
205 child.setChildrenParentDiagram();
206 updateAllBlocksColor();
207 // only for loading and generate sub block UID
218 public SuperBlockDiagram getChild() {
222 public void setChild(SuperBlockDiagram child) {
226 public ScilabMList getAsScilabObj() {
228 setRealParameters(BlockWriter.convertDiagramToMList(child));
230 return BasicBlockInfo.getAsScilabObj(this);
233 protected List<mxCell> getAllExplicitInBlock() {
234 List<mxCell> list = new ArrayList<mxCell>();
239 int blockCount = child.getModel().getChildCount(
240 child.getDefaultParent());
242 for (int i = 0; i < blockCount; i++) {
243 mxCell cell = (mxCell) child.getModel().getChildAt(
244 child.getDefaultParent(), i);
245 if (cell instanceof ExplicitInBlock) {
252 protected List<mxCell> getAllImplicitInBlock() {
253 List<mxCell> list = new ArrayList<mxCell>();
258 int blockCount = child.getModel().getChildCount(
259 child.getDefaultParent());
261 for (int i = 0; i < blockCount; i++) {
262 mxCell cell = (mxCell) child.getModel().getChildAt(
263 child.getDefaultParent(), i);
264 if (cell instanceof ImplicitInBlock) {
271 protected List<mxCell> getAllEventInBlock() {
272 List<mxCell> list = new ArrayList<mxCell>();
277 int blockCount = child.getModel().getChildCount(
278 child.getDefaultParent());
280 for (int i = 0; i < blockCount; i++) {
281 mxCell cell = (mxCell) child.getModel().getChildAt(
282 child.getDefaultParent(), i);
283 if (cell instanceof EventInBlock) {
290 protected List<mxCell> getAllExplicitOutBlock() {
291 List<mxCell> list = new ArrayList<mxCell>();
296 int blockCount = child.getModel().getChildCount(
297 child.getDefaultParent());
299 for (int i = 0; i < blockCount; i++) {
300 mxCell cell = (mxCell) child.getModel().getChildAt(
301 child.getDefaultParent(), i);
302 if (cell instanceof ExplicitOutBlock) {
309 protected List<mxCell> getAllImplicitOutBlock() {
310 List<mxCell> list = new ArrayList<mxCell>();
315 int blockCount = child.getModel().getChildCount(
316 child.getDefaultParent());
318 for (int i = 0; i < blockCount; i++) {
319 mxCell cell = (mxCell) child.getModel().getChildAt(
320 child.getDefaultParent(), i);
321 if (cell instanceof ImplicitOutBlock) {
328 protected List<mxCell> getAllEventOutBlock() {
329 List<mxCell> list = new ArrayList<mxCell>();
331 int blockCount = child.getModel().getChildCount(
332 child.getDefaultParent());
334 for (int i = 0; i < blockCount; i++) {
335 mxCell cell = (mxCell) child.getModel().getChildAt(
336 child.getDefaultParent(), i);
337 if (cell instanceof EventOutBlock) {
344 protected int getBlocksConsecutiveUniqueValueCount(List<mxCell> blocks) {
345 if (blocks == null) {
349 int count = blocks.size();
350 int[] array = new int[blocks.size()];
353 for (int i = 0; i < array.length; i++) {
358 for (int i = 0; i < array.length; i++) {
359 int index = (Integer) ((BasicBlock) blocks.get(i)).getValue();
360 if (index <= array.length) {
361 array[index - 1] = 1;
366 for (int i = 0; i < array.length; i++) {
376 public void updateAllBlocksColor() {
377 updateBlocksColor(getAllExplicitInBlock());
378 updateBlocksColor(getAllImplicitInBlock());
379 updateBlocksColor(getAllEventInBlock());
381 updateBlocksColor(getAllExplicitOutBlock());
382 updateBlocksColor(getAllImplicitOutBlock());
383 updateBlocksColor(getAllEventOutBlock());
386 private void updateBlocksColor(List<mxCell> blocks) {
389 child.getModel().beginUpdate();
390 if (blocks == null || blocks.size() == 0) {
394 int countUnique = getBlocksConsecutiveUniqueValueCount(blocks);
395 boolean isDone[] = new boolean[countUnique];
398 for (int i = 0; i < countUnique; i++) {
402 for (int i = 0; i < blocks.size(); i++) {
403 int index = (Integer) ((BasicBlock) blocks.get(i)).getValue();
404 if (index > countUnique || isDone[index - 1] == true) {
405 child.getAsComponent().setCellWarning(blocks.get(i),
406 "Wrong port number");
408 isDone[index - 1] = true;
409 child.getAsComponent().setCellWarning(blocks.get(i), null);
413 child.getModel().endUpdate();
417 public void updateExportedPort() {
422 updateExportedExplicitInputPort();
423 updateExportedImplicitInputPort();
424 updateExportedEventInputPort();
425 updateExportedExplicitOutputPort();
426 updateExportedImplicitOutputPort();
427 updateExportedEventOutputPort();
428 getParentDiagram().fireEvent(XcosEvent.SUPER_BLOCK_UPDATED,
429 new mxEventObject(new Object[] { this }));
432 private void updateExportedExplicitInputPort() {
433 int blockCount = getBlocksConsecutiveUniqueValueCount(getAllExplicitInBlock());
434 List<ExplicitInputPort> ports = BasicBlockInfo
435 .getAllExplicitInputPorts(this, false);
437 int portCount = ports.size();
439 while (blockCount > portCount) { // add if required
440 ExplicitInputPort port = new ExplicitInputPort();
441 port.setDefaultValues();
446 while (portCount > blockCount) { // remove if required
447 removePort(ports.get(portCount - 1));
452 private void updateExportedImplicitInputPort() {
453 int blockCount = getBlocksConsecutiveUniqueValueCount(getAllImplicitInBlock());
454 List<ImplicitInputPort> ports = BasicBlockInfo
455 .getAllImplicitInputPorts(this, false);
457 int portCount = ports.size();
459 while (blockCount > portCount) { // add if required
460 addPort(new ImplicitInputPort());
464 while (portCount > blockCount) { // remove if required
465 removePort(ports.get(portCount - 1));
470 private void updateExportedEventInputPort() {
471 int blockCount = getBlocksConsecutiveUniqueValueCount(getAllEventInBlock());
472 List<ControlPort> ports = BasicBlockInfo
473 .getAllControlPorts(this, false);
475 int portCount = ports.size();
477 while (blockCount > portCount) { // add if required
478 addPort(new ControlPort());
482 while (portCount > blockCount) { // remove if required
483 removePort(ports.get(portCount - 1));
488 private void updateExportedExplicitOutputPort() {
489 int blockCount = getBlocksConsecutiveUniqueValueCount(getAllExplicitOutBlock());
490 List<ExplicitOutputPort> ports = BasicBlockInfo
491 .getAllExplicitOutputPorts(this, false);
493 int portCount = ports.size();
495 while (blockCount > portCount) { // add if required
496 ExplicitOutputPort port = new ExplicitOutputPort();
497 port.setDefaultValues();
502 while (portCount > blockCount) { // remove if required
503 removePort(ports.get(portCount - 1));
508 private void updateExportedImplicitOutputPort() {
509 int blockCount = getBlocksConsecutiveUniqueValueCount(getAllImplicitOutBlock());
510 List<ImplicitOutputPort> ports = BasicBlockInfo
511 .getAllImplicitOutputPorts(this, false);
513 int portCount = ports.size();
515 while (blockCount > portCount) { // add if required
516 addPort(new ImplicitOutputPort());
520 while (portCount > blockCount) { // remove if required
521 removePort(ports.get(portCount - 1));
526 private void updateExportedEventOutputPort() {
527 int blockCount = getBlocksConsecutiveUniqueValueCount(getAllEventOutBlock());
528 List<CommandPort> ports = BasicBlockInfo
529 .getAllCommandPorts(this, false);
531 int portCount = ports.size();
533 while (blockCount > portCount) { // add if required
534 addPort(new CommandPort());
538 while (portCount > blockCount) { // remove if required
539 removePort(ports.get(portCount - 1));
545 * Mask the SuperBlock
548 setInterfaceFunctionName("DSUPER");
549 setSimulationFunctionName("csuper");
553 * Unmask the SuperBlock
555 public void unmask() {
556 setInterfaceFunctionName("SUPER_f");
557 setSimulationFunctionName("super");
561 * @return True is the SuperBlock is masked, false otherwise
563 public boolean isMasked() {
564 return getInterfaceFunctionName().compareTo("SUPER_f") != 0;