]>
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; | |
68 | int noCancel = 0; | |
69 | int noItem = 0; | |
70 | int scrollText = 0; | |
71 | int rc = 0; | |
72 | int flags = 0; | |
73 | int defaultNo = 0; | |
b3ddfdd7 | 74 | const char * result; |
75 | const char ** selections, ** next; | |
649a0152 | 76 | char * title = NULL; |
feef2cb5 | 77 | char *default_item = NULL; |
649a0152 | 78 | struct poptOption optionsTable[] = { |
6f481af2 | 79 | { "checklist", '\0', 0, 0, OPT_CHECKLIST }, |
80 | { "defaultno", '\0', 0, &defaultNo, 0 }, | |
81 | { "inputbox", '\0', 0, 0, OPT_INPUTBOX }, | |
82 | { "menu", '\0', 0, 0, OPT_MENU }, | |
83 | { "msgbox", '\0', 0, 0, OPT_MSGBOX }, | |
84 | { "nocancel", '\0', 0, &noCancel, 0 }, | |
85 | { "noitem", '\0', 0, &noItem, 0 }, | |
86 | { "radiolist", '\0', 0, 0, OPT_RADIOLIST }, | |
87 | { "scrolltext", '\0', 0, &scrollText, 0 }, | |
88 | { "title", '\0', POPT_ARG_STRING, &title, 0 }, | |
feef2cb5 | 89 | { "default-item", '\0', POPT_ARG_STRING, &default_item, 0 }, |
6f481af2 | 90 | { "yesno", '\0', 0, 0, OPT_YESNO }, |
91 | { 0, 0, 0, 0, 0 } | |
649a0152 | 92 | }; |
feef2cb5 | 93 | |
1eda60fb | 94 | #ifdef ENABLE_NLS |
feef2cb5 | 95 | setlocale (LC_ALL, ""); |
96 | bindtextdomain (PACKAGE, LOCALEDIR); | |
97 | textdomain (PACKAGE); | |
1eda60fb | 98 | #endif |
feef2cb5 | 99 | |
649a0152 | 100 | optCon = poptGetContext("whiptcl", argc, argv, optionsTable, 0); |
101 | ||
102 | while ((arg = poptGetNextOpt(optCon)) > 0) { | |
6f481af2 | 103 | optArg = poptGetOptArg(optCon); |
104 | ||
105 | switch (arg) { | |
106 | case OPT_MENU: | |
107 | if (mode != MODE_NONE) rc = -1; | |
108 | mode = MODE_MENU; | |
109 | break; | |
110 | ||
111 | case OPT_MSGBOX: | |
112 | if (mode != MODE_NONE) rc = -1; | |
113 | mode = MODE_MSGBOX; | |
114 | break; | |
115 | ||
116 | case OPT_RADIOLIST: | |
117 | if (mode != MODE_NONE) rc = -1; | |
118 | mode = MODE_RADIOLIST; | |
119 | break; | |
120 | ||
121 | case OPT_CHECKLIST: | |
122 | if (mode != MODE_NONE) rc = -1; | |
123 | mode = MODE_CHECKLIST; | |
124 | break; | |
125 | ||
126 | case OPT_YESNO: | |
127 | if (mode != MODE_NONE) rc = -1; | |
128 | mode = MODE_YESNO; | |
129 | break; | |
130 | ||
131 | case OPT_INPUTBOX: | |
132 | if (mode != MODE_NONE) rc = -1; | |
133 | mode = MODE_INPUTBOX; | |
134 | break; | |
135 | } | |
649a0152 | 136 | } |
137 | ||
138 | if (arg < -1) { | |
6f481af2 | 139 | /* this could buffer oveflow, bug we're not setuid so I don't care */ |
140 | interp->result = malloc(200); | |
141 | interp->freeProc = TCL_DYNAMIC; | |
142 | sprintf(interp->result, "%s: %s\n", | |
143 | poptBadOption(optCon, POPT_BADOPTION_NOALIAS), | |
144 | poptStrerror(arg)); | |
145 | ||
146 | return TCL_ERROR; | |
649a0152 | 147 | } |
148 | ||
149 | if (mode == MODE_NONE) { | |
6f481af2 | 150 | interp->result = "no dialog mode was specified"; |
151 | return TCL_ERROR; | |
649a0152 | 152 | } else if (rc) { |
6f481af2 | 153 | interp->result = "multiple modes were specified"; |
154 | return TCL_ERROR; | |
649a0152 | 155 | } |
156 | ||
157 | if (!(text = poptGetArg(optCon))) { | |
6f481af2 | 158 | interp->result = "missing text parameter"; |
159 | return TCL_ERROR; | |
649a0152 | 160 | } |
161 | ||
162 | if (!(nextArg = poptGetArg(optCon))) { | |
6f481af2 | 163 | interp->result = "height missing"; |
164 | return TCL_ERROR; | |
649a0152 | 165 | } |
166 | height = strtoul(nextArg, &end, 10); | |
167 | if (*end) { | |
6f481af2 | 168 | interp->result = "height is not a number"; |
169 | return TCL_ERROR; | |
649a0152 | 170 | } |
171 | ||
172 | if (!(nextArg = poptGetArg(optCon))) { | |
6f481af2 | 173 | interp->result = "width missing"; |
174 | return TCL_ERROR; | |
649a0152 | 175 | } |
176 | width = strtoul(nextArg, &end, 10); | |
177 | if (*end) { | |
6f481af2 | 178 | interp->result = "width is not a number"; |
179 | return TCL_ERROR; | |
649a0152 | 180 | } |
181 | ||
182 | width -= 2; | |
183 | height -= 2; | |
184 | newtOpenWindow((80 - width) / 2, (24 - height) / 2, width, height, title); | |
185 | ||
186 | if (noCancel) flags |= FLAG_NOCANCEL; | |
187 | if (noItem) flags |= FLAG_NOITEM; | |
188 | if (scrollText) flags |= FLAG_SCROLL_TEXT; | |
189 | if (defaultNo) flags |= FLAG_DEFAULT_NO; | |
190 | ||
191 | switch (mode) { | |
192 | case MODE_MSGBOX: | |
6f481af2 | 193 | rc = messageBox(text, height, width, MSGBOX_MSG, flags); |
194 | break; | |
649a0152 | 195 | |
196 | case MODE_YESNO: | |
6f481af2 | 197 | rc = messageBox(text, height, width, MSGBOX_YESNO, flags); |
198 | if (rc == DLG_OKAY) | |
199 | interp->result = "yes"; | |
200 | else | |
201 | interp->result = "no"; | |
202 | if (rc == DLG_ERROR) rc = 0; | |
203 | break; | |
649a0152 | 204 | |
205 | case MODE_INPUTBOX: | |
6f481af2 | 206 | rc = inputBox(text, height, width, optCon, flags, &result); |
feef2cb5 | 207 | if (rc ==DLG_OKAY) { |
6f481af2 | 208 | interp->result = strdup(result); |
209 | interp->freeProc = TCL_DYNAMIC; | |
210 | } | |
211 | break; | |
649a0152 | 212 | |
213 | case MODE_MENU: | |
feef2cb5 | 214 | rc = listBox(text, height, width, optCon, flags, default_item, &result); |
215 | if (rc==DLG_OKAY) { | |
6f481af2 | 216 | interp->result = strdup(result); |
217 | interp->freeProc = TCL_DYNAMIC; | |
218 | } | |
219 | break; | |
649a0152 | 220 | |
221 | case MODE_RADIOLIST: | |
6f481af2 | 222 | rc = checkList(text, height, width, optCon, 1, flags, &selections); |
feef2cb5 | 223 | if (rc==DLG_OKAY) { |
6f481af2 | 224 | interp->result = strdup(selections[0]); |
225 | interp->freeProc = TCL_DYNAMIC; | |
226 | } | |
227 | break; | |
649a0152 | 228 | |
229 | case MODE_CHECKLIST: | |
6f481af2 | 230 | rc = checkList(text, height, width, optCon, 0, flags, &selections); |
649a0152 | 231 | |
feef2cb5 | 232 | if (rc==DLG_OKAY) { |
6f481af2 | 233 | for (next = selections; *next; next++) |
234 | Tcl_AppendElement(interp, *next); | |
649a0152 | 235 | |
6f481af2 | 236 | free(selections); |
237 | } | |
238 | break; | |
649a0152 | 239 | |
240 | case MODE_NONE: | |
4e66d95a | 241 | ; /* this can't happen */ |
b3ddfdd7 | 242 | break; |
649a0152 | 243 | } |
244 | ||
245 | newtPopWindow(); | |
246 | ||
247 | if (rc == DLG_ERROR) { | |
6f481af2 | 248 | interp->result = "bad paramter for whiptcl dialog box"; |
249 | return TCL_ERROR; | |
649a0152 | 250 | } |
251 | ||
252 | Tcl_SetVar(interp, "whiptcl_canceled", (rc == DLG_CANCEL) ? "1" : "0", | |
6f481af2 | 253 | 0); |
feef2cb5 | 254 | Tcl_SetVar(interp, "whiptcl_escaped", (rc == DLG_ESCAPE) ? "1" : "0", |
255 | 0); | |
649a0152 | 256 | |
257 | return TCL_OK; | |
258 | } | |
259 | ||
260 | static char * setBacktext(ClientData data, Tcl_Interp * interp, | |
4e66d95a | 261 | const char * name1, const char * name2, int flags) { |
649a0152 | 262 | static char blankLine[81] = " " |
263 | " "; | |
264 | ||
265 | newtDrawRootText(0, 0, blankLine); | |
266 | newtDrawRootText(0, 0, Tcl_GetVar(interp, "whiptcl_backtext", | |
6f481af2 | 267 | TCL_GLOBAL_ONLY)); |
649a0152 | 268 | |
269 | return NULL; | |
270 | } | |
271 | ||
272 | static char * setHelptext(ClientData data, Tcl_Interp * interp, | |
4e66d95a ML |
273 | const char * name1, const char * name2, int flags) { |
274 | const char * text = Tcl_GetVar(interp, "whiptcl_helpline", TCL_GLOBAL_ONLY); | |
649a0152 | 275 | |
276 | if (!text) | |
6f481af2 | 277 | text = ""; |
649a0152 | 278 | else if (!strlen(text)) |
6f481af2 | 279 | text = NULL; |
649a0152 | 280 | |
281 | newtPopHelpLine(); | |
282 | newtPushHelpLine(text); | |
283 | ||
284 | return NULL; | |
285 | } | |
286 | ||
287 | static char * setFullButtons(ClientData data, Tcl_Interp * interp, | |
4e66d95a ML |
288 | const char * name1, const char * name2, int flags) { |
289 | const char * val = Tcl_GetVar(interp, "whiptcl_fullbuttons", TCL_GLOBAL_ONLY); | |
649a0152 | 290 | int rc; |
291 | int state; | |
292 | ||
293 | if ((rc = Tcl_ExprBoolean(interp, val, &state))) { | |
6f481af2 | 294 | Tcl_FreeResult(interp); |
295 | return "whiptcl_fullbuttons may only contain a boolean value"; | |
649a0152 | 296 | } |
297 | ||
298 | useFullButtons(state); | |
299 | ||
300 | return NULL; | |
301 | } | |
302 | ||
303 | int Whiptcl_Init(Tcl_Interp * interp) { | |
304 | Tcl_CreateCommand(interp, "whiptcl_finish", wtFinish, NULL, NULL); | |
305 | Tcl_CreateCommand(interp, "whiptcl_init", wtInit, NULL, NULL); | |
b3ddfdd7 | 306 | Tcl_CreateCommand(interp, "whiptcl_cmd", (Tcl_CmdProc *) wtCmd, NULL, NULL); |
649a0152 | 307 | |
4e66d95a ML |
308 | Tcl_PkgProvide(interp, "Whip", VERSION); |
309 | ||
649a0152 | 310 | return TCL_OK; |
311 | } |