Bug 13386 fixed: There was a npe thrown in the graphic
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / editor / LegendHandler.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Pedro Arthur dos S. Souza
4  * Copyright (C) 2012 - Caio Lucas dos S. Souza
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.1-en.txt
11  *
12  */
13
14 package org.scilab.modules.gui.editor;
15
16 import java.util.Arrays;
17 import java.util.List;
18 import java.util.ArrayList;
19 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
20 import org.scilab.modules.graphic_objects.graphicObject.GraphicObject;
21 import org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties;
22
23 import org.scilab.modules.gui.editor.ObjectSearcher;
24 import org.scilab.modules.gui.editor.PolylineHandler;
25
26
27 /**
28 * Implements all legend manipulation functions for the editor.
29 *
30 * @author Caio Souza <caioc2bolado@gmail.com>
31 * @author Pedro Souza <bygrandao@gmail.com>
32 *
33 * @since 2012-06-01
34 */
35 public class LegendHandler {
36
37     public static Integer searchLegend(Integer uid) {
38         if (uid == null) {
39             return null;
40         }
41
42         int childCount = (Integer)GraphicController.getController().getProperty(uid, GraphicObjectProperties.__GO_CHILDREN_COUNT__);
43         Integer[] child = (Integer[])GraphicController.getController().getProperty(uid, GraphicObjectProperties.__GO_CHILDREN__);
44         if (child != null) {
45             for (int i = 0; i < childCount; i++) {
46                 Object o = GraphicController.getController().getProperty(child[i], GraphicObjectProperties.__GO_TYPE__);
47                 if (o instanceof Integer) {
48                     Integer type = (Integer) o;
49                     if (type == GraphicObjectProperties.__GO_LEGEND__) {
50                         return child[i];
51                     }
52                 }
53             }
54         }
55         return null;
56     }
57
58     /**
59     * Set or create a legend for one polyline.
60     *
61     * @param axes The axes that will recieve the legend.
62     * @param polyline The polyline to set/create legend.
63     * @param text The text for the legend.
64     */
65
66     public static void setLegend(Integer axes, Integer polyline, String text) {
67         if (text == null || text == "" || polyline == null || axes == null) {
68             return;
69         }
70
71         Integer legend = searchLegend(axes);
72         Integer[] dimension = { 0, 0 };
73         ArrayList<String> texts = new ArrayList<String>();
74         ArrayList<Integer> links = new ArrayList<Integer>();
75         texts.add(text);
76         if (legend != null) {
77             String[] textOld = (String[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_TEXT_STRINGS__);
78             Integer[] linksOld = (Integer[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_LINKS__);
79             int length = linksOld.length;
80             for (int i = 0; i < length; i++) {
81                 if (polyline != linksOld[i]) {
82                     texts.add(textOld[i]);
83                     links.add(linksOld[i]);
84                 } else {
85                     removeLegend(axes, polyline);
86                     setLegend(axes, polyline, text);
87                     return;
88                 }
89             }
90             CommonHandler.delete(legend);
91         }
92         legend = GraphicController.getController().askObject(GraphicObject.getTypeFromName(GraphicObjectProperties.__GO_LEGEND__));
93         GraphicController.getController().setGraphicObjectRelationship(axes, legend);
94
95         links.add(polyline);
96         String[] textToSet = new String[texts.size()];
97         texts.toArray(textToSet);
98         Integer[] linksToSet = new Integer[links.size()];
99         links.toArray(linksToSet);
100         dimension[0] = linksToSet.length;
101         dimension[1] = 1;
102         if (dimension[0] != 0) {
103             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_TEXT_ARRAY_DIMENSIONS__, dimension);
104             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_LINE_MODE__, true);
105             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_TEXT_STRINGS__, textToSet);
106             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_LINKS__, linksToSet);
107             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_LEGEND_LOCATION__, 0);
108         }
109     }
110
111     /**
112     * Remove a legend from axes.
113     *
114     * @param axes The axes to remove the legend.
115     * @param polyline The polyline that is linked to the legend.
116     */
117
118     public static void removeLegend(Integer axes, Integer polyline) {
119         if (polyline == null || axes == null) {
120             return;
121         }
122
123         Integer legend = searchLegend(axes);
124         Integer[] dimension = { 0, 0 };
125         ArrayList<String> texts = new ArrayList<String>();
126         ArrayList<Integer> links = new ArrayList<Integer>();
127         if (legend == null) {
128             return;
129         } else {
130             String[] textOld = (String[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_TEXT_STRINGS__);
131             Integer[] linksOld = (Integer[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_LINKS__);
132             int remove = -1;
133             for (int i = 0; i < linksOld.length; i++) {
134                 if (polyline != linksOld[i]) {
135                     links.add(linksOld[i]);
136                 } else {
137                     remove = i;
138                 }
139             }
140             for (int i = 0; i < textOld.length; i++) {
141                 if (i != (textOld.length - remove - 1)) {
142                     texts.add(textOld[i]);
143                 }
144             }
145         }
146         String[] textToSet = new String[texts.size()];
147         texts.toArray(textToSet);
148         Integer[] linksToSet = new Integer[links.size()];
149         links.toArray(linksToSet);
150         dimension[0] = linksToSet.length;
151         dimension[1] = 1;
152         if (dimension[0] != 0) {
153             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_TEXT_ARRAY_DIMENSIONS__, dimension);
154             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_LINE_MODE__, true);
155             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_TEXT_STRINGS__, textToSet);
156             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_LINKS__, linksToSet);
157             GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_LEGEND_LOCATION__, 0);
158         } else {
159             CommonHandler.delete(legend);
160         }
161     }
162
163     /**
164     * Get the text of the legend.
165     *
166     * @param axes The axes where is the legend.
167     * @param polyline The polyline that is linked to the legend.
168     * @return The text of the legend.
169     */
170
171     public static String getLegendText(Integer axes, Integer polyline) {
172         if (polyline != null && axes != null) {
173             Integer legend = searchLegend(axes);
174             if (legend == null) {
175                 return null;
176             } else {
177                 String[] textOld = (String[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_TEXT_STRINGS__);
178                 Integer[] linksOld = (Integer[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_LINKS__);
179                 for (int i = 0; i < linksOld.length; i++) {
180                     if (linksOld[i] == polyline) {
181                         return textOld[linksOld.length - i - 1];
182                     }
183                 }
184             }
185         }
186         return null;
187     }
188
189     /**
190     * Drag the given legend.
191     *
192     * @param legend  the legend uid.
193     * @param position click position (x,y).
194     * @param nextPosition dragged position (x,y).
195     */
196
197     public static void dragLegend(Integer legend, Integer[] position, Integer[] nextPosition) {
198         ObjectSearcher searcher = new ObjectSearcher();
199         Integer axes = searcher.searchParent(legend, GraphicObjectProperties.__GO_AXES__);
200         Integer figure = searcher.searchParent(legend, GraphicObjectProperties.__GO_FIGURE__);
201         Integer[] axesSize = { 0, 0 };
202         Double[] axesBounds = { 0., 0. }, diff = { 0., 0. }, legendPos = { 0., 0. };
203         if (legend == null || axes == null || figure == null) {
204             return;
205         }
206
207         axesSize = (Integer[])GraphicController.getController().getProperty(figure, GraphicObjectProperties.__GO_AXES_SIZE__);
208         axesBounds = (Double[])GraphicController.getController().getProperty(axes, GraphicObjectProperties.__GO_AXES_BOUNDS__);
209         legendPos = (Double[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_POSITION__);
210         if ( nextPosition[0] > (axesSize[0] - 10) || nextPosition[1] > (axesSize[1] - 10)) {
211             return;
212         }
213         diff[0] = (nextPosition[0] - position[0]) / (axesBounds[2] * axesSize[0]);
214         diff[1] = (nextPosition[1] - position[1]) / (axesBounds[3] * axesSize[1]);
215         legendPos[0] += diff[0];
216         legendPos[1] += diff[1];
217         GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_LEGEND_LOCATION__, 10);
218         GraphicController.getController().setProperty(legend, GraphicObjectProperties.__GO_POSITION__, legendPos);
219     }
220
221     /**
222     * Get the links of a Legend
223     *
224     * @param legend The legend to get the links
225     * @return Links of the legend
226     */
227     public static Integer[] getLinks(Integer legend) {
228         if (legend == null) {
229             return null;
230         } else {
231             return (Integer[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_LINKS__);
232         }
233     }
234
235     /**
236     * Get the text of a Legend
237     *
238     * @param legend The legend to get the text
239     * @return Text of the legend
240     */
241     public static String[] getText(Integer legend) {
242         if (legend == null) {
243             return null;
244         } else {
245             return (String[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_TEXT_STRINGS__);
246         }
247     }
248
249     /**
250     * Get the position of a Legend
251     *
252     * @param legend The legend to get the position
253     * @return The legend position
254     */
255     public static Double[] getPosition(Integer legend) {
256         if (legend == null) {
257             return null;
258         } else {
259             return (Double[])GraphicController.getController().getProperty(legend, GraphicObjectProperties.__GO_POSITION__);
260         }
261     }
262 }