4bb5ec360394a1ec2b723051da1653c57744cc2a
[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     int iParentType = -1;
74     int *piParentType = &iParentType;
75     int iParentStyle = -1;
76     int *piParentStyle = &iParentStyle;
77     char const* pstCurrentFigure = NULL;
78
79     CheckLhs(0, 1);
80
81     if (Rhs == 0)
82     {
83         /* Create a pushbutton in current figure */
84
85         /* Create a new pushbutton */
86         GraphicHandle = getHandle(CreateUIControl(NULL));
87
88         /* Set current figure as parent */
89         pstCurrentFigure = getCurrentFigure();
90         if (pstCurrentFigure == NULL)
91         {
92             pstCurrentFigure = createNewFigureWithAxes();
93         }
94         setGraphicObjectRelationship(pstCurrentFigure, (char*)getObjectFromHandle(GraphicHandle));
95     }
96     else if (Rhs == 1)
97     {
98         /* Create a pushbutton in figure given as parameter */
99         /* Or give focus to the uicontrol given as parameter */
100
101         if (VarType(1) != sci_handles)
102         {
103             lw = 1 + Top - Rhs;
104             C2F(overload) (&lw, "uicontrol", 9);
105             return FALSE;
106         }
107         else                    /* Get parent ID */
108         {
109             GetRhsVar(1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
110
111             if (nbRow * nbCol != 1)
112             {
113                 Scierror(999, _("%s: Wrong size for input argument #%d: A graphic handle expected.\n"), fname, 1);
114                 return FALSE;
115             }
116             pParentUID = (char*)getObjectFromHandle((long) * hstk(stkAdr));
117             if (pParentUID != NULL)
118             {
119                 getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
120                 if (iParentType == __GO_UICONTROL__)  /* Focus management */
121                 {
122                     GraphicHandle = (long) * hstk(stkAdr);
123                     requestFocus(pParentUID);
124                 }
125                 else if (iParentType == __GO_FIGURE__ || iParentType == __GO_UIMENU__)  /* PushButton creation */
126                 {
127                     /* Create a new pushbutton */
128                     GraphicHandle = getHandle(CreateUIControl(NULL));
129
130                     /* First parameter is the parent */
131                     setGraphicObjectRelationship(pParentUID, getObjectFromHandle(GraphicHandle));
132                     setStatus = callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_handles, nbRow, nbCol, (char *)propertiesNames[1]);
133                     if (setStatus == SET_PROPERTY_ERROR)
134                     {
135                         Scierror(999, _("%s: Could not set property '%s'.\n"), fname, propertyName);
136                         return FALSE;
137                     }
138                 }
139                 else
140                 {
141                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s', '%s' or '%s' handle expected.\n"), fname, 1, "Uicontrol",
142                              "Figure", "Uimenu");
143                     return FALSE;
144                 }
145             }
146             else
147             {
148                 Scierror(999, _("%s: Wrong type for input argument #%d: A '%s', '%s' or '%s' handle expected.\n"), fname, 1, "Uicontrol", "Figure",
149                          "Uimenu");
150                 return FALSE;
151             }
152         }
153     }
154     else
155     {
156         if ((VarType(1) != sci_handles) && (VarType(1) != sci_strings))
157         {
158             lw = 1 + Top - Rhs;
159             C2F(overload) (&lw, "uicontrol", 9);
160             return FALSE;
161         }
162
163         /* Allocate memory to store the position of properties in uicontrol call */
164         if ((propertiesValuesIndices = (int *)MALLOC(sizeof(int) * NBPROPERTIES)) == NULL)
165         {
166             Scierror(999, _("%s: No more memory.\n"), fname);
167             return FALSE;
168         }
169
170         /* Init all positions to NOT_FOUND */
171         for (inputIndex = 0; inputIndex < NBPROPERTIES; inputIndex++)
172         {
173             propertiesValuesIndices[inputIndex] = NOT_FOUND;    /* Property initialized as not found */
174         }
175
176         /**
177          * Odd number of input arguments
178          * First input is the parent ID
179          * All event inputs are property names
180          * All odd (except first) inputs are property values
181          */
182         if (Rhs % 2 == 1)
183         {
184             if (VarType(1) != sci_handles)
185             {
186                 if (VarType(1) == sci_matrix)
187                 {
188                     GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
189                     if (nbRow * nbCol == 1)
190                     {
191                         pParentUID = (char*)getFigureFromIndex((int)(*stk(stkAdr)));
192
193                         if (pParentUID == NULL)
194                         {
195                             Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
196                                      "Frame uicontrol");
197                             return FALSE;
198                         }
199                         getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
200                         if (iParentType != __GO_FIGURE__)
201                         {
202                             getGraphicObjectProperty(pParentUID, __GO_STYLE__, jni_int, (void **)&piParentStyle);
203                             if (iParentType != __GO_UICONTROL__ || iParentStyle != __GO_UI_FRAME__)
204                             {
205                                 Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
206                                          "Frame uicontrol");
207                                 return FALSE;
208                             }
209                         }
210                         /* First parameter is the parent */
211                         propertiesValuesIndices[1] = 1;
212                     }
213                     else
214                     {
215                         Scierror(999, _("%s: Wrong size for input argument #%d: A graphic handle expected.\n"), fname, 1);
216                         return FALSE;
217                     }
218                 }
219                 else
220                 {
221                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
222                              "Frame uicontrol");
223                     return FALSE;
224                 }
225             }
226             else                /* Get parent ID */
227             {
228                 GetRhsVar(1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
229
230                 if (nbRow * nbCol != 1)
231                 {
232                     Scierror(999, _("%s: Wrong size for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
233                              "Frame uicontrol");
234                     return FALSE;
235                 }
236                 pParentUID = (char*)getObjectFromHandle((long) * hstk(stkAdr));
237                 if (pParentUID == NULL)
238                 {
239                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
240                              "Frame uicontrol");
241                     return FALSE;
242                 }
243                 getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
244                 if (iParentType != __GO_FIGURE__)
245                 {
246                     getGraphicObjectProperty(pParentUID, __GO_STYLE__, jni_int, (void **)&piParentStyle);
247                     if (iParentType != __GO_UICONTROL__ || iParentStyle != __GO_UI_FRAME__)
248                     {
249                         Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
250                                  "Frame uicontrol");
251                         return FALSE;
252                     }
253                 }
254                 /* First parameter is the parent */
255                 propertiesValuesIndices[1] = 1;
256             }
257
258             // First input parameter which is a property name
259             beginIndex = 2;
260         }
261         /**
262          * Even number of input arguments
263          * All odd inputs are property names
264          * All even inputs are property values
265          */
266         else
267         {
268             // First input parameter which is a property name
269             beginIndex = 1;
270         }
271
272         /* Get all properties positions */
273         for (inputIndex = beginIndex; inputIndex < Rhs; inputIndex = inputIndex + 2)
274         {
275             /* Read property name */
276             if (VarType(inputIndex) != sci_strings)
277             {
278                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, inputIndex);
279                 return FALSE;
280             }
281             else
282             {
283                 GetRhsVar(inputIndex, STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
284                 propertyName = cstk(stkAdr);
285
286                 /* Bug 3031 */
287                 /* We only want to compare propertyName along its length */
288                 /* 'posi' must be matched to 'position' */
289                 propertyPart = (char *)MALLOC(sizeof(char) * (MAXPROPERTYNAMELENGTH + 1));
290                 if (propertyPart == NULL)
291                 {
292                     Scierror(999, _("%s: No more memory.\n"), fname);
293                     return FALSE;
294                 }
295
296                 found = 0;
297                 for (k = 0; k < NBPROPERTIES; k++)
298                 {
299                     if (strlen(propertyName) <= MAXPROPERTYNAMELENGTH)
300                     {
301                         strncpy(propertyPart, propertiesNames[k], strlen(propertyName));
302                         propertyPart[strlen(propertyName)] = '\0';
303
304                         if (stricmp(propertyName, propertyPart) == 0)
305                         {
306                             propertiesValuesIndices[k] = inputIndex + 1;    /* Position of value for property */
307                             found = 1;
308                             break;
309                         }
310                     }
311                 }
312
313                 FREE(propertyPart);
314
315                 if (found == 0)
316                 {
317                     Scierror(999, _("%s: Unknown property: %s for '%s' handles.\n"), fname, propertyName, "Uicontrol");
318                     return FALSE;
319                 }
320             }
321         }
322
323         if (propertiesValuesIndices[0] != NOT_FOUND)    /* Style found */
324         {
325             if (VarType(propertiesValuesIndices[0]) == sci_strings)
326             {
327                 GetRhsVar(propertiesValuesIndices[0], STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
328                 styleProperty = cstk(stkAdr);
329             }
330             else
331             {
332                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, propertiesValuesIndices[0]);
333                 return FALSE;
334             }
335         }
336
337         /* Create a new uicontrol */
338         pUicontrol = CreateUIControl(styleProperty);
339         if (pUicontrol == NULL) /* Error in creation */
340         {
341             Scierror(999, _("%s: Could not create 'Uicontrol' handle.\n"), fname);
342             return FALSE;
343         }
344         GraphicHandle = getHandle(pUicontrol);
345
346         /* If no parent given then the current figure is the parent */
347         if (propertiesValuesIndices[1] == NOT_FOUND)
348         {
349             char *graphicObjectUID = (char*)getObjectFromHandle(GraphicHandle);
350
351             /* Set the parent */
352             pstCurrentFigure = (char*)getCurrentFigure();
353
354             if (pstCurrentFigure == NULL)
355             {
356                 pstCurrentFigure = createNewFigureWithAxes();
357             }
358             setGraphicObjectRelationship(pstCurrentFigure, graphicObjectUID);
359         }
360
361         /* Read and set all properties */
362         for (inputIndex = 1; inputIndex < NBPROPERTIES; inputIndex++)   /* Style has already been set */
363         {
364             if (propertiesValuesIndices[inputIndex] != NOT_FOUND)
365             {
366                 if (inputIndex == 21 || inputIndex == 23)   /* User data settings */
367                 {
368                     stkAdr = propertiesValuesIndices[inputIndex];   /* Special management */
369                     nbRow = -1;
370                     nbCol = -1;
371                     setStatus =
372                         callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, VarType(propertiesValuesIndices[inputIndex]), nbRow, nbCol,
373                                         (char *)propertiesNames[inputIndex]);
374                 }
375                 else            /* All other properties */
376                 {
377                     /* Read property value */
378                     switch (VarType(propertiesValuesIndices[inputIndex]))
379                     {
380                         case sci_matrix:
381                             GetRhsVar(propertiesValuesIndices[inputIndex], MATRIX_OF_DOUBLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
382                             setStatus =
383                                 callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_matrix, nbRow, nbCol,
384                                                 (char *)propertiesNames[inputIndex]);
385                             break;
386                         case sci_strings:
387                             /* Index for String & TooltipString properties: Can be more than one character string */
388                             if ((inputIndex == 4) || (inputIndex == 27))
389                             {
390                                 GetRhsVar(propertiesValuesIndices[inputIndex], MATRIX_OF_STRING_DATATYPE, &nbRow, &nbCol, &stkAdrForStrings);
391                                 setStatus =
392                                     callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), (size_t) stkAdrForStrings, sci_strings, nbRow, nbCol,
393                                                     (char *)propertiesNames[inputIndex]);
394                                 freeArrayOfString(stkAdrForStrings, nbRow * nbCol);
395                             }
396                             else
397                             {
398                                 GetRhsVar(propertiesValuesIndices[inputIndex], STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
399                                 setStatus =
400                                     callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_strings, nbRow, nbCol,
401                                                     (char *)propertiesNames[inputIndex]);
402                             }
403                             break;
404                         case sci_handles:
405                             GetRhsVar(propertiesValuesIndices[inputIndex], GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
406                             setStatus =
407                                 callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_handles, nbRow, nbCol,
408                                                 (char *)propertiesNames[inputIndex]);
409                             break;
410                         default:
411                             setStatus = SET_PROPERTY_ERROR;
412                             break;
413                     }
414                 }
415                 if (setStatus == SET_PROPERTY_ERROR)
416                 {
417                     Scierror(999, _("%s: Could not set property '%s'.\n"), fname, (char *)propertiesNames[inputIndex]);
418                     return FALSE;
419                 }
420             }
421         }
422     }
423
424     if (propertiesValuesIndices[24] == NOT_FOUND)    /* Visible property not set */
425     {
426         /* Force the uicontrol to be visible because is invisible by default in the model (See bug #10346) */
427         int b = (int)TRUE;
428         setGraphicObjectProperty(pUicontrol, __GO_VISIBLE__, &b, jni_bool, 1);
429     }
430
431     if (propertiesValuesIndices[14] == NOT_FOUND)    /* SliderStep property not set */
432     {
433         /* Set SliderStep property to [1/100*(Max-Min) 1/10*(Max-Min)] */
434         double maxValue = 0;
435         double* pdblMaxValue = &maxValue;
436         double minValue = 0;
437         double* pdblMinValue = &minValue;
438         double pdblStep[2];
439
440         getGraphicObjectProperty(pUicontrol, __GO_UI_MIN__, jni_double, (void**) &pdblMinValue);
441         getGraphicObjectProperty(pUicontrol, __GO_UI_MAX__, jni_double, (void**) &pdblMaxValue);
442
443         pdblStep[0] = 0.01 * (maxValue - minValue);
444         pdblStep[1] = 0.1 * (maxValue - minValue);
445
446         setGraphicObjectProperty(pUicontrol, __GO_UI_SLIDERSTEP__, pdblStep, jni_double_vector, 2);
447     }
448
449     FREE(propertiesValuesIndices);
450
451     /* Create return variable */
452     nbRow = 1;
453     nbCol = 1;
454     CreateVar(Rhs + 1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
455     *hstk(stkAdr) = GraphicHandle;
456
457     LhsVar(1) = Rhs + 1;
458
459     PutLhsVar();
460
461     return TRUE;
462 }
463
464 /*--------------------------------------------------------------------------*/