1666fb554e0709cd049e7c3a6f7451190d8d48b6
[scilab.git] / scilab / modules / graphics / src / c / Plo2dn.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2002-2004 - INRIA - Djalel Abdemouche
4  * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
5  * Copyright (C) 2010-2011 - DIGITEO - Manuel Juliachs
6  * Copyright (C) 2011 - DIGITEO - Bruno JOFRET
7  * Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
8  *
9  * This file must be used under the terms of the CeCILL.
10  * This source file is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution.  The terms
12  * are also available at
13  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
14  *
15  */
16
17 /*------------------------------------------------------------------------
18  *    Graphic library
19  --------------------------------------------------------------------------*/
20 #include <stdio.h>
21 #include <string.h>
22 #include "math_graphics.h"
23 #include "PloEch.h"
24 #include "Plot2d.h"
25
26 #define spINSIDE_SPARSE
27 #include "../../sparse/includes/spConfig.h"
28
29 #include "SetProperty.h"
30 #include "DrawObjects.h"
31 #include "BuildObjects.h"
32 #include "Axes.h"
33 #include "BasicAlgos.h"
34 #include "sciprint.h"
35 #include "Scierror.h"
36
37 #include "MALLOC.h"             /* MALLOC */
38 #include "scitokenize.h"
39 #include "localization.h"
40 #include "get_ticks_utils.h"
41 #include "HandleManagement.h"
42 #include "freeArrayOfString.h"
43
44 #include "getGraphicObjectProperty.h"
45 #include "setGraphicObjectProperty.h"
46 #include "graphicObjectProperties.h"
47 #include "CurrentFigure.h"
48 #include "CurrentSubwin.h"
49 #include "CurrentObject.h"
50
51 /*--------------------------------------------------------------------
52  *  plot2dn(ptype,Logflags,x,y,n1,n2,style,strflag,legend,brect,aaint,lstr1,lstr2)
53  *
54  *  Draw *n1 curves of *n2 points each
55  *
56  *  ptype is an int which gives the polyline drawind mode (0,1,2,3,4)
57  *
58  *  Logflags is a two character string
59  *
60  *  (x[i+(*n2)*j] ,y[i+(*n2)*j]) Double values giving the point
61  *  position of point i of curve j (i=0,*n2-1 j=0,*n1-1)
62  *
63  *  style[*n1]-> give the style to use for each curve
64  *     if style is positive --> a mark is used (mark id = style[i])
65  *     if style is strictly negative --> a dashed line is used
66  *        (dash id = abs(style[i])
67  *     if there's only one curve, style can be of type style[0]=style,
68  *     style[1]=pos ( pos in [1,6])
69  *     pos give the legend position (1 to 6) (this can be iteresting
70  *     if you want to superpose curves with different legends by
71  *     calling plot2d more than one time.
72  *
73  *  strflag[3] is a string
74  *
75  *     if strflag[0] == '1' then legends are added
76  *        legend = "leg1@leg2@....@legn"; gives the legend for each curve
77  *      else no legend
78  *
79  *     if strflag[1] == '1' then  the values of brect are used to fix
80  *        the drawing boundaries :  brect[]= <xmin,ymin,xmax,ymax>;
81  *      if strflag[1] == '2' then the values  are computed from data
82  *      else if strflag[1]=='0' the previous values
83  *                (previous call or defaut values) are used
84  *
85  *     if  strflag[2] == '1' ->then an axis is added
86  *        the number of intervals
87  *        is specified by the vector aaint[4] of integers
88  *         <aaint[0],aaint[1]> specifies the x-axis number of  points
89  *         <aaint[2],aaint[3]> same for y-axis
90  *     if  strflag[2] == '2' -> no axis, only a box around the curves
91  *     else no box and no axis
92
93  * lstr* : unused ( but used by Fortran )
94  *--------------------------------------------------------------------------*/
95
96 int plot2dn(int ptype, char *logflags, double *x, double *y, int *n1, int *n2, int *style, char *strflag, char *legend, double *brect, int *aaint,
97             BOOL flagNax, int lstr1, int lstr2)
98 {
99     char *psubwinUID = NULL;
100     char *curFigureUID = NULL;
101     int closeflag = 0;
102     int jj = 0;
103     long long *tabofhandles = NULL;
104     long hdl = 0;
105     long *hdltab = NULL;
106     int cmpt = 0;
107     int with_leg = 0;
108     double drect[6];
109     char dataflag = 0;
110
111     BOOL bounds_changed = FALSE;
112     BOOL axes_properties_changed = FALSE;
113
114     double rotationAngles[2];
115     int clipState = 0;
116     int autoScale = 0;
117     int logFlags[3];
118     int iTmp = 0;
119     int *piTmp = &iTmp;
120     char textLogFlags[3];
121     int firstPlot = 0;
122     int newFirstPlot = 0;
123     int autoSubticks = 0;
124
125     psubwinUID = (char*)getOrCreateDefaultSubwin();
126
127     /*
128      * Check if the auto_clear property is on and then erase everything
129      * To be implemented
130      */
131     checkRedrawing();
132
133     rotationAngles[0] = 0.0;
134     rotationAngles[1] = 270.0;
135
136     setGraphicObjectProperty(psubwinUID, __GO_ROTATION_ANGLES__, rotationAngles, jni_double_vector, 2);
137
138     /* Force logflags to those given by argument */
139
140     getGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
141     firstPlot = iTmp;
142
143     /* Reset x and y logflags */
144     if (firstPlot)
145     {
146         logFlags[0] = getBooleanLogFlag(logflags[1]);
147         logFlags[1] = getBooleanLogFlag(logflags[2]);
148
149         setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, &logFlags[0], jni_bool, 1);
150         setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, &logFlags[1], jni_bool, 1);
151     }
152
153     /* Forces "clipgrf" clipping (1) */
154     clipState = 1;
155     setGraphicObjectProperty(psubwinUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
156
157     getGraphicObjectProperty(psubwinUID, __GO_AUTO_SCALE__, jni_bool, (void **)&piTmp);
158     autoScale = iTmp;
159
160     if (autoScale)
161     {
162         /* compute and merge new specified bounds with the data bounds */
163         switch (strflag[1])
164         {
165             case '0':
166                 /* do not change data bounds */
167                 break;
168             case '1':
169             case '3':
170             case '5':
171             case '7':
172                 /* Force data bounds=brect */
173                 re_index_brect(brect, drect);
174                 break;
175             case '2':
176             case '4':
177             case '6':
178             case '8':
179             case '9':
180                 /* Force data bounds to the x and y bounds */
181                 if ((int)strlen(logflags) < 1)
182                     dataflag = 'g';
183                 else
184                     dataflag = logflags[0];
185
186                 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
187                 logFlags[0] = iTmp;
188                 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
189                 logFlags[1] = iTmp;
190                 getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
191                 logFlags[2] = iTmp;
192
193                 /* Conversion required by compute_data_bounds2 */
194                 textLogFlags[0] = getTextLogFlag(logFlags[0]);
195                 textLogFlags[1] = getTextLogFlag(logFlags[1]);
196                 textLogFlags[2] = getTextLogFlag(logFlags[2]);
197
198                 compute_data_bounds2(0, dataflag, textLogFlags, x, y, *n1, *n2, drect);
199
200                 break;
201         }
202
203         /* merge data bounds and drect */
204         if (!firstPlot && (strflag[1] == '5' || strflag[1] == '7' || strflag[1] == '8' || strflag[1] == '9'))
205         {
206             double *dataBounds;
207
208             getGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
209
210             drect[0] = Min(dataBounds[0], drect[0]);    /*xmin */
211             drect[2] = Min(dataBounds[2], drect[2]);    /*ymin */
212             drect[1] = Max(dataBounds[1], drect[1]);    /*xmax */
213             drect[3] = Max(dataBounds[3], drect[3]);    /*ymax */
214         }
215
216         if (strflag[1] != '0')
217         {
218             bounds_changed = update_specification_bounds(psubwinUID, drect, 2);
219         }
220     }
221
222     if (firstPlot)
223     {
224         bounds_changed = TRUE;
225     }
226
227     /* Adapted to the MVC */
228     axes_properties_changed = strflag2axes_properties(psubwinUID, strflag);
229
230     /* just after strflag2axes_properties */
231     newFirstPlot = 0;
232     setGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, &newFirstPlot, jni_bool, 1);
233
234     with_leg = (strflag[0] == '1');
235
236     /* F.Leray 07.10.04 : trigger algo to init. manual graduation u_xgrads and
237      * u_ygrads if nax (in matdes.c which is == aaint HERE) was specified */
238
239     /* The MVC AUTO_SUBTICKS property corresponds to !flagNax */
240     autoSubticks = !flagNax;
241     setGraphicObjectProperty(psubwinUID, __GO_AUTO_SUBTICKS__, &autoSubticks, jni_bool, 1);
242
243     if (flagNax == TRUE)
244     {
245         getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
246         logFlags[0] = iTmp;
247         getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
248         logFlags[1] = iTmp;
249
250         if (logFlags[0] == 0 && logFlags[1] == 0)
251         {
252             int autoTicks = 0;
253             int i = 0;
254             int iSize = 0;
255             double dblFabs = 0;
256             double* dXGrads = (double*) malloc(aaint[1] * sizeof(double));
257             double* dYGrads = (double*) malloc(aaint[3] * sizeof(double));
258             char** stringVector = NULL;
259
260             // set auto ticks to off
261             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
262             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
263
264             // Compute X grads
265             dXGrads[0] = drect[0];
266             if (aaint[1] > 1)
267             {
268                 double pas = (drect[1] - drect[0]) / (aaint[1] - 1);
269                 for (i = 0; i < aaint[1]; i++)
270                 {
271                     dXGrads[i] = drect[0] + pas * i;
272                 }
273             }
274
275             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_TICKS_LOCATIONS__, dXGrads, jni_double_vector, aaint[1]);
276
277             // Compute Y grads
278             dYGrads[0] = drect[2];
279             if (aaint[3] > 1)
280             {
281                 double pas = (drect[3] - drect[2]) / (aaint[3] - 1);
282                 for (i = 0; i < aaint[3]; i++)
283                 {
284                     dYGrads[i] = drect[2] + pas * i;
285                 }
286             }
287
288             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_TICKS_LOCATIONS__, dYGrads, jni_double_vector, aaint[3]);
289
290             // Create X Labels
291             stringVector = (char **) malloc(aaint[1] * sizeof(char*));
292             for (i = 0; i < aaint[1]; i++)
293             {
294                 iSize = 6;
295                 if (dXGrads[i] < 0)
296                 {
297                     iSize += 2;
298                 }
299                 dblFabs = fabs(dXGrads[i]);
300                 if (dblFabs >= 10)
301                 {
302                     iSize = iSize + (int)floor(log10(dblFabs));
303                 }
304
305                 stringVector[i] = (char*) malloc(iSize * sizeof(char));
306                 sprintf(stringVector[i], "%.3f", dXGrads[i]);
307                 stringVector[i][iSize - 1] = '\0';
308             }
309
310             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[1]);
311
312             for (i = 0; i < aaint[1]; i++)
313             {
314                 free(stringVector[i]);
315             }
316
317             free(stringVector);
318             stringVector = NULL;
319
320             // Create Y Labels
321             stringVector = (char**) malloc(aaint[3] * sizeof(char*));
322             for (i = 0; i < aaint[3]; i++)
323             {
324                 iSize = 6;
325                 if (dYGrads[i] < 0)
326                 {
327                     iSize += 2;
328                 }
329                 dblFabs = fabs(dYGrads[i]);
330                 if (dblFabs >= 10)
331                 {
332                     iSize = iSize + (int)floor(log10(dblFabs));
333                 }
334                 stringVector[i] = (char*) malloc(iSize * sizeof(char));
335                 sprintf(stringVector[i], "%.3f", dYGrads[i]);
336                 stringVector[i][iSize - 1] = '\0';
337             }
338
339             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[3]);
340
341             for (i = 0; i < aaint[3]; i++)
342             {
343                 free(stringVector[i]);
344             }
345
346             free(stringVector);
347             free(dXGrads);
348             free(dYGrads);
349
350             // X and Y subticks
351             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_SUBTICKS__, aaint, jni_int, 1);
352             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_SUBTICKS__, &aaint[2], jni_int, 1);
353
354         }
355         else
356         {
357             sciprint(_("Warning: Nax does not work with logarithmic scaling.\n"));
358         }
359
360     }
361
362     /*---- Drawing the curves and the legends ----*/
363     if (*n1 != 0)
364     {
365         if ((hdltab = MALLOC((*n1 + 1) * sizeof(long))) == NULL)
366         {
367             Scierror(999, _("%s: No more memory.\n"), "plot2d");
368             return -1;
369         }
370         if (with_leg)
371         {
372             /* tabofhandles allocated for legends */
373             if ((tabofhandles = MALLOC((*n1) * sizeof(long long))) == NULL)
374             {
375                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
376                 FREE(hdltab);
377                 return -1;
378             }
379         }
380
381         /*A.Djalel 3D axes */
382         for (jj = 0; jj < *n1; jj++)
383         {
384             char *pobjUID = NULL;
385
386             if (style[jj] > 0)
387             {
388                 BOOL isline = TRUE;
389
390                 if (ptype == 3)
391                 {
392                     isline = FALSE;
393                 }
394                 pobjUID = ConstructPolyline((char*)getCurrentSubWin(), &(x[jj * (*n2)]),
395                                             &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
396                                             &style[jj], NULL, NULL, NULL, NULL, isline, FALSE, FALSE, FALSE);
397             }
398             else
399             {
400                 int minusstyle = -style[jj];
401
402                 pobjUID = ConstructPolyline((char*)getCurrentSubWin(), &(x[jj * (*n2)]),
403                                             &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
404                                             NULL, NULL, &minusstyle, NULL, NULL, FALSE, FALSE, TRUE, FALSE);
405             }
406             if (pobjUID == NULL)
407             {
408                 // skip
409                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
410             }
411             else
412             {
413                 setCurrentObject(pobjUID);
414
415                 hdl = getHandle(pobjUID);
416                 releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
417                 pobjUID = NULL;
418                 if (with_leg)
419                 {
420                     tabofhandles[cmpt] = hdl;
421                 }
422
423                 hdltab[cmpt] = hdl;
424                 cmpt++;
425             }
426
427         }
428
429         /*---- Drawing the Legends ----*/
430         if (with_leg)
431         {
432             char *legUID;
433             char **Str;
434             int nleg;
435
436             if (scitokenize(legend, &Str, &nleg))
437             {
438                 FREE(tabofhandles);
439                 FREE(hdltab);
440                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
441                 return 0;
442             }
443
444             legUID = ConstructLegend((char*)getCurrentSubWin(), Str, tabofhandles, Min(nleg, cmpt));
445
446             if (legUID != NULL)
447             {
448                 int legendLocation;
449                 int contourMode;
450
451                 /* 9: LOWER_CAPTION */
452                 legendLocation = 9;
453                 setGraphicObjectProperty(legUID, __GO_LEGEND_LOCATION__, &legendLocation, jni_int, 1);
454
455                 contourMode = 0;
456
457                 setGraphicObjectProperty(legUID, __GO_FILL_MODE__, &contourMode, jni_bool, 1);
458                 setGraphicObjectProperty(legUID, __GO_LINE_MODE__, &contourMode, jni_bool, 1);
459             }
460
461             freeArrayOfString(Str, nleg);
462
463             FREE(tabofhandles);
464         }
465
466         /*---- construct Compound ----*/
467         if (cmpt > 0)
468         {
469             int parentVisible = 0;
470             int *piParentVisible = &parentVisible;
471             char* compoundUID = ConstructCompound (hdltab, cmpt);
472             setCurrentObject(compoundUID);
473             setGraphicObjectRelationship(psubwinUID, compoundUID);
474             getGraphicObjectProperty(psubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
475             setGraphicObjectProperty(compoundUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
476         }
477         FREE(hdltab);
478
479     }
480     /* End of the curves and legend block */
481
482     return (0);
483 }
484
485 /* Given two set of coordinates x and y this routine computes the corresponding
486  *  data bounds rectangle drect=[xmin,ymin,xmax,ymax] taking into account the logflag
487  *  -> means we have to find among the data the min > 0.
488  */
489 void compute_data_bounds2(int cflag, char dataflag, char *logflags, double *x, double *y, int n1, int n2, double *drect)
490 {
491     int size_x = 0, size_y = 0;
492     double xd[2];
493     double *x1 = NULL;
494
495     switch (dataflag)
496     {
497         case 'e':
498             xd[0] = 1.0;
499             xd[1] = (double)n2;
500             x1 = xd;
501             size_x = (n2 != 0) ? 2 : 0;
502             break;
503         case 'o':
504             x1 = x;
505             size_x = n2;
506             break;
507         case 'g':
508         default:
509             x1 = x;
510             size_x = (cflag == 1) ? n1 : (n1 * n2);
511             break;
512     }
513
514     if (size_x != 0)
515     {
516         if (logflags[0] != 'l')
517         {
518             drect[0] = Mini(x1, size_x);
519             drect[1] = Maxi(x1, size_x);
520         }
521         else
522         {
523             /* log. case */
524             drect[0] = sciFindStPosMin(x1, size_x);
525             drect[1] = Maxi(x1, size_x);
526         }
527
528     }
529     else
530     {
531         if (logflags[0] != 'l')
532         {
533             drect[0] = 0.0;
534             drect[1] = 10.0;
535         }
536         else
537         {
538             /* log. case */
539             drect[0] = 1.0;
540             drect[1] = 10.0;
541         }
542     }
543
544     size_y = (cflag == 1) ? n2 : (n1 * n2);
545     if (size_y != 0)
546     {
547         if (logflags[1] != 'l')
548         {
549             drect[2] = Mini(y, size_y);
550             drect[3] = Maxi(y, size_y);
551         }
552         else
553         {
554             /* log. case */
555             drect[2] = sciFindStPosMin(y, size_y);
556             drect[3] = Maxi(y, size_y);
557         }
558
559     }
560     else
561     {
562         if (logflags[1] != 'l')
563         {
564             drect[2] = 0.0;
565             drect[3] = 10.0;
566         }
567         else
568         {
569             /* log. case */
570             drect[2] = 1.0;
571             drect[3] = 10.0;
572         }
573     }
574     /* back to default values for  x=[] and y = [] */
575     if (drect[2] == LARGEST_REAL)
576     {
577         drect[2] = 0.0;
578         drect[3] = 10.0;
579     }
580     if (drect[0] == LARGEST_REAL)
581     {
582         drect[0] = 0.0;
583         drect[1] = 10.0;
584     }
585
586 }
587
588 BOOL update_specification_bounds(char *psubwinUID, double rect[6], int flag)
589 {
590     double *dataBounds = NULL;
591
592     /*
593      * 2D: keep the existing zmin and zmax
594      * which is why they must be fetched
595      */
596     if (flag != 3)
597     {
598         getGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
599
600         rect[4] = dataBounds[4];
601         rect[5] = dataBounds[5];
602     }
603
604     setGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, rect, jni_double_vector, 6);
605
606     return TRUE;
607 }
608
609 /* F.Leray */
610 /* brect must have the same format as drect i.e.: [xmin,xmax,ymin,ymax] */
611 /* brect = INPUT ; drect = OUTPUT (warning drect is dim 6) */
612 int re_index_brect(double *brect, double *drect)
613 {
614     drect[0] = brect[0];
615     drect[1] = brect[2];
616     drect[2] = brect[1];
617     drect[3] = brect[3];
618
619     return 0;
620 }
621
622 /* F.Leray 07.05.04 */
623 /* Dispatch info contained in strflag to all the flag available in
624    sciSubwin object (tight_limits, isoview, isaxes...) */
625 /*
626  * This function has been adapted to the MVC framework
627  */
628 BOOL strflag2axes_properties(char *psubwinUID, char *strflag)
629 {
630     BOOL haschanged = FALSE;
631     BOOL tightLimitsPrev = FALSE;
632     BOOL isoviewPrev = FALSE;
633     int boxPrev = 0;
634     int tightLimits = 0;
635     int firstPlot = 0;
636     int axisVisible = 0;
637     int boxType = 0;
638     int xLocationPrev = 0;
639     int yLocationPrev = 0;
640     int xLocation = 0;
641     int yLocation = 0;
642     int isoview = 0;
643     int axesVisiblePrev[3];
644     int axesVisible[3];
645
646     int iTmp = 0;
647     int *piTmp = &iTmp;
648
649     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
650     axesVisiblePrev[0] = iTmp;
651     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
652     axesVisiblePrev[1] = iTmp;
653     getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
654     axesVisiblePrev[2] = iTmp;
655
656     getGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
657     boxPrev = iTmp;
658
659     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
660     xLocationPrev = iTmp;
661     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
662     yLocationPrev = iTmp;
663
664     getGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
665     tightLimitsPrev = iTmp;
666     getGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
667     isoviewPrev = iTmp;
668
669     /* F.Leray 07.05.04 */
670     /* strflag[1] Isoview & tight_limits flags management */
671     switch (strflag[1])
672     {
673         case '0':
674         case '9':
675             /* no changes */
676             break;
677         case '1':
678         case '2':
679         case '7':
680         case '8':
681             tightLimits = 1;
682             setGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
683             break;
684         case '3':
685         case '4':
686             isoview = 1;
687             setGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, &isoview, jni_bool, 1);
688             break;
689         case '5':
690         case '6':
691             /* pretty axes */
692             tightLimits = 0;
693             setGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
694             break;
695     }
696
697     /* F.Leray 07.05.04 */
698     /* strflag[2] */
699     switch (strflag[2])
700     {
701
702         case '0':
703             getGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
704             firstPlot = iTmp;
705
706             if (firstPlot)
707             {
708                 axisVisible = 0;
709                 /* 0: OFF */
710                 boxType = 0;
711
712                 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
713                 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
714                 /* also trigger z axis */
715                 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
716                 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
717             }
718             /*else no changes : the isaxes properties is driven by the previous plot */
719             break;
720         case '1':
721             axisVisible = 1;
722             /* 1: ON */
723             boxType = 1;
724             /* 4: LEFT */
725             yLocation = 4;
726
727             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
728             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
729             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
730             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
731             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
732
733             break;
734         case '2':
735             axisVisible = 0;
736             boxType = 1;
737
738             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
739             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
740             /* also trigger z axis */
741             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
742             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
743
744             break;
745         case '3':
746             axisVisible = 1;
747             boxType = 0;
748             /* 5: RIGHT */
749             yLocation = 5;
750
751             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
752             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
753             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
754             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
755             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
756
757             break;
758         case '4':
759             axisVisible = 1;
760             /* 2: MIDDLE */
761             xLocation = 2;
762             yLocation = 2;
763             boxType = 0;
764
765             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
766             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
767             /* also trigger z axis */
768             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
769             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
770             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
771             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
772
773             break;
774         case '5':
775             axisVisible = 1;
776             xLocation = 2;
777             yLocation = 2;
778             boxType = 1;
779
780             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
781             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
782             /* also trigger z axis */
783             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
784             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
785             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
786             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
787
788             break;
789         case '9':
790             axisVisible = 1;
791
792             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
793             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
794             /* also trigger z axis */
795             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
796     }
797
798     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
799     axesVisible[0] = iTmp;
800     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
801     axesVisible[1] = iTmp;
802     getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
803     axesVisible[2] = iTmp;
804
805     getGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
806     boxType = iTmp;
807
808     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
809     xLocation = iTmp;
810     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
811     yLocation = iTmp;
812
813     getGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
814     tightLimits = iTmp;
815     getGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
816     isoview = iTmp;
817
818     /* Find if something has changed */
819     if (axesVisible[0] != axesVisiblePrev[0]
820             || axesVisible[1] != axesVisiblePrev[1]
821             || axesVisible[2] != axesVisiblePrev[2]
822             || xLocation != xLocationPrev || yLocation != yLocationPrev || boxType != boxPrev || tightLimits != tightLimitsPrev || isoview != isoviewPrev)
823     {
824         haschanged = TRUE;
825     }
826     else
827     {
828         haschanged = FALSE;
829     }
830
831     return haschanged;
832 }