1 /* simple dialog boxes, used by both whiptail and tcl dialog bindings */
13 #include "dialogboxes.h"
22 static int buttonHeight
= 1;
24 int max (int a
, int b
)
26 return (a
> b
) ? a
: b
;
29 int min (int a
, int b
)
31 return ( a
< b
) ? a
: b
;
34 static newtComponent (*makeButton
)(int left
, int right
, const char * text
) =
37 static void addButtons(int height
, int width
, newtComponent form
,
38 newtComponent
* okay
, newtComponent
* cancel
,
40 // FIXME: DO SOMETHING ABOUT THE HARD-CODED CONSTANTS
41 if (flags
& FLAG_NOCANCEL
) {
42 *okay
= makeButton((width
- 8) / 2, height
- buttonHeight
- 1,
43 dgettext(PACKAGE
, "Ok"));
45 newtFormAddComponent(form
, *okay
);
47 *okay
= makeButton((width
- 18) / 3, height
- buttonHeight
- 1,
48 dgettext(PACKAGE
,"Ok"));
49 *cancel
= makeButton(((width
- 18) / 3) * 2 + 9,
50 height
- buttonHeight
- 1,
51 dgettext(PACKAGE
,"Cancel"));
52 newtFormAddComponents(form
, *okay
, *cancel
, NULL
);
56 static newtComponent
textbox(int maxHeight
, int width
, const char * text
,
57 int flags
, int * height
) {
59 int sFlag
= (flags
& FLAG_SCROLL_TEXT
) ? NEWT_FLAG_SCROLL
: 0;
64 dst
= buf
= alloca(strlen(text
) + 1);
67 if (*src
== '\\' && *(src
+ 1) == 'n') {
75 tb
= newtTextbox(1, 0, width
, maxHeight
, NEWT_FLAG_WRAP
| sFlag
);
76 newtTextboxSetText(tb
, buf
);
78 i
= newtTextboxGetNumLines(tb
);
80 newtTextboxSetHeight(tb
, i
);
89 int gauge(const char * text
, int height
, int width
, poptContext optCon
, int fd
,
91 newtComponent form
, scale
, tb
;
96 FILE * f
= fdopen(fd
, "r");
103 if (!(arg
= poptGetArg(optCon
))) return DLG_ERROR
;
104 val
= strtoul(arg
, &end
, 10);
105 if (*end
) return DLG_ERROR
;
107 tb
= textbox(height
- 3, width
- 2, text
, flags
, &top
);
109 form
= newtForm(NULL
, NULL
, 0);
111 scale
= newtScale(2, height
- 2, width
- 4, 100);
112 newtScaleSet(scale
, val
);
114 newtFormAddComponents(form
, tb
, scale
, NULL
);
119 while (fgets(buf
, sizeof(buf
) - 1, f
)) {
120 buf
[strlen(buf
) - 1] = '\0';
122 if (!strcmp(buf
, "XXX")) {
123 fgets(buf3
, sizeof(buf3
) - 1, f
);
124 buf3
[strlen(buf3
) - 1] = '\0';
128 while (fgets(buf
+ i
, sizeof(buf
) - 1 - i
, f
)) {
129 buf
[strlen(buf
) - 1] = '\0';
130 if (!strcmp(buf
+ i
, "XXX")) {
137 newtTextboxSetText(tb
, buf
);
142 val
= strtoul(buf
, &end
, 10);
144 newtScaleSet(scale
, val
);
153 int inputBox(const char * text
, int height
, int width
, poptContext optCon
,
154 int flags
, const char ** result
) {
155 newtComponent form
, entry
, okay
, cancel
, answer
, tb
;
157 int pFlag
= (flags
& FLAG_PASSWORD
) ? NEWT_FLAG_PASSWORD
: 0;
161 val
= poptGetArg(optCon
);
162 tb
= textbox(height
- 3 - buttonHeight
, width
- 2,
165 form
= newtForm(NULL
, NULL
, 0);
166 entry
= newtEntry(1, top
+ 1, val
, width
- 2, &val
,
167 NEWT_FLAG_SCROLL
| NEWT_FLAG_RETURNEXIT
| pFlag
);
169 newtFormAddComponents(form
, tb
, entry
, NULL
);
171 addButtons(height
, width
, form
, &okay
, &cancel
, flags
);
173 answer
= newtRunForm(form
);
174 if (answer
== cancel
)
176 else if (answer
== NULL
)
184 static int mystrncpyw(char *dest
, const char *src
, int n
, int *maxwidth
)
193 memset(&ps
, 0, sizeof(ps
));
196 int ret
= mbrtowc(&c
, p
, MB_CUR_MAX
, &ps
);
198 if (ret
+ i
>= n
) break;
201 if (cw
+ w
> *maxwidth
) break;
213 int listBox(const char * text
, int height
, int width
, poptContext optCon
,
214 int flags
, const char *default_item
, const char ** result
) {
215 newtComponent form
, okay
, tb
, answer
, listBox
;
216 newtComponent cancel
= NULL
;
221 int allocedItems
= 5;
226 int maxTextWidth
= 0;
229 int lineWidth
, textWidth
, tagWidth
;
233 } * itemInfo
= malloc(allocedItems
* sizeof(*itemInfo
));
235 if (itemInfo
== NULL
) return DLG_ERROR
;
236 if (!(arg
= poptGetArg(optCon
))) return DLG_ERROR
;
237 listHeight
= strtoul(arg
, &end
, 10);
238 if (*end
) return DLG_ERROR
;
240 while ((arg
= poptGetArg(optCon
))) {
241 if (allocedItems
== numItems
) {
243 itemInfo
= realloc(itemInfo
, sizeof(*itemInfo
) * allocedItems
);
244 if (itemInfo
== NULL
) return DLG_ERROR
;
247 itemInfo
[numItems
].tag
= arg
;
248 if (default_item
&& (strcmp(default_item
, arg
) == 0)) {
251 if (!(arg
= poptGetArg(optCon
))) return DLG_ERROR
;
253 if (!(flags
& FLAG_NOITEM
)) {
254 itemInfo
[numItems
].text
= arg
;
256 itemInfo
[numItems
].text
= "";
258 if (wstrlen(itemInfo
[numItems
].text
,-1) > (unsigned int)maxTextWidth
)
259 maxTextWidth
= wstrlen(itemInfo
[numItems
].text
,-1);
260 if (wstrlen(itemInfo
[numItems
].tag
,-1) > (unsigned int)maxTagWidth
)
261 maxTagWidth
= wstrlen(itemInfo
[numItems
].tag
,-1);
268 if (flags
& FLAG_NOTAGS
) {
272 form
= newtForm(NULL
, NULL
, 0);
274 tb
= textbox(height
- 4 - buttonHeight
- listHeight
, width
- 2,
277 if (listHeight
>= numItems
) {
281 scrollFlag
= NEWT_FLAG_SCROLL
;
285 lineWidth
= min(maxTagWidth
+ maxTextWidth
+ i
, SLtt_Screen_Cols
- 10);
286 listBox
= newtListbox( (width
- lineWidth
) / 2 , top
+ 1, listHeight
,
287 NEWT_FLAG_RETURNEXIT
| scrollFlag
);
289 textWidth
= maxTextWidth
;
290 tagWidth
= maxTagWidth
;
291 if (maxTextWidth
== 0) {
292 tagWidth
= lineWidth
;
294 if (maxTextWidth
+ maxTagWidth
+ i
> lineWidth
)
295 tagWidth
= textWidth
= (lineWidth
/ 2) - 2;
302 if (!(flags
& FLAG_NOTAGS
)) {
303 for (i
= 0; i
< numItems
; i
++) {
306 len
= mystrncpyw(buf
, itemInfo
[i
].tag
, MAXBUF
, &w
);
307 for (j
= 0; j
< tagWidth
- w
; j
++) {
308 if (len
>= MAXBUF
) break;
313 mystrncpyw(buf
+ len
, itemInfo
[i
].text
, MAXBUF
-len
, &w
);
314 newtListboxAddEntry(listBox
, buf
, (void *) i
);
317 for (i
= 0; i
< numItems
; i
++) {
318 snprintf(buf
, MAXBUF
, "%s", itemInfo
[i
].text
);
319 newtListboxAddEntry(listBox
, buf
, (void *) i
);
324 newtListboxSetCurrent (listBox
, defItem
);
326 newtFormAddComponents(form
, tb
, listBox
, NULL
);
328 addButtons(height
, width
, form
, &okay
, &cancel
, flags
);
330 answer
= newtRunForm(form
);
331 if (answer
== cancel
)
336 i
= (int) newtListboxGetCurrent(listBox
);
337 *result
= itemInfo
[i
].tag
;
342 int checkList(const char * text
, int height
, int width
, poptContext optCon
,
343 int useRadio
, int flags
, const char *** selections
) {
344 newtComponent form
, okay
, tb
, subform
, answer
;
345 newtComponent sb
= NULL
, cancel
= NULL
;
350 int allocedBoxes
= 5;
354 char buf
[MAXBUF
], format
[MAXFORMAT
];
361 } * cbInfo
= malloc(allocedBoxes
* sizeof(*cbInfo
));
362 char * cbStates
= malloc(allocedBoxes
* sizeof(cbStates
));
364 if ( (cbInfo
== NULL
) || (cbStates
== NULL
)) return DLG_ERROR
;
365 if (!(arg
= poptGetArg(optCon
))) return DLG_ERROR
;
366 listHeight
= strtoul(arg
, &end
, 10);
367 if (*end
) return DLG_ERROR
;
369 while ((arg
= poptGetArg(optCon
))) {
370 if (allocedBoxes
== numBoxes
) {
372 cbInfo
= realloc(cbInfo
, sizeof(*cbInfo
) * allocedBoxes
);
373 cbStates
= realloc(cbStates
, sizeof(*cbStates
) * allocedBoxes
);
374 if ((cbInfo
== NULL
) || (cbStates
== NULL
)) return DLG_ERROR
;
377 cbInfo
[numBoxes
].tag
= arg
;
378 if (!(arg
= poptGetArg(optCon
))) return DLG_ERROR
;
380 if (!(flags
& FLAG_NOITEM
)) {
381 cbInfo
[numBoxes
].text
= arg
;
382 if (!(arg
= poptGetArg(optCon
))) return DLG_ERROR
;
384 cbInfo
[numBoxes
].text
= "";
386 if (!strcmp(arg
, "1") || !strcasecmp(arg
, "on") ||
387 !strcasecmp(arg
, "yes"))
388 cbStates
[numBoxes
] = '*';
390 cbStates
[numBoxes
] = ' ';
392 if (wstrlen(cbInfo
[numBoxes
].tag
,-1) > (unsigned int)maxWidth
)
393 maxWidth
= wstrlen(cbInfo
[numBoxes
].tag
,-1);
398 form
= newtForm(NULL
, NULL
, 0);
400 tb
= textbox(height
- 3 - buttonHeight
- listHeight
, width
- 2,
403 if (listHeight
< numBoxes
) {
404 sb
= newtVerticalScrollbar(width
- 4,
406 listHeight
, NEWT_COLORSET_CHECKBOX
,
407 NEWT_COLORSET_ACTCHECKBOX
);
408 newtFormAddComponent(form
, sb
);
410 subform
= newtForm(sb
, NULL
, 0);
411 newtFormSetBackground(subform
, NEWT_COLORSET_CHECKBOX
);
413 snprintf(format
, MAXFORMAT
, "%%-%ds %%s", maxWidth
);
414 for (i
= 0; i
< numBoxes
; i
++) {
415 snprintf(buf
, MAXBUF
, format
, cbInfo
[i
].tag
, cbInfo
[i
].text
);
418 cbInfo
[i
].comp
= newtRadiobutton(4, top
+ 1 + i
, buf
,
420 i
? cbInfo
[i
- 1].comp
: NULL
);
422 cbInfo
[i
].comp
= newtCheckbox(4, top
+ 1 + i
, buf
,
423 cbStates
[i
], NULL
, cbStates
+ i
);
425 newtCheckboxSetFlags(cbInfo
[i
].comp
, NEWT_FLAG_RETURNEXIT
, NEWT_FLAGS_SET
);
426 newtFormAddComponent(subform
, cbInfo
[i
].comp
);
429 newtFormSetHeight(subform
, listHeight
);
430 newtFormSetWidth(subform
, width
- 10);
432 newtFormAddComponents(form
, tb
, subform
, NULL
);
434 addButtons(height
, width
, form
, &okay
, &cancel
, flags
);
436 answer
= newtRunForm(form
);
437 if (answer
== cancel
)
443 answer
= newtRadioGetCurrent(cbInfo
[0].comp
);
444 for (i
= 0; i
< numBoxes
; i
++)
445 if (cbInfo
[i
].comp
== answer
) {
446 *selections
= malloc(sizeof(char *) * 2);
447 if (*selections
== NULL
) return DLG_ERROR
;
448 (*selections
)[0] = cbInfo
[i
].tag
;
449 (*selections
)[1] = NULL
;
454 for (i
= 0; i
< numBoxes
; i
++) {
455 if (cbStates
[i
] != ' ') numSelected
++;
458 *selections
= malloc(sizeof(char *) * (numSelected
+ 1));
459 if (*selections
== NULL
) return DLG_ERROR
;
462 for (i
= 0; i
< numBoxes
; i
++) {
463 if (cbStates
[i
] != ' ')
464 (*selections
)[numSelected
++] = cbInfo
[i
].tag
;
467 (*selections
)[numSelected
] = NULL
;
473 int messageBox(const char * text
, int height
, int width
, int type
, int flags
) {
474 newtComponent form
, yes
, tb
, answer
;
475 newtComponent no
= NULL
;
477 int tFlag
= (flags
& FLAG_SCROLL_TEXT
) ? NEWT_FLAG_SCROLL
: 0;
479 form
= newtForm(NULL
, NULL
, 0);
481 tb
= newtTextbox(1, 1, width
- 2, height
- 3 - buttonHeight
,
482 NEWT_FLAG_WRAP
| tFlag
);
483 newtTextboxSetText(tb
, text
);
485 newtFormAddComponent(form
, tb
);
491 // FIXME Do something about the hard-coded constants
492 yes
= makeButton((width
- 8) / 2, height
- 1 - buttonHeight
,
493 dgettext(PACKAGE
,"Ok"));
494 newtFormAddComponent(form
, yes
);
497 yes
= makeButton((width
- 16) / 3, height
- 1 - buttonHeight
,
498 dgettext(PACKAGE
,"Yes"));
499 no
= makeButton(((width
- 16) / 3) * 2 + 9, height
- 1 - buttonHeight
,
500 dgettext(PACKAGE
,"No"));
501 newtFormAddComponents(form
, yes
, no
, NULL
);
503 if (flags
& FLAG_DEFAULT_NO
)
504 newtFormSetCurrent(form
, no
);
507 if ( type
!= MSGBOX_INFO
) {
508 if (newtRunForm(form
) == NULL
)
511 answer
= newtFormGetCurrent(form
);
526 void useFullButtons(int state
) {
529 makeButton
= newtButton
;
532 makeButton
= newtCompactButton
;