1
/* simple dialog boxes, used by both whiptail and tcl dialog bindings */
13
#include "dialogboxes.h"
23
static int buttonHeight = 1;
24
static const char * buttonText[BUTTONS];
26
int max (int a, int b)
28
return (a > b) ? a : b;
31
int min (int a, int b)
33
return ( a < b) ? a : b ;
36
static newtComponent (*makeButton)(int left, int right, const char * text) =
39
static const char * getButtonText(int button) {
41
if (button < 0 || button >= BUTTONS)
44
text = buttonText[button];
49
case 0: return dgettext(PACKAGE, "Ok");
50
case 1: return dgettext(PACKAGE, "Cancel");
51
case 2: return dgettext(PACKAGE, "Yes");
52
case 3: return dgettext(PACKAGE, "No");
58
static void addButtons(int height, int width, newtComponent form,
59
newtComponent * okay, newtComponent * cancel,
61
// FIXME: DO SOMETHING ABOUT THE HARD-CODED CONSTANTS
62
if (flags & FLAG_NOCANCEL) {
63
*okay = makeButton((width - 8) / 2, height - buttonHeight - 1,
64
getButtonText(BUTTON_OK));
66
newtFormAddComponent(form, *okay);
68
*okay = makeButton((width - 18) / 3, height - buttonHeight - 1,
69
getButtonText(BUTTON_OK));
70
*cancel = makeButton(((width - 18) / 3) * 2 + 9,
71
height - buttonHeight - 1,
72
getButtonText(BUTTON_CANCEL));
73
newtFormAddComponents(form, *okay, *cancel, NULL);
77
static void cleanNewlines(char *text)
81
for (p = q = text; *p; p++, q++)
82
if (*p == '\\' && p[1] == 'n') {
90
static newtComponent textbox(int maxHeight, int width, const char * text,
91
int flags, int * height) {
93
int sFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
97
buf = alloca(strlen(text) + 1);
101
tb = newtTextbox(1, 0, width, maxHeight, NEWT_FLAG_WRAP | sFlag);
102
newtTextboxSetText(tb, buf);
104
i = newtTextboxGetNumLines(tb);
106
newtTextboxSetHeight(tb, i);
115
int gauge(const char * text, int height, int width, poptContext optCon, int fd,
117
newtComponent form, scale, tb;
122
FILE * f = fdopen(fd, "r");
129
if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
130
val = strtoul(arg, &end, 10);
131
if (*end) return DLG_ERROR;
133
tb = textbox(height - 3, width - 2, text, flags, &top);
135
form = newtForm(NULL, NULL, 0);
137
scale = newtScale(2, height - 2, width - 4, 100);
138
newtScaleSet(scale, val);
140
newtFormAddComponents(form, tb, scale, NULL);
146
if (!fgets(buf, sizeof(buf) - 1, f))
148
buf[strlen(buf) - 1] = '\0';
150
if (!strcmp(buf, "XXX")) {
151
while (!fgets(buf3, sizeof(buf3) - 1, f) && !feof(f))
155
buf3[strlen(buf3) - 1] = '\0';
159
if (!fgets(buf + i, sizeof(buf) - 1 - i, f))
161
if (!strcmp(buf + i, "XXX\n")) {
169
buf[strlen(buf) - 1] = '\0';
174
newtTextboxSetText(tb, buf);
181
val = strtoul(arg, &end, 10);
183
newtScaleSet(scale, val);
189
newtFormDestroy(form);
194
int inputBox(const char * text, int height, int width, poptContext optCon,
195
int flags, char ** result) {
196
newtComponent form, entry, okay, cancel, answer, tb;
198
int pFlag = (flags & FLAG_PASSWORD) ? NEWT_FLAG_PASSWORD : 0;
202
val = poptGetArg(optCon);
203
tb = textbox(height - 3 - buttonHeight, width - 2,
206
form = newtForm(NULL, NULL, 0);
207
entry = newtEntry(1, top + 1, val, width - 2, &val,
208
NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT | pFlag);
210
newtFormAddComponents(form, tb, entry, NULL);
212
addButtons(height, width, form, &okay, &cancel, flags);
214
answer = newtRunForm(form);
216
if (answer == cancel)
218
else if (answer == NULL)
221
*result = strdup(val);
223
newtFormDestroy(form);
228
static int mystrncpyw(char *dest, const char *src, int n, int *maxwidth)
237
memset(&ps, 0, sizeof(ps));
240
int ret = mbrtowc(&c, p, MB_CUR_MAX, &ps);
242
if (ret + i >= n) break;
245
if (cw + w > *maxwidth) break;
257
int listBox(const char * text, int height, int width, poptContext optCon,
258
int flags, const char *default_item, char ** result) {
259
newtComponent form, okay, tb, answer, listBox;
260
newtComponent cancel = NULL;
265
int allocedItems = 5;
270
int maxTextWidth = 0;
273
int lineWidth, textWidth, tagWidth;
277
} * itemInfo = malloc(allocedItems * sizeof(*itemInfo));
279
if (itemInfo == NULL) return DLG_ERROR;
280
if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
281
listHeight = strtoul(arg, &end, 10);
282
if (*end) return DLG_ERROR;
284
while ((arg = poptGetArg(optCon))) {
285
if (allocedItems == numItems) {
287
itemInfo = realloc(itemInfo, sizeof(*itemInfo) * allocedItems);
288
if (itemInfo == NULL) return DLG_ERROR;
291
itemInfo[numItems].tag = arg;
292
if (default_item && (strcmp(default_item, arg) == 0)) {
295
if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
297
if (!(flags & FLAG_NOITEM)) {
298
itemInfo[numItems].text = arg;
300
itemInfo[numItems].text = "";
302
if (wstrlen(itemInfo[numItems].text,-1) > (unsigned int)maxTextWidth)
303
maxTextWidth = wstrlen(itemInfo[numItems].text,-1);
304
if (wstrlen(itemInfo[numItems].tag,-1) > (unsigned int)maxTagWidth)
305
maxTagWidth = wstrlen(itemInfo[numItems].tag,-1);
312
if (flags & FLAG_NOTAGS) {
316
form = newtForm(NULL, NULL, 0);
318
tb = textbox(height - 4 - buttonHeight - listHeight, width - 2,
321
if (listHeight >= numItems) {
325
scrollFlag = NEWT_FLAG_SCROLL;
329
lineWidth = min(maxTagWidth + maxTextWidth + i, SLtt_Screen_Cols - 10);
330
listBox = newtListbox( (width - lineWidth) / 2 , top + 1, listHeight,
331
NEWT_FLAG_RETURNEXIT | scrollFlag);
333
textWidth = maxTextWidth;
334
tagWidth = maxTagWidth;
335
if (maxTextWidth == 0) {
336
tagWidth = lineWidth;
338
if (maxTextWidth + maxTagWidth + i > lineWidth)
339
tagWidth = textWidth = (lineWidth / 2) - 2;
346
if (!(flags & FLAG_NOTAGS)) {
347
for (i = 0; i < numItems; i++) {
350
len = mystrncpyw(buf, itemInfo[i].tag, MAXBUF, &w);
351
for (j = 0; j < tagWidth - w; j++) {
352
if (len + 1 >= MAXBUF)
358
mystrncpyw(buf + len, itemInfo[i].text, MAXBUF-len, &w);
359
newtListboxAddEntry(listBox, buf, (void *)(long) i);
362
for (i = 0; i < numItems; i++) {
363
snprintf(buf, MAXBUF, "%s", itemInfo[i].text);
364
newtListboxAddEntry(listBox, buf, (void *)(long) i);
369
newtListboxSetCurrent (listBox, defItem);
371
newtFormAddComponents(form, tb, listBox, NULL);
373
addButtons(height, width, form, &okay, &cancel, flags);
375
answer = newtRunForm(form);
377
if (answer == cancel)
382
i = (long) newtListboxGetCurrent(listBox);
383
*result = strdup(itemInfo[i].tag);
386
newtFormDestroy(form);
392
int checkList(const char * text, int height, int width, poptContext optCon,
393
int useRadio, int flags, char *** selections) {
394
newtComponent form, okay, tb, subform, answer;
395
newtComponent sb = NULL, cancel = NULL;
400
int allocedBoxes = 5;
404
char buf[MAXBUF], format[MAXFORMAT];
411
} * cbInfo = malloc(allocedBoxes * sizeof(*cbInfo));
412
char * cbStates = malloc(allocedBoxes * sizeof(*cbStates));
414
if ( (cbInfo == NULL) || (cbStates == NULL)) return DLG_ERROR;
415
if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
416
listHeight = strtoul(arg, &end, 10);
417
if (*end) return DLG_ERROR;
419
while ((arg = poptGetArg(optCon))) {
420
if (allocedBoxes == numBoxes) {
422
cbInfo = realloc(cbInfo, sizeof(*cbInfo) * allocedBoxes);
423
cbStates = realloc(cbStates, sizeof(*cbStates) * allocedBoxes);
424
if ((cbInfo == NULL) || (cbStates == NULL)) return DLG_ERROR;
427
cbInfo[numBoxes].tag = arg;
428
if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
430
if (!(flags & FLAG_NOITEM)) {
431
cbInfo[numBoxes].text = arg;
432
if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
434
cbInfo[numBoxes].text = "";
436
if (!strcmp(arg, "1") || !strcasecmp(arg, "on") ||
437
!strcasecmp(arg, "yes"))
438
cbStates[numBoxes] = '*';
440
cbStates[numBoxes] = ' ';
442
if (wstrlen(cbInfo[numBoxes].tag,-1) > (unsigned int)maxWidth)
443
maxWidth = wstrlen(cbInfo[numBoxes].tag,-1);
448
form = newtForm(NULL, NULL, 0);
450
tb = textbox(height - 3 - buttonHeight - listHeight, width - 2,
453
if (listHeight < numBoxes) {
454
sb = newtVerticalScrollbar(width - 4,
456
listHeight, NEWT_COLORSET_CHECKBOX,
457
NEWT_COLORSET_ACTCHECKBOX);
458
newtFormAddComponent(form, sb);
460
subform = newtForm(sb, NULL, 0);
461
newtFormSetBackground(subform, NEWT_COLORSET_CHECKBOX);
463
snprintf(format, MAXFORMAT, "%%-%ds %%s", maxWidth);
464
for (i = 0; i < numBoxes; i++) {
465
snprintf(buf, MAXBUF, format, cbInfo[i].tag, cbInfo[i].text);
468
cbInfo[i].comp = newtRadiobutton(4, top + 1 + i, buf,
470
i ? cbInfo[i - 1].comp : NULL);
472
cbInfo[i].comp = newtCheckbox(4, top + 1 + i, buf,
473
cbStates[i], NULL, cbStates + i);
475
newtCheckboxSetFlags(cbInfo[i].comp, NEWT_FLAG_RETURNEXIT, NEWT_FLAGS_SET);
476
newtFormAddComponent(subform, cbInfo[i].comp);
479
newtFormSetHeight(subform, listHeight);
480
newtFormSetWidth(subform, width - 10);
482
newtFormAddComponents(form, tb, subform, NULL);
484
addButtons(height, width, form, &okay, &cancel, flags);
486
answer = newtRunForm(form);
488
if (answer == cancel)
494
answer = newtRadioGetCurrent(cbInfo[0].comp);
495
*selections = malloc(sizeof(char *) * 2);
496
if (*selections == NULL)
498
(*selections)[0] = (*selections)[1] = NULL;
499
for (i = 0; i < numBoxes; i++)
500
if (cbInfo[i].comp == answer) {
501
(*selections)[0] = strdup(cbInfo[i].tag);
506
for (i = 0; i < numBoxes; i++) {
507
if (cbStates[i] != ' ') numSelected++;
510
*selections = malloc(sizeof(char *) * (numSelected + 1));
511
if (*selections == NULL)
515
for (i = 0; i < numBoxes; i++) {
516
if (cbStates[i] != ' ')
517
(*selections)[numSelected++] = strdup(cbInfo[i].tag);
520
(*selections)[numSelected] = NULL;
526
newtFormDestroy(form);
531
int messageBox(const char * text, int height, int width, int type, int flags) {
532
newtComponent form, yes, tb, answer;
533
newtComponent no = NULL;
535
int tFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
537
form = newtForm(NULL, NULL, 0);
539
tb = newtTextbox(1, 1, width - 2, height - 3 - buttonHeight,
540
NEWT_FLAG_WRAP | tFlag);
541
newtTextboxSetText(tb, text);
543
newtFormAddComponent(form, tb);
549
// FIXME Do something about the hard-coded constants
550
yes = makeButton((width - 8) / 2, height - 1 - buttonHeight,
551
getButtonText(BUTTON_OK));
552
newtFormAddComponent(form, yes);
555
yes = makeButton((width - 16) / 3, height - 1 - buttonHeight,
556
getButtonText(BUTTON_YES));
557
no = makeButton(((width - 16) / 3) * 2 + 9, height - 1 - buttonHeight,
558
getButtonText(BUTTON_NO));
559
newtFormAddComponents(form, yes, no, NULL);
561
if (flags & FLAG_DEFAULT_NO)
562
newtFormSetCurrent(form, no);
565
if ( type != MSGBOX_INFO ) {
566
if (newtRunForm(form) == NULL)
569
answer = newtFormGetCurrent(form);
579
newtFormDestroy(form);
584
void useFullButtons(int state) {
587
makeButton = newtButton;
590
makeButton = newtCompactButton;
594
void setButtonText(const char * text, int button) {
595
if (button < 0 || button >= BUTTONS)
597
buttonText[button] = text;