1 #include <cerrno>
2 #include <cstring>
3 #include <cstdlib>
4 #include <iomanip>
5 #include <QFile>
6 #include <QTextStream>
7 #include <QMessageBox>
8 #include <QSettings>
9 
10 #include "filter.h"
11 #include "config.h"
12 #include "formulas.h"
13 #include "ui_helper.h"
14 #include "plane.h"
15 #include "xmenu.h"
16 #include "play.h"
17 #include "i18n.h"
18 #include "xthread.h"
19 #include "customdialog.h"
20 
21 #define LANG(name, name2)                                                      \
22     MENUSTRING("lang", NULL, name, name2, 0,                                   \
23                (void (*)(struct uih_context * c, char *)) uih_loadcatalog,     \
24                name2)
25 #define TUTOR(name1, name2, name3)                                             \
26     MENUSTRING(name1, NULL, name2, name3, MENUFLAG_INTERRUPT | UI,             \
27                uih_playtutorial, name3)
28 #define LANG_I(name, name2)                                                    \
29     MENUSTRING_I("lang", NULL, name, name2, 0,                                 \
30                  (void (*)(struct uih_context * c, char *)) uih_loadcatalog,   \
31                  name2)
32 #define TUTOR_I(name1, name2, name3)                                           \
33     MENUSTRING_I(name1, NULL, name2, name3, MENUFLAG_INTERRUPT | UI,           \
34                  uih_playtutorial, name3)
35 
36 const static char *const morphstypes[] = {"view", "julia", "angle", "line"};
37 
38 static const char *const imgtypes[] = {"Truecolor", "256 colors", NULL};
39 
40 static const char *const yesno[] = {"No", "Yes", NULL};
41 
42 const static char *const lineposs[] = {"screen", "scaled", "fractal", NULL};
43 
44 const char *const uih_colornames[] = {"white", "black", "red", NULL};
45 
46 /* Registering internationalized dialogs.
47  *
48  * The method we are internationalizing dialogs is similar to
49  * menu i18n. The original version of XaoS (without i18n)
50  * contained lots of static variables. Each row of a variable
51  * (which is a structure) contains a widget of a dialog.
52  * The last row contains NULL and 0 values to show
53  * that the dialog does not contain any other widgets.
54  *
55  * Here we are using a huge static variable which contains
56  * all widget from all dialogs. We copy each dialog after
57  * each other into this huge array. The original static
58  * variables will now be pointers pointing to the first
59  * row of the widget data from the appropriate line
60  * of the huge array.
61  *
62  * Note that in the first version there are only 2
63  * internationalized text, the rest will be "converted"
64  * continuously (as I have enough time :-).
65  *
66  * Zoltan Kovacs <kovzol@math.u-szeged.hu>, 2003-01-05
67  */
68 
69 #define MAX_MENUDIALOGS_I18N 150
70 #define Register(variable) variable = &menudialogs_i18n[no_menudialogs_i18n]
71 static menudialog menudialogs_i18n[MAX_MENUDIALOGS_I18N];
72 // static int no_menudialogs_i18n;
73 
74 static menudialog *uih_perturbationdialog, *uih_juliadialog,
75     *uih_smoothmorphdialog, *uih_renderdialog, *uih_viewdialog, *uih_linedialog,
76     *uih_colordialog, *uih_rotationdialog, *uih_lettersdialog, *uih_iterdialog,
77     *dtextparam, *dcommand, *loaddialog, *playdialog, *saveimgdialog,
78     *saveposdialog, *uih_formuladialog, *uih_plviewdialog, *uih_coorddialog,
79     *uih_angledialog, *uih_autorotatedialog, *uih_fastrotatedialog,
80     *uih_filterdialog, *uih_shiftdialog, *uih_speeddialog, *printdialog,
81     *uih_bailoutdialog, *uih_threaddialog, *saveanimdialog, *uih_juliamodedialog,
82     *uih_textposdialog, *uih_fastmodedialog, *uih_timedialog, *uih_numdialog,
83     *uih_fpdialog, *palettedialog, *uih_cyclingdialog, *palettegradientdialog,
84     *uih_renderimgdialog, *palettepickerdialog, *loadgpldialog, *savegpldialog,
85     *uih_palettecolorsdialog
86 #ifdef USE_SFFE
87     ,
88     *uih_sffedialog, *uih_sffeinitdialog
89 #endif
90     ;
91 
uih_registermenudialogs_i18n(void)92 void uih_registermenudialogs_i18n(void)
93 {
94     int no_menudialogs_i18n = 0;
95 
96     /*
97      * The original code was:
98 
99     static menudialog uih_perturbationdialog[] = {
100       DIALOGCOORD ("Perturbation:", 0, 0),
101       {NULL}
102 
103     };
104 
105      * Now first the static variable have to be registered (1),
106      * the widget must be inserted into the huge array (2),
107      * and the last row shows that no more widget comes (3).
108      */
109 
110     Register(uih_perturbationdialog);                   // (1)
111     DIALOGCOORD_I(TR("Dialog", "Perturbation:"), 0, 0); // (2)
112     NULL_I();                                           // (3)
113 
114     Register(uih_juliadialog);
115     DIALOGCOORD_I(TR("Dialog", "Julia-seed:"), 0, 0);
116     NULL_I();
117 
118     Register(uih_smoothmorphdialog);
119     DIALOGCHOICE_I(TR("Dialog", "Morphing type:"), morphstypes, 0);
120     DIALOGINT_I(TR("Dialog", "Startuptime:"), 0);
121     DIALOGINT_I(TR("Dialog", "Stoptime:"), 0);
122     NULL_I();
123 
124     Register(uih_renderdialog);
125     DIALOGIFILES_I(TR("Dialog", "Files to render:"), 0);
126     DIALOGOFILE_I(TR("Dialog", "Basename:"), "anim");
127     DIALOGINT_I(TR("Dialog", "Width:"), 640);
128     DIALOGINT_I(TR("Dialog", "Height:"), 480);
129     DIALOGFLOAT_I(TR("Dialog", "Pixel width (cm):"), 0.025);
130     DIALOGFLOAT_I(TR("Dialog", "Pixel height (cm):"), 0.025);
131     DIALOGFLOAT_I(TR("Dialog", "Framerate:"), 30);
132     DIALOGCHOICE_I(TR("Dialog", "Image type:"), imgtypes, 0);
133     DIALOGCHOICE_I(TR("Dialog", "Antialiasing:"), yesno, 0);
134     DIALOGCHOICE_I(TR("Dialog", "Always recalculate:"), yesno, 0);
135     NULL_I();
136 
137     Register(uih_renderimgdialog);
138     DIALOGOFILE_I(TR("Dialog", "Basename:"), "anim");
139     DIALOGINT_I(TR("Dialog", "Width:"), 640);
140     DIALOGINT_I(TR("Dialog", "Height:"), 480);
141     DIALOGFLOAT_I(TR("Dialog", "Pixel width (cm):"), 0.025);
142     DIALOGFLOAT_I(TR("Dialog", "Pixel height (cm):"), 0.025);
143     DIALOGCHOICE_I(TR("Dialog", "Image type:"), imgtypes, 0);
144     DIALOGCHOICE_I(TR("Dialog", "Antialiasing:"), yesno, 0);
145     NULL_I();
146 
147     Register(uih_viewdialog);
148     DIALOGCOORD_I(TR("Dialog", "Center:"), 0, 0);
149     DIALOGFLOAT_I(TR("Dialog", "Radius:"), 1);
150     DIALOGFLOAT_I(TR("Dialog", "Angle:"), 0);
151     NULL_I();
152 
153     Register(uih_linedialog);
154     DIALOGCHOICE_I(TR("Dialog", "Mode:"), lineposs, 0);
155     DIALOGCOORD_I(TR("Dialog", "Start:"), 0, 0);
156     DIALOGCOORD_I(TR("Dialog", "End:"), 0, 0);
157     NULL_I();
158 
159     Register(uih_colordialog);
160     DIALOGCHOICE_I(TR("Dialog", "Color:"), uih_colornames, 0);
161     NULL_I();
162 
163     Register(uih_rotationdialog);
164     DIALOGFLOAT_I(TR("Dialog", "Rotations per second:"), 0);
165     NULL_I();
166 
167     Register(uih_lettersdialog);
168     DIALOGINT_I(TR("Dialog", "Letters per second:"), 0);
169     NULL_I();
170 
171     Register(uih_iterdialog);
172     DIALOGINT_I(TR("Dialog", "Iterations:"), 0);
173     NULL_I();
174 
175     Register(dtextparam);
176     DIALOGSTR_I(TR("Dialog", "Text:"), "");
177     NULL_I();
178 
179     Register(dcommand);
180     DIALOGSTR_I(TR("Dialog", "Your command:"), "");
181     NULL_I();
182 
183     Register(loaddialog);
184     DIALOGIFILE_I(TR("Dialog", "Filename:"), "*.png *.xpf");
185     NULL_I();
186 
187     Register(playdialog);
188     DIALOGIFILE_I(TR("Dialog", "Filename:"), "anim*.xaf");
189     NULL_I();
190 
191     Register(saveimgdialog);
192     DIALOGOFILE_I(TR("Dialog", "Filename:"), "fract*.png");
193     NULL_I();
194 
195     Register(saveposdialog);
196     DIALOGOFILE_I(TR("Dialog", "Filename:"), "fract*.xpf");
197     NULL_I();
198 
199     Register(uih_formuladialog);
200     DIALOGKEYSTR_I(TR("Dialog", "Formula:"), "mandel");
201     NULL_I();
202 
203     Register(uih_plviewdialog);
204     DIALOGFLOAT_I(TR("Dialog", "X center:"), 0);
205     DIALOGFLOAT_I(TR("Dialog", "Y center:"), 0);
206     DIALOGFLOAT_I(TR("Dialog", "X Radius:"), 1);
207     DIALOGFLOAT_I(TR("Dialog", "Y Radius:"), 1);
208     NULL_I();
209 
210     Register(uih_coorddialog);
211     DIALOGCOORD_I(TR("Dialog", "Coordinates:"), 0, 0);
212     NULL_I();
213 
214     Register(uih_angledialog);
215     DIALOGFLOAT_I(TR("Dialog", "Angle:"), 1);
216     NULL_I();
217 
218     Register(uih_autorotatedialog);
219     DIALOGONOFF_I(TR("Dialog", "continuous rotation"), 0);
220     NULL_I();
221 
222     Register(uih_fastrotatedialog);
223     DIALOGONOFF_I(TR("Dialog", "Fast rotation"), 0);
224     NULL_I();
225 
226     Register(uih_filterdialog);
227     DIALOGKEYSTR_I(TR("Dialog", "filter"), "");
228     DIALOGONOFF_I(TR("Dialog", "enable"), 0);
229     NULL_I();
230 
231     Register(uih_shiftdialog);
232     DIALOGINT_I(TR("Dialog", "Amount:"), 0);
233     NULL_I();
234 
235     Register(uih_speeddialog);
236     DIALOGFLOAT_I(TR("Dialog", "Zooming speed:"), 0);
237     NULL_I();
238 
239     Register(printdialog);
240     DIALOGSTR_I(TR("Dialog", "Name:"), "");
241     NULL_I();
242 
243     Register(uih_bailoutdialog);
244     DIALOGFLOAT_I(TR("Dialog", "Bailout:"), 0);
245     NULL_I();
246 
247     Register(uih_threaddialog);
248     DIALOGINT_I(TR("Dialog", "Threads:"), 0);
249     NULL_I();
250 
251     Register(saveanimdialog);
252     DIALOGOFILE_I(TR("Dialog", "Filename:"), "anim*.xaf");
253     NULL_I();
254 
255     Register(uih_juliamodedialog);
256     DIALOGONOFF_I(TR("Dialog", "Julia mode:"), 0);
257     NULL_I();
258 
259     Register(uih_textposdialog);
260     DIALOGCHOICE_I(TR("Dialog", "Horizontal position:"), xtextposnames, 0);
261     DIALOGCHOICE_I(TR("Dialog", "Vertical position:"), ytextposnames, 0);
262     NULL_I();
263 
264     Register(uih_fastmodedialog);
265     DIALOGCHOICE_I(TR("Dialog", "Dynamic resolution:"), save_fastmode, 0);
266     NULL_I();
267 
268     Register(uih_timedialog);
269     DIALOGINT_I(TR("Dialog", "Time:"), 0);
270     NULL_I();
271 
272     Register(uih_numdialog);
273     DIALOGINT_I(TR("Dialog", "Number:"), 0);
274     NULL_I();
275 
276     Register(uih_fpdialog);
277     DIALOGFLOAT_I(TR("Dialog", "Number:"), 0);
278     NULL_I();
279 
280     Register(palettedialog);
281     DIALOGINT_I(TR("Dialog", "Algorithm number:"), 0);
282     DIALOGINT_I(TR("Dialog", "Seed:"), 0);
283     DIALOGINT_I(TR("Dialog", "Shift:"), 0);
284     NULL_I();
285 
286     Register(palettegradientdialog);
287     DIALOGPALSLIDER_I("Visualiser:", 0);
288     NULL_I();
289 
290     Register(uih_palettecolorsdialog);
291     for (int colidx = 0; colidx < 31; colidx++) {
292         DIALOGSTR_I(TR("Dialog", "Color:"), "000000");
293     }
294     NULL_I();
295 
296     Register(palettepickerdialog);
297     DIALOGPALPICKER_I("Palette:", 0);
298     NULL_I();
299 
300     Register(loadgpldialog);
301     DIALOGIFILE_I(TR("Dialog", "Load Palette Config"), "file*.gpl");
302     NULL_I();
303 
304     Register(savegpldialog);
305     DIALOGOFILE_I(TR("Dialog", "Save Palette Config"), "file*.gpl");
306     NULL_I();
307 
308     Register(uih_cyclingdialog);
309     DIALOGINT_I(TR("Dialog", "Frames per second:"), 0);
310     NULL_I();
311 
312 #ifdef USE_SFFE
313     Register(uih_sffedialog);
314     DIALOGLIST_I(TR("Dialog", "Formula"), USER_FORMULA);
315     NULL_I();
316 
317     Register(uih_sffeinitdialog);
318     DIALOGSTR_I(TR("Dialog", "Initialization:"), "");
319     NULL_I();
320 #endif
321 
322     if (no_menudialogs_i18n > MAX_MENUDIALOGS_I18N) {
323         fprintf(stderr, "MAX_MENUDIALOGS_I18N is set to an insufficiently low number, please increase it to %d\n", no_menudialogs_i18n);
324         fflush(stderr);
325         exit(1);
326     }
327 #ifdef DEBUG
328     printf("Filled %d widgets out of %d.\n", no_menudialogs_i18n,
329            MAX_MENUDIALOGS_I18N);
330     fflush(stdout);
331 #endif
332 
333 }
334 
335 #undef Register
336 
337 /*
338  * End of registering internationalized dialogs.
339  */
340 
341 #ifdef USE_SFFE
342 void uih_sffein(uih_context *c, const char *text);
343 void uih_sffeinitin(uih_context *c, const char *text);
344 #endif
345 
uih_smoothmorph(struct uih_context * c,dialogparam * p)346 static void uih_smoothmorph(struct uih_context *c, dialogparam *p)
347 {
348     if (!c->playc)
349         return;
350     switch (p[0].dint) {
351         case 0:
352             c->playc->morphtimes[0] = p[1].dint;
353             c->playc->morphtimes[1] = p[2].dint;
354             break;
355         case 1:
356             c->playc->morphjuliatimes[0] = p[1].dint;
357             c->playc->morphjuliatimes[1] = p[2].dint;
358             break;
359         case 2:
360             c->playc->morphangletimes[0] = p[1].dint;
361             c->playc->morphangletimes[1] = p[2].dint;
362             break;
363         case 3:
364             c->playc->morphlinetimes[0] = p[1].dint;
365             c->playc->morphlinetimes[1] = p[2].dint;
366             break;
367     }
368 }
369 
uih_render(struct uih_context * c,dialogparam * d)370 static void uih_render(struct uih_context *c, dialogparam *d)
371 {
372 
373     if(fnames.size() == 0) {
374         uih_error(c, "No file Selected");
375         return;
376     }
377     if (d[2].dint <= 0 || d[2].dint > 4096) {
378         uih_error(
379             c,
380             TR("Error",
381                "renderanim: Width parameter must be positive integer in the range 0..4096"));
382         return;
383     }
384     if (d[3].dint <= 0 || d[3].dint > 4096) {
385         uih_error(
386             c,
387             TR("Error",
388                "renderanim: Height parameter must be positive integer in the range 0..4096"));
389         return;
390     }
391     if (d[4].number <= 0 || d[5].number <= 0) {
392         uih_error(c,
393                   TR("Error",
394                      "renderanim: Invalid real width and height dimensions"));
395         return;
396     }
397     if (d[6].number <= 0 || d[6].number >= 1000000) {
398         uih_error(c, TR("Error", "renderanim: invalid framerate"));
399         return;
400     }
401     if (d[7].dint && d[8].dint) {
402         uih_error(
403             c, TR("Error",
404                   "renderanim: antialiasing not supported in 256 color mode"));
405         return;
406     }
407     for(int i=0; i < (int)fnames.size(); i++) {
408 
409         QString hlpmsg = "Rendering (" + QString::number(i) + "/" +
410                 QString::number(fnames.size()) + ") " + fnames[i];
411         uih_message(c, hlpmsg.toStdString().c_str());
412 
413         char* curr_file = strdup(fnames[i].toStdString().c_str());
414 
415         QString file_number = "_" + fnames[i].split("/").back().split(".").front() + "_";
416         char* file_suffix = strdup(file_number.toStdString().c_str());
417         char* base_name = (char *)malloc(strlen(d[1].dstring) + strlen(file_suffix) + 2);
418         strcpy(base_name, d[1].dstring);
419         strcat(base_name, file_suffix);
420 
421         uih_renderanimation(c, base_name, (xio_path)curr_file, d[2].dint,
422                                 d[3].dint, d[4].number, d[5].number,
423                                 (int)(1000000 / d[6].number),
424         #ifdef STRUECOLOR24
425                                 d[7].dint ? C256 : TRUECOLOR24,
426         #else
427                                 d[7].dint ? C256 : TRUECOLOR,
428         #endif
429                                 d[8].dint, d[9].dint, c->letterspersec, NULL);
430         free(base_name);
431     }
432 }
433 
uih_renderimg(struct uih_context * c,dialogparam * d)434 static void uih_renderimg(struct uih_context *c, dialogparam *d)
435 {
436     xio_file f = xio_wopen(".xaos_temp.xpf");
437     if(!f) {
438         uih_error(c, "Could not Render Image");
439         return;
440     }
441 
442     uih_save_position(c, f, 0);
443     xio_constpath path = ".xaos_temp.xpf";
444 
445     if (d[1].dint <= 0 || d[1].dint > 4096) {
446         uih_error(
447             c,
448             TR("Error",
449                "renderanim: Width parameter must be positive integer in the range 0..4096"));
450         return;
451     }
452     if (d[2].dint <= 0 || d[2].dint > 4096) {
453         uih_error(
454             c,
455             TR("Error",
456                "renderanim: Height parameter must be positive integer in the range 0..4096"));
457         return;
458     }
459     if (d[3].number <= 0 || d[4].number <= 0) {
460         uih_error(c,
461                   TR("Error",
462                      "renderanim: Invalid real width and height dimensions"));
463         return;
464     }
465     if (d[5].dint && d[6].dint) {
466         uih_error(
467             c, TR("Error",
468                   "renderanim: antialiasing not supported in 256 color mode"));
469         return;
470     }
471 
472     uih_renderanimation(c, d[0].dstring, (xio_path)path, d[1].dint,
473                             d[2].dint, d[3].number, d[4].number,
474                             (int)(1000000 / 30),
475     #ifdef STRUECOLOR24
476                             d[5].dint ? C256 : TRUECOLOR24,
477     #else
478                             d[5].dint ? C256 : TRUECOLOR,
479     #endif
480                             d[6].dint, 0, c->letterspersec, NULL);
481 
482     remove(".xaos_temp.xpf");
483 }
484 
uih_getcolordialog(struct uih_context * c)485 static menudialog *uih_getcolordialog(struct uih_context *c)
486 {
487     if (c != NULL) {
488         uih_colordialog[0].defint = c->color;
489     }
490     return (uih_colordialog);
491 }
492 
uih_setcolor(struct uih_context * c,int color)493 static void uih_setcolor(struct uih_context *c, int color) { c->color = color; }
494 
uih_getperturbationdialog(struct uih_context * c)495 static menudialog *uih_getperturbationdialog(struct uih_context *c)
496 {
497     if (c != NULL) {
498         uih_perturbationdialog[0].deffloat = c->fcontext->bre;
499         uih_perturbationdialog[0].deffloat2 = c->fcontext->bim;
500     }
501     return (uih_perturbationdialog);
502 }
503 
uih_getjuliadialog(struct uih_context * c)504 static menudialog *uih_getjuliadialog(struct uih_context *c)
505 {
506     if (c != NULL) {
507         uih_juliadialog[0].deffloat = c->fcontext->pre;
508         uih_juliadialog[0].deffloat2 = c->fcontext->pim;
509     }
510     return (uih_juliadialog);
511 }
512 
uih_plview(struct uih_context * c,dialogparam * d)513 static void uih_plview(struct uih_context *c, dialogparam *d)
514 {
515     if (d[2].number <= 0 || d[3].number <= 0) {
516         uih_error(c, TR("Error", "animateview: Invalid viewpoint"));
517         return;
518     }
519     c->fcontext->s.cr = d[0].number;
520     c->fcontext->s.ci = d[1].number;
521     c->fcontext->s.rr = d[2].number;
522     c->fcontext->s.ri = d[3].number;
523     uih_newimage(c);
524 }
525 
uih_plview2(struct uih_context * c,dialogparam * d)526 static void uih_plview2(struct uih_context *c, dialogparam *d)
527 {
528     if (d[2].number <= 0 || d[3].number <= 0) {
529         uih_error(c, TR("Error", "animateview: Invalid viewpoint"));
530         return;
531     }
532     c->fcontext->s.cr = d[0].number;
533     c->fcontext->s.ci = d[1].number;
534     c->fcontext->s.rr = d[2].number;
535     c->fcontext->s.ri = d[3].number;
536     uih_animate_image(c);
537 }
538 
uih_dview(struct uih_context * c,dialogparam * d)539 static void uih_dview(struct uih_context *c, dialogparam *d)
540 {
541     if (d[1].number <= 0) {
542         uih_error(c, TR("Error", "Invalid viewpoint"));
543         return;
544     }
545     c->fcontext->s.cr = d[0].dcoord[0];
546     c->fcontext->s.ci = d[0].dcoord[1];
547     c->fcontext->s.rr = d[1].number;
548     c->fcontext->s.ri = d[1].number;
549     uih_angle(c, d[2].number);
550     uih_newimage(c);
551 }
552 
uih_getviewdialog(struct uih_context * c)553 static menudialog *uih_getviewdialog(struct uih_context *c)
554 {
555     number_t xs, ys;
556     if (c != NULL) {
557         xs = c->fcontext->s.rr;
558         ys = c->fcontext->s.ri * c->fcontext->windowwidth /
559              c->fcontext->windowheight;
560         uih_viewdialog[0].deffloat = c->fcontext->s.cr;
561         uih_viewdialog[0].deffloat2 = c->fcontext->s.ci;
562         uih_viewdialog[2].deffloat = c->fcontext->angle;
563         if (xs > ys)
564             uih_viewdialog[1].deffloat = c->fcontext->s.rr;
565         else
566             uih_viewdialog[1].deffloat = c->fcontext->s.ri;
567     }
568     return (uih_viewdialog);
569 }
570 
uih_getlettersdialog(struct uih_context * c)571 static menudialog *uih_getlettersdialog(struct uih_context *c)
572 {
573     if (c != NULL)
574         uih_lettersdialog[0].defint = c->letterspersec;
575     return (uih_lettersdialog);
576 }
577 
uih_getiterdialog(struct uih_context * c)578 static menudialog *uih_getiterdialog(struct uih_context *c)
579 {
580     if (c != NULL)
581         uih_iterdialog[0].defint = c->fcontext->maxiter;
582     return (uih_iterdialog);
583 }
584 
uih_getbailoutdialog(struct uih_context * c)585 static menudialog *uih_getbailoutdialog(struct uih_context *c)
586 {
587     if (c != NULL)
588         uih_bailoutdialog[0].deffloat = c->fcontext->bailout;
589     return (uih_bailoutdialog);
590 }
591 
592 int defthreads = 0;
593 
uih_getthreaddialog(struct uih_context * c)594 static menudialog *uih_getthreaddialog(struct uih_context *c)
595 {
596     if (c != NULL)
597         uih_threaddialog[0].defint = defthreads;
598     return (uih_threaddialog);
599 }
600 
uih_setthreads(uih_context *,int threads)601 void uih_setthreads(uih_context */*c*/, int threads)
602 {
603     if (threads < 1)
604         threads = 1;
605     if (threads > MAXTHREADS)
606         threads = MAXTHREADS;
607     if (threads != defthreads) {
608         QSettings settings;
609         settings.setValue("MainWindow/threadCount", threads);
610         QMessageBox msgBox;
611         msgBox.setText(
612             TR("Message", "XaoS must restart to change the thread count."));
613         msgBox.setInformativeText(TR("Message", "Do you want to quit now?"));
614         msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
615         int ret = msgBox.exec();
616         if (ret == QMessageBox::Yes) {
617             exit(0);
618         }
619     }
620 }
621 
uih_saveanimenabled(struct uih_context * c)622 static int uih_saveanimenabled(struct uih_context *c)
623 {
624     if (c == NULL)
625         return 0;
626     return (c->save);
627 }
628 
uih_getrotationdialog(struct uih_context * c)629 static menudialog *uih_getrotationdialog(struct uih_context *c)
630 {
631     if (c != NULL)
632         uih_rotationdialog[0].deffloat = c->rotationspeed;
633     return (uih_rotationdialog);
634 }
635 
636 #ifdef USE_SFFE
uih_getsffedialog(struct uih_context * c)637 static menudialog *uih_getsffedialog(struct uih_context *c)
638 {
639     if (c != NULL) {
640         if (c->fcontext->userformula->expression)
641             uih_sffedialog[0].defstr = c->fcontext->userformula->expression;
642         else
643             uih_sffedialog[0].defstr = USER_FORMULA;
644     }
645     return (uih_sffedialog);
646 }
647 
uih_getsffeinitdialog(struct uih_context * c)648 static menudialog *uih_getsffeinitdialog(struct uih_context *c)
649 {
650     if (c != NULL) {
651         if (c->fcontext->userinitial->expression)
652             uih_sffeinitdialog[0].defstr = c->fcontext->userinitial->expression;
653         else
654             uih_sffeinitdialog[0].defstr = "";
655     }
656     return (uih_sffeinitdialog);
657 }
658 #endif
659 
uih_getpalettedialog(struct uih_context * uih)660 static menudialog *uih_getpalettedialog(struct uih_context *uih)
661 {
662     if (uih != NULL) {
663         palettedialog[0].defint = uih->palettetype;
664         palettedialog[1].defint = uih->paletteseed;
665         palettedialog[2].defint = uih->paletteshift + uih->manualpaletteshift;
666     }
667     return (palettedialog);
668 }
669 
uih_palettepickerdialog(struct uih_context * uih)670 static menudialog *uih_palettepickerdialog(struct uih_context *uih)
671 {
672     return (palettepickerdialog);
673 }
674 
uih_getpalettegradientdialog(struct uih_context * uih)675 static menudialog *uih_getpalettegradientdialog(struct uih_context *uih)
676 {
677     if (uih != NULL) {
678         palettegradientdialog[0].defint = 0;
679     }
680     return (palettegradientdialog);
681 }
682 
uih_getcyclingdialog(struct uih_context * uih)683 static menudialog *uih_getcyclingdialog(struct uih_context *uih)
684 {
685     if (uih != NULL)
686         uih_cyclingdialog[0].defint = uih->cyclingspeed * uih->direction;
687     return (uih_cyclingdialog);
688 }
689 
uih_getspeeddialog(struct uih_context * uih)690 static menudialog *uih_getspeeddialog(struct uih_context *uih)
691 {
692     if (uih != NULL)
693         uih_speeddialog[0].deffloat = uih->speedup / STEP;
694     return (uih_speeddialog);
695 }
696 
uih_setspeed(uih_context * c,number_t p)697 static void uih_setspeed(uih_context *c, number_t p)
698 {
699     if (p >= 100)
700         p = 1.0;
701     if (p < 0)
702         p = 0;
703     c->speedup = STEP * p;
704     c->maxstep = MAXSTEP * p;
705 }
706 
uih_palette(struct uih_context * uih,dialogparam * p)707 static void uih_palette(struct uih_context *uih, dialogparam *p)
708 {
709     int n1 = p[0].dint;
710     int n2 = p[1].dint;
711     int shift = p[2].dint;
712 
713     if (!n1) {
714         uih_playdefpalette(uih, shift);
715         return;
716     }
717     if (n1 < 1 || n1 > PALGORITHMS) {
718         uih_error(uih, TR("Error", "Unknown palette type"));
719     }
720     if (uih->zengine->fractalc->palette == NULL)
721         return;
722     if (mkpalette(uih->zengine->fractalc->palette, n2, n1 - 1) != 0) {
723         uih_newimage(uih);
724     }
725     uih->manualpaletteshift = 0;
726     uih->palettetype = n1;
727     uih->palettechanged = 1;
728     uih->paletteseed = n2;
729     if (shiftpalette(uih->zengine->fractalc->palette, shift)) {
730         uih_newimage(uih);
731     }
732     uih->paletteshift = shift;
733     uih->palettepickerenabled = 0;
734 }
735 
uih_palettegradient(struct uih_context * uih,dialogparam * p)736 static void uih_palettegradient(struct uih_context *uih, dialogparam *p)
737 {
738     int n1 = uih->palettetype;
739     int n2 = uih->paletteseed;
740     int shift = uih->paletteshift;
741 
742     if (!n1) {
743         uih_playdefpalette(uih, shift);
744         return;
745     }
746     if (n1 < 1 || n1 > PALGORITHMS) {
747         uih_error(uih, TR("Error", "Unknown palette type"));
748     }
749     if (uih->zengine->fractalc->palette == NULL)
750         return;
751     if (mkpalette(uih->zengine->fractalc->palette, n2, n1 - 1) != 0) {
752         uih_newimage(uih);
753     }
754     uih->manualpaletteshift = 0;
755     uih->palettetype = n1;
756     uih->palettechanged = 1;
757     uih->paletteseed = n2;
758     if (shiftpalette(uih->zengine->fractalc->palette, shift)) {
759         uih_newimage(uih);
760     }
761     uih->paletteshift = shift;
762     uih->palettepickerenabled = 0;
763 }
764 
uih_palettecolors(struct uih_context * uih,dialogparam * p)765 static void uih_palettecolors(struct uih_context *uih, dialogparam *p){
766     unsigned char colors[31][3];
767     memset(colors, 0, sizeof (colors));
768     for(int i=0; i < 31; i++) {
769         rgb_t color;
770         hextorgb(p[i].dstring, color);
771         colors[i][0] = color[0];
772         colors[i][1] = color[1];
773         colors[i][2] = color[2];
774     }
775     mkcustompalette(uih->palette, colors);
776     uih_newimage(uih);
777     uih->palettepickerenabled = 1;
778 }
779 
uih_palettepicker(struct uih_context * uih,dialogparam * p)780 static void uih_palettepicker(struct uih_context *uih, dialogparam *p)
781 {
782     uih_newimage(uih);
783     uih->palettepickerenabled = 1;
784 }
785 
uih_loadgpl(struct uih_context * uih,xio_constpath d)786 static void uih_loadgpl(struct uih_context *uih, xio_constpath d)
787 {
788     QFile *loadfile = new QFile(d);
789     unsigned char colors[31][3];
790     memset(colors, 0, sizeof (colors));
791 
792     if (loadfile->open(QIODevice::ReadOnly | QIODevice::Text)) {
793         QTextStream in(loadfile);
794         QStringList colorvals= in.readAll().split("\n");
795         if((int)colorvals.size() != 36) {
796             uih_error(uih, "Corrupted palette File");
797             loadfile->close();
798             return;
799         }
800 
801         for(int i = 4; i < 35; i++) {
802             QStringList currcolors = colorvals[i].split(QRegExp("\\s+"));
803             int r = currcolors[0].toInt();
804             int g = currcolors[1].toInt();
805             int b = currcolors[2].toInt();
806 
807             if (r < 0 || r > 255 ||
808                 g < 0 || g > 255 ||
809                 b < 0 || b > 255) {
810                 uih_error(uih, "RGB out of range. Failed to load palette.");
811                 loadfile->close();
812                 return;
813             }
814 
815             colors[i-4][0] = r;
816             colors[i-4][1] = g;
817             colors[i-4][2] = b;
818         }
819         mkcustompalette(uih->palette, colors);
820         loadfile->close();
821         char s[256];
822         sprintf(s, TR("Message", "File %s opened."), d);
823         uih_message(uih, s);
824 
825     } else {
826         uih_error(uih, "Failed to open palette configuration");
827         return;
828     }
829 
830     uih_newimage(uih);
831     uih->palettepickerenabled = 1;
832 }
833 
uih_savegpl(struct uih_context * uih,xio_constpath d)834 static void uih_savegpl(struct uih_context *uih, xio_constpath d) {
835     QFile *savefile = new QFile(d);
836     unsigned char colors[31][3];
837 
838     if(savefile->open(QIODevice::WriteOnly | QIODevice::Text)) {
839             getDEFSEGMENTColor(colors);
840             QTextStream stream(savefile);
841             stream << "GIMP Palette" << "\n";
842             stream << "Name: XaoS_Palette" << "\n";
843             stream << "Columns: 16" << "\n" << "#" << "\n";
844             for(int i=0; i < 31; i++){
845                 char s[256];
846                 sprintf(s, "%3d %3d %3d", colors[i][0], colors[i][1], colors[i][2]);
847                 stream << s << "\t color_" << QString::number(i) << "\n";
848             }
849             savefile->close();
850             char s[256];
851             sprintf(s, TR("Message", "File %s saved."), d);
852             uih_message(uih, s);
853 
854         } else {
855         uih_error(uih, "Failed to save palette Configuration");
856     }
857     uih->palettepickerenabled = 1;
858 }
859 
uih_rotateselected(struct uih_context * c,int n)860 static int uih_rotateselected(struct uih_context *c, int n)
861 {
862     if (c == NULL)
863         return 0;
864     if (!c->fastrotate)
865         return !n;
866     return (c->rotatemode == n);
867 }
868 
uih_guessingselected(struct uih_context * c,int n)869 static int uih_guessingselected(struct uih_context *c, int n)
870 {
871     if (c == NULL)
872         return 0;
873     return (c->fcontext->range == n);
874 }
875 
uih_fastmode(struct uih_context * c,int n)876 static int uih_fastmode(struct uih_context *c, int n)
877 {
878     if (c == NULL)
879         return 0;
880     return (c->fastmode == n);
881 }
882 
uih_periodicityselected(struct uih_context * c)883 static int uih_periodicityselected(struct uih_context *c)
884 {
885     if (c == NULL)
886         return 0;
887     return (c->fcontext->periodicity);
888 }
889 
uih_periodicitysw(struct uih_context * c)890 static void uih_periodicitysw(struct uih_context *c)
891 {
892     uih_setperiodicity(c, c->fcontext->periodicity ^ 1);
893 }
894 
uih_cyclingselected(struct uih_context * c)895 static int uih_cyclingselected(struct uih_context *c)
896 {
897     if (c == NULL)
898         return 0;
899     return (c->cycling && c->cyclingdirection == 1);
900 }
901 
uih_rcyclingselected(struct uih_context * c)902 static int uih_rcyclingselected(struct uih_context *c)
903 {
904     if (c == NULL)
905         return 0;
906     return (c->cycling && c->cyclingdirection == -1);
907 }
908 
uih_cyclingsw(struct uih_context * c)909 static void uih_cyclingsw(struct uih_context *c)
910 {
911     // Andrew Stone: this fixes what I consider a bug - switching from Y to y
912     // should keep cycling:
913     if (c->cycling && c->cyclingdirection == -1)
914         uih_cycling_off(c);
915     c->cyclingdirection = 1;
916     if (c->cycling)
917         uih_cycling_off(c);
918     else if (!uih_cycling_on(c))
919         uih_error(c, TR("Error", "Initialization of color cycling failed.")),
920             uih_message(c,
921                         TR("Error", "Try to enable palette emulation filter"));
922 }
923 
uih_rcyclingsw(struct uih_context * c)924 static void uih_rcyclingsw(struct uih_context *c)
925 {
926     // Andrew Stone: this fixes what I consider a bug - switching from y to Y
927     // should keep cycling:
928     if (c->cycling && c->cyclingdirection == 1)
929         uih_cycling_off(c);
930     c->cyclingdirection = -1;
931     if (c->cycling)
932         uih_cycling_off(c);
933     else if (!uih_cycling_on(c))
934         uih_error(c, TR("Error", "Initialization of color cycling failed.")),
935             uih_message(c,
936                         TR("Error", "Try to enable palette emulation filter"));
937 }
938 
uih_juliasw(struct uih_context * c)939 static void uih_juliasw(struct uih_context *c)
940 {
941     if (!c->juliamode)
942         uih_enablejulia(c);
943     else
944         uih_disablejulia(c);
945 }
946 
uih_juliaselected(struct uih_context * c)947 static int uih_juliaselected(struct uih_context *c)
948 {
949     if (c == NULL)
950         return 0;
951     return (c->juliamode);
952 }
953 
uih_mandelbrotselected(struct uih_context * c)954 static int uih_mandelbrotselected(struct uih_context *c)
955 {
956     if (c == NULL)
957         return 0;
958     return (c->fcontext->mandelbrot);
959 }
960 
uih_mandelbrotsw(struct uih_context * c,number_t x,number_t y)961 static void uih_mandelbrotsw(struct uih_context *c, number_t x, number_t y)
962 {
963     c->fcontext->mandelbrot ^= 1;
964     if (c->fcontext->mandelbrot == 0 && !c->juliamode) {
965         c->fcontext->pre = x;
966         c->fcontext->pim = y;
967     } else
968         uih_disablejulia(c);
969     c->fcontext->version++;
970     uih_newimage(c);
971     uih_updatemenus(c, "uimandelbrot");
972 }
973 
uih_autopilotselected(struct uih_context * c)974 static int uih_autopilotselected(struct uih_context *c)
975 {
976     if (c == NULL)
977         return 0;
978     return (c->autopilot);
979 }
980 
uih_fixedstepselected(struct uih_context * c)981 static int uih_fixedstepselected(struct uih_context *c)
982 {
983     if (c == NULL)
984         return 0;
985     return (c->fixedstep);
986 }
987 
uih_persw(struct uih_context * c,number_t x,number_t y)988 static void uih_persw(struct uih_context *c, number_t x, number_t y)
989 {
990     if (c->fcontext->bre || c->fcontext->bim)
991         uih_setperbutation(c, 0.0, 0.0);
992     else
993         uih_setperbutation(c, x, y);
994     // printf(""); // fixme: some newer versions of gcc crashes without this
995 }
996 
uih_perselected(struct uih_context * c)997 static int uih_perselected(struct uih_context *c)
998 {
999     if (c == NULL)
1000         return 0;
1001     return (c->fcontext->bre || c->fcontext->bim);
1002 }
1003 
uih_autopilotsw(struct uih_context * c)1004 static void uih_autopilotsw(struct uih_context *c)
1005 {
1006     if (c->autopilot)
1007         uih_autopilot_off(c);
1008     else
1009         uih_autopilot_on(c);
1010 }
1011 
uih_fixedstepsw(struct uih_context * c)1012 static void uih_fixedstepsw(struct uih_context *c) { c->fixedstep ^= 1; }
1013 
uih_setxtextpos(uih_context * c,int p)1014 static void uih_setxtextpos(uih_context *c, int p)
1015 {
1016     uih_settextpos(c, p, c->ytextpos);
1017 }
1018 
uih_xtextselected(uih_context * c,int p)1019 static int uih_xtextselected(uih_context *c, int p)
1020 {
1021     if (c == NULL)
1022         return 0;
1023     return (c->xtextpos == p);
1024 }
1025 
uih_setytextpos(uih_context * c,int p)1026 static void uih_setytextpos(uih_context *c, int p)
1027 {
1028     uih_settextpos(c, c->xtextpos, p);
1029 }
1030 
uih_ytextselected(uih_context * c,int p)1031 static int uih_ytextselected(uih_context *c, int p)
1032 {
1033     if (c == NULL)
1034         return 0;
1035     return (c->ytextpos == p);
1036 }
1037 
uih_menumkpalette(uih_context * c)1038 static void uih_menumkpalette(uih_context *c)
1039 {
1040     char s[256];
1041     uih_mkpalette(c);
1042     sprintf(s, TR("Error", "Algorithm:%i seed:%i size:%i"), c->palettetype,
1043             c->paletteseed, c->zengine->fractalc->palette->size);
1044     uih_message(c, s);
1045 }
1046 
uih_shiftpalette(uih_context * c,int shift)1047 static void uih_shiftpalette(uih_context *c, int shift)
1048 {
1049     if (shiftpalette(c->zengine->fractalc->palette, shift)) {
1050         uih_newimage(c);
1051     }
1052     c->manualpaletteshift += shift;
1053 }
1054 
uih_fshift(uih_context * c)1055 static void uih_fshift(uih_context *c) { uih_shiftpalette(c, 1); }
1056 
uih_bshift(uih_context * c)1057 static void uih_bshift(uih_context *c) { uih_shiftpalette(c, -1); }
1058 
1059 static const menuitem *menuitems; /*XaoS menu specifications */
1060 /* This structure is now empty. All static definitions have been moved
1061    to uih_registermenus_i18n() which fills up its own static array. */
1062 
1063 /* Registering internationalized menus. See also include/xmenu.h
1064    for details. Note that MAX_MENUITEMS_I18N should be increased
1065    if more items will be added in future.
1066 
1067    On 2006-07-12 J.B. Langston wrote:
1068 
1069    The menu.c.diff file changes the MAX_MENUITEMS_I18N macro from
1070    200 to 250.  As of 3.2.1, the number of allocated menu items had
1071    been exceeded (there are 201 menu items now). This was causing
1072    the memory within the application to be clobbered, resulting
1073    in subtle bugs on the PowerPC platform (both X11 and OSX drivers).
1074    For example, rendering animations generated a segmentation fault.
1075    It's quite possible it could have been causing other subtle bugs
1076    elsewhere in the program. */
1077 
1078 #define MAX_MENUITEMS_I18N 250
1079 static menuitem menuitems_i18n[MAX_MENUITEMS_I18N];
1080 int uih_no_menuitems_i18n;
1081 
uih_registermenus_i18n(void)1082 void uih_registermenus_i18n(void)
1083 {
1084     // Special version (currently it's OK):
1085     int no_menuitems_i18n = 0;
1086     SUBMENU_I("", NULL, TR("Menu", "Root menu"), "root");
1087     SUBMENU_I("", NULL, TR("Menu", "Animation root menu"), "animroot");
1088     SUBMENU_I("", NULL, TR("Menu", "Replay only commands"), "plc");
1089 #define MP (MENUFLAG_NOMENU | MENUFLAG_NOOPTION)
1090     /* Commands suitable only for animation replay */
1091     SUBMENU_I("plc", NULL, TR("Menu", "Line drawing functions"), "linemenu");
1092     MENUDIALOG_I("linemenu", NULL, TR("Menu", "Line"), "line", MP, uih_line,
1093                  uih_linedialog);
1094     MENUDIALOG_I("linemenu", NULL, TR("Menu", "Morph line"), "morphline", MP,
1095                  uih_morphline, uih_linedialog);
1096     MENUDIALOG_I("linemenu", NULL, TR("Menu", "Morph last line"),
1097                  "morphlastline", MP, uih_morphlastline, uih_linedialog);
1098     MENUDIALOG_I("linemenu", NULL, TR("Menu", "Set line key"), "linekey", MP,
1099                  uih_setkey, uih_numdialog);
1100     MENUNOP_I("linemenu", NULL, TR("Menu", "Clear line"), "clearline", MP,
1101               uih_clear_line);
1102     MENUNOP_I("linemenu", NULL, TR("Menu", "Clear all lines"), "clearlines", MP,
1103               uih_clear_lines);
1104     SUBMENU_I("plc", NULL, TR("Menu", "Animation functions"), "animf");
1105     MENUDIALOG_I("animf", NULL, TR("Menu", "View"), "animateview", MP,
1106                  uih_plview2, uih_plviewdialog);
1107     MENUDIALOG_I("animf", NULL, TR("Menu", "Morph view"), "morphview", MP,
1108                  uih_playmorph, uih_plviewdialog);
1109     MENUDIALOG_I("animf", NULL, TR("Menu", "Morph julia"), "morphjulia", MP,
1110                  uih_playmorphjulia, uih_coorddialog);
1111     MENUDIALOG_I("animf", NULL, TR("Menu", "Move view"), "moveview", MP,
1112                  uih_playmove, uih_coorddialog);
1113     MENUDIALOG_I("animf", NULL, TR("Menu", "Morph angle"), "morphangle", MP,
1114                  uih_playmorphangle, uih_angledialog);
1115     MENUDIALOG_I("animf", NULL, TR("Menu", "Zoom center"), "zoomcenter", MP,
1116                  uih_zoomcenter, uih_coorddialog);
1117     MENUNOP_I("animf", NULL, TR("Menu", "Zoom"), "zoom", MP, uih_playzoom);
1118     MENUNOP_I("animf", NULL, TR("Menu", "Un-zoom"), "unzoom", MP,
1119               uih_playunzoom);
1120     MENUNOP_I("animf", NULL, TR("Menu", "Stop zooming"), "stop", MP,
1121               uih_playstop);
1122     MENUDIALOG_I("animf", NULL, TR("Menu", "Smooth morphing parameters"),
1123                  "smoothmorph", MP, uih_smoothmorph, uih_smoothmorphdialog);
1124     SUBMENU_I("plc", NULL, TR("Menu", "Timing functions"), "time");
1125     MENUDIALOG_I("time", NULL, TR("Menu", "Usleep"), "usleep", MP,
1126                  uih_playusleep, uih_timedialog);
1127     MENUNOP_I("time", NULL, TR("Menu", "Wait for text"), "textsleep", MP,
1128               uih_playtextsleep);
1129     MENUNOP_I("time", NULL, TR("Menu", "Wait for complete image"), "wait", MP,
1130               uih_playwait);
1131     MENUDIALOG_I("plc", NULL, TR("Menu", "Include file"), "load", MP,
1132                  uih_playload, loaddialog);
1133     MENUDIALOG_I("palette", NULL, TR("Menu", "Default palette"),
1134                  "defaultpalette", MP, uih_playdefpalette, uih_numdialog);
1135     MENUDIALOG_I("fractal", NULL, TR("Menu", "Formula"), "formula", MP,
1136                  uih_play_formula, uih_formuladialog);
1137     MENUDIALOG_I("ui", NULL, TR("Menu", "Maximal zooming step"), "maxstep", MP,
1138                  uih_setmaxstep, uih_fpdialog);
1139     MENUDIALOG_I("ui", NULL, TR("Menu", "Zooming speedup"), "speedup", MP,
1140                  uih_setspeedup, uih_fpdialog);
1141     MENUDIALOG_I("mfilter", NULL, TR("Menu", "Filter"), "filter", MP,
1142                  uih_playfilter, uih_filterdialog);
1143 #undef MP
1144 #define UI (MENUFLAG_NOPLAY | MENUFLAG_NOOPTION)
1145     MENUCDIALOG_I("ui", NULL, TR("Menu", "Letters per second"), "letterspersec",
1146                   MENUFLAG_NOMENU, uih_letterspersec, uih_getlettersdialog);
1147     MENUCDIALOG_I("uia", NULL, TR("Menu", "Letters per second"), "letters", UI,
1148                   uih_letterspersec, uih_getlettersdialog);
1149     MENUNOP_I("uia", "z", TR("Menu", "Interrupt"), "animinterrupt",
1150               MENUFLAG_INTERRUPT | MENUFLAG_INCALC, uih_interrupt);
1151     MENUSEPARATOR_I("ui");
1152     MENUNOPCB_I("ui", "/", TR("Menu", "Status"), "status", MENUFLAG_INCALC,
1153                 uih_status, uih_statusenabled); /*FIXME: add also ? as key */
1154 
1155     MENUNOPCB_I("ui", "l", TR("Menu", "Ministatus"), "ministatus",
1156                 MENUFLAG_INCALC, uih_ministatus, uih_ministatusenabled);
1157     MENUNOPCB_I("ui", "g", TR("Menu", "Cartesian Grid"), "cartesiangrid",
1158                 MENUFLAG_INCALC, uih_cartesiangrid, uih_cartesiangridenabled);
1159     MENUSEPARATOR_I("ui");
1160     MENUSEPARATOR_I("uia");
1161     MENUNOPCB_I("uia", "/", TR("Menu", "Status"), "animstatus",
1162                 UI | MENUFLAG_INCALC, uih_status,
1163                 uih_statusenabled); /*FIXME: add also ? as key */
1164 
1165     MENUNOPCB_I("uia", "l", TR("Menu", "Ministatus"), "animministatus",
1166                 UI | MENUFLAG_INCALC, uih_ministatus, uih_ministatusenabled);
1167     MENUNOPCB_I("uia", "g", TR("Menu", "Cartesian Grid"), "animcartesiangrid",
1168                 MENUFLAG_INCALC, uih_cartesiangrid, uih_cartesiangridenabled);
1169     MENUSEPARATOR_I("uia");
1170     SUBMENU_I("root", "s", TR("Menu", "File"), "file");
1171     SUBMENU_I("root", NULL, TR("Menu", "Edit"), "edit");
1172     SUBMENU_I("root", NULL, TR("Menu", "Fractal"), "fractal");
1173     SUBMENU_I("root", NULL, TR("Menu", "Calculation"), "calc");
1174     SUBMENU_I("root", "e", TR("Menu", "Filters"), "mfilter");
1175     SUBMENU_I("root", NULL, TR("Menu", "Action"), "action");
1176     SUBMENU_I("root", NULL, TR("Menu", "View"), "ui");
1177     SUBMENU_I("root", NULL, TR("Menu", "Help"), "helpmenu");
1178     SUBMENU_I("helpmenu", NULL, TR("Menu", "Tutorials"), "tutor");
1179     SUBMENUNOOPT_I("animroot", "f", TR("Menu", "File"), "file");
1180     // You cannot have menu items directly on the root menu in some OS
1181     // So we put the "Stop Replay" item in the UI menu instead
1182     MENUSEPARATOR_I("uia");
1183     MENUNOP_I("uia", "s", TR("Menu", "Stop replay"), "stopreplay",
1184               UI | MENUFLAG_INTERRUPT, uih_replaydisable);
1185     SUBMENUNOOPT_I("animroot", NULL, TR("Menu", "View"), "uia");
1186     SUBMENUNOOPT_I("animroot", NULL, TR("Menu", "Help"), "helpmenu");
1187     MENUDIALOG_I("action", "!", TR("Menu", "Command"), "command", UI,
1188                  uih_command, dcommand);
1189     MENUDIALOG_I("action", NULL, TR("Menu", "Play string"), "playstr",
1190                  MENUFLAG_NOMENU, uih_playstr, dcommand);
1191     MENUSEPARATOR_I("action");
1192     MENUNOP_I("action", NULL, TR("Menu", "Clear screen"), "clearscreen",
1193               MENUFLAG_NOOPTION, uih_clearscreen);
1194     MENUNOP_I("action", NULL, TR("Menu", "Display fractal"), "display",
1195               MENUFLAG_NOOPTION, uih_display);
1196     MENUSEPARATOR_I("action");
1197     MENUDIALOG_I("action", NULL, TR("Menu", "Display text"), "text", 0,
1198                  uih_text, dtextparam); /*FIXME: Should allow multiline */
1199 
1200     MENUCDIALOG_I("action", NULL, TR("Menu", "Text color"), "color", 0,
1201                   uih_setcolor, uih_getcolordialog);
1202     SUBMENU_I("action", NULL, TR("Menu", "Horizontal text position"),
1203               "xtextpos");
1204     SUBMENU_I("action", NULL, TR("Menu", "Vertical text position"), "ytextpos");
1205     MENUDIALOG_I("action", NULL, TR("Menu", "Text position"), "textposition",
1206                  MENUFLAG_NOMENU | MENUFLAG_INCALC, uih_playtextpos,
1207                  uih_textposdialog);
1208     MENUDIALOG_I("action", NULL, TR("Menu", "Message"), "message",
1209                  MENUFLAG_NOMENU, uih_playmessage, dtextparam);
1210     /* The following 6 menu options should not be translated. The example
1211        files heavily use these constants and lots of examples will not work
1212        anymore... :-(  Anyway, this should be fixed somehow. */
1213 
1214     MENUINTRB_I("ytextpos", NULL, "Up", "ytextup", UI, uih_setytextpos,
1215                 UIH_TEXTTOP, uih_ytextselected);
1216     MENUINTRB_I("ytextpos", NULL, "Middle", "ytextmiddle", UI, uih_setytextpos,
1217                 UIH_TEXTMIDDLE, uih_ytextselected);
1218     MENUINTRB_I("ytextpos", NULL, "Bottom", "ytextbottom", UI, uih_setytextpos,
1219                 UIH_TEXTBOTTOM, uih_ytextselected);
1220     MENUINTRB_I("xtextpos", NULL, "Left", "xtextleft", UI, uih_setxtextpos,
1221                 UIH_TEXTLEFT, uih_xtextselected);
1222     MENUINTRB_I("xtextpos", NULL, "Center", "xtextcenter", UI, uih_setxtextpos,
1223                 UIH_TEXTCENTER, uih_xtextselected);
1224     MENUINTRB_I("xtextpos", NULL, "Right", "xtexteight", UI, uih_setxtextpos,
1225                 UIH_TEXTRIGHT, uih_xtextselected);
1226     MENUNOP_I("file", NULL, TR("Menu", "New"), "initstate", 0, uih_initstate);
1227     MENUDIALOG_I("file", NULL, TR("Menu", "Open"), "loadpos",
1228                  MENUFLAG_INTERRUPT | MENUFLAG_NOPLAY, uih_loadfile,
1229                  loaddialog);
1230     MENUDIALOG_I("file", NULL, TR("Menu", "Save"), "savepos", 0,
1231                  uih_saveposfile, saveposdialog);
1232     SUBMENU_I("file", NULL, TR("Menu", "Save as"), "saveas");
1233     MENUDIALOG_I("saveas", NULL, TR("Menu", "PNG"), "saveimg", 0,
1234                  uih_savepngfile, saveimgdialog);
1235     MENUSEPARATOR_I("file")
1236     MENUDIALOGCB_I("file", NULL, TR("Menu", "Record"), "record", 0,
1237                    uih_saveanimfile, saveanimdialog, uih_saveanimenabled);
1238     MENUDIALOG_I("file", NULL, TR("Menu", "Replay"), "play",
1239                  MENUFLAG_INTERRUPT | MENUFLAG_NOPLAY, uih_playfile,
1240                  playdialog);
1241     MENUSEPARATOR_I("file");
1242     MENUDIALOG_I("file", NULL, TR("Menu", "Render"), "renderanim", UI,
1243                  uih_render, uih_renderdialog);
1244     MENUDIALOG_I("file", NULL, TR("Menu", "Render Image"), "renderimg", UI,
1245                  uih_renderimg, uih_renderimgdialog);
1246     MENUSEPARATOR_I("file");
1247     MENUNOP_I("file", NULL, TR("Menu", "Load random example"), "loadexample",
1248               MENUFLAG_INTERRUPT, uih_loadexample);
1249     MENUNOP_I("file", NULL, TR("Menu", "Save configuration"), "savecfg", 0,
1250               uih_savecfg);
1251     MENUSEPARATOR_I("file");
1252     MENUNOP_I("edit", "u", TR("Menu", "Undo"), "undo",
1253               MENUFLAG_INTERRUPT | MENUFLAG_NOPLAY | MENUFLAG_NOOPTION,
1254               uih_undo);
1255     MENUNOP_I("edit", NULL, TR("Menu", "Redo"), "redo",
1256               MENUFLAG_INTERRUPT | MENUFLAG_NOPLAY | MENUFLAG_NOOPTION,
1257               uih_redo);
1258     SUBMENU_I("fractal", NULL, TR("Menu", "Formulae"), "mformula");
1259     SUBMENU_I("fractal", NULL, TR("Menu", "More formulae"), "oformula");
1260 
1261 #ifdef USE_SFFE
1262     /*FIXME: Should allow multiline */
1263     MENUSEPARATOR_I("fractal");
1264     MENUCDIALOG_I("fractal", NULL, TR("Menu", "User formula"), "usrform", 0,
1265                   uih_sffein, uih_getsffedialog);
1266     MENUCDIALOG_I("fractal", NULL, TR("Menu", "User initialization"),
1267                   "usrformInit", 0, uih_sffeinitin, uih_getsffeinitdialog);
1268 #endif
1269 
1270     MENUSEPARATOR_I("fractal");
1271     SUBMENU_I("fractal", "f", TR("Menu", "Incoloring mode"), "mincoloring");
1272     SUBMENU_I("fractal", "c", TR("Menu", "Outcoloring mode"), "moutcoloring");
1273     SUBMENU_I("fractal", "i", TR("Menu", "Plane"), "mplane");
1274     SUBMENU_I("fractal", NULL, TR("Menu", "Palette"), "palettemenu");
1275     MENUSEPARATOR_I("fractal");
1276     MENUCDIALOGCB_I(
1277         "fractal", "m", TR("Menu", "Mandelbrot mode"), "uimandelbrot",
1278         MENUFLAG_DIALOGATDISABLE | MENUFLAG_INTERRUPT | UI, uih_mandelbrotsw,
1279         uih_getjuliadialog, uih_mandelbrotselected);
1280     MENUDIALOG_I("fractal", NULL, TR("Menu", "Julia mode"), "julia",
1281                  MENUFLAG_NOMENU | MENUFLAG_INTERRUPT, uih_playjulia,
1282                  uih_juliamodedialog);
1283     MENUNOPCB_I("fractal", "j", TR("Menu", "Fast julia mode"), "fastjulia", 0,
1284                 uih_juliasw, uih_juliaselected);
1285     MENUSEPARATOR_I("fractal");
1286     MENUCDIALOG_I("fractal", NULL, TR("Menu", "View"), "uiview",
1287                   MENUFLAG_INTERRUPT | UI, uih_dview, uih_getviewdialog);
1288     MENUDIALOG_I("fractal", NULL, TR("Menu", "View"), "view",
1289                  MENUFLAG_NOMENU | MENUFLAG_INTERRUPT, uih_plview,
1290                  uih_plviewdialog);
1291     SUBMENU_I("fractal", "o", TR("Menu", "Rotation"), "rotate");
1292     MENUDIALOG_I("fractal", NULL, TR("Menu", "Set angle"), "angle",
1293                  MENUFLAG_NOMENU | MENUFLAG_INTERRUPT, uih_angle,
1294                  uih_angledialog);
1295     MENUDIALOG_I("fractal", NULL, TR("Menu", "Set plane"), "plane",
1296                  MENUFLAG_NOMENU | MENUFLAG_INTERRUPT, uih_setplane,
1297                  uih_numdialog);
1298     MENUDIALOG_I("fractal", NULL, TR("Menu", "Inside coloring mode"),
1299                  "incoloring", MENUFLAG_NOMENU | MENUFLAG_INTERRUPT,
1300                  uih_setincoloringmode, uih_numdialog);
1301     MENUDIALOG_I("fractal", NULL, TR("Menu", "Outside coloring mode"),
1302                  "outcoloring", MENUFLAG_NOMENU | MENUFLAG_INTERRUPT,
1303                  uih_setoutcoloringmode, uih_numdialog);
1304     MENUDIALOG_I("fractal", NULL, TR("Menu", "Inside truecolor coloring mode"),
1305                  "intcoloring", MENUFLAG_NOMENU | MENUFLAG_INTERRUPT,
1306                  uih_setintcolor, uih_numdialog);
1307     MENUDIALOG_I("fractal", NULL, TR("Menu", "Outside truecolor coloring mode"),
1308                  "outtcoloring", MENUFLAG_NOMENU | MENUFLAG_INTERRUPT,
1309                  uih_setouttcolor, uih_numdialog);
1310     MENUDIALOG_I("fractal", NULL, TR("Menu", "Julia seed"), "juliaseed",
1311                  MENUFLAG_NOMENU | MENUFLAG_INTERRUPT, uih_setjuliaseed,
1312                  uih_coorddialog);
1313     MENUNOP_I("palettemenu", "d", TR("Menu", "Default palette"), "defpalette",
1314               0, uih_mkdefaultpalette);
1315     MENUNOP_I("palettemenu", "p", TR("Menu", "Random palette"), "randompalette",
1316               0, uih_menumkpalette);
1317     MENUCDIALOG_I("", NULL, TR("Menu", "Custom palette"), "palette",
1318                   0, uih_palette, uih_getpalettedialog); //This is a placeholder menu
1319     MENUCDIALOG_I("palettemenu", NULL, TR("Menu", "Custom palette"), "palettegradient",
1320                   0, uih_palettegradient, uih_getpalettegradientdialog);
1321     MENUSEPARATOR_I("palettemenu");
1322     MENUDIALOG_I("fractal", NULL, TR("Menu", "Palette Colors"), "palettecolors",
1323                  MENUFLAG_NOMENU | MENUFLAG_INTERRUPT, uih_palettecolors,
1324                  uih_palettecolorsdialog);
1325     MENUCDIALOG_I("palettemenu", "x", TR("Menu", "Palette Editor"), "palettepicker",
1326                   0, uih_palettepicker, uih_palettepickerdialog);
1327     MENUDIALOG_I("palettemenu", NULL, TR("Menu", "Load Palette Config"), "loadgpl",
1328                  0, uih_loadgpl, loadgpldialog);
1329     MENUDIALOG_I("palettemenu", NULL, TR("Menu", "Save Palette Config"), "savegpl",
1330                  0, uih_savegpl, savegpldialog);
1331     MENUSEPARATOR_I("palettemenu");
1332     MENUNOPCB_I("palettemenu", "y", TR("Menu", "Color cycling"), "cycling", 0,
1333                 uih_cyclingsw, uih_cyclingselected);
1334     MENUNOPCB_I("palettemenu", "Y", TR("Menu", "Reversed color cycling"),
1335                 "rcycling", MENUFLAG_NOOPTION | MENUFLAG_NOPLAY, uih_rcyclingsw,
1336                 uih_rcyclingselected);
1337     MENUCDIALOG_I("palettemenu", NULL, TR("Menu", "Color cycling speed"),
1338                   "cyclingspeed", 0, uih_setcycling, uih_getcyclingdialog);
1339     MENUSEPARATOR_I("palettemenu");
1340     MENUDIALOG_I("palettemenu", NULL, TR("Menu", "Shift palette"),
1341                  "shiftpalette", 0, uih_shiftpalette, uih_shiftdialog);
1342     MENUNOP_I("palettemenu", "+", TR("Menu", "Shift one forward"), "fshift",
1343               MENUFLAG_NOOPTION | MENUFLAG_NOPLAY, uih_fshift);
1344     MENUNOP_I("palettemenu", "-", TR("Menu", "Shift one backward"), "bshift",
1345               MENUFLAG_NOOPTION | MENUFLAG_NOPLAY, uih_bshift);
1346     SUBMENU_I("calc", NULL, TR("Menu", "Solid guessing"), "mguess");
1347     MENUINTRB_I("mguess", NULL, TR("Menu", "Disable solid guessing"), "noguess",
1348                 UI, uih_setguessing, 1, uih_guessingselected);
1349     MENUSEPARATOR_I("mguess");
1350     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess 2x2 rectangles"), "guess2",
1351                 UI, uih_setguessing, 2, uih_guessingselected);
1352     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess 3x3 rectangles"), "guess3",
1353                 UI, uih_setguessing, 3, uih_guessingselected);
1354     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess 4x4 rectangles"), "guess4",
1355                 UI, uih_setguessing, 4, uih_guessingselected);
1356     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess 5x5 rectangles"), "guess5",
1357                 UI, uih_setguessing, 5, uih_guessingselected);
1358     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess 6x6 rectangles"), "guess6",
1359                 UI, uih_setguessing, 6, uih_guessingselected);
1360     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess 7x7 rectangles"), "guess7",
1361                 UI, uih_setguessing, 7, uih_guessingselected);
1362     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess 8x8 rectangles"), "guess8",
1363                 UI, uih_setguessing, 8, uih_guessingselected);
1364     MENUINTRB_I("mguess", NULL, TR("Menu", "Guess unlimited rectangles"),
1365                 "guessall", UI, uih_setguessing, 2048, uih_guessingselected);
1366     SUBMENU_I("calc", NULL, TR("Menu", "Dynamic resolution"), "dynamic");
1367     MENUNOPCB_I("calc", "k", TR("Menu", "Periodicity checking"), "periodicity",
1368                 0, uih_periodicitysw, uih_periodicityselected);
1369     MENUSEPARATOR_I("calc");
1370     MENUCDIALOG_I("calc", NULL, TR("Menu", "Threads"), "threads",
1371                   MENUFLAG_INTERRUPT, uih_setthreads, uih_getthreaddialog);
1372     MENUCDIALOG_I("calc", NULL, TR("Menu", "Iterations"), "maxiter",
1373                   MENUFLAG_INTERRUPT, uih_setmaxiter, uih_getiterdialog);
1374     MENUCDIALOG_I("calc", NULL, TR("Menu", "Bailout"), "bailout",
1375                   MENUFLAG_INTERRUPT, uih_setbailout, uih_getbailoutdialog);
1376     MENUCDIALOGCB_I("calc", "b", TR("Menu", "Perturbation"), "uiperturbation",
1377                     MENUFLAG_INTERRUPT | UI, uih_persw,
1378                     uih_getperturbationdialog, uih_perselected);
1379     MENUCDIALOG_I("calc", NULL, TR("Menu", "Perturbation"), "perturbation",
1380                   MENUFLAG_NOMENU | MENUFLAG_INTERRUPT, uih_setperbutation,
1381                   uih_getperturbationdialog);
1382     MENUSEPARATOR_I("calc");
1383     MENUCDIALOG_I("calc", NULL, TR("Menu", "Zooming speed"), "speed", 0,
1384                   uih_setspeed, uih_getspeeddialog);
1385     MENUNOPCB_I("calc", NULL, TR("Menu", "Fixed step"), "fixedstep", 0,
1386                 uih_fixedstepsw, uih_fixedstepselected);
1387     MENUSEPARATOR_I("calc");
1388     MENUDIALOG_I("calc", NULL, TR("Menu", "Solid guessing range"), "range",
1389                  MENUFLAG_NOMENU, uih_setguessing, uih_numdialog);
1390     MENUINTRB_I("rotate", NULL, TR("Menu", "Disable rotation"), "norotate", UI,
1391                 uih_rotate, 0, uih_rotateselected);
1392     MENUSEPARATOR_I("rotate");
1393     MENUINTRB_I("rotate", NULL, TR("Menu", "Continuous rotation"), "controtate",
1394                 UI, uih_rotate, ROTATE_CONTINUOUS, uih_rotateselected);
1395     MENUINTRB_I("rotate", NULL, TR("Menu", "Rotate by mouse"), "mouserotate",
1396                 UI, uih_rotate, ROTATE_MOUSE, uih_rotateselected);
1397     MENUCDIALOG_I("rotate", NULL, TR("Menu", "Rotation speed"), "rotationspeed",
1398                   0, uih_rotationspeed, uih_getrotationdialog);
1399     MENUDIALOG_I("rotate", NULL, TR("Menu", "Automatic rotation"), "autorotate",
1400                  MENUFLAG_NOMENU, uih_playautorotate, uih_autorotatedialog);
1401     MENUDIALOG_I("rotate", NULL, TR("Menu", "Fast rotation mode"), "fastrotate",
1402                  MENUFLAG_NOMENU, (funcptr)uih_fastrotate,
1403                  uih_fastrotatedialog);
1404     MENUSEPARATOR_I("calc");
1405     MENUNOP_I("calc", "r", TR("Menu", "Recalculate"), "recalculate", 0,
1406               uih_recalculate);
1407     MENUNOP_I("calc", "z", TR("Menu", "Interrupt"), "interrupt",
1408               MENUFLAG_INTERRUPT | MENUFLAG_INCALC, uih_interrupt);
1409     MENUINTRB_I("dynamic", NULL, TR("Menu", "Disable dynamic resolution"),
1410                 "nodynamic", UI, uih_setfastmode, 1, uih_fastmode);
1411     MENUSEPARATOR_I("dynamic");
1412     MENUINTRB_I("dynamic", NULL, TR("Menu", "Use only during animation"),
1413                 "dynamicanimation", UI, uih_setfastmode, 2, uih_fastmode);
1414     MENUINTRB_I("dynamic", NULL, TR("Menu", "Use also for new images"),
1415                 "dynamicnew", UI, uih_setfastmode, 3, uih_fastmode);
1416     MENUDIALOG_I("dynamic", NULL, TR("Menu", "Dynamic resolution mode"),
1417                  "fastmode", MENUFLAG_NOMENU, uih_setfastmode,
1418                  uih_fastmodedialog);
1419     MENUNOPCB_I("ui", "a", TR("Menu", "Autopilot"), "autopilot", 0,
1420                 uih_autopilotsw, uih_autopilotselected);
1421     MENUSEPARATOR_I("ui");
1422     MENUNOPCB_I("ui", "v", TR("Menu", "Hide Messages"), "inhibittextoutput", 0,
1423                 uih_inhibittextsw, uih_inhibittextselected);
1424     /* Language selection is not sensible anymore if i18n is used: */
1425     SUBMENU_I("tutor", NULL, TR("Menu", "An introduction to fractals"),
1426               "intro");
1427     SUBMENU_I("tutor", NULL, TR("Menu", "XaoS features overview"), "features");
1428     SUBMENU_I("tutor", NULL, TR("Menu", "Math behind fractals"), "fmath");
1429     SUBMENU_I("tutor", NULL, TR("Menu", "Other fractal types in XaoS"),
1430               "otherf");
1431     SUBMENU_I("tutor", NULL, TR("Menu", "What's new?"), "new");
1432     /* Language selection is not sensible anymore if i18n is used: */
1433     TUTOR_I("intro", TR("Menu", "Whole story"), "fractal.xaf");
1434     MENUSEPARATOR_I("intro");
1435     TUTOR_I("intro", TR("Menu", "Introduction"), "intro.xaf");
1436     TUTOR_I("intro", TR("Menu", "Mandelbrot set"), "mset.xaf");
1437     TUTOR_I("intro", TR("Menu", "Julia set"), "julia.xaf");
1438     TUTOR_I("intro", TR("Menu", "Higher power Mandelbrots"), "power.xaf");
1439     TUTOR_I("intro", TR("Menu", "Newton's method"), "newton.xaf");
1440     TUTOR_I("intro", TR("Menu", "Barnsley's formula"), "barnsley.xaf");
1441     TUTOR_I("intro", TR("Menu", "Phoenix"), "phoenix.xaf");
1442     TUTOR_I("intro", TR("Menu", "Octo"), "octo.xaf");
1443     TUTOR_I("intro", TR("Menu", "Magnet"), "magnet.xaf");
1444     TUTOR_I("features", TR("Menu", "All features"), "features.xaf");
1445     MENUSEPARATOR_I("features");
1446     TUTOR_I("features", TR("Menu", "Outcoloring modes"), "outcolor.xaf");
1447     TUTOR_I("features", TR("Menu", "Incoloring modes"), "incolor.xaf");
1448     TUTOR_I("features", TR("Menu", "True-color coloring modes"), "truecol.xaf");
1449     TUTOR_I("features", TR("Menu", "Filters"), "filter.xaf");
1450     TUTOR_I("features", TR("Menu", "Planes"), "plane.xaf");
1451     TUTOR_I("features", TR("Menu", "Animations and position files"),
1452             "anim.xaf");
1453     TUTOR_I("features", TR("Menu", "Perturbation"), "pert.xaf");
1454     TUTOR_I("features", TR("Menu", "Random palettes"), "palette.xaf");
1455     TUTOR_I("features", TR("Menu", "Other noteworthy features"), "other.xaf");
1456     TUTOR_I("fmath", TR("Menu", "Whole story"), "fmath.xaf");
1457     MENUSEPARATOR_I("fmath");
1458     TUTOR_I("fmath", TR("Menu", "The definition and fractal dimension"),
1459             "dimension.xaf");
1460     TUTOR_I("fmath", TR("Menu", "Escape time fractals"), "escape.xaf");
1461     TUTOR_I("otherf", TR("Menu", "Other fractal types in XaoS"), "otherfr.xaf");
1462     MENUSEPARATOR_I("otherf");
1463     TUTOR_I("otherf", TR("Menu", "Triceratops and Catseye fractals"),
1464             "trice.xaf");
1465     TUTOR_I("otherf", TR("Menu", "Mandelbar, Lambda, Manowar and Spider"),
1466             "fourfr.xaf");
1467     TUTOR_I("otherf", TR("Menu", "Sierpinski Gasket, S.Carpet, Koch Snowflake"),
1468             "classic.xaf");
1469     TUTOR_I("new", TR("Menu", "What's new in 3.0?"), "new30.xaf");
1470     TUTOR_I("new", TR("Menu", "What's new in 4.0?"), "new40.xaf");
1471     if (no_menuitems_i18n > MAX_MENUITEMS_I18N) {
1472         fprintf(stderr, "MAX_MENUITEMS_I18N is set to an insufficiently low number, please increase it to %d\n", no_menuitems_i18n);
1473         fflush(stderr);
1474         exit(1);
1475     }
1476 #ifdef DEBUG
1477     printf("Filled %d menu items out of %d.\n", no_menuitems_i18n,
1478            MAX_MENUITEMS_I18N);
1479 #endif
1480     menu_add(menuitems_i18n, no_menuitems_i18n);
1481     uih_no_menuitems_i18n = no_menuitems_i18n;
1482 }
1483 
1484 static const menuitem menuitems2[] = {
1485     SUBMENU("mincoloring", NULL, "True-color incoloring mode", "tincoloring"),
1486     SUBMENU("moutcoloring", NULL, "True-color outcoloring mode",
1487             "toutcoloring")};
1488 
uih_selectedformula(struct uih_context * c,int n)1489 static int uih_selectedformula(struct uih_context *c, int n)
1490 {
1491     if (c == NULL)
1492         return 0;
1493     return (c->fcontext->currentformula == formulas + n);
1494 }
1495 
uih_selectedincoloring(struct uih_context * c,int n)1496 static int uih_selectedincoloring(struct uih_context *c, int n)
1497 {
1498     if (c == NULL)
1499         return 0;
1500     return (c->fcontext->incoloringmode == n);
1501 }
1502 
uih_setintruecolor(struct uih_context * c,int n)1503 static void uih_setintruecolor(struct uih_context *c, int n)
1504 {
1505     uih_setincoloringmode(c, 10);
1506     uih_setintcolor(c, n);
1507 }
1508 
uih_selectedintcoloring(struct uih_context * c,int n)1509 static int uih_selectedintcoloring(struct uih_context *c, int n)
1510 {
1511     if (c == NULL)
1512         return 0;
1513     return (c->fcontext->intcolor == n);
1514 }
1515 
uih_selectedoutcoloring(struct uih_context * c,int n)1516 static int uih_selectedoutcoloring(struct uih_context *c, int n)
1517 {
1518     if (c == NULL)
1519         return 0;
1520     return (c->fcontext->coloringmode == n);
1521 }
1522 
uih_selectedplane(struct uih_context * c,int n)1523 static int uih_selectedplane(struct uih_context *c, int n)
1524 {
1525     if (c == NULL)
1526         return 0;
1527     return (c->fcontext->plane == n);
1528 }
1529 
uih_setouttruecolor(struct uih_context * c,int n)1530 static void uih_setouttruecolor(struct uih_context *c, int n)
1531 {
1532     uih_setoutcoloringmode(c, 10);
1533     uih_setouttcolor(c, n);
1534 }
1535 
uih_selectedouttcoloring(struct uih_context * c,int n)1536 static int uih_selectedouttcoloring(struct uih_context *c, int n)
1537 {
1538     if (c == NULL)
1539         return 0;
1540     return (c->fcontext->outtcolor == n);
1541 }
1542 
uih_filterenabled(struct uih_context * c,int n)1543 static int uih_filterenabled(struct uih_context *c, int n)
1544 {
1545     if (c == NULL)
1546         return 0;
1547     return (c->filter[n] != NULL);
1548 }
1549 
uih_filtersw(struct uih_context * c,int n)1550 static void uih_filtersw(struct uih_context *c, int n)
1551 {
1552     if (c->filter[n] != NULL)
1553         uih_disablefilter(c, n);
1554     else
1555         uih_enablefilter(c, n);
1556 }
1557 
1558 static menuitem *formulaitems;
1559 static menuitem *filteritems;
uih_registermenus(void)1560 void uih_registermenus(void)
1561 {
1562     char keys[2];
1563     menuitem *item;
1564     int i;
1565     menu_add(menuitems, NITEMS(menuitems));
1566     formulaitems = item = (menuitem *)malloc(sizeof(menuitem) * nformulas);
1567 
1568     /* This code automatically generates code for fractal, incoloring and other
1569      * menus*/
1570     for (i = 0; i < nformulas; i++) {
1571         if (i < nmformulas) {
1572             item[i].menuname = "mformula";
1573         } else {
1574             item[i].menuname = "oformula";
1575         }
1576         if (i < 9)
1577             keys[0] = '1' + i;
1578         else if (i == 9)
1579             keys[0] = '0';
1580         else
1581             keys[0] = '7' + i;
1582         keys[1] = 0;
1583         item[i].key = strdup(keys);
1584         item[i].type = MENU_INT;
1585         item[i].flags = MENUFLAG_RADIO | MENUFLAG_INTERRUPT | MENUFLAG_NOPLAY;
1586         item[i].iparam = i;
1587         item[i].name = formulas[i].name[!formulas[i].mandelbrot];
1588         item[i].shortname = formulas[i].shortname;
1589         item[i].function = (void (*)(void))uih_setformula;
1590         item[i].control = (int (*)(void))uih_selectedformula;
1591     }
1592     menu_add(item, nformulas);
1593 
1594     menu_genernumbered(INCOLORING - 1, "mincoloring", incolorname, NULL,
1595                        MENU_INT, UI | MENUFLAG_RADIO | MENUFLAG_INTERRUPT,
1596                        uih_setincoloringmode, uih_selectedincoloring, "in");
1597 
1598     menu_genernumbered(TCOLOR - 1, "tincoloring", tcolorname, NULL, MENU_INT,
1599                        UI | MENUFLAG_RADIO | MENUFLAG_INTERRUPT,
1600                        uih_setintruecolor, uih_selectedintcoloring, "int");
1601 
1602     menu_genernumbered(OUTCOLORING - 1, "moutcoloring", outcolorname, NULL,
1603                        MENU_INT, UI | MENUFLAG_RADIO | MENUFLAG_INTERRUPT,
1604                        uih_setoutcoloringmode, uih_selectedoutcoloring, "out");
1605 
1606     menu_genernumbered(TCOLOR - 1, "toutcoloring", tcolorname, NULL, MENU_INT,
1607                        UI | MENUFLAG_RADIO | MENUFLAG_INTERRUPT,
1608                        uih_setouttruecolor, uih_selectedouttcoloring, "outt");
1609 
1610     {
1611         int i;
1612         for (i = 0; planename[i] != NULL; i++)
1613             ;
1614         menu_genernumbered(i, "mplane", planename, NULL, MENU_INT,
1615                            UI | MENUFLAG_RADIO | MENUFLAG_INTERRUPT,
1616                            uih_setplane, uih_selectedplane, "plane");
1617     }
1618     filteritems = item = (menuitem *)malloc(sizeof(menuitem) * uih_nfilters);
1619 
1620     /* This code automatically generates code for fractal, incoloring and other
1621      * menus*/
1622     for (i = 0; i < uih_nfilters; i++) {
1623         item[i].menuname = "mfilter";
1624         item[i].key = NULL;
1625         item[i].type = MENU_INT;
1626         item[i].flags =
1627             MENUFLAG_CHECKBOX | MENUFLAG_INTERRUPT | MENUFLAG_NOPLAY;
1628         item[i].iparam = i;
1629         item[i].name = uih_filters[i]->name;
1630         item[i].shortname = uih_filters[i]->shortname;
1631         if (!strcmp(item[i].shortname, "palette"))
1632             item[i].shortname = "palettef";
1633         /*this is one name collision because of ugly historical reasons */
1634         item[i].function = (void (*)(void))uih_filtersw;
1635         item[i].control = (int (*)(void))uih_filterenabled;
1636     }
1637     menu_add(item, uih_nfilters);
1638 
1639     menu_add(menuitems2, NITEMS(menuitems2));
1640 }
1641 
uih_unregistermenus(void)1642 void uih_unregistermenus(void)
1643 {
1644     menu_delete(menuitems, NITEMS(menuitems));
1645     menu_delete(menuitems_i18n, uih_no_menuitems_i18n);
1646 
1647     menu_delete(formulaitems, nformulas);
1648     free(formulaitems);
1649 
1650     menu_delnumbered(INCOLORING - 1, "in");
1651 
1652     menu_delnumbered(TCOLOR - 1, "int");
1653 
1654     menu_delnumbered(OUTCOLORING - 1, "out");
1655 
1656     menu_delnumbered(TCOLOR - 1, "outt");
1657     {
1658         int i;
1659         for (i = 0; planename[i] != NULL; i++)
1660             ;
1661         menu_delnumbered(i, "plane");
1662     }
1663 
1664     menu_delete(filteritems, uih_nfilters);
1665     free(filteritems);
1666 
1667     menu_delete(menuitems2, NITEMS(menuitems2));
1668 }
1669 
1670 #ifdef USE_SFFE
uih_sffein(uih_context * c,const char * text)1671 void uih_sffein(uih_context *c, const char *text)
1672 {
1673     // Keep only top 10 entries
1674     QSettings settings;
1675     QStringList values = settings.value("Formulas/UserFormulas").toStringList();
1676     values.push_front(text);
1677     while (values.size() > 10) values.pop_back();
1678     settings.setValue("Formulas/UserFormulas", values);
1679 
1680     uih_sffeset(c, c->fcontext->userformula, text);
1681 }
1682 
uih_sffeinitin(uih_context * c,const char * text)1683 void uih_sffeinitin(uih_context *c, const char *text)
1684 {
1685     uih_sffeset(c, c->fcontext->userinitial, text);
1686 }
1687 #endif
1688