2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015-2015 - Scilab Enterprises - Clement DAVID
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
16 package org.scilab.modules.xcos.graph.model;
18 import java.util.Collections;
19 import java.util.List;
21 import org.scilab.modules.xcos.JavaController;
22 import org.scilab.modules.xcos.Kind;
23 import org.scilab.modules.xcos.ObjectProperties;
24 import org.scilab.modules.xcos.PortKind;
25 import org.scilab.modules.xcos.VectorOfDouble;
26 import org.scilab.modules.xcos.VectorOfScicosID;
28 import com.mxgraph.model.mxCell;
29 import com.mxgraph.model.mxGeometry;
30 import com.mxgraph.model.mxICell;
31 import com.mxgraph.util.mxPoint;
32 import java.util.regex.Pattern;
34 public class XcosCell extends mxCell {
35 private static final long serialVersionUID = 1L;
36 private static Pattern validCIdentifier = Pattern.compile("[a-zA-Z][a-zA-Z0-9_]+");
38 private transient ScicosObjectOwner owner;
41 * Construct an Xcos graphical object.
43 * This Java object owns the corresponding MVC object and thus will unrefererence it on GC.
46 * the shared controller
48 * the associated MVC identifier
50 * the associated MVC kind
52 public XcosCell(final JavaController controller, long uid, Kind kind, Object value, mxGeometry geometry, String style, String id) {
55 // defensive programming
57 throw new IllegalArgumentException();
60 owner = new ScicosObjectOwner(controller, uid, kind);
61 setValue(controller, value);
62 setGeometry(controller, geometry);
63 setStyle(controller, style);
64 setId(controller, id);
68 * @return the MVC unique identifier
70 public long getUID() {
71 return owner.getUID();
75 * @return the MVC kind of object
77 public Kind getKind() {
78 return owner.getKind();
82 * Override setters and hierarchy modifiers to propagate changes to the model
88 * @see com.mxgraph.model.mxCell#setValue(java.lang.Object)
91 public void setValue(Object value) {
92 setValue(new JavaController(), value);
95 public final void setValue(JavaController controller, Object value) {
96 super.setValue(value);
97 setMVCValue(controller, value);
100 private void setMVCValue(JavaController controller, Object value) {
107 if (validCIdentifier.matcher(String.valueOf(value)).matches()) {
108 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.LABEL, String.valueOf(value));
110 // no break on purpose
112 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DESCRIPTION, String.valueOf(value));
116 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.LABEL, String.valueOf(value));
126 * @see com.mxgraph.model.mxCell#setId(java.lang.String)
129 public void setId(String id) {
130 setId(new JavaController(), id);
133 public final void setId(JavaController controller, String id) {
135 setMVCId(controller, id);
138 private void setMVCId(JavaController controller, String id) {
148 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.UID, id);
158 * @see com.mxgraph.model.mxCell#setGeometry(com.mxgraph.model.mxGeometry)
161 public void setGeometry(mxGeometry geometry) {
162 setGeometry(new JavaController(), geometry);
165 public final void setGeometry(JavaController controller, mxGeometry geometry) {
166 super.setGeometry(geometry);
167 setMVCGeometry(controller, geometry);
170 private void setMVCGeometry(JavaController controller, mxGeometry geometry) {
171 if (geometry == null) {
178 VectorOfDouble v = new VectorOfDouble(4);
179 v.set(0, geometry.getX());
180 v.set(1, geometry.getY());
181 v.set(2, geometry.getWidth());
182 v.set(3, geometry.getHeight());
183 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.GEOMETRY, v);
188 * try to find the origin of the source and target accordingly to the JGraphX implementation
190 mxPoint sourcePoint = null;
191 mxPoint targetPoint = null;
192 mxICell sourceCell = getSource();
193 mxICell targetCell = getTarget();
194 if (sourceCell != null && sourceCell.getGeometry() != null) {
195 sourcePoint = new mxPoint(sourceCell.getGeometry().getCenterX(), sourceCell.getGeometry().getCenterY());
197 if (targetCell != null && targetCell.getGeometry() != null) {
198 targetPoint = new mxPoint(targetCell.getGeometry().getCenterX(), targetCell.getGeometry().getCenterY());
200 if (sourcePoint == null) {
201 sourcePoint = geometry.getSourcePoint();
203 if (targetPoint == null) {
204 targetPoint = geometry.getTargetPoint();
206 if (sourcePoint == null) {
207 sourcePoint = new mxPoint();
209 if (targetPoint == null) {
210 targetPoint = new mxPoint();
212 List<mxPoint> points = geometry.getPoints();
213 if (points == null) {
214 points = Collections.emptyList();
218 * At that point, the sourcePoint, targetPoint and points are valid values (but may be unknown) encode them to the the CONTROL_POINTS
221 // Allocate some space to contains them all
222 int nbOfPoints = 2 + points.size();
223 VectorOfDouble v = new VectorOfDouble(2 * nbOfPoints);
225 // then fill the allocation space
226 v.set(2 * i, sourcePoint.getX());
227 v.set(2 * i + 1, sourcePoint.getY());
229 for (; i < nbOfPoints - 1; i++) {
230 v.set(2 * i, points.get(i - 1).getX());
231 v.set(2 * i + 1, points.get(i - 1).getY());
233 v.set(2 * i, targetPoint.getX());
234 v.set(2 * i + 1, targetPoint.getY());
237 * Finally push the values to the model
239 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.CONTROL_POINTS, v);
250 * @see com.mxgraph.model.mxCell#setStyle(java.lang.String)
253 public void setStyle(String style) {
254 setStyle(new JavaController(), style);
257 public final void setStyle(JavaController controller, String style) {
258 super.setStyle(style);
259 setMVCStyle(controller, style);
262 private void setMVCStyle(JavaController controller, String style) {
272 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.STYLE, style);
282 * @see com.mxgraph.model.mxCell#removeFromParent()
285 public void removeFromParent() {
286 super.removeFromParent();
288 // do not remove from parent on SUPER_f diagram creation : there is an MVC parent but no JGraphX one
289 if (parent == null) {
293 JavaController controller = new JavaController();
299 * Retrieve the parent
301 long[] parent = new long[1];
302 Kind parentKind = Kind.BLOCK;
303 ObjectProperties prop = ObjectProperties.PARENT_BLOCK;
304 controller.getObjectProperty(getUID(), getKind(), prop, parent);
305 if (parent[0] == 0l) {
306 parentKind = Kind.DIAGRAM;
307 prop = ObjectProperties.PARENT_DIAGRAM;
308 controller.getObjectProperty(getUID(), getKind(), prop, parent);
312 * If there is a parent, clear it
314 if (parent[0] != 0l) {
315 VectorOfScicosID children = new VectorOfScicosID();
316 controller.getObjectProperty(parent[0], parentKind, ObjectProperties.CHILDREN, children);
317 children.remove(getUID());
318 controller.setObjectProperty(parent[0], parentKind, ObjectProperties.CHILDREN, children);
320 controller.setObjectProperty(getUID(), getKind(), prop, 0l);
325 long[] parent = new long[1];
326 Kind parentKind = Kind.BLOCK;
327 controller.getObjectProperty(getUID(), getKind(), ObjectProperties.SOURCE_BLOCK, parent);
329 int[] portKind = new int[1];
330 controller.getObjectProperty(getUID(), getKind(), ObjectProperties.PORT_KIND, portKind);
331 ObjectProperties property = relatedPortKindProperty(portKind[0]);
333 VectorOfScicosID ports = new VectorOfScicosID();
334 controller.getObjectProperty(parent[0], parentKind, property, ports);
335 ports.remove(getUID());
336 controller.setObjectProperty(parent[0], parentKind, property, ports);
338 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SOURCE_BLOCK, 0l);
346 private ObjectProperties relatedPortKindProperty(int portKind) {
347 ObjectProperties property;
348 switch (PortKind.values()[portKind]) {
350 property = ObjectProperties.INPUTS;
353 property = ObjectProperties.OUTPUTS;
356 property = ObjectProperties.EVENT_INPUTS;
359 property = ObjectProperties.EVENT_OUTPUTS;
371 * @see com.mxgraph.model.mxCell#setParent(com.mxgraph.model.mxICell)
374 public void setParent(mxICell parent) {
375 super.setParent(parent);
377 if (parent instanceof XcosCell) {
378 XcosCell p = (XcosCell) parent;
379 JavaController controller = new JavaController();
384 if (p.getKind() == Kind.DIAGRAM) {
385 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.PARENT_DIAGRAM, p.getUID());
387 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.PARENT_BLOCK, p.getUID());
389 long[] root = new long[1];
390 controller.getObjectProperty(p.getUID(), p.getKind(), ObjectProperties.PARENT_DIAGRAM, root);
391 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.PARENT_DIAGRAM, root[0]);
395 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SOURCE_BLOCK, p.getUID());
404 public mxICell setTerminal(mxICell terminal, boolean isSource) {
405 mxICell cell = super.setTerminal(terminal, isSource);
410 // a terminal of an XcosCell is always another XcosCell
411 final long uid = ((XcosCell) cell).getUID();
412 final Kind kind = ((XcosCell) cell).getKind();
414 JavaController controller = new JavaController();
418 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.SOURCE_PORT, uid);
420 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DESTINATION_PORT, uid);
423 controller.setObjectProperty(uid, kind, ObjectProperties.CONNECTED_SIGNALS, getUID());
436 * @see com.mxgraph.model.mxCell#insert(com.mxgraph.model.mxICell, int)
439 public mxICell insert(mxICell child, int index) {
440 mxICell inserted = super.insert(child, index);
442 // the child might not be an XcosCell but just an mxCell label
443 if (child instanceof XcosCell) {
444 XcosCell c = (XcosCell) child;
447 if (c.getKind() == Kind.PORT) {
448 insertPort(c, index);
450 insertChild(c, index);
454 insertChild(c, index);
460 JavaController controller = new JavaController();
461 controller.referenceObject(c.getUID());
467 private void insertPort(XcosCell c, int index) {
468 JavaController controller = new JavaController();
469 int[] v = new int[1];
470 controller.getObjectProperty(c.getUID(), c.getKind(), ObjectProperties.PORT_KIND, v);
472 VectorOfScicosID children = new VectorOfScicosID();
473 final ObjectProperties property = relatedPortKindProperty(v[0]);
475 if (property != null) {
476 controller.getObjectProperty(getUID(), getKind(), property, children);
477 // do no use the index argument as it is not possible to insert out of order on the MVC (as we have kind of port)
478 children.add(c.getUID());
479 controller.setObjectProperty(getUID(), getKind(), property, children);
483 private void insertChild(XcosCell c, int index) {
484 JavaController controller = new JavaController();
485 VectorOfScicosID children = new VectorOfScicosID();
487 controller.getObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
488 children.add(index, c.getUID());
489 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
495 * @see com.mxgraph.model.mxCell#remove(com.mxgraph.model.mxICell)
498 public mxICell remove(mxICell child) {
499 mxICell removed = super.remove(child);
501 // the child might not be an XcosCell but just an mxCell label
502 if (child instanceof XcosCell) {
503 XcosCell c = (XcosCell) child;
506 if (c.getKind() == Kind.PORT) {
519 JavaController controller = new JavaController();
520 controller.deleteObject(c.getUID());
525 private void removePort(XcosCell c) {
526 JavaController controller = new JavaController();
527 int[] v = new int[1];
528 controller.getObjectProperty(c.getUID(), c.getKind(), ObjectProperties.PORT_KIND, v);
530 VectorOfScicosID children = new VectorOfScicosID();
531 final ObjectProperties property;
532 switch (PortKind.values()[v[0]]) {
534 property = ObjectProperties.INPUTS;
537 property = ObjectProperties.OUTPUTS;
540 property = ObjectProperties.EVENT_INPUTS;
543 property = ObjectProperties.EVENT_OUTPUTS;
550 controller.getObjectProperty(getUID(), getKind(), property, children);
551 children.remove(c.getUID());
552 controller.setObjectProperty(getUID(), getKind(), property, children);
555 private void removeChild(XcosCell c) {
556 JavaController controller = new JavaController();
557 VectorOfScicosID children = new VectorOfScicosID();
559 controller.getObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
560 children.remove(c.getUID());
561 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
566 * Override methods from Object
570 public Object clone() throws CloneNotSupportedException {
571 JavaController controller = new JavaController();
572 XcosCell c = (XcosCell) super.clone();
574 c.owner = new ScicosObjectOwner(controller.cloneObject(getUID(), true, false), getKind());