5 #include <X11/StringDefs.h>
6 #include <X11/Intrinsic.h>
7 #include <X11/IntrinsicP.h>
10 #include <X11/CompositeP.h>
11 #include <X11/cursorfont.h>
16 static char rcsid[] = "$Header$";
18 void extra_help_callback();
19 extern EntryForm *MoiraForms[];
21 static Widget logwidget = NULL;
24 /* No-op action to mask built-in actions */
26 void noopACT(w, event, p, n)
35 /* Action to do a moira retrieve on what was clicked at */
37 void moiraRetrieveACT(w, event, p, n)
46 be = (XButtonEvent *)event;
48 pos = XmTextXYToPos(w, be->x, be->y);
49 DoMoiraSelect(pos, w, 0);
53 /* Action to modify the moira object that was clicked on */
55 void moiraModifyACT(w, event, p, n)
64 be = (XButtonEvent *)event;
66 pos = XmTextXYToPos(w, be->x, be->y);
67 DoMoiraSelect(pos, w, 1);
71 static XtActionsRec myactions[] = {
72 { "moiraRetrieve", moiraRetrieveACT },
73 { "moiraModify", moiraModifyACT },
78 /* These are the additional translations added to the Motif text widget
79 * for the log window. The two noop translations are here to avoid
80 * nasty interactions with the selection mechanism. They match the
81 * existing translations that involve shifted mouse buttons.
84 #define newtrans "~Ctrl Shift ~Meta ~Alt<Btn1Down>: moiraRetrieve()\n\
85 ~Ctrl ~Meta ~Alt<Btn1Up>: noop()\n\
86 ~Ctrl Shift ~Meta ~Alt<Btn1Motion>: noop()\n\
87 ~Ctrl Shift ~Meta ~Alt<Btn2Down>: moiraModify()"
90 /* Create the log window, and setup the translation table to taking
95 SetupLogWidget(parent)
100 XtTranslations trans;
106 XtSetArg(wargs[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
107 XtSetArg(wargs[n], XmNeditable, False); n++;
109 logwidget = XmCreateScrolledText( parent,
112 XtManageChild(logwidget);
114 XtAppAddActions(XtWidgetToApplicationContext(logwidget),
115 myactions, XtNumber(myactions));
116 trans = XtParseTranslationTable(newtrans);
117 XtOverrideTranslations(logwidget, trans);
122 /* This actually does all of the work for handling mouse clicks. It
123 * finds the surrounding text and decides what to do with the click,
124 * the actually starts the moira query or pops up the form.
127 static DoMoiraSelect(pos, w, modify)
132 char *log, *p, *p1, *p2;
133 char name[256], type[256], type2[256];
135 log = XmTextGetString(w);
136 for (p = &log[pos]; p > log; p--)
137 if (isspace(*p) || *p == ':') break;
139 /* p now points to the beginning of the word on which the mouse was
140 * clicked. Begin gross hacking to find the name and type of object.
145 while (*p1 && !isspace(*p1)) *p2++ = *p1++;
147 /* backup two words before for type2 */
148 while (p >= log && isspace(*p) || *p == ':') p--;
149 while (p >= log && !isspace(*p)) p--;
150 while (p >= log && isspace(*p)) p--;
151 while (p >= log && !isspace(*p)) p--;
156 while (!isspace(*p)) *p2++ = *p++;
158 /* skip additional whitespace */
159 while (isspace(*p)) p++;
161 /* get type & rest of type2 */
163 while (*p && *p != ':' && !isspace(*p)) *p2++ = *p1++ = *p++;
167 printf("name \"%s\", type \"%s\" type2 \"%s\"\n", name, type, type2);
169 if (!strcasecmp(type, "USER") ||
170 !strcmp(type, "name") ||
171 !strcmp(type2, "Modified by") ||
172 !strcmp(type2, "User Ownership") ||
173 !strcmp(type2, "Login name") ||
174 !strcmp(type, "login")) {
175 DoReference(name, "select_user", MM_MOD_USER, MM_SHOW_USER,
176 "get_user_account_by_login", modify);
177 } else if (!strcasecmp(type, "LIST") ||
178 !strcmp(type2, "Group Ownership")) {
179 DoReference(name, "select_list", MM_MOD_LIST, MM_SHOW_LIST,
180 "get_list_info", modify);
181 } else if (!strcasecmp(type, "MACHINE") ||
182 !strcmp(type, "host") ||
183 !strcmp(type, "Server") ||
184 !strcmp(type, "on") ||
185 !strcmp(type, "Box")) {
186 DoReference(name, "select_machine", MM_MOD_MACH, MM_SHOW_MACH,
187 "get_machine", modify);
188 } else if (!strcasecmp(type, "CLUSTER")) {
189 DoReference(name, "select_cluster", MM_MOD_CLUSTER, MM_SHOW_CLUSTER,
190 "get_cluster", modify);
191 } else if (!strcasecmp(type, "FILESYSTEM") ||
192 !strcmp(type, "FILESYS") ||
193 !strcmp(type2, "syslib Data")) {
194 DoReference(name, "select_filsys", MM_MOD_FILSYS, MM_SHOW_FILSYS,
195 "get_filesys_by_label", modify);
196 } else if (!strcmp(type, "Printer") ||
197 !strcmp(type2, "lpr Data")) {
198 DoReference(name, "select_printer", MM_MOD_PCAP, MM_SHOW_PCAP,
199 "get_printcap_entry", modify);
201 XBell(XtDisplay(w), 100);
207 /* This is the heart of handling the reference once we have found out
208 * what type of reference it is.
211 static DoReference(name, formname, modop, showop, query, modify)
221 char *argv[2], **aargv;
225 form = GetAndClearForm(formname);
226 StoreField(form, 0, name);
231 MoiraFormApply(0, form);
234 if (showop == MM_SHOW_FILSYS) f.extrastuff = (caddr_t) sq_create();
236 m.operation = showop;
237 status = MoiraQuery(query, 1, argv, DisplayCallback, &f);
238 if (showop == MM_SHOW_FILSYS) {
239 while (sq_get_data(f.extrastuff, &aargv)) {
242 sq_destroy(f.extrastuff);
245 com_err(program_name, status, " while looking up data");
253 ** PopupErrorMessage(text)
255 ** Given a char* pointing to an error message, possibly with imbedded
256 ** newlines, display the text in a popup window and put two buttons
257 ** at the bottom of the window, labelled "OK" and "Cancel." Pop down
258 ** when one of the buttons is pressed.
260 ** Return 0 if "OK" is pressed, 1 for "Cancel."
264 PopupErrorMessage(text, extrahelp)
271 static XmString label;
275 XtDestroyWidget(child);
279 label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
282 XtSetArg(wargs[n], XmNmessageString, label); n++;
284 child = (Widget) XmCreateErrorDialog(logwidget, "errormessage", wargs, n);
286 XtAddCallback (child, XmNhelpCallback, extra_help_callback, extrahelp);
288 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
289 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
290 XtManageChild(child);
294 ** PopupHelpWindow(text)
296 ** Given a char* pointing to an help message, possibly with imbedded
297 ** newlines, display the text in a popup window and put a single button
298 ** at the bottom of the window, labelled "OK." Pop down when the
299 ** the buttons is pressed.
303 PopupHelpWindow(text)
310 static XmString label;
313 XtDestroyWidget(child);
316 label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
319 XtSetArg(wargs[n], XmNmessageString, label); n++;
321 child = (Widget) XmCreateMessageDialog(logwidget, "helpmessage", wargs, n);
322 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
323 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
325 XtManageChild(child);
329 ** Given a char* to a single line of text, append this line at the bottom
330 ** of the log window. Return 0 of the append was sucessful, non-zero
331 ** for an error condition.
341 string = XmTextGetString(logwidget);
342 pos = strlen(string);
345 XmTextReplace(logwidget, pos, pos, text);
346 XmTextSetCursorPosition(logwidget, pos + strlen(text));
347 if (pos > MAXLOGSIZE) {
348 for (p = &string[pos - MAXLOGSIZE]; *p && *p != '\n'; p++);
351 XmTextReplace(logwidget, 0, pos, "");
356 MakeWatchCursor(topW)
359 static Cursor mycursor = NULL;
366 mycursor = XCreateFontCursor (XtDisplay(topW), XC_watch);
368 XDefineCursor(XtDisplay(topW), XtWindow(topW), mycursor);
369 for (fp = MoiraForms; *fp; fp++)
370 if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
371 XDefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer), mycursor);
375 MakeNormalCursor(topW)
383 XUndefineCursor(XtDisplay(topW), XtWindow(topW));
384 for (fp = MoiraForms; *fp; fp++)
385 if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
386 XUndefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer));
390 ** Move through the fields of the spec and make certain that the
391 ** form's widgets actually reflect the current values.
398 UserPrompt **myinputlines = spec->inputlines;
404 if (spec->formpointer == NULL) return;
406 for ( current = (*myinputlines);
408 myinputlines++, current = (*myinputlines)) {
410 if (current->changed) {
412 XtSetArg(wargs[n], XmNsensitive,
413 current->insensitive ? False : True); n++;
414 XtSetValues(current->mywidget, wargs, n);
415 current->changed = False;
418 switch (current->type) {
420 if (current->returnvalue.stringvalue) {
421 XmTextSetString (current->mywidget, current->returnvalue.stringvalue);
427 XtSetArg(wargs[n], XmNset,
428 current->returnvalue.booleanvalue ? True : False); n++;
429 XtSetValues (current->mywidget, wargs, n);
433 kidcount = ((CompositeRec *)(current->mywidget))->
434 composite.num_children;
438 kid = ((CompositeRec *)(current->mywidget))->
439 composite.children[kidcount];
440 if (current->returnvalue.stringvalue &&
441 (!strcmp (XtName(kid), current->returnvalue.stringvalue))) {
442 XtSetArg(wargs[n], XmNset, True);
446 XtSetArg(wargs[n], XmNset, False);
449 XtSetValues (kid, wargs, n);
457 XtSetArg(wargs[n], XtNsensitive, !(current->insensitive)); n++;
458 XtSetValues (current->mywidget, wargs, n);
463 extra_help_callback(w, client_data, call_data)
466 XmAnyCallbackStruct *call_data;
472 int write_log_to_file(fn)
475 char *string, buf[256];
479 string = XmTextGetString(logwidget);
480 fd = open(fn, O_WRONLY|O_CREAT, 0666);
482 sprintf(buf, "opening output file \"%s\"", fn);
483 com_err(program_name, errno, buf);
486 if ((i = write(fd, string, strlen(string))) < 0) {
487 sprintf(buf, "writing output file \"%s\"", fn);
488 com_err(program_name, errno, buf);
491 if ((i = close(fd)) < 0) {
492 sprintf(buf, "closing output file \"%s\"", fn);
493 com_err(program_name, errno, buf);
500 void yesCallback(w, ret, dummy)
505 int *ip = (int *)ret;
509 void noCallback(w, ret, dummy)
514 int *ip = (int *)ret;
520 static XtCallbackRec yescb[] = { { yesCallback, (XtPointer) &value },
522 static XtCallbackRec nocb[] = { { noCallback, (XtPointer) &value },
525 Boolean AskQuestion(text, helpname)
526 char *text, *helpname;
531 static XmString label, yes = NULL, no;
535 yes = XmStringCreate("Yes", XmSTRING_DEFAULT_CHARSET);
536 no = XmStringCreate("No", XmSTRING_DEFAULT_CHARSET);
540 XtDestroyWidget(child);
543 label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
546 XtSetArg(wargs[n], XmNmessageString, label); n++;
547 XtSetArg(wargs[n], XmNokLabelString, yes); n++;
548 XtSetArg(wargs[n], XmNcancelLabelString, no); n++;
549 XtSetArg(wargs[n], XmNokCallback, yescb); n++;
550 XtSetArg(wargs[n], XmNcancelCallback, nocb); n++;
552 child = (Widget) XmCreateQuestionDialog(logwidget, "question", wargs, n);
554 XtAddCallback (child, XmNhelpCallback, extra_help_callback, helpname);
556 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
558 XtManageChild(child);
561 XtAppNextEvent(_XtDefaultAppContext(), &event);
562 XtDispatchEvent(&event);
572 /******* temporary ********/
576 PopupErrorMessage(msg, "no_more_help");