]> git.ipfire.org Git - thirdparty/newt.git/blob - dialogboxes.c
split whiptail dialog stuff out; added whiptcl
[thirdparty/newt.git] / dialogboxes.c
1 /* simple dialog boxes, used by both whiptail and tcl dialog bindings */
2
3 #include <fcntl.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8
9 #include "dialogboxes.h"
10 #include "newt.h"
11 #include "popt.h"
12
13 /* globals -- ick */
14 int buttonHeight = 1;
15 newtComponent (*makeButton)(int left, int right, char * text) =
16 newtCompactButton;
17
18 static void addButtons(int height, int width, newtComponent form,
19 newtComponent * okay, newtComponent * cancel,
20 int flags) {
21 if (flags & FLAG_NOCANCEL) {
22 *okay = makeButton((width - 8) / 2, height - buttonHeight - 1, "Ok");
23 *cancel = NULL;
24 newtFormAddComponent(form, *okay);
25 } else {
26 *okay = makeButton((width - 18) / 3, height - buttonHeight - 1, "Ok");
27 *cancel = makeButton(((width - 18) / 3) * 2 + 9,
28 height - buttonHeight - 1, "Cancel");
29 newtFormAddComponents(form, *okay, *cancel, NULL);
30 }
31 }
32
33 static newtComponent textbox(int maxHeight, int width, char * text, int flags,
34 int * height) {
35 newtComponent tb;
36 int sFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
37 int i;
38 char * buf, * src, * dst;
39
40 dst = buf = alloca(strlen(text) + 1);
41 src = text;
42 while (*src) {
43 if (*src == '\\' && *(src + 1) == 'n') {
44 src += 2;
45 *dst++ = '\n';
46 } else
47 *dst++ = *src++;
48 }
49 *dst++ = '\0';
50
51 tb = newtTextbox(1, 0, width, maxHeight, NEWT_FLAG_WRAP | sFlag);
52 newtTextboxSetText(tb, buf);
53
54 i = newtTextboxGetNumLines(tb);
55 if (i < maxHeight) {
56 newtTextboxSetHeight(tb, i);
57 maxHeight = i;
58 }
59
60 *height = maxHeight;
61
62 return tb;
63 }
64
65 int gauge(char * text, int height, int width, poptContext optCon, int fd,
66 int flags) {
67 newtComponent form, scale, tb;
68 int top;
69 char * arg, * end;
70 int val;
71 FILE * f = fdopen(fd, "r");
72 char buf[3000];
73 char buf3[50];
74 int i;
75
76 setlinebuf(f);
77
78 if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
79 val = strtoul(arg, &end, 10);
80 if (*end) return DLG_ERROR;
81
82 tb = textbox(height - 3, width - 2, text, flags, &top);
83
84 form = newtForm(NULL, NULL, 0);
85
86 scale = newtScale(2, height - 2, width - 4, 100);
87 newtScaleSet(scale, val);
88
89 newtFormAddComponents(form, tb, scale, NULL);
90
91 newtDrawForm(form);
92 newtRefresh();
93
94 while (fgets(buf, sizeof(buf) - 1, f)) {
95 buf[strlen(buf) - 1] = '\0';
96
97 if (!strcmp(buf, "XXX")) {
98 fgets(buf3, sizeof(buf3) - 1, f);
99 buf3[strlen(buf3) - 1] = '\0';
100 arg = buf3;
101
102 i = 0;
103 while (fgets(buf + i, sizeof(buf) - 1 - i, f)) {
104 buf[strlen(buf) - 1] = '\0';
105 if (!strcmp(buf + i, "XXX")) {
106 *(buf + i) = '\0';
107 break;
108 }
109 i = strlen(buf);
110 }
111
112 newtTextboxSetText(tb, buf);
113 } else {
114 arg = buf;
115 }
116
117 val = strtoul(buf, &end, 10);
118 if (!*end) {
119 newtScaleSet(scale, val);
120 newtDrawForm(form);
121 newtRefresh();
122 }
123 }
124
125 return DLG_OKAY;
126 }
127
128 int inputBox(char * text, int height, int width, poptContext optCon,
129 int flags, char ** result) {
130 newtComponent form, entry, okay, cancel, answer, tb;
131 char * val;
132 int rc = DLG_OKAY;
133 int top;
134
135 val = poptGetArg(optCon);
136 tb = textbox(height - 3 - buttonHeight, width - 2,
137 text, flags, &top);
138
139 form = newtForm(NULL, NULL, 0);
140 entry = newtEntry(1, top + 1, val, width - 2, &val,
141 NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
142
143 newtFormAddComponents(form, tb, entry, NULL);
144
145 addButtons(height, width, form, &okay, &cancel, flags);
146
147 answer = newtRunForm(form);
148 if (answer == cancel)
149 rc = DLG_CANCEL;
150
151 *result = val;
152
153 return rc;
154 }
155
156 int listBox(char * text, int height, int width, poptContext optCon,
157 int flags, char ** result) {
158 newtComponent form, okay, tb, answer, listBox;
159 newtComponent cancel = NULL;
160 char * arg, * end;
161 int listHeight;
162 int numItems = 0;
163 int allocedItems = 5;
164 int i, top;
165 int rc = DLG_OKAY;
166 char buf[80], format[20];
167 int maxTagWidth = 0;
168 int maxTextWidth = 0;
169 int noScrollFlag;
170 struct {
171 char * text;
172 char * tag;
173 } * itemInfo = malloc(allocedItems * sizeof(*itemInfo));
174
175 if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
176 listHeight = strtoul(arg, &end, 10);
177 if (*end) return DLG_ERROR;
178
179 while ((arg = poptGetArg(optCon))) {
180 if (allocedItems == numItems) {
181 allocedItems += 5;
182 itemInfo = realloc(itemInfo, sizeof(*itemInfo) * allocedItems);
183 }
184
185 itemInfo[numItems].tag = arg;
186 if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
187
188 if (!(flags & FLAG_NOITEM)) {
189 itemInfo[numItems].text = arg;
190 } else
191 itemInfo[numItems].text = "";
192
193 if (strlen(itemInfo[numItems].text) > maxTextWidth)
194 maxTextWidth = strlen(itemInfo[numItems].text);
195 if (strlen(itemInfo[numItems].tag) > maxTagWidth)
196 maxTagWidth = strlen(itemInfo[numItems].tag);
197
198 numItems++;
199 }
200
201 form = newtForm(NULL, NULL, 0);
202
203 tb = textbox(height - 4 - buttonHeight - listHeight, width - 2,
204 text, flags, &top);
205
206 if (listHeight >= numItems) {
207 noScrollFlag = NEWT_FLAG_NOSCROLL;
208 i = 0;
209 } else {
210 noScrollFlag = 0;
211 i = 2;
212 }
213
214 listBox = newtListbox(3 + ((width - 10 - maxTagWidth - maxTextWidth - i)
215 / 2),
216 top + 1, listHeight,
217 NEWT_FLAG_RETURNEXIT | noScrollFlag);
218
219 sprintf(format, "%%-%ds %%s", maxTagWidth);
220 for (i = 0; i < numItems; i++) {
221 sprintf(buf, format, itemInfo[i].tag, itemInfo[i].text);
222 newtListboxAddEntry(listBox, buf, (void *) i);
223 }
224
225 newtFormAddComponents(form, tb, listBox, NULL);
226
227 addButtons(height, width, form, &okay, &cancel, flags);
228
229 answer = newtRunForm(form);
230 if (answer == cancel)
231 rc = DLG_CANCEL;
232
233 i = (int) newtListboxGetCurrent(listBox);
234 *result = itemInfo[i].tag;
235
236 return rc;
237 }
238
239 int checkList(char * text, int height, int width, poptContext optCon,
240 int useRadio, int flags, char *** selections) {
241 newtComponent form, okay, tb, subform, answer;
242 newtComponent sb = NULL, cancel = NULL;
243 char * arg, * end;
244 int listHeight;
245 int numBoxes = 0;
246 int allocedBoxes = 5;
247 int i;
248 int numSelected;
249 int rc = DLG_OKAY;
250 char buf[80], format[20];
251 int maxWidth = 0;
252 int top;
253 struct {
254 char * text;
255 char * tag;
256 newtComponent comp;
257 } * cbInfo = malloc(allocedBoxes * sizeof(*cbInfo));
258 char * cbStates = malloc(allocedBoxes * sizeof(cbStates));
259
260 if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
261 listHeight = strtoul(arg, &end, 10);
262 if (*end) return DLG_ERROR;
263
264 while ((arg = poptGetArg(optCon))) {
265 if (allocedBoxes == numBoxes) {
266 allocedBoxes += 5;
267 cbInfo = realloc(cbInfo, sizeof(*cbInfo) * allocedBoxes);
268 cbStates = realloc(cbStates, sizeof(*cbStates) * allocedBoxes);
269 }
270
271 cbInfo[numBoxes].tag = arg;
272 if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
273
274 if (!(flags & FLAG_NOITEM)) {
275 cbInfo[numBoxes].text = arg;
276 if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
277 } else
278 cbInfo[numBoxes].text = "";
279
280 if (!strcmp(arg, "1") || !strcasecmp(arg, "on") ||
281 !strcasecmp(arg, "yes"))
282 cbStates[numBoxes] = '*';
283 else
284 cbStates[numBoxes] = ' ';
285
286 if (strlen(cbInfo[numBoxes].tag) > maxWidth)
287 maxWidth = strlen(cbInfo[numBoxes].tag);
288
289 numBoxes++;
290 }
291
292 form = newtForm(NULL, NULL, 0);
293
294 tb = textbox(height - 3 - buttonHeight - listHeight, width - 2,
295 text, flags, &top);
296
297 if (listHeight < numBoxes) {
298 sb = newtVerticalScrollbar(width - 4,
299 top + 1,
300 listHeight, NEWT_COLORSET_CHECKBOX,
301 NEWT_COLORSET_ACTCHECKBOX);
302 newtFormAddComponent(form, sb);
303 }
304 subform = newtForm(sb, NULL, 0);
305 newtFormSetBackground(subform, NEWT_COLORSET_CHECKBOX);
306
307 sprintf(format, "%%-%ds %%s", maxWidth);
308 for (i = 0; i < numBoxes; i++) {
309 sprintf(buf, format, cbInfo[i].tag, cbInfo[i].text);
310
311 if (useRadio)
312 cbInfo[i].comp = newtRadiobutton(4, top + 1 + i, buf,
313 cbStates[i] != ' ',
314 i ? cbInfo[i - 1].comp : NULL);
315 else
316 cbInfo[i].comp = newtCheckbox(4, top + 1 + i, buf,
317 cbStates[i], NULL, cbStates + i);
318
319 newtFormAddComponent(subform, cbInfo[i].comp);
320 }
321
322 newtFormSetHeight(subform, listHeight);
323 newtFormSetWidth(subform, width - 10);
324
325 newtFormAddComponents(form, tb, subform, NULL);
326
327 addButtons(height, width, form, &okay, &cancel, flags);
328
329 answer = newtRunForm(form);
330 if (answer == cancel)
331 rc = DLG_CANCEL;
332
333 if (useRadio) {
334 answer = newtRadioGetCurrent(cbInfo[0].comp);
335 for (i = 0; i < numBoxes; i++)
336 if (cbInfo[i].comp == answer) {
337 *selections = malloc(sizeof(char *) * 2);
338 (*selections)[0] = cbInfo[i].tag;
339 (*selections)[1] = NULL;
340 break;
341 }
342 } else {
343 numSelected = 0;
344 for (i = 0; i < numBoxes; i++) {
345 if (cbStates[i] != ' ') numSelected++;
346 }
347
348 *selections = malloc(sizeof(char *) * (numSelected + 1));
349
350 numSelected = 0;
351 for (i = 0; i < numBoxes; i++) {
352 if (cbStates[i] != ' ')
353 (*selections)[numSelected++] = cbInfo[i].tag;
354 }
355
356 (*selections)[numSelected] = NULL;
357 }
358
359 return rc;
360 }
361
362 int messageBox(char * text, int height, int width, int type, int flags) {
363 newtComponent form, yes, tb, answer;
364 newtComponent no = NULL;
365 int tFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
366
367 form = newtForm(NULL, NULL, 0);
368
369 tb = newtTextbox(1, 1, width - 2, height - 3 - buttonHeight,
370 NEWT_FLAG_WRAP | tFlag);
371 newtTextboxSetText(tb, text);
372
373 newtFormAddComponent(form, tb);
374
375 if (type == MSGBOX_MSG) {
376 yes = makeButton((width - 8) / 2, height - 1 - buttonHeight, "Ok");
377 newtFormAddComponent(form, yes);
378 } else {
379 yes = makeButton((width - 16) / 3, height - 1 - buttonHeight, "Yes");
380 no = makeButton(((width - 16) / 3) * 2 + 9, height - 1 - buttonHeight,
381 "No");
382 newtFormAddComponents(form, yes, no, NULL);
383
384 if (flags & FLAG_DEFAULT_NO)
385 newtFormSetCurrent(form, no);
386 }
387
388 newtRunForm(form);
389 answer = newtFormGetCurrent(form);
390
391 if (answer == no)
392 return DLG_CANCEL;
393
394 return DLG_OKAY;
395 }
396
397 void useFullButtons(int state) {
398 if (state) {
399 buttonHeight = 3;
400 makeButton = newtButton;
401 } else {
402 buttonHeight = 1;
403 makeButton = newtCompactButton;
404 }
405 }