/* simple dialog boxes, used by both whiptail and tcl dialog bindings */ #include #include #include #include #include #include "dialogboxes.h" #include "newt.h" #include "newt_pr.h" #include "popt.h" /* globals -- ick */ static int buttonHeight = 1; static newtComponent (*makeButton)(int left, int right, const char * text) = newtCompactButton; static void addButtons(int height, int width, newtComponent form, newtComponent * okay, newtComponent * cancel, int flags) { if (flags & FLAG_NOCANCEL) { *okay = makeButton((width - 8) / 2, height - buttonHeight - 1, "Ok"); *cancel = NULL; newtFormAddComponent(form, *okay); } else { *okay = makeButton((width - 18) / 3, height - buttonHeight - 1, "Ok"); *cancel = makeButton(((width - 18) / 3) * 2 + 9, height - buttonHeight - 1, "Cancel"); newtFormAddComponents(form, *okay, *cancel, NULL); } } static newtComponent textbox(int maxHeight, int width, const char * text, int flags, int * height) { newtComponent tb; int sFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0; int i; char * buf, * dst; const char * src; dst = buf = alloca(strlen(text) + 1); src = text; while (*src) { if (*src == '\\' && *(src + 1) == 'n') { src += 2; *dst++ = '\n'; } else *dst++ = *src++; } *dst++ = '\0'; tb = newtTextbox(1, 0, width, maxHeight, NEWT_FLAG_WRAP | sFlag); newtTextboxSetText(tb, buf); i = newtTextboxGetNumLines(tb); if (i < maxHeight) { newtTextboxSetHeight(tb, i); maxHeight = i; } *height = maxHeight; return tb; } int gauge(const char * text, int height, int width, poptContext optCon, int fd, int flags) { newtComponent form, scale, tb; int top; const char * arg; char * end; int val; FILE * f = fdopen(fd, "r"); char buf[3000]; char buf3[50]; int i; setlinebuf(f); if (!(arg = poptGetArg(optCon))) return DLG_ERROR; val = strtoul(arg, &end, 10); if (*end) return DLG_ERROR; tb = textbox(height - 3, width - 2, text, flags, &top); form = newtForm(NULL, NULL, 0); scale = newtScale(2, height - 2, width - 4, 100); newtScaleSet(scale, val); newtFormAddComponents(form, tb, scale, NULL); newtDrawForm(form); newtRefresh(); while (fgets(buf, sizeof(buf) - 1, f)) { buf[strlen(buf) - 1] = '\0'; if (!strcmp(buf, "XXX")) { fgets(buf3, sizeof(buf3) - 1, f); buf3[strlen(buf3) - 1] = '\0'; arg = buf3; i = 0; while (fgets(buf + i, sizeof(buf) - 1 - i, f)) { buf[strlen(buf) - 1] = '\0'; if (!strcmp(buf + i, "XXX")) { *(buf + i) = '\0'; break; } i = strlen(buf); } newtTextboxSetText(tb, buf); } else { arg = buf; } val = strtoul(buf, &end, 10); if (!*end) { newtScaleSet(scale, val); newtDrawForm(form); newtRefresh(); } } return DLG_OKAY; } int inputBox(const char * text, int height, int width, poptContext optCon, int flags, char ** result) { newtComponent form, entry, okay, cancel, answer, tb; char * val; int rc = DLG_OKAY; int top; val = poptGetArg(optCon); tb = textbox(height - 3 - buttonHeight, width - 2, text, flags, &top); form = newtForm(NULL, NULL, 0); entry = newtEntry(1, top + 1, val, width - 2, &val, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); newtFormAddComponents(form, tb, entry, NULL); addButtons(height, width, form, &okay, &cancel, flags); answer = newtRunForm(form); if (answer == cancel) rc = DLG_CANCEL; *result = val; return rc; } int listBox(const char * text, int height, int width, poptContext optCon, int flags, char ** result) { newtComponent form, okay, tb, answer, listBox; newtComponent cancel = NULL; const char * arg; char * end; int listHeight; int numItems = 0; int allocedItems = 5; int i, top; int rc = DLG_OKAY; char buf[80], format[20]; int maxTagWidth = 0; int maxTextWidth = 0; int scrollFlag; struct { const char * text; const char * tag; } * itemInfo = malloc(allocedItems * sizeof(*itemInfo)); if (!(arg = poptGetArg(optCon))) return DLG_ERROR; listHeight = strtoul(arg, &end, 10); if (*end) return DLG_ERROR; while ((arg = poptGetArg(optCon))) { if (allocedItems == numItems) { allocedItems += 5; itemInfo = realloc(itemInfo, sizeof(*itemInfo) * allocedItems); } itemInfo[numItems].tag = arg; if (!(arg = poptGetArg(optCon))) return DLG_ERROR; if (!(flags & FLAG_NOITEM)) { itemInfo[numItems].text = arg; } else itemInfo[numItems].text = ""; if (wstrlen(itemInfo[numItems].text,-1) > (unsigned int)maxTextWidth) maxTextWidth = wstrlen(itemInfo[numItems].text,-1); if (wstrlen(itemInfo[numItems].tag,-1) > (unsigned int)maxTagWidth) maxTagWidth = wstrlen(itemInfo[numItems].tag,-1); numItems++; } form = newtForm(NULL, NULL, 0); tb = textbox(height - 4 - buttonHeight - listHeight, width - 2, text, flags, &top); if (listHeight >= numItems) { scrollFlag = 0; i = 0; } else { scrollFlag = NEWT_FLAG_SCROLL; i = 2; } listBox = newtListbox(3 + ((width - 10 - maxTagWidth - maxTextWidth - i) / 2), top + 1, listHeight, NEWT_FLAG_RETURNEXIT | scrollFlag); sprintf(format, "%%-%ds %%s", maxTagWidth); for (i = 0; i < numItems; i++) { sprintf(buf, format, itemInfo[i].tag, itemInfo[i].text); newtListboxAddEntry(listBox, buf, (void *) i); } newtFormAddComponents(form, tb, listBox, NULL); addButtons(height, width, form, &okay, &cancel, flags); answer = newtRunForm(form); if (answer == cancel) rc = DLG_CANCEL; i = (int) newtListboxGetCurrent(listBox); *result = itemInfo[i].tag; return rc; } int checkList(const char * text, int height, int width, poptContext optCon, int useRadio, int flags, char *** selections) { newtComponent form, okay, tb, subform, answer; newtComponent sb = NULL, cancel = NULL; const char * arg; char * end; int listHeight; int numBoxes = 0; int allocedBoxes = 5; int i; int numSelected; int rc = DLG_OKAY; char buf[80], format[20]; int maxWidth = 0; int top; struct { const char * text; const char * tag; newtComponent comp; } * cbInfo = malloc(allocedBoxes * sizeof(*cbInfo)); char * cbStates = malloc(allocedBoxes * sizeof(cbStates)); if (!(arg = poptGetArg(optCon))) return DLG_ERROR; listHeight = strtoul(arg, &end, 10); if (*end) return DLG_ERROR; while ((arg = poptGetArg(optCon))) { if (allocedBoxes == numBoxes) { allocedBoxes += 5; cbInfo = realloc(cbInfo, sizeof(*cbInfo) * allocedBoxes); cbStates = realloc(cbStates, sizeof(*cbStates) * allocedBoxes); } cbInfo[numBoxes].tag = arg; if (!(arg = poptGetArg(optCon))) return DLG_ERROR; if (!(flags & FLAG_NOITEM)) { cbInfo[numBoxes].text = arg; if (!(arg = poptGetArg(optCon))) return DLG_ERROR; } else cbInfo[numBoxes].text = ""; if (!strcmp(arg, "1") || !strcasecmp(arg, "on") || !strcasecmp(arg, "yes")) cbStates[numBoxes] = '*'; else cbStates[numBoxes] = ' '; if (wstrlen(cbInfo[numBoxes].tag,-1) > (unsigned int)maxWidth) maxWidth = wstrlen(cbInfo[numBoxes].tag,-1); numBoxes++; } form = newtForm(NULL, NULL, 0); tb = textbox(height - 3 - buttonHeight - listHeight, width - 2, text, flags, &top); if (listHeight < numBoxes) { sb = newtVerticalScrollbar(width - 4, top + 1, listHeight, NEWT_COLORSET_CHECKBOX, NEWT_COLORSET_ACTCHECKBOX); newtFormAddComponent(form, sb); } subform = newtForm(sb, NULL, 0); newtFormSetBackground(subform, NEWT_COLORSET_CHECKBOX); sprintf(format, "%%-%ds %%s", maxWidth); for (i = 0; i < numBoxes; i++) { sprintf(buf, format, cbInfo[i].tag, cbInfo[i].text); if (useRadio) cbInfo[i].comp = newtRadiobutton(4, top + 1 + i, buf, cbStates[i] != ' ', i ? cbInfo[i - 1].comp : NULL); else cbInfo[i].comp = newtCheckbox(4, top + 1 + i, buf, cbStates[i], NULL, cbStates + i); newtFormAddComponent(subform, cbInfo[i].comp); } newtFormSetHeight(subform, listHeight); newtFormSetWidth(subform, width - 10); newtFormAddComponents(form, tb, subform, NULL); addButtons(height, width, form, &okay, &cancel, flags); answer = newtRunForm(form); if (answer == cancel) rc = DLG_CANCEL; if (useRadio) { answer = newtRadioGetCurrent(cbInfo[0].comp); for (i = 0; i < numBoxes; i++) if (cbInfo[i].comp == answer) { *selections = malloc(sizeof(char *) * 2); (*selections)[0] = cbInfo[i].tag; (*selections)[1] = NULL; break; } } else { numSelected = 0; for (i = 0; i < numBoxes; i++) { if (cbStates[i] != ' ') numSelected++; } *selections = malloc(sizeof(char *) * (numSelected + 1)); numSelected = 0; for (i = 0; i < numBoxes; i++) { if (cbStates[i] != ' ') (*selections)[numSelected++] = cbInfo[i].tag; } (*selections)[numSelected] = NULL; } return rc; } int messageBox(const char * text, int height, int width, int type, int flags) { newtComponent form, yes, tb, answer; newtComponent no = NULL; int tFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0; form = newtForm(NULL, NULL, 0); tb = newtTextbox(1, 1, width - 2, height - 3 - buttonHeight, NEWT_FLAG_WRAP | tFlag); newtTextboxSetText(tb, text); newtFormAddComponent(form, tb); switch ( type ) { case MSGBOX_INFO: break; case MSGBOX_MSG: yes = makeButton((width - 8) / 2, height - 1 - buttonHeight, "Ok"); newtFormAddComponent(form, yes); break; default: yes = makeButton((width - 16) / 3, height - 1 - buttonHeight, "Yes"); no = makeButton(((width - 16) / 3) * 2 + 9, height - 1 - buttonHeight, "No"); newtFormAddComponents(form, yes, no, NULL); if (flags & FLAG_DEFAULT_NO) newtFormSetCurrent(form, no); } if ( type != MSGBOX_INFO ) { newtRunForm(form); answer = newtFormGetCurrent(form); if (answer == no) return DLG_CANCEL; } else { newtDrawForm(form); newtRefresh(); } return DLG_OKAY; } void useFullButtons(int state) { if (state) { buttonHeight = 3; makeButton = newtButton; } else { buttonHeight = 1; makeButton = newtCompactButton; } }