/** {@inheritDoc} */ @Override public void actionPerformed(ActionEvent e) { final XcosDiagram parentGraph = (XcosDiagram) getGraph(e); // action disabled when the cell is edited final ScilabComponent comp = ((ScilabComponent) parentGraph.getAsComponent()); if (comp.isEditing()) { return; } parentGraph.info(XcosMessages.GENERATE_SUPERBLOCK); parentGraph.getModel().beginUpdate(); try { final SuperBlock superBlock; final Collection<Broken> brokenLinks; final Set<Object> inSelectionCells; /* * Allocate superBlock */ final Object[] selection = parentGraph.getSelectionCells(); final Object[] blocks = XcosDiagram.filterByClass(selection, BasicBlock.class); inSelectionCells = new LinkedHashSet<Object>(Arrays.asList(blocks)); superBlock = allocateSuperBlock(parentGraph, selection); /* * First perform all modification on the parent diagram to handle * well undo/redo operations. */ brokenLinks = updateParent(parentGraph, superBlock, inSelectionCells); /* * Then move some cells to the child diagram */ final SuperBlockDiagram childGraph = moveToChild(parentGraph, superBlock, brokenLinks, inSelectionCells); /* * Finish the install on the child and sync it. */ childGraph.installListeners(); childGraph.installSuperBlockListeners(); superBlock.invalidateRpar(); Xcos.getInstance().addDiagram(parentGraph.getSavedFile(), childGraph); } finally { parentGraph.getModel().endUpdate(); parentGraph.info(XcosMessages.EMPTY_INFO); } }
/** * Create child cells and add them to the parent diagram. All links are also reconnected * * @param parentGraph the parent diagram * @param superBlock the superblock * @param inSelectionCells the cells in the selection * @return the broken descriptor set */ private Collection<Broken> updateParent( final XcosDiagram parentGraph, final SuperBlock superBlock, final Set<Object> inSelectionCells) { final Collection<Broken> brokenLinks; final mxGraphModel parentModel = (mxGraphModel) parentGraph.getModel(); parentModel.beginUpdate(); try { /* * Add the internal links and fill border links Sort the broken * links by position (to perform a good numbering order) and keep * only one occurrence of a broken link. */ brokenLinks = new TreeSet<Broken>(); fillLinks(parentModel, inSelectionCells, brokenLinks); /* * Disconnect the broken links */ for (Broken broken : brokenLinks) { mxGraphModel.setTerminals(parentModel, broken.getParentLink(), null, null); } /* * Add the super block */ parentGraph.addCell(superBlock); /* * Main broken loop */ // ordering access is : IN, OUT, e_IN, e_OUT final int[] ordering = {0, 0, 0, 0}; for (Broken broken : brokenLinks) { // set the ordering incrementOrdering(ordering, broken); connectParent(parentGraph, parentModel, superBlock, broken); connectChild(parentGraph, parentModel, broken); /* * Update the view */ BlockPositioning.updateBlockView(broken.getChildBlock()); } } finally { parentModel.endUpdate(); } return brokenLinks; }