Do not recreate default axes on deletion.
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_delete.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - ENPC - Jean-Philipe Chancelier
4  * Copyright (C) 2006 - INRIA - Fabrice Leray
5  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
6  * Copyright (C) 2011 - DIGITEO - Bruno JOFRET
7  *
8  * This file must be used under the terms of the CeCILL.
9  * This source file is licensed as described in the file COPYING, which
10  * you should have received as part of this distribution.  The terms
11  * are also available at
12  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
13  *
14  */
15
16 /*------------------------------------------------------------------------*/
17 /* file: sci_delete.c                                                     */
18 /* desc : interface for delete routine                                    */
19 /*------------------------------------------------------------------------*/
20
21 #include "MALLOC.h"
22 #include "gw_graphics.h"
23 #include "api_scilab.h"
24 #include "DestroyObjects.h"
25 #include "SetProperty.h"
26 #include "GetProperty.h"
27 #include "DrawObjects.h"
28 #include "Interaction.h"
29 #include "localization.h"
30 #include "Scierror.h"
31 #include "HandleManagement.h"
32 #include "FigureList.h"
33 #include "deleteGraphicObject.h"
34 #include "CurrentObject.h"
35 #include "CurrentFigure.h"
36 #include "BuildObjects.h"
37
38 #include "AxesModel.h"
39 #include "FigureModel.h"
40
41 #include "getGraphicObjectProperty.h"
42 #include "graphicObjectProperties.h"
43 #include "getConsoleIdentifier.h"
44 #include "CurrentSubwin.h"
45 #include "sciprint.h"
46 #include "createGraphicObject.h"
47
48 #ifdef _MSC_VER
49 #include "strdup_windows.h"
50 #endif
51 /*--------------------------------------------------------------------------*/
52 int sci_delete(char *fname, unsigned long fname_len)
53 {
54     SciErr sciErr;
55
56     int* piAddrl1 = NULL;
57     long long* l1 = NULL;
58     int* piAddrl2 = NULL;
59     char* l2 = NULL;
60
61     int m1 = 0, n1 = 0, lw = 0;
62     unsigned long hdl = 0;
63     int nb_handles = 0, i = 0, dont_overload = 0;
64     int iObjUID = 0;
65     int iFigureUID = 0;
66     int* piChildrenUID = NULL;
67     int iChildrenCount = 0;
68     int* childrencount = &iChildrenCount;
69     int iHidden = 0;
70     int *piHidden = &iHidden;
71
72     int iParentUID = 0;
73     int* piParentUID = &iParentUID;
74     int iParentType = -1;
75     int *piParentType = &iParentType;
76     int iObjType = -1;
77     int *piObjType = &iObjType;
78
79     CheckInputArgument(pvApiCtx, 0, 1);
80     CheckOutputArgument(pvApiCtx, 0, 1);
81
82     if (nbInputArgument(pvApiCtx) == 0)               /* Delete current object */
83     {
84         iObjUID = getCurrentObject();
85         if (iObjUID == 0)
86         {
87             //No current object, we can leave
88             AssignOutputVariable(pvApiCtx, 1) = 0;
89             ReturnArguments(pvApiCtx);
90             return 0;
91         }
92
93         hdl = (unsigned long)getHandle(iObjUID);
94         dont_overload = 1;
95         nb_handles = 1;
96     }
97     else
98     {
99         sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddrl1);
100         if (sciErr.iErr)
101         {
102             printError(&sciErr, 0);
103             return 1;
104         }
105
106         switch (getInputArgumentType(pvApiCtx, 1))
107         {
108             case sci_matrix:
109             {
110                 if (isEmptyMatrix(pvApiCtx, piAddrl1))
111                 {
112                     AssignOutputVariable(pvApiCtx, 1) = 0;
113                     ReturnArguments(pvApiCtx);
114                     return 1;
115                 }
116                 else
117                 {
118                     Scierror(202, _("%s: Wrong type for input argument #%d: Handle matrix expected.\n"), fname, 1);
119                     return 1;
120                 }
121                 break;
122             }
123             case sci_handles:      /* delete Entity given by a handle */
124
125                 // Retrieve a matrix of handle at position 1.
126                 sciErr = getMatrixOfHandle(pvApiCtx, piAddrl1, &m1, &n1, &l1); /* Gets the Handle passed as argument */
127                 if (sciErr.iErr)
128                 {
129                     printError(&sciErr, 0);
130                     Scierror(202, _("%s: Wrong type for input argument #%d: Handle matrix expected.\n"), fname, 1);
131                     return 1;
132                 }
133
134                 nb_handles = m1 * n1;
135
136                 if (nbInputArgument(pvApiCtx) == 2)
137                 {
138                     sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddrl2);
139                     if (sciErr.iErr)
140                     {
141                         printError(&sciErr, 0);
142                         return 1;
143                     }
144
145                     // Retrieve a matrix of double at position 2.
146                     if (getAllocatedSingleString(pvApiCtx, piAddrl2, &l2))   /* Gets the command name */
147                     {
148                         Scierror(202, _("%s: Wrong type for argument #%d: A string expected.\n"), fname, 2);
149                         return 1;
150                     }
151                 }
152                 hdl = (unsigned long) * (l1); /* Puts the value of the Handle to hdl */
153                 break;
154             case sci_strings:      /* delete("all") */
155                 CheckInputArgument(pvApiCtx, 1, 1);
156                 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddrl2);
157                 if (sciErr.iErr)
158                 {
159                     printError(&sciErr, 0);
160                     return 1;
161                 }
162
163                 // Retrieve a matrix of double at position 1.
164                 if (getAllocatedSingleString(pvApiCtx, piAddrl2, &l2))
165                 {
166                     Scierror(202, _("%s: Wrong type for argument #%d: A string expected.\n"), fname, 1);
167                     return 1;
168                 }
169
170                 if (strcmp((l2), "all") == 0)
171                 {
172                     int i = 0;
173                     int iFigureNumber = sciGetNbFigure();
174
175                     if (iFigureNumber == 0)
176                     {
177                         //no graphic windows, we can leave
178                         AssignOutputVariable(pvApiCtx, 1) = 0;
179                         ReturnArguments(pvApiCtx);
180                         return 0;
181                     }
182
183                     iFigureUID = getCurrentFigure();
184
185                     getGraphicObjectProperty(iFigureUID, __GO_CHILDREN_COUNT__, jni_int, (void **)&childrencount);
186
187                     getGraphicObjectProperty(iFigureUID, __GO_CHILDREN__, jni_int_vector, (void **)&piChildrenUID);
188
189                     for (i = 0; i < childrencount[0]; ++i)
190                     {
191                         getGraphicObjectProperty(piChildrenUID[i], __GO_HIDDEN__, jni_bool, (void **)&piHidden);
192                         if (iHidden == 0)
193                         {
194                             deleteGraphicObject(piChildrenUID[i]);
195                         }
196                     }
197                     /*
198                      * Clone a new Axes object using the Axes model which is then
199                      * attached to the 'cleaned' Figure.
200                      */
201                     cloneAxesModel(iFigureUID);
202
203                     AssignOutputVariable(pvApiCtx, 1) = 0;
204                     ReturnArguments(pvApiCtx);
205
206                     return 0;
207                 }
208                 else
209                 {
210                     Scierror(999, _("%s: Wrong value for input argument #%d: '%s' expected.\n"), fname, 1, "all");
211                     return 0;
212                 }
213                 break;
214             default:
215                 // Overload
216                 lw = 1 + nbArgumentOnStack(pvApiCtx) - nbInputArgument(pvApiCtx);
217                 C2F(overload) (&lw, "delete", 6);
218                 return 0;
219         }
220     }
221
222     for (i = 0; i < nb_handles; i++)
223     {
224         int iTemp = 0;
225         if (nbInputArgument(pvApiCtx) != 0)
226         {
227             hdl = (unsigned long) * (l1 + i); /* Puts the value of the Handle to hdl */
228         }
229
230         iObjUID = getObjectFromHandle(hdl);
231
232         if (iObjUID == 0)
233         {
234             Scierror(999, _("%s: The handle is not valid.\n"), fname);
235             return 0;
236         }
237
238         if (isFigureModel(iObjUID) || isAxesModel(iObjUID))
239         {
240             Scierror(999, _("This object cannot be deleted.\n"));
241             return 0;
242         }
243
244         /* Object type */
245         getGraphicObjectProperty(iObjUID, __GO_TYPE__, jni_int, (void **)&piObjType);
246         if (iObjType == __GO_AXES__)
247         {
248             /* Parent object */
249             iParentUID = getParentObject(iObjUID);
250             /* Parent type */
251             getGraphicObjectProperty(iParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
252         }
253
254         if (iObjType == __GO_LABEL__)
255         {
256             Scierror(999, _("A Label object cannot be deleted.\n"));
257             return 0;
258         }
259
260         //bug #11485 : duplicate pobjUID before delete it.
261         iTemp = iObjUID;
262         deleteGraphicObject(iObjUID);
263
264         /*
265          ** All figure must have at least one axe child.
266          ** If the last one is removed, add a new default one.
267          */
268         if (iObjType == __GO_AXES__ && iParentType == __GO_FIGURE__)
269         {
270             int iChild = 0;
271             int iChildCount = 0;
272             int *piChildCount = &iChildCount;
273             char **pstChildren = NULL;
274             int iChildType = -1;
275             int *piChildType = &iChildType;
276             int iAxesFound = 0;
277             int iDefaultAxes = -1;
278             int *piDefaultAxes = &iDefaultAxes;
279
280             getGraphicObjectProperty(iParentUID, __GO_CHILDREN_COUNT__, jni_int, (void **)&piChildCount);
281             getGraphicObjectProperty(iParentUID, __GO_CHILDREN__, jni_int_vector, (void **)&piChildrenUID);
282             getGraphicObjectProperty(iParentUID, __GO_DEFAULT_AXES__, jni_bool, (void **)&piDefaultAxes);
283
284             for (iChild = 0; iChild < iChildCount; iChild++)
285             {
286                 getGraphicObjectProperty(piChildrenUID[iChild], __GO_TYPE__, jni_int, (void **)&piChildType);
287                 if (iChildType == __GO_AXES__)
288                 {
289                     if (getCurrentSubWin() == iTemp) // Current axes has been deleted
290                     {
291                         setCurrentSubWin(piChildrenUID[iChild]);
292                     }
293                     iAxesFound = 1;
294                     break;
295                 }
296             }
297             if (!iAxesFound && iDefaultAxes != 0)
298             {
299
300                 /*
301                  * Clone a new Axes object using the Axes model which is then
302                  * attached to the newly created Figure.
303                  */
304                 cloneAxesModel(iParentUID);
305             }
306         }
307     }
308
309     if (!dont_overload)
310     {
311         // Overload
312         lw = 1 + nbArgumentOnStack(pvApiCtx) - nbInputArgument(pvApiCtx);
313         C2F(overload) (&lw, "delete", 6);
314     }
315     else
316     {
317         AssignOutputVariable(pvApiCtx, 1) = 0;
318         ReturnArguments(pvApiCtx);
319     }
320
321     if (l2)
322     {
323         freeAllocatedSingleString(l2);
324     }
325
326     return 0;
327 }