* Bug #10346 fixed - An uicontrol was visible during few milliseconds even if its
[scilab.git] / scilab / modules / gui / sci_gateway / c / sci_uicontrol.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Allan CORNET
4  * Copyright (C) 2007 - INRIA - Vincent COUVERT
5  * Copyright (C) 2010 - DIGITEO - Yann COLLETTE
6  * Copyright (C) 2011 - DIGITEO - Vincent COUVERT
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 #include "gw_gui.h"
17 /*--------------------------------------------------------------------------*/
18 #include "CreateUIControl.h"
19 #include "HandleManagement.h"
20 #include "MALLOC.h"             /* MALLOC */
21 #include "localization.h"
22 #include "stricmp.h"
23 #include "stack-c.h"
24 #include "SetPropertyStatus.h"
25 #include "SetHashTable.h"
26 #include "Scierror.h"
27 #include "FigureList.h"         /* getFigureFromIndex */
28 #include "Widget.h"             /* requestWidgetFocus */
29 #include "freeArrayOfString.h"
30 #include "setGraphicObjectProperty.h"
31 #include "getGraphicObjectProperty.h"
32 #include "graphicObjectProperties.h"
33 #include "CurrentFigure.h"
34 #include "BuildObjects.h"
35 #include "api_scilab.h"
36 /*--------------------------------------------------------------------------*/
37 #define NBPROPERTIES 28
38 #define MAXPROPERTYNAMELENGTH 20
39 /*--------------------------------------------------------------------------*/
40 int sci_uicontrol(char *fname, unsigned long fname_len)
41 {
42     int nbRow = 0, nbCol = 0, stkAdr = 0, k = 0;
43     char **stkAdrForStrings = NULL;
44
45     int setStatus = SET_PROPERTY_SUCCEED;
46
47     int NOT_FOUND = -1;
48
49     int inputIndex = 0, beginIndex = 0;
50
51     char *propertyName = NULL;
52     char *styleProperty = NULL;
53
54     char *pParentUID = NULL;
55     char *pUicontrol = NULL;
56
57     unsigned long GraphicHandle = 0;
58
59     int found = 0;              /* Does the property exists ? */
60
61     /* @TODO remove this crappy initialization */
62     /* DO NOT CHANGE ORDER !! */
63     char propertiesNames[NBPROPERTIES][MAXPROPERTYNAMELENGTH] =
64     {
65         "style", "parent", "backgroundcolor", "foregroundcolor", "string", "units", "fontweight", "min", "max", "tag", "position", "relief",
66         "horizontalalignment", "verticalalignment", "sliderstep", "fontname", "callback", "fontangle", "fontunits", "fontsize", "listboxtop", "user_data", "value", "userdata", "visible", "enable",
67         "callback_type", "tooltipstring"
68     };
69     int *propertiesValuesIndices = NULL;
70     int lw = 0;
71     char *propertyPart = NULL;
72
73     char *parentType = NULL;
74     char *parentStyle = NULL;
75     char const* pstCurrentFigure = NULL;
76
77     CheckLhs(0, 1);
78
79     if (Rhs == 0)
80     {
81         /* Create a pushbutton in current figure */
82
83         /* Create a new pushbutton */
84         GraphicHandle = getHandle(CreateUIControl(NULL));
85
86         /* Set current figure as parent */
87         pstCurrentFigure = getCurrentFigure();
88         if (pstCurrentFigure == NULL)
89         {
90             pstCurrentFigure = createNewFigureWithAxes();
91         }
92         setGraphicObjectRelationship(pstCurrentFigure, (char*)getObjectFromHandle(GraphicHandle));
93     }
94     else if (Rhs == 1)
95     {
96         /* Create a pushbutton in figure given as parameter */
97         /* Or give focus to the uicontrol given as parameter */
98
99         if (VarType(1) != sci_handles)
100         {
101             lw = 1 + Top - Rhs;
102             C2F(overload) (&lw, "uicontrol", 9);
103             return FALSE;
104         }
105         else                    /* Get parent ID */
106         {
107             GetRhsVar(1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
108
109             if (nbRow * nbCol != 1)
110             {
111                 Scierror(999, _("%s: Wrong size for input argument #%d: A graphic handle expected.\n"), fname, 1);
112                 return FALSE;
113             }
114             pParentUID = (char*)getObjectFromHandle((long) * hstk(stkAdr));
115             if (pParentUID != NULL)
116             {
117                 getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_string, (void **)&parentType);
118                 if (strcmp(parentType, __GO_UICONTROL__) == 0)  /* Focus management */
119                 {
120                     GraphicHandle = (long) * hstk(stkAdr);
121                     requestFocus(pParentUID);
122                 }
123                 else if ((strcmp(parentType, __GO_FIGURE__) == 0) || (strcmp(parentType, __GO_UIMENU__) == 0))  /* PushButton creation */
124                 {
125                     /* Create a new pushbutton */
126                     GraphicHandle = getHandle(CreateUIControl(NULL));
127
128                     /* First parameter is the parent */
129                     setGraphicObjectRelationship(pParentUID, getObjectFromHandle(GraphicHandle));
130                     setStatus = callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_handles, nbRow, nbCol, (char *)propertiesNames[1]);
131                     if (setStatus == SET_PROPERTY_ERROR)
132                     {
133                         Scierror(999, _("%s: Could not set property '%s'.\n"), fname, propertyName);
134                         return FALSE;
135                     }
136                 }
137                 else
138                 {
139                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s', '%s' or '%s' handle expected.\n"), fname, 1, "Uicontrol",
140                              "Figure", "Uimenu");
141                     return FALSE;
142                 }
143                 free(parentType);
144             }
145             else
146             {
147                 Scierror(999, _("%s: Wrong type for input argument #%d: A '%s', '%s' or '%s' handle expected.\n"), fname, 1, "Uicontrol", "Figure",
148                          "Uimenu");
149                 return FALSE;
150             }
151         }
152     }
153     else
154     {
155         if ((VarType(1) != sci_handles) && (VarType(1) != sci_strings))
156         {
157             lw = 1 + Top - Rhs;
158             C2F(overload) (&lw, "uicontrol", 9);
159             return FALSE;
160         }
161
162         /* Allocate memory to store the position of properties in uicontrol call */
163         if ((propertiesValuesIndices = (int *)MALLOC(sizeof(int) * NBPROPERTIES)) == NULL)
164         {
165             Scierror(999, _("%s: No more memory.\n"), fname);
166             return FALSE;
167         }
168
169         /* Init all positions to NOT_FOUND */
170         for (inputIndex = 0; inputIndex < NBPROPERTIES; inputIndex++)
171         {
172             propertiesValuesIndices[inputIndex] = NOT_FOUND;    /* Property initialized as not found */
173         }
174
175         /**
176          * Odd number of input arguments
177          * First input is the parent ID
178          * All event inputs are property names
179          * All odd (except first) inputs are property values
180          */
181         if (Rhs % 2 == 1)
182         {
183             if (VarType(1) != sci_handles)
184             {
185                 if (VarType(1) == sci_matrix)
186                 {
187                     GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
188                     if (nbRow * nbCol == 1)
189                     {
190                         pParentUID = (char*)getFigureFromIndex((int)(*stk(stkAdr)));
191
192                         if (pParentUID == NULL)
193                         {
194                             Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
195                                      "Frame uicontrol");
196                             return FALSE;
197                         }
198                         getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_string, (void **)&parentType);
199                         if (strcmp(parentType, __GO_FIGURE__) != 0)
200                         {
201                             getGraphicObjectProperty(pParentUID, __GO_STYLE__, jni_string, (void **)&parentStyle);
202                             if ((strcmp(parentType, __GO_UICONTROL__) != 0) || (strcmp(parentStyle, __GO_UI_FRAME__) != 0))
203                             {
204                                 Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
205                                          "Frame uicontrol");
206                                 return FALSE;
207                             }
208                         }
209                         /* First parameter is the parent */
210                         propertiesValuesIndices[1] = 1;
211                     }
212                     else
213                     {
214                         Scierror(999, _("%s: Wrong size for input argument #%d: A graphic handle expected.\n"), fname, 1);
215                         return FALSE;
216                     }
217                 }
218                 else
219                 {
220                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
221                              "Frame uicontrol");
222                     return FALSE;
223                 }
224             }
225             else                /* Get parent ID */
226             {
227                 GetRhsVar(1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
228
229                 if (nbRow * nbCol != 1)
230                 {
231                     Scierror(999, _("%s: Wrong size for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
232                              "Frame uicontrol");
233                     return FALSE;
234                 }
235                 pParentUID = (char*)getObjectFromHandle((long) * hstk(stkAdr));
236                 if (pParentUID == NULL)
237                 {
238                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
239                              "Frame uicontrol");
240                     return FALSE;
241                 }
242                 getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_string, (void **)&parentType);
243                 if (strcmp(parentType, __GO_FIGURE__) != 0)
244                 {
245                     getGraphicObjectProperty(pParentUID, __GO_STYLE__, jni_string, (void **)&parentStyle);
246                     if ((strcmp(parentType, __GO_UICONTROL__) != 0) || (strcmp(parentStyle, __GO_UI_FRAME__) != 0))
247                     {
248                         Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
249                                  "Frame uicontrol");
250                         return FALSE;
251                     }
252                 }
253                 /* First parameter is the parent */
254                 propertiesValuesIndices[1] = 1;
255             }
256
257             // First input parameter which is a property name
258             beginIndex = 2;
259         }
260         /**
261          * Even number of input arguments
262          * All odd inputs are property names
263          * All even inputs are property values
264          */
265         else
266         {
267             // First input parameter which is a property name
268             beginIndex = 1;
269         }
270
271         /* Get all properties positions */
272         for (inputIndex = beginIndex; inputIndex < Rhs; inputIndex = inputIndex + 2)
273         {
274             /* Read property name */
275             if (VarType(inputIndex) != sci_strings)
276             {
277                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, inputIndex);
278                 return FALSE;
279             }
280             else
281             {
282                 GetRhsVar(inputIndex, STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
283                 propertyName = cstk(stkAdr);
284
285                 /* Bug 3031 */
286                 /* We only want to compare propertyName along its length */
287                 /* 'posi' must be matched to 'position' */
288                 propertyPart = (char *)MALLOC(sizeof(char) * (MAXPROPERTYNAMELENGTH + 1));
289                 if (propertyPart == NULL)
290                 {
291                     Scierror(999, _("%s: No more memory.\n"), fname);
292                     return FALSE;
293                 }
294
295                 found = 0;
296                 for (k = 0; k < NBPROPERTIES; k++)
297                 {
298                     if (strlen(propertyName) <= MAXPROPERTYNAMELENGTH)
299                     {
300                         strncpy(propertyPart, propertiesNames[k], strlen(propertyName));
301                         propertyPart[strlen(propertyName)] = '\0';
302
303                         if (stricmp(propertyName, propertyPart) == 0)
304                         {
305                             propertiesValuesIndices[k] = inputIndex + 1;    /* Position of value for property */
306                             found = 1;
307                             break;
308                         }
309                     }
310                 }
311
312                 FREE(propertyPart);
313
314                 if (found == 0)
315                 {
316                     Scierror(999, _("%s: Unknown property: %s for '%s' handles.\n"), fname, propertyName, "Uicontrol");
317                     return FALSE;
318                 }
319             }
320         }
321
322         if (propertiesValuesIndices[0] != NOT_FOUND)    /* Style found */
323         {
324             if (VarType(propertiesValuesIndices[0]) == sci_strings)
325             {
326                 GetRhsVar(propertiesValuesIndices[0], STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
327                 styleProperty = cstk(stkAdr);
328             }
329             else
330             {
331                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, propertiesValuesIndices[0]);
332                 return FALSE;
333             }
334         }
335
336         /* Create a new uicontrol */
337         pUicontrol = CreateUIControl(styleProperty);
338         if (pUicontrol == NULL) /* Error in creation */
339         {
340             Scierror(999, _("%s: Could not create 'Uicontrol' handle.\n"), fname);
341             return FALSE;
342         }
343         GraphicHandle = getHandle(pUicontrol);
344
345         /* If no parent given then the current figure is the parent */
346         if (propertiesValuesIndices[1] == NOT_FOUND)
347         {
348             char *graphicObjectUID = (char*)getObjectFromHandle(GraphicHandle);
349
350             /* Set the parent */
351             pstCurrentFigure = (char*)getCurrentFigure();
352
353             if (pstCurrentFigure == NULL)
354             {
355                 pstCurrentFigure = createNewFigureWithAxes();
356             }
357             setGraphicObjectRelationship(pstCurrentFigure, graphicObjectUID);
358         }
359
360         /* Read and set all properties */
361         for (inputIndex = 1; inputIndex < NBPROPERTIES; inputIndex++)   /* Style has already been set */
362         {
363             if (propertiesValuesIndices[inputIndex] != NOT_FOUND)
364             {
365                 if (inputIndex == 21 || inputIndex == 23)   /* User data settings */
366                 {
367                     stkAdr = propertiesValuesIndices[inputIndex];   /* Special management */
368                     nbRow = -1;
369                     nbCol = -1;
370                     setStatus =
371                         callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, VarType(propertiesValuesIndices[inputIndex]), nbRow, nbCol,
372                                         (char *)propertiesNames[inputIndex]);
373                 }
374                 else            /* All other properties */
375                 {
376                     /* Read property value */
377                     switch (VarType(propertiesValuesIndices[inputIndex]))
378                     {
379                         case sci_matrix:
380                             GetRhsVar(propertiesValuesIndices[inputIndex], MATRIX_OF_DOUBLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
381                             setStatus =
382                                 callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_matrix, nbRow, nbCol,
383                                                 (char *)propertiesNames[inputIndex]);
384                             break;
385                         case sci_strings:
386                             /* Index for String & TooltipString properties: Can be more than one character string */
387                             if ((inputIndex == 4) || (inputIndex == 27))
388                             {
389                                 GetRhsVar(propertiesValuesIndices[inputIndex], MATRIX_OF_STRING_DATATYPE, &nbRow, &nbCol, &stkAdrForStrings);
390                                 setStatus =
391                                     callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), (size_t) stkAdrForStrings, sci_strings, nbRow, nbCol,
392                                                     (char *)propertiesNames[inputIndex]);
393                                 freeArrayOfString(stkAdrForStrings, nbRow * nbCol);
394                             }
395                             else
396                             {
397                                 GetRhsVar(propertiesValuesIndices[inputIndex], STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
398                                 setStatus =
399                                     callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_strings, nbRow, nbCol,
400                                                     (char *)propertiesNames[inputIndex]);
401                             }
402                             break;
403                         case sci_handles:
404                             GetRhsVar(propertiesValuesIndices[inputIndex], GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
405                             setStatus =
406                                 callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_handles, nbRow, nbCol,
407                                                 (char *)propertiesNames[inputIndex]);
408                             break;
409                         default:
410                             setStatus = SET_PROPERTY_ERROR;
411                             break;
412                     }
413                 }
414                 if (setStatus == SET_PROPERTY_ERROR)
415                 {
416                     Scierror(999, _("%s: Could not set property '%s'.\n"), fname, (char *)propertiesNames[inputIndex]);
417                     return FALSE;
418                 }
419             }
420         }
421     }
422
423     if (propertiesValuesIndices[24] == NOT_FOUND)    /* Visible property not set */
424     {
425         /* Force the uicontrol to be visible because is invisible by default in the model (See bug #10346) */
426         int b = (int)TRUE;
427         setGraphicObjectProperty(pUicontrol, __GO_VISIBLE__, &b, jni_bool, 1);
428     }
429
430     FREE(propertiesValuesIndices);
431
432     /* Create return variable */
433     nbRow = 1;
434     nbCol = 1;
435     CreateVar(Rhs + 1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
436     *hstk(stkAdr) = GraphicHandle;
437
438     LhsVar(1) = Rhs + 1;
439
440     PutLhsVar();
441
442     return TRUE;
443 }
444
445 /*--------------------------------------------------------------------------*/