Merge remote-tracking branch 'origin/5.4'
[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-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
47 #ifdef _MSC_VER
48 #include "strdup_windows.h"
49 #endif
50 /*--------------------------------------------------------------------------*/
51 int sci_delete(char *fname, unsigned long fname_len)
52 {
53     SciErr sciErr;
54
55     int* piAddrl1 = NULL;
56     long long* l1 = NULL;
57     int* piAddrl2 = NULL;
58     char* l2 = NULL;
59
60     int m1 = 0, n1 = 0, lw = 0;
61     unsigned long hdl = 0;
62     int nb_handles = 0, i = 0, dont_overload = 0;
63     char *pobjUID = NULL;
64     char* pFigureUID = NULL;
65     char** childrenUID = NULL;
66     int iChildrenCount = 0;
67     int* childrencount = &iChildrenCount;
68     int iHidden = 0;
69     int *piHidden = &iHidden;
70
71     char *pstParentUID = NULL;
72     int iParentType = -1;
73     int *piParentType = &iParentType;
74     int iObjType = -1;
75     int *piObjType = &iObjType;
76
77     CheckInputArgument(pvApiCtx, 0, 1);
78     CheckOutputArgument(pvApiCtx, 0, 1);
79
80     if (nbInputArgument(pvApiCtx) == 0)               /* Delete current object */
81     {
82         pobjUID = (char*)getCurrentObject();
83         if (pobjUID == NULL)
84         {
85             //No current object, we can leave
86             AssignOutputVariable(pvApiCtx, 1) = 0;
87             ReturnArguments(pvApiCtx);
88             return 0;
89         }
90
91         hdl = (unsigned long)getHandle(pobjUID);
92         dont_overload = 1;
93         nb_handles = 1;
94     }
95     else
96     {
97         sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddrl1);
98         if (sciErr.iErr)
99         {
100             printError(&sciErr, 0);
101             return 1;
102         }
103
104         switch (getInputArgumentType(pvApiCtx, 1))
105         {
106             case sci_handles:      /* delete Entity given by a handle */
107
108                 // Retrieve a matrix of handle at position 1.
109                 sciErr = getMatrixOfHandle(pvApiCtx, piAddrl1, &m1, &n1, &l1); /* Gets the Handle passed as argument */
110                 if (sciErr.iErr)
111                 {
112                     printError(&sciErr, 0);
113                     Scierror(202, _("%s: Wrong type for argument %d: Handle matrix expected.\n"), fname, 1);
114                     return 1;
115                 }
116
117                 nb_handles = m1 * n1;
118
119                 if (nbInputArgument(pvApiCtx) == 2)
120                 {
121                     sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddrl2);
122                     if (sciErr.iErr)
123                     {
124                         printError(&sciErr, 0);
125                         return 1;
126                     }
127
128                     // Retrieve a matrix of double at position 2.
129                     if (getAllocatedSingleString(pvApiCtx, piAddrl2, &l2))   /* Gets the command name */
130                     {
131                         Scierror(202, _("%s: Wrong type for argument #%d: A string expected.\n"), fname, 2);
132                         return 1;
133                     }
134                 }
135                 hdl = (unsigned long) * (l1); /* Puts the value of the Handle to hdl */
136                 break;
137             case sci_strings:      /* delete("all") */
138                 CheckInputArgument(pvApiCtx, 1, 1);
139                 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddrl2);
140                 if (sciErr.iErr)
141                 {
142                     printError(&sciErr, 0);
143                     return 1;
144                 }
145
146                 // Retrieve a matrix of double at position 1.
147                 if (getAllocatedSingleString(pvApiCtx, piAddrl2, &l2))
148                 {
149                     Scierror(202, _("%s: Wrong type for argument #%d: A string expected.\n"), fname, 1);
150                     return 1;
151                 }
152
153                 if (strcmp((l2), "all") == 0)
154                 {
155                     int i = 0;
156                     int iFigureNumber = sciGetNbFigure();
157
158                     if (iFigureNumber == 0)
159                     {
160                         //no graphic windows, we can leave
161                         AssignOutputVariable(pvApiCtx, 1) = 0;
162                         ReturnArguments(pvApiCtx);
163                         return 0;
164                     }
165
166                     pFigureUID = (char*)getCurrentFigure();
167
168                     getGraphicObjectProperty(pFigureUID, __GO_CHILDREN_COUNT__, jni_int, (void **)&childrencount);
169
170                     getGraphicObjectProperty(pFigureUID, __GO_CHILDREN__, jni_string_vector, (void **)&childrenUID);
171
172                     for (i = 0; i < childrencount[0]; ++i)
173                     {
174                         getGraphicObjectProperty(childrenUID[i], __GO_HIDDEN__, jni_bool, (void **)&piHidden);
175                         if (iHidden == 0)
176                         {
177                             deleteGraphicObject(childrenUID[i]);
178                         }
179                     }
180                     /*
181                      * Clone a new Axes object using the Axes model which is then
182                      * attached to the 'cleaned' Figure.
183                      */
184                     cloneAxesModel(pFigureUID);
185
186                     AssignOutputVariable(pvApiCtx, 1) = 0;
187                     ReturnArguments(pvApiCtx);
188
189                     return 0;
190                 }
191                 else
192                 {
193                     Scierror(999, _("%s: Wrong value for input argument #%d: '%s' expected.\n"), fname, 1, "all");
194                     return 0;
195                 }
196                 break;
197             default:
198                 // Overload
199                 lw = 1 + nbArgumentOnStack(pvApiCtx) - nbInputArgument(pvApiCtx);
200                 C2F(overload) (&lw, "delete", 6);
201                 return 0;
202         }
203     }
204
205     for (i = 0; i < nb_handles; i++)
206     {
207         char* pstTemp = NULL;
208         if (nbInputArgument(pvApiCtx) != 0)
209         {
210             hdl = (unsigned long) * (l1 + i); /* Puts the value of the Handle to hdl */
211         }
212
213         pobjUID = (char*)getObjectFromHandle(hdl);
214
215         if (pobjUID == NULL)
216         {
217             Scierror(999, _("%s: The handle is not valid.\n"), fname);
218             return 0;
219         }
220
221         if (isFigureModel(pobjUID) || isAxesModel(pobjUID))
222         {
223             Scierror(999, _("This object cannot be deleted.\n"));
224             return 0;
225         }
226
227         /* Object type */
228         getGraphicObjectProperty(pobjUID, __GO_TYPE__, jni_int, (void **)&piObjType);
229         if (iObjType == __GO_AXES__)
230         {
231             /* Parent object */
232             getGraphicObjectProperty(pobjUID, __GO_PARENT__, jni_string, (void **)&pstParentUID);
233             /* Parent type */
234             getGraphicObjectProperty(pstParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
235         }
236
237         if (iObjType == __GO_LABEL__)
238         {
239             Scierror(999, _("A Label object cannot be deleted.\n"));
240             return 0;
241         }
242
243         //bug #11485 : duplicate pobjUID before delete it.
244         pstTemp = strdup(pobjUID);
245         deleteGraphicObject(pobjUID);
246
247         /*
248          ** All figure must have at least one axe child.
249          ** If the last one is removed, add a new default one.
250          */
251         if (iObjType == __GO_AXES__ && iParentType == __GO_FIGURE__)
252         {
253             int iChild = 0;
254             int iChildCount = 0;
255             int *piChildCount = &iChildCount;
256             char **pstChildren = NULL;
257             int iChildType = -1;
258             int *piChildType = &iChildType;
259             int iAxesFound = 0;
260
261             getGraphicObjectProperty(pstParentUID, __GO_CHILDREN_COUNT__, jni_int, (void **)&piChildCount);
262             getGraphicObjectProperty(pstParentUID, __GO_CHILDREN__, jni_string_vector, (void **)&pstChildren);
263             for (iChild = 0; iChild < iChildCount; iChild++)
264             {
265                 getGraphicObjectProperty(pstChildren[iChild], __GO_TYPE__, jni_int, (void **)&piChildType);
266                 if (iChildType == __GO_AXES__)
267                 {
268                     if (strcmp(getCurrentSubWin(), pstTemp) == 0) // Current axes has been deleted
269                     {
270                         setCurrentSubWin(pstChildren[iChild]);
271                     }
272                     iAxesFound = 1;
273                     break;
274                 }
275             }
276             if (!iAxesFound)
277             {
278                 /*
279                  * Clone a new Axes object using the Axes model which is then
280                  * attached to the newly created Figure.
281                  */
282                 cloneAxesModel(pstParentUID);
283             }
284         }
285
286         FREE(pstTemp);
287     }
288
289     if (!dont_overload)
290     {
291         // Overload
292         lw = 1 + nbArgumentOnStack(pvApiCtx) - nbInputArgument(pvApiCtx);
293         C2F(overload) (&lw, "delete", 6);
294     }
295     else
296     {
297         AssignOutputVariable(pvApiCtx, 1) = 0;
298         ReturnArguments(pvApiCtx);
299     }
300
301     if (l2)
302     {
303         freeAllocatedSingleString(l2);
304     }
305
306     return 0;
307 }