]>
Commit | Line | Data |
---|---|---|
feef2cb5 | 1 | #include "config.h" |
649a0152 | 2 | #include <string.h> |
3 | #include <stdlib.h> | |
4 | ||
feef2cb5 | 5 | #include "nls.h" |
649a0152 | 6 | #include "dialogboxes.h" |
7 | #include "newt.h" | |
4e66d95a ML |
8 | #include <popt.h> |
9 | #include <tcl.h> | |
649a0152 | 10 | |
11 | enum mode { MODE_NONE, MODE_MSGBOX, MODE_YESNO, MODE_CHECKLIST, MODE_INPUTBOX, | |
6f481af2 | 12 | MODE_RADIOLIST, MODE_MENU }; |
649a0152 | 13 | |
6f481af2 | 14 | #define OPT_MSGBOX 1000 |
15 | #define OPT_CHECKLIST 1001 | |
16 | #define OPT_YESNO 1002 | |
17 | #define OPT_INPUTBOX 1003 | |
18 | #define OPT_MENU 1005 | |
19 | #define OPT_RADIOLIST 1006 | |
649a0152 | 20 | |
21 | static char * setBacktext(ClientData data, Tcl_Interp * interp, | |
4e66d95a | 22 | const char * name1, const char * name2, int flags); |
649a0152 | 23 | static char * setHelptext(ClientData data, Tcl_Interp * interp, |
4e66d95a | 24 | const char * name1, const char * name2, int flags); |
649a0152 | 25 | static char * setFullButtons(ClientData data, Tcl_Interp * interp, |
4e66d95a | 26 | const char * name1, const char * name2, int flags); |
649a0152 | 27 | |
28 | static int wtFinish(ClientData clientData, Tcl_Interp * interp, int argc, | |
4e66d95a | 29 | const char ** argv) { |
649a0152 | 30 | newtFinished(); |
31 | ||
32 | return TCL_OK; | |
33 | } | |
34 | ||
35 | static int wtInit(ClientData clientData, Tcl_Interp * interp, int argc, | |
4e66d95a | 36 | const char ** argv) { |
649a0152 | 37 | newtInit(); |
38 | newtCls(); | |
39 | ||
40 | newtPushHelpLine(""); | |
41 | ||
42 | Tcl_TraceVar(interp, "whiptcl_backtext", | |
6f481af2 | 43 | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, setBacktext, NULL); |
649a0152 | 44 | Tcl_TraceVar(interp, "whiptcl_helpline", |
6f481af2 | 45 | TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, |
46 | setHelptext, NULL); | |
649a0152 | 47 | Tcl_TraceVar(interp, "whiptcl_fullbuttons", |
6f481af2 | 48 | TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, |
49 | setFullButtons, NULL); | |
649a0152 | 50 | |
51 | Tcl_SetVar(interp, "whiptcl_helpline", "", TCL_GLOBAL_ONLY); | |
52 | Tcl_SetVar(interp, "whiptcl_fullbuttons", "1", TCL_GLOBAL_ONLY); | |
53 | ||
54 | return TCL_OK; | |
55 | } | |
56 | ||
57 | static int wtCmd(ClientData clientData, Tcl_Interp * interp, int argc, | |
b3ddfdd7 | 58 | const char ** argv) { |
649a0152 | 59 | enum mode mode = MODE_NONE; |
60 | poptContext optCon; | |
61 | int arg; | |
eb0a0545 | 62 | const char * optArg; |
63 | const char * text; | |
64 | const char * nextArg; | |
649a0152 | 65 | char * end; |
66 | int height; | |
67 | int width; | |
9c4eb622 | 68 | int listHeight; |
649a0152 | 69 | int noCancel = 0; |
70 | int noItem = 0; | |
71 | int scrollText = 0; | |
72 | int rc = 0; | |
73 | int flags = 0; | |
74 | int defaultNo = 0; | |
f40f18ae ML |
75 | char * result; |
76 | char ** selections, ** next; | |
649a0152 | 77 | char * title = NULL; |
feef2cb5 | 78 | char *default_item = NULL; |
649a0152 | 79 | struct poptOption optionsTable[] = { |
6f481af2 | 80 | { "checklist", '\0', 0, 0, OPT_CHECKLIST }, |
81 | { "defaultno", '\0', 0, &defaultNo, 0 }, | |
82 | { "inputbox", '\0', 0, 0, OPT_INPUTBOX }, | |
83 | { "menu", '\0', 0, 0, OPT_MENU }, | |
84 | { "msgbox", '\0', 0, 0, OPT_MSGBOX }, | |
85 | { "nocancel", '\0', 0, &noCancel, 0 }, | |
86 | { "noitem", '\0', 0, &noItem, 0 }, | |
87 | { "radiolist", '\0', 0, 0, OPT_RADIOLIST }, | |
88 | { "scrolltext", '\0', 0, &scrollText, 0 }, | |
89 | { "title", '\0', POPT_ARG_STRING, &title, 0 }, | |
feef2cb5 | 90 | { "default-item", '\0', POPT_ARG_STRING, &default_item, 0 }, |
6f481af2 | 91 | { "yesno", '\0', 0, 0, OPT_YESNO }, |
92 | { 0, 0, 0, 0, 0 } | |
649a0152 | 93 | }; |
feef2cb5 | 94 | |
1eda60fb | 95 | #ifdef ENABLE_NLS |
feef2cb5 | 96 | setlocale (LC_ALL, ""); |
97 | bindtextdomain (PACKAGE, LOCALEDIR); | |
98 | textdomain (PACKAGE); | |
1eda60fb | 99 | #endif |
feef2cb5 | 100 | |
649a0152 | 101 | optCon = poptGetContext("whiptcl", argc, argv, optionsTable, 0); |
102 | ||
103 | while ((arg = poptGetNextOpt(optCon)) > 0) { | |
6f481af2 | 104 | optArg = poptGetOptArg(optCon); |
105 | ||
106 | switch (arg) { | |
107 | case OPT_MENU: | |
108 | if (mode != MODE_NONE) rc = -1; | |
109 | mode = MODE_MENU; | |
110 | break; | |
111 | ||
112 | case OPT_MSGBOX: | |
113 | if (mode != MODE_NONE) rc = -1; | |
114 | mode = MODE_MSGBOX; | |
115 | break; | |
116 | ||
117 | case OPT_RADIOLIST: | |
118 | if (mode != MODE_NONE) rc = -1; | |
119 | mode = MODE_RADIOLIST; | |
120 | break; | |
121 | ||
122 | case OPT_CHECKLIST: | |
123 | if (mode != MODE_NONE) rc = -1; | |
124 | mode = MODE_CHECKLIST; | |
125 | break; | |
126 | ||
127 | case OPT_YESNO: | |
128 | if (mode != MODE_NONE) rc = -1; | |
129 | mode = MODE_YESNO; | |
130 | break; | |
131 | ||
132 | case OPT_INPUTBOX: | |
133 | if (mode != MODE_NONE) rc = -1; | |
134 | mode = MODE_INPUTBOX; | |
135 | break; | |
136 | } | |
649a0152 | 137 | } |
138 | ||
139 | if (arg < -1) { | |
6f481af2 | 140 | /* this could buffer oveflow, bug we're not setuid so I don't care */ |
141 | interp->result = malloc(200); | |
142 | interp->freeProc = TCL_DYNAMIC; | |
143 | sprintf(interp->result, "%s: %s\n", | |
144 | poptBadOption(optCon, POPT_BADOPTION_NOALIAS), | |
145 | poptStrerror(arg)); | |
146 | ||
147 | return TCL_ERROR; | |
649a0152 | 148 | } |
149 | ||
150 | if (mode == MODE_NONE) { | |
6f481af2 | 151 | interp->result = "no dialog mode was specified"; |
152 | return TCL_ERROR; | |
649a0152 | 153 | } else if (rc) { |
6f481af2 | 154 | interp->result = "multiple modes were specified"; |
155 | return TCL_ERROR; | |
649a0152 | 156 | } |
157 | ||
158 | if (!(text = poptGetArg(optCon))) { | |
6f481af2 | 159 | interp->result = "missing text parameter"; |
160 | return TCL_ERROR; | |
649a0152 | 161 | } |
162 | ||
163 | if (!(nextArg = poptGetArg(optCon))) { | |
6f481af2 | 164 | interp->result = "height missing"; |
165 | return TCL_ERROR; | |
649a0152 | 166 | } |
167 | height = strtoul(nextArg, &end, 10); | |
168 | if (*end) { | |
6f481af2 | 169 | interp->result = "height is not a number"; |
170 | return TCL_ERROR; | |
649a0152 | 171 | } |
172 | ||
173 | if (!(nextArg = poptGetArg(optCon))) { | |
6f481af2 | 174 | interp->result = "width missing"; |
175 | return TCL_ERROR; | |
649a0152 | 176 | } |
177 | width = strtoul(nextArg, &end, 10); | |
178 | if (*end) { | |
6f481af2 | 179 | interp->result = "width is not a number"; |
180 | return TCL_ERROR; | |
649a0152 | 181 | } |
182 | ||
9c4eb622 ML |
183 | switch (mode) { |
184 | case MODE_MENU: | |
185 | case MODE_RADIOLIST: | |
186 | case MODE_CHECKLIST: | |
187 | if (!(nextArg = poptGetArg(optCon))) { | |
188 | interp->result = "list-height missing"; | |
189 | return TCL_ERROR; | |
190 | } | |
191 | listHeight = strtoul(nextArg, &end, 10); | |
192 | if (*end) { | |
193 | interp->result = "list-height is not a number"; | |
194 | return TCL_ERROR; | |
195 | } | |
196 | break; | |
197 | } | |
198 | ||
649a0152 | 199 | width -= 2; |
200 | height -= 2; | |
201 | newtOpenWindow((80 - width) / 2, (24 - height) / 2, width, height, title); | |
202 | ||
203 | if (noCancel) flags |= FLAG_NOCANCEL; | |
204 | if (noItem) flags |= FLAG_NOITEM; | |
205 | if (scrollText) flags |= FLAG_SCROLL_TEXT; | |
206 | if (defaultNo) flags |= FLAG_DEFAULT_NO; | |
207 | ||
208 | switch (mode) { | |
209 | case MODE_MSGBOX: | |
6f481af2 | 210 | rc = messageBox(text, height, width, MSGBOX_MSG, flags); |
211 | break; | |
649a0152 | 212 | |
213 | case MODE_YESNO: | |
6f481af2 | 214 | rc = messageBox(text, height, width, MSGBOX_YESNO, flags); |
215 | if (rc == DLG_OKAY) | |
216 | interp->result = "yes"; | |
217 | else | |
218 | interp->result = "no"; | |
219 | if (rc == DLG_ERROR) rc = 0; | |
220 | break; | |
649a0152 | 221 | |
222 | case MODE_INPUTBOX: | |
6f481af2 | 223 | rc = inputBox(text, height, width, optCon, flags, &result); |
feef2cb5 | 224 | if (rc ==DLG_OKAY) { |
f40f18ae | 225 | interp->result = result; |
6f481af2 | 226 | interp->freeProc = TCL_DYNAMIC; |
227 | } | |
228 | break; | |
649a0152 | 229 | |
230 | case MODE_MENU: | |
9c4eb622 ML |
231 | rc = listBox(text, height, width, listHeight, optCon, flags, default_item, |
232 | &result); | |
feef2cb5 | 233 | if (rc==DLG_OKAY) { |
f40f18ae | 234 | interp->result = result; |
6f481af2 | 235 | interp->freeProc = TCL_DYNAMIC; |
236 | } | |
237 | break; | |
649a0152 | 238 | |
239 | case MODE_RADIOLIST: | |
9c4eb622 ML |
240 | rc = checkList(text, height, width, listHeight, optCon, 1, flags, |
241 | &selections); | |
feef2cb5 | 242 | if (rc==DLG_OKAY) { |
f40f18ae | 243 | interp->result = selections[0]; |
6f481af2 | 244 | interp->freeProc = TCL_DYNAMIC; |
f40f18ae ML |
245 | |
246 | free(selections); | |
6f481af2 | 247 | } |
248 | break; | |
649a0152 | 249 | |
250 | case MODE_CHECKLIST: | |
9c4eb622 ML |
251 | rc = checkList(text, height, width, listHeight, optCon, 0, flags, |
252 | &selections); | |
649a0152 | 253 | |
feef2cb5 | 254 | if (rc==DLG_OKAY) { |
6f481af2 | 255 | for (next = selections; *next; next++) |
256 | Tcl_AppendElement(interp, *next); | |
649a0152 | 257 | |
6f481af2 | 258 | free(selections); |
259 | } | |
260 | break; | |
649a0152 | 261 | |
262 | case MODE_NONE: | |
4e66d95a | 263 | ; /* this can't happen */ |
b3ddfdd7 | 264 | break; |
649a0152 | 265 | } |
266 | ||
267 | newtPopWindow(); | |
268 | ||
269 | if (rc == DLG_ERROR) { | |
6f481af2 | 270 | interp->result = "bad paramter for whiptcl dialog box"; |
271 | return TCL_ERROR; | |
649a0152 | 272 | } |
273 | ||
274 | Tcl_SetVar(interp, "whiptcl_canceled", (rc == DLG_CANCEL) ? "1" : "0", | |
6f481af2 | 275 | 0); |
feef2cb5 | 276 | Tcl_SetVar(interp, "whiptcl_escaped", (rc == DLG_ESCAPE) ? "1" : "0", |
277 | 0); | |
649a0152 | 278 | |
279 | return TCL_OK; | |
280 | } | |
281 | ||
282 | static char * setBacktext(ClientData data, Tcl_Interp * interp, | |
4e66d95a | 283 | const char * name1, const char * name2, int flags) { |
649a0152 | 284 | static char blankLine[81] = " " |
285 | " "; | |
286 | ||
287 | newtDrawRootText(0, 0, blankLine); | |
288 | newtDrawRootText(0, 0, Tcl_GetVar(interp, "whiptcl_backtext", | |
6f481af2 | 289 | TCL_GLOBAL_ONLY)); |
649a0152 | 290 | |
291 | return NULL; | |
292 | } | |
293 | ||
294 | static char * setHelptext(ClientData data, Tcl_Interp * interp, | |
4e66d95a ML |
295 | const char * name1, const char * name2, int flags) { |
296 | const char * text = Tcl_GetVar(interp, "whiptcl_helpline", TCL_GLOBAL_ONLY); | |
649a0152 | 297 | |
298 | if (!text) | |
6f481af2 | 299 | text = ""; |
649a0152 | 300 | else if (!strlen(text)) |
6f481af2 | 301 | text = NULL; |
649a0152 | 302 | |
303 | newtPopHelpLine(); | |
304 | newtPushHelpLine(text); | |
305 | ||
306 | return NULL; | |
307 | } | |
308 | ||
309 | static char * setFullButtons(ClientData data, Tcl_Interp * interp, | |
4e66d95a ML |
310 | const char * name1, const char * name2, int flags) { |
311 | const char * val = Tcl_GetVar(interp, "whiptcl_fullbuttons", TCL_GLOBAL_ONLY); | |
649a0152 | 312 | int rc; |
313 | int state; | |
314 | ||
315 | if ((rc = Tcl_ExprBoolean(interp, val, &state))) { | |
6f481af2 | 316 | Tcl_FreeResult(interp); |
317 | return "whiptcl_fullbuttons may only contain a boolean value"; | |
649a0152 | 318 | } |
319 | ||
320 | useFullButtons(state); | |
321 | ||
322 | return NULL; | |
323 | } | |
324 | ||
325 | int Whiptcl_Init(Tcl_Interp * interp) { | |
326 | Tcl_CreateCommand(interp, "whiptcl_finish", wtFinish, NULL, NULL); | |
327 | Tcl_CreateCommand(interp, "whiptcl_init", wtInit, NULL, NULL); | |
b3ddfdd7 | 328 | Tcl_CreateCommand(interp, "whiptcl_cmd", (Tcl_CmdProc *) wtCmd, NULL, NULL); |
649a0152 | 329 | |
4e66d95a ML |
330 | Tcl_PkgProvide(interp, "Whip", VERSION); |
331 | ||
649a0152 | 332 | return TCL_OK; |
333 | } |