929fb264b21b42a926b67c28462b261c9eb8c41a
[scilab.git] / scilab / modules / graphic_objects / src / java / org / scilab / modules / graphic_objects / graphicObject / GraphicObject.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2011 - DIGITEO - Manuel JULIACHS
4  * Copyright (C) 2011 - DIGITEO - Vincent COUVERT
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 package org.scilab.modules.graphic_objects.graphicObject;
15
16 import org.scilab.modules.graphic_objects.ObjectRemovedException;
17 import org.scilab.modules.graphic_objects.axes.Axes;
18 import org.scilab.modules.graphic_objects.figure.Figure;
19 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
20 import org.scilab.modules.graphic_objects.legend.Legend;
21
22 import java.util.Arrays;
23 import java.util.LinkedList;
24 import java.util.List;
25
26 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.*;
27
28 /**
29  * GraphicObject class
30  * @author Manuel JULIACHS
31  * @author Vincent COUVERT
32  */
33 public abstract class GraphicObject implements Cloneable {
34
35     public enum UpdateStatus {
36         Success,        // Property updated with new values
37         NoChange,       // Property leave unchanged
38         Fail            // Update Fail
39     };
40
41     /** User data array default size */
42     public static final int USER_DATA_DEFAULT_SIZE = 0;
43
44     /** Graphic objects types */
45     public enum Type { ARC, AXES, AXESMODEL, AXIS, CHAMP, COMPOUND, FAC3D, FEC, FIGURE, FIGUREMODEL, GRAYPLOT,
46                        LABEL, LEGEND, MATPLOT, PLOT3D, POLYLINE, RECTANGLE, SEGS, TEXT, CHECKBOX, EDIT, FRAME,
47                        IMAGE, LISTBOX, POPUPMENU, PUSHBUTTON, RADIOBUTTON, CONSOLE, JAVACONSOLE, SLIDER, TABLE, UITEXT, UIMENU, UIMENUMODEL,
48                        PROGRESSIONBAR, WAITBAR, UICONTEXTMENU, UNKNOWNOBJECT
49                      };
50
51     /** GraphicObject properties */
52     public enum GraphicObjectPropertyType { PARENT, CHILDREN, CHILDREN_COUNT, HIDDEN, VISIBLE, USERDATA, USERDATASIZE, TYPE, REFERENCED, VALID, DATA,
53                                             PARENT_FIGURE, PARENT_AXES, HASLEGENDCHILD, LEGENDCHILD, SELECTEDCHILD, TAG, CALLBACK, CALLBACKTYPE, UNKNOWNPROPERTY
54                                           };
55
56     /** Identifier */
57     private String identifier;
58
59     /** Parent object is known by its UID */
60     private String parent;
61
62     /** Child objects list. Known by their UID */
63     private List <String> children;
64
65     /** Specifies whether the object is visible or not */
66     private boolean visible;
67
68     /** Specifies if the "handle" is referenced in scilab */
69     private boolean referenced;
70
71     /** Specifies if the "handle" is valid, i.e included in a rendered object */
72     private boolean valid;
73
74     /** Specifies if the "handle" is hidden, i.e not listed as children in Scilab view */
75     private boolean hidden;
76
77     /** User data */
78     private Integer[] userData;
79
80     /** Tag */
81     private String tag;
82
83     /** Callback */
84     private CallBack callback;
85
86     /**
87      * Identifier of the selected child
88      * This was previously implemented as a list, but is used in practice
89      * to store only the identifier of the currently selected child.
90      * To do: use a list if required
91      */
92     private String selectedChild;
93
94     /** Constructor */
95     public GraphicObject() {
96         identifier = null;
97         parent = "";
98         children = new LinkedList<String>();
99         visible = true;
100         userData = null;
101         valid = true;
102         referenced = false;
103         selectedChild = "";
104         tag = "";
105         callback = new CallBack("");
106     }
107
108     /**
109      * Clone
110      * @return clone
111      * @see java.lang.Object#clone()
112      */
113     public GraphicObject clone() {
114         GraphicObject copy = null;
115
116         try {
117             copy = (GraphicObject) super.clone();
118         } catch (CloneNotSupportedException e) {
119             // TODO Auto-generated catch block
120             e.printStackTrace();
121         }
122
123         /*
124          * Creating an empty list is done to avoid
125          * still referencing the original object's own list,
126          * which occurs when the Figure model is cloned.
127          */
128         copy.setChildren(new LinkedList<String>());
129
130         /*
131          * Avoids keeping the Figure model as a parent
132          * when the Axes model is cloned.
133          */
134         copy.setParent("");
135
136         /*
137          * Sets no object as the selected child.
138          */
139         copy.setSelectedChild("");
140
141         return copy;
142     }
143
144     abstract public void accept(Visitor visitor) throws ObjectRemovedException;
145
146     /**
147      * Returns the enum associated to a type name
148      * @param typeName the property name
149      * @return the type enum
150      */
151     public static Type getTypeFromName(int typeName) {
152         switch (typeName) {
153         case __GO_ARC__ :
154             return Type.ARC;
155         case __GO_AXES__ :
156             return Type.AXES;
157         case __GO_AXESMODEL__ :
158             return Type.AXESMODEL;
159         case __GO_AXIS__ :
160             return Type.AXIS;
161         case __GO_CHAMP__ :
162             return Type.CHAMP;
163         case __GO_COMPOUND__ :
164             return Type.COMPOUND;
165         case __GO_FAC3D__ :
166             return Type.FAC3D;
167         case __GO_FEC__ :
168             return Type.FEC;
169         case __GO_FIGURE__ :
170             return Type.FIGURE;
171         case __GO_FIGUREMODEL__ :
172             return Type.FIGUREMODEL;
173         case __GO_GRAYPLOT__ :
174             return Type.GRAYPLOT;
175         case __GO_LABEL__ :
176             return Type.LABEL;
177         case __GO_LEGEND__ :
178             return Type.LEGEND;
179         case __GO_MATPLOT__ :
180             return Type.MATPLOT;
181         case __GO_PLOT3D__ :
182             return Type.PLOT3D;
183         case __GO_POLYLINE__ :
184             return Type.POLYLINE;
185         case __GO_RECTANGLE__ :
186             return Type.RECTANGLE;
187         case __GO_SEGS__ :
188             return Type.SEGS;
189         case __GO_TEXT__ :
190             return Type.TEXT;
191         case __GO_UI_CHECKBOX__ :
192             return Type.CHECKBOX;
193         case __GO_UI_EDIT__ :
194             return Type.EDIT;
195         case __GO_UI_FRAME__ :
196             return Type.FRAME;
197         case __GO_UI_IMAGE__ :
198             return Type.IMAGE;
199         case __GO_UI_LISTBOX__ :
200             return Type.LISTBOX;
201         case __GO_UI_POPUPMENU__ :
202             return Type.POPUPMENU;
203         case __GO_UI_PUSHBUTTON__ :
204             return Type.PUSHBUTTON;
205         case __GO_UI_RADIOBUTTON__ :
206             return Type.RADIOBUTTON;
207         case __GO_UI_SLIDER__ :
208             return Type.SLIDER;
209         case __GO_UI_TABLE__ :
210             return Type.TABLE;
211         case __GO_UI_TEXT__ :
212             return Type.UITEXT;
213         case __GO_UIMENU__ :
214             return Type.UIMENU;
215         case __GO_UICONTEXTMENU__ :
216             return Type.UICONTEXTMENU;
217         case __GO_PROGRESSIONBAR__ :
218             return Type.PROGRESSIONBAR;
219         case __GO_WAITBAR__ :
220             return Type.WAITBAR;
221         default :
222             return Type.UNKNOWNOBJECT;
223         }
224     }
225
226     /**
227      * Returns the enum associated to a property name
228      * @param propertyName the property name
229      * @return the property enum
230      */
231     public Object getPropertyFromName(int propertyName) {
232         switch (propertyName) {
233         case __GO_PARENT__ :
234             return  GraphicObjectPropertyType.PARENT;
235         case __GO_CHILDREN__ :
236             return GraphicObjectPropertyType.CHILDREN;
237         case __GO_CHILDREN_COUNT__ :
238             return GraphicObjectPropertyType.CHILDREN_COUNT;
239         case __GO_HIDDEN__ :
240             return GraphicObjectPropertyType.HIDDEN;
241         case __GO_VISIBLE__ :
242             return GraphicObjectPropertyType.VISIBLE;
243         case __GO_USER_DATA__ :
244             return GraphicObjectPropertyType.USERDATA;
245         case __GO_USER_DATA_SIZE__ :
246             return GraphicObjectPropertyType.USERDATASIZE;
247         case __GO_REFERENCED__ :
248             return GraphicObjectPropertyType.REFERENCED;
249         case __GO_VALID__ :
250             return GraphicObjectPropertyType.VALID;
251         case __GO_PARENT_FIGURE__ :
252             return GraphicObjectPropertyType.PARENT_FIGURE;
253         case __GO_PARENT_AXES__ :
254             return GraphicObjectPropertyType.PARENT_AXES;
255         case __GO_HAS_LEGEND_CHILD__ :
256             return GraphicObjectPropertyType.HASLEGENDCHILD;
257         case __GO_LEGEND_CHILD__ :
258             return GraphicObjectPropertyType.LEGENDCHILD;
259         case __GO_SELECTED_CHILD__ :
260             return GraphicObjectPropertyType.SELECTEDCHILD;
261         case __GO_TYPE__ :
262             return GraphicObjectPropertyType.TYPE;
263         case __GO_DATA_MODEL__ :
264             return GraphicObjectPropertyType.DATA;
265         case __GO_TAG__ :
266             return GraphicObjectPropertyType.TAG;
267         case __GO_CALLBACK__ :
268             return GraphicObjectPropertyType.CALLBACK;
269         case __GO_CALLBACKTYPE__ :
270             return GraphicObjectPropertyType.CALLBACKTYPE;
271         default:
272             //System.err.println("[ERROR] Unknown Property : "+propertyName+" !!!!!!!!!!");
273             return GraphicObjectPropertyType.UNKNOWNPROPERTY;
274         }
275     }
276
277     /**
278      * Fast property get method
279      * @param property the property to get
280      * @return the property value
281      */
282     public Object getProperty(Object property) {
283         if (property == GraphicObjectPropertyType.PARENT) {
284             return getParent();
285         } else if (property == GraphicObjectPropertyType.CHILDREN) {
286             return getChildren();
287         } else if (property == GraphicObjectPropertyType.CHILDREN_COUNT) {
288             return getChildren().length;
289         } else if (property == GraphicObjectPropertyType.VALID) {
290             return isValid();
291         } else if (property == GraphicObjectPropertyType.HIDDEN) {
292             return isHidden();
293         } else if (property == GraphicObjectPropertyType.VISIBLE) {
294             return getVisible();
295         } else if (property == GraphicObjectPropertyType.USERDATA) {
296             return getUserData();
297         } else if (property == GraphicObjectPropertyType.USERDATASIZE) {
298             return getUserDataSize();
299         } else if (property == GraphicObjectPropertyType.PARENT_FIGURE) {
300             return getParentFigure();
301         } else if (property == GraphicObjectPropertyType.PARENT_AXES) {
302             return getParentAxes();
303         } else if (property == GraphicObjectPropertyType.HASLEGENDCHILD) {
304             return getHasLegendChild();
305         } else if (property == GraphicObjectPropertyType.LEGENDCHILD) {
306             return getLegendChild();
307         } else if (property == GraphicObjectPropertyType.SELECTEDCHILD) {
308             return getSelectedChild();
309         } else if (property == GraphicObjectPropertyType.TYPE) {
310             return getType();
311         }  else if (property == GraphicObjectPropertyType.DATA) {
312             return getIdentifier();
313         }  else if (property == GraphicObjectPropertyType.TAG) {
314             return getTag();
315         }  else if (property == GraphicObjectPropertyType.CALLBACK) {
316             return getCallbackString();
317         }  else if (property == GraphicObjectPropertyType.CALLBACKTYPE) {
318             return getCallbackType();
319         }  else if (property == GraphicObjectPropertyType.UNKNOWNPROPERTY) {
320             return null;
321         } else {
322             return null;
323         }
324     }
325
326     /**
327      * Fast property set method
328      * @param property the property to set
329      * @param value the property value
330      * @return true if the property has been set, false otherwise
331      */
332     public UpdateStatus setProperty(Object property, Object value) {
333         if (property == GraphicObjectPropertyType.PARENT) {
334             setParent((String) value);
335         } else if (property == GraphicObjectPropertyType.CHILDREN) {
336             setChildren((String[]) value);
337         } else if (property == GraphicObjectPropertyType.VALID) {
338             setValid((Boolean) value);
339         } else if (property == GraphicObjectPropertyType.HIDDEN) {
340             setHidden((Boolean) value);
341         } else if (property == GraphicObjectPropertyType.VISIBLE) {
342             setVisible((Boolean) value);
343         } else if (property == GraphicObjectPropertyType.USERDATA) {
344             setUserData((Integer[]) value);
345         } else if (property == GraphicObjectPropertyType.USERDATASIZE) {
346             return UpdateStatus.Fail;
347         } else if (property == GraphicObjectPropertyType.SELECTEDCHILD) {
348             setSelectedChild((String) value);
349         } else if (property == GraphicObjectPropertyType.DATA) {
350             return UpdateStatus.Success;
351         } else if (property == GraphicObjectPropertyType.TAG) {
352             setTag((String) value);
353         } else if (property == GraphicObjectPropertyType.CALLBACK) {
354             setCallbackString((String) value);
355         } else if (property == GraphicObjectPropertyType.CALLBACKTYPE) {
356             setCallbackType((Integer) value);
357         } else if (property == GraphicObjectPropertyType.UNKNOWNPROPERTY) {
358             return UpdateStatus.Fail;
359         }
360
361         return UpdateStatus.Success;
362     }
363
364     /**
365      * Returns a null property
366      * @param property property name
367      * @return null property
368      */
369     public Object getNullProperty(String property) {
370         return null;
371     }
372
373     /**
374      * Void property get method
375      * @param property the property name
376      */
377     public Object getPropertyVoid(String property) {
378         // TODO
379         return null;
380     }
381
382     /* TODO */
383     /**
384      * Void property set method
385      * @param property the property name
386      * @param value the property value
387      */
388     public void setPropertyVoid(String property, Object value) {
389         // TODO
390     }
391
392     /**
393      * @return the children
394      */
395     public String[] getChildren() {
396         return children.toArray(new String[children.size()]);
397     }
398
399     /**
400      * Adds a child.
401      * @param child the identifier of the added child.
402      */
403     public void addChild(String child) {
404         if (!children.contains(child)) {
405             children.add(0, child);
406         }
407     }
408
409     /**
410      * Removes a child.
411      * @param child the identifier of the removed child.
412      */
413     public void removeChild(String child) {
414         children.remove(child);
415     }
416
417     /**
418      * @param children the children to set
419      */
420     private void setChildren(List<String> children) {
421         this.children = children;
422     }
423
424     /**
425      * @param children the children to set
426      */
427     public void setChildren(String[] children) {
428         this.children = new LinkedList<String>(Arrays.asList(children));
429     }
430
431     /**
432      * @return the identifier
433      */
434     public String getIdentifier() {
435         return identifier;
436     }
437
438     /**
439      * @param identifier the identifier to set
440      */
441     public void setIdentifier(String identifier) {
442         this.identifier = identifier;
443     }
444
445     /**
446      * @return the parent
447      */
448     public String getParent() {
449         return parent;
450     }
451
452     /**
453      * @param parent the parent to set
454      */
455     public void setParent(String parent) {
456         this.parent = parent;
457     }
458
459     /**
460      * @return the userData
461      */
462     public Object getUserData() {
463         return userData;
464     }
465
466     /**
467      * @param userData the userData to set
468      */
469     public void setUserData(Integer[] userData) {
470         this.userData = userData;
471     }
472
473     /**
474      * @return the userDataSize
475      */
476     public Integer getUserDataSize() {
477         if (userData != null) {
478             return userData.length;
479         }
480         return 0;
481     }
482
483     /**
484      * @return the tag
485      */
486     public String getTag() {
487         return tag;
488     }
489
490     /**
491      * @param tag the tag to set
492      */
493     public void setTag(String tag) {
494         this.tag = tag;
495     }
496
497     /**
498      * @return the callback
499      */
500     public String getCallbackString() {
501         return callback.getCommand();
502     }
503
504     /**
505      * @param callback the callback to set
506      */
507     public void setCallbackString(String callback) {
508         this.callback.setCommand(callback);
509     }
510
511     /**
512      * @return the callbackType
513      */
514     public Integer getCallbackType() {
515         return callback.getCommandType();
516     }
517
518     /**
519      * @param callbackType the callbackType to set
520      */
521     public void setCallbackType(Integer callbackType) {
522         this.callback.setCommandType(callbackType);
523     }
524
525     /**
526      * Get parent Figure method
527      * Returns the identifier of the object's parent Figure
528      * If the object is a Figure, then returns its own identifier.
529      * To be done: use a member variable storing the up-to-date current parent Figure,
530      * returned instead of recursively ascending the hierarchy at each call.
531      * @return the parent Figure identifier
532      */
533     public String getParentFigure() {
534         if (this instanceof Figure) {
535             return getIdentifier();
536         } else {
537             if (getParent() != null && GraphicController.getController().getObjectFromId(getParent()) != null) {
538                 return GraphicController.getController().getObjectFromId(getParent()).getParentFigure();
539             } else {
540                 /* No parent Figure found */
541                 return "";
542             }
543         }
544     }
545
546     /**
547      * Get parent Axes method
548      * Returns the identifier of the object's parent Axes
549      * If the object is an Axes, then returns its own identifier.
550      * To be done: use a member variable storing the up-to-date current parent Axes,
551      * returned instead of recursively ascending the hierarchy at each call.
552      * @return the parent Axes identifier
553      */
554     public String getParentAxes() {
555         if (this instanceof Axes) {
556             return getIdentifier();
557         } else {
558             if (getParent() != null && GraphicController.getController().getObjectFromId(getParent()) != null) {
559                 return GraphicController.getController().getObjectFromId(getParent()).getParentAxes();
560             } else {
561                 /* No parent Axes found */
562                 return "";
563             }
564         }
565     }
566
567     /**
568      * Get has legend child method
569      * Returns a boolean indicating whether one of the object's direct children
570      * is a Legend object. Only one Legend is supposed to be present in the list.
571      * To be done: storing the property and updating it only when a Legend object
572      * is inserted or deleted instead of searching the children list when the
573      * property is queried.
574      * @return a Boolean indicating whether the object has a child Legend object or not
575      */
576     public Boolean getHasLegendChild() {
577         for (int i = 0; i < children.size(); i++) {
578             GraphicObject currentObject = GraphicController.getController().getObjectFromId(children.get(i));
579
580             if (currentObject instanceof Legend) {
581                 return true;
582             }
583         }
584
585         return false;
586     }
587
588     /**
589      * Returns the identifier of the object's direct child that is a Legend object.
590      * It returns an empty string if the object has no Legend in its children list
591      * (one Legend is supposed to be present at most).
592      * @return the object's child Legend object identifier, or an empty string if no child Legend found.
593      */
594     public String getLegendChild() {
595         for (int i = 0; i < children.size(); i++) {
596             GraphicObject currentObject = GraphicController.getController().getObjectFromId(children.get(i));
597
598             if (currentObject instanceof Legend) {
599                 return currentObject.getIdentifier();
600             }
601         }
602
603         /* No child legend found */
604         return "";
605     }
606
607     /**
608      * Get selected child method
609      * @return the selected child
610      */
611     public String getSelectedChild() {
612         return selectedChild;
613     }
614
615     /**
616      * Set selected child method
617      * @param selectedChild the selected child to set
618      */
619     public void setSelectedChild(String selectedChild) {
620         this.selectedChild = selectedChild;
621     }
622
623     /**
624      * Get visible method
625      * @return the visible
626      */
627     public Boolean getVisible() {
628         return visible;
629     }
630
631     /**
632      * Set visible method
633      * @param visible the visible to set
634      */
635     public void setVisible(Boolean visible) {
636         this.visible = visible;
637     }
638
639     /**
640      * Each type should name itself
641      * @return Type as String
642      */
643     public abstract Integer getType();
644
645     /**
646      * isValid method
647      * @return valid
648      */
649     public Boolean isValid() {
650         return valid;
651     }
652
653     /**
654      * Set hidden method
655      * @param hidden the value to set
656      */
657     public void setHidden(Boolean hidden) {
658         this.hidden = hidden;
659     }
660
661     /**
662      * isHidden method
663      * @return hidden
664      */
665     public Boolean isHidden() {
666         return hidden;
667     }
668
669     /**
670      * Set valid method
671      * @param valid the validity to set
672      */
673     public void setValid(Boolean valid) {
674         this.valid = valid;
675     }
676
677     /**
678      * isReferenced method
679      * @return referenced
680      */
681     public Boolean isReferenced() {
682         return referenced;
683     }
684
685     /**
686      * Set referenced method
687      * @param referenced the reference status to set
688      */
689     public void setReferenced(Boolean referenced) {
690         this.referenced = referenced;
691     }
692 }