michael@uunet.UU.NET (Michael Wagnitz) (06/16/91)
Submitted-by: stratus!voder!nsc!berlioz.nsc.com!michael@uunet.UU.NET (Michael Wagnitz) Posting-number: Volume 13, Issue 50 Archive-name: xmail/part08 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 8 (of 11)." # Contents: actions.c # Wrapped by michael@harley on Fri May 3 13:35:52 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'actions.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'actions.c'\" else echo shar: Extracting \"'actions.c'\" \(28772 characters\) sed "s/^X//" >'actions.c' <<'END_OF_FILE' X/* X * xmail - X window system interface to the mail program X * X * Copyright 1989 The University of Texas at Austin X * X * Author: Po Cheung X * Date: March 10, 1989 X * X * Permission to use, copy, modify, and distribute this software and X * its documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation. The University of Texas at Austin makes no X * representations about the suitability of this software for any purpose. X * It is provided "as is" without express or implied warranty. X * X * Copyright 1990 by National Semiconductor Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose is hereby granted without fee, provided that X * the above copyright notice appear in all copies and that both that X * copyright notice and this permission notice appear in supporting X * documentation, and that the name of National Semiconductor Corporation not X * be used in advertising or publicity pertaining to distribution of the X * software without specific, written prior permission. X * X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" X * WITHOUT EXPRESS OR IMPLIED WARRANTY. NATIONAL SEMICONDUCTOR CORPORATION X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL, X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE X * OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR X * PERFORMANCE OF THIS SOFTWARE. X * X * The following software modules were created and are Copyrighted by X * National Semiconductor Corporation: X * X * 1. CheckInsert X * 2. DeleteChar X * 3. EraseIt: X * 4. DoCmd: X * 5. DoNothing: X * 6. DoReply: X * 7. DoSave: X * 8. DoSelected: X * 9. Folder: X * 10. Iconify: X * 11. MyNotify: X * 12. NextField: X * 13. PrintMsg: X * 14. SetAliases: X * 15. SetFolders: X * 16. SetMenu: X * 17. SetPopup: X * 18. SetSelect: and X * 19. ShowHelp. X * X * Author: Michael C. Wagnitz - National Semiconductor Corporation X * X */ X X X#include "global.h" X#include "xmailregex.h" X#include <ctype.h> X X#ifdef USE_DIRENT X#include <dirent.h> X#else X#include <sys/dir.h> X#endif X X X/* X** @(#)CheckInsert() - prevents the user from munging up the File: prompt. X** If the current insertion point is less than the minimum StartPos, move X** the insertion point to the StartPos. X*/ X/* ARGSUSED */ XXtActionProc XCheckInsert(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X if (XawTextGetInsertionPoint(w) < StartPos) X XawTextSetInsertionPoint(w, StartPos); X} /* CheckInsert */ X X X/* X** @(#)EraseIt() - Delete the specified portion of text. X*/ Xvoid XEraseIt(w, i, pos) XWidget w; XXawTextPosition i, pos; X{ X XawTextBlock textblock; X X textblock.firstPos = 0; X textblock.length = 0; X textblock.ptr = ""; X X XawTextReplace(w, i, pos, &textblock); X X XawTextSetInsertionPoint(w, i); X} /* EraseIt */ X X X/* X** @(#)DeleteChar() - prevents the user from deleting past the File: prompt. X** If the current insertion point is greater than the minimum StartPos, then X** delete the previous character. X*/ X/* ARGSUSED */ XXtActionProc XDeleteChar(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X XawTextPosition pos, i; X X pos = XawTextGetInsertionPoint(w); X if (pos > StartPos) { X i = pos - 1; X EraseIt(w, i, pos); X } X} /* DeleteChar */ X X X/* X** @(#)DeleteLine() - Deletes the entire current line from the file window. X** Simulates the action of the KILL character (ctrl-U). X*/ X/* ARGSUSED */ XXtActionProc XDeleteLine(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X XawTextPosition pos, i; X X X pos = XawTextGetInsertionPoint(w); X if (pos > StartPos) { X for (i = pos; i > StartPos && FileBuf[i - 1] != '\n'; i--); X X EraseIt(w, i, pos); X } X} /* DeleteLine */ X X X/* X** @(#)DeleteWord() - Erases the preceding word in the fileWindow buffer. X** Simulates the action of the WERASE character (ctrl-W). X*/ X/* ARGSUSED */ XXtActionProc XDeleteWord(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X XawTextPosition pos, i; X X pos = XawTextGetInsertionPoint(w); X if (pos > StartPos) { X for (i = pos; i > StartPos && FileBuf[i - 1] == ' '; i--); X for (; i > StartPos && FileBuf[i - 1] != ' '; i--); X X EraseIt(w, i, pos); X } X} /* DeleteWord */ X X X/* ARGSUSED */ X/* X** @(#)DoCmd() - send (multi-word) command to mail X*/ XXtActionProc XDoCmd(w, event, params, num_params) XWidget w; /* unused */ XXEvent *event; /* unused */ XString *params; XCardinal *num_params; X{ X int i, n; X char buf[BUFSIZ]; X Arg args[1]; X LabelWidget lw = (LabelWidget) XtNameToWidget(toplevel, "topBox.titleBar.title"); X X X SetCursor(1); X if (strcmp(params[0], "drop") == 0) X DropIt(w, *params, NULL); X else { X Command[0] = '\0'; X for (i = 0; i < *num_params; i++) { X strcat(Command, params[i]); X strcat(Command, " "); X } X if (i) X Command[strlen(Command)-1] = '\0'; /* Drop the last trailing blank */ X strcat(Command, "\n"); X X if (mailpid) { /* If connections are okay,... */ X if ((n = match(&command_pattern, Command)) != C_FILE && n != C_NEWMAIL) X writeMail(Command); X else { /* check for commit of any changes */ X XtSetArg(args[0], XtNlabel, (XtArgVal) NULL); X XtGetValues(lw, args, ONE); X strcpy(buf, (char *)args[0].value); X X if (strcmp(&buf[strlen(buf)-7],"deleted") || X strcmp(params[0], "inc") == 0 || X Confirm("COMMIT all changes to this folder")) X writeMail(Command); X } X } else if (C_NEWMAIL != match(&command_pattern, Command)) X Bell("No current mail connection\n"); /* If not 'Newmail' */ X else { X if (strcmp(mailargv[mailargc - 2], "-f") == 0) { X mailargc -= 2; /* throw away any folder argument */ X mailargv[mailargc] = NULL; /* and NULL end of argument list */ X } X callMail(mailargc, mailargv); /* restart the mail connections */ X strcpy(Command, "Start"); /* Let em know we've re-started */ X UnsetNewmail(w, NULL, NULL); X } X } X} /* DoCmd */ X X X/* ARGSUSED */ X/* X** @(#)DoNothing() - dummy action for unwanted button(s) X*/ XXtActionProc XDoNothing(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X return; X} /* DoNothing */ X X X/* X** @(#)DoReply() - call Reply() CallbackProc from an ActionProc X*/ X/* ARGSUSED */ XXtActionProc XDoReply(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X Reply(w, *params, NULL); X} /* DoReply */ X X X/* X** @(#)DoSave() - call Save() CallbackProc from an ActionProc X*/ X/* ARGSUSED */ XXtActionProc XDoSave(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X Save(w, *params, NULL); X} /* DoSave */ X X X/* ARGSUSED */ X/* X** @(#)DoSelected() - execute specified command using selected message number X*/ XXtActionProc XDoSelected(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X int num = 0; X X X SetCursor(1); X if (! mailpid) Bell("No current mail connection\n"); X else if (num_params) { X if (*params[0] != 'n' && *params[0] != '-') X num = SelectionNumber(*params[0] == 'u'); X X if (num) sprintf(Command, "%s %d\n", params[0], num); X else sprintf(Command, "%s\n", params[0]); X X writeMail(Command); X X if (strcmp(params[0], "preserve") == 0) X markIndex("P"); X } X} /* DoSelected */ X X X/* X** @(#)Folder() - change folders - must have specified folder name or error X*/ X/* ARGSUSED */ XXtActionProc XFolder(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X char buf[BUFSIZ]; X Arg args[1]; X LabelWidget lw = (LabelWidget) XtNameToWidget(toplevel, "topBox.titleBar.title"); X XawTextPosition pos; X char *p; X Cardinal n; X X X SetCursor(1); /* restore normally by next msg read */ X pos = TextGetLastPos(XtNameToWidget(toplevel, "topBox.commandPanel.fileWindow")); X if ((n = pos - StartPos) <= 0) { X Bell("Specify a folder name (in the [File: ] box) first\n"); X } else { X FileBuf[StartPos + n] = '\0'; X p = FileBuf + StartPos; X if (mailpid) { /* check for commit of any changes */ X XtSetArg(args[0], XtNlabel, (XtArgVal) NULL); X XtGetValues(lw, args, ONE); X strcpy(buf, (char *)args[0].value); X X if (strcmp(&buf[strlen(buf) - 7], "deleted") || X Confirm("COMMIT all changes to this folder")) { X sprintf(Command, "file %s\n", p); X writeMail(Command); X } X } else { X/* X** We must first re-establish contact with the mail utility. X** This time, we indicate a specific mail folder to process. X*/ X XMail.MFileName = XtNewString(p); X if (strcmp(mailargv[mailargc - 2], "-f") == 0) { X mailargv[mailargc - 1] = XMail.MFileName; X } else { X mailargv[mailargc++] = "-f"; X mailargv[mailargc++] = XMail.MFileName; X mailargv[mailargc] = NULL; /* list MUST be NULL terminated */ X } X callMail(mailargc, mailargv); X strcpy(Command, "Start"); /* Let em know we've re-started */ X } X } X} /* Folder */ X X X/* ARGSUSED */ X/* X** @(#)Iconify() - request window iconification X*/ XXtActionProc XIconify(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X Display *disp; X X disp = XtDisplay(toplevel); X X if (! XIconifyWindow(disp, XtWindow(toplevel), DefaultScreen(disp))) X XBell(XtDisplay(toplevel), 33); X} X X X/* ARGSUSED */ X/* X** @(#)MyNotify() - call widget callbacks with passed parameter X*/ XXtActionProc XMyNotify(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X XtCallCallbacks(w, XtNcallback, *params); X} /* MyNotify */ X X X/* X** @(#)NextField() - warps pointer to next field in the Send command window. X** This allows carriage return to focus attention on the next data requirement. X*/ X/* ARGSUSED */ XXtActionProc XNextField(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X String name; X Widget shell; X X X if (strcmp(w->core.name, "Cc") == 0) X name = "Bcc"; else X if (strcmp(w->core.name, "Bcc") == 0) X name = "To"; else X if (strcmp(w->core.name, "To") == 0) X name = "Subject"; else X name = "Cc"; X X if ((shell = XtNameToWidget(XtParent(w), name)) != NULL) X XWarpPointer(XtDisplay(toplevel), None, XtWindow(shell), 0,0,0,0, 10, 5); X X} /* NextField */ X X X/* X** @(#)PrintMsg() - sends the selected mail message to the system printer X*/ X/* ARGSUSED */ XXtActionProc XPrintMsg(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X char *cp; X int num; X X X SetCursor(1); X if (! mailpid) Bell("No current mail connection\n"); X else { X num = SelectionNumber(False); /* no current message returns zero */ X if (! num) Bell("No messages to print.\n"); X else { X cp = GetMailEnv("printmail"); X if (! cp) { X sprintf(Command, "| %d \"lpr -p\"\n", num); X } else { X sprintf(Command, "| %d \"%s\"\n", num, cp); X XtFree(cp); X } X writeMail(Command); X } X } X} /* PrintMsg */ X X X/* X** @(#)Quit() - call DoQuit() CallbackProc from the Quit ActionProc X*/ X/* ARGSUSED */ XXtActionProc XQuit(w, event, params, num_params) XWidget w; /* unused */ XXEvent *event; /* unused */ XString *params; XCardinal *num_params; X{ X if (event->type == ClientMessage && X event->xclient.data.l[0] != wmDeleteWindow) { X XBell (XtDisplay(w), 0); X return; X } X X DoQuit(w, *params, NULL); X} /* Quit */ X X X/* X** @(#)SetAliases() - create a menu list of alias names X*/ X/* ARGSUSED */ XXtActionProc XSetAliases(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X Arg args[7]; X Cardinal i, j, k, n; X Widget bw, lw, popup, hold, left; X X static String l_Trans = "<Btn3Up>: MenuPopdown(aliasList)"; X X static String fl_trans = "<EnterWindow>: set() \n\ X <LeaveWindow>: unset() \n\ X <Btn3Up>: notify()"; X X static XtCallbackRec fl_callbacks[] = { X { (XtCallbackProc) GetAliasName, NULL }, X { NULL, NULL } X }; X X X SetCursor(1); X popup = XtNameToWidget(w, "aliasList"); X X if (! popup || popup->core.being_destroyed) { X XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(l_Trans)); X popup = XtCreatePopupShell("aliasList",overrideShellWidgetClass,w,args,1); X X (void) alias(NULL); /* ensure our aliases list is set */ X/* X** determine proper label width by finding longest name length X*/ X i = j = k = 0; X for (n = 0; aliases[n]; n++) X if ((k = strlen(aliases[n]->name)) > j) { X j = k; X i = n; X } X X if (j == 0) { /* If no alias names exist */ X XtSetArg(args[0], XtNwidth, 1); /* set these so MenuPopup */ X XtSetArg(args[1], XtNheight, 1); /* won't complain about a */ X XtSetValues(popup, (ArgList) args, 2); /* zero width or height */ X XtDestroyWidget(popup); /* to bad MenuPopup() doesn't care */ X } else { X/* X** Make equal width command buttons which contain the alias names X*/ X XtSetArg(args[0], XtNdefaultDistance, (XtArgVal) 1); X lw = XtCreateManagedWidget("table", formWidgetClass, popup, args, ONE); X X bw = left = NULL; X XtSetArg(args[0], XtNwidth, XTextWidth(XMail.buttonFont, aliases[i]->name, j) + 14); X XtSetArg(args[1], XtNfont, XMail.buttonFont); X XtSetArg(args[2], XtNtranslations, XtParseTranslationTable(fl_trans)); X XtSetArg(args[3], XtNcallback, fl_callbacks); X X i = j = 0; X if (n > 10) { /* if more than ten aliases, try to */ X j = n / 4; /* make an approximately square list */ X while (j * j < n) j++; /* (int. hack to avoid sqrt usage) */ X i = n / --j; X while (i * j < n) i++; X while (j > 3 && i < 25) { /* try to keep box inside main shell */ X i++; X j--; X } X } X X for (n = 0; aliases[n]; n++) { X XtSetArg(args[4], XtNlabel, aliases[n]->name); X XtSetArg(args[5], XtNfromVert, bw); j = 6; X if (left) { X XtSetArg(args[j], XtNfromHoriz, left); j++; X } X bw = XtCreateManagedWidget("entry", commandWidgetClass, lw, args, j); X AddInfoHandler(bw, "Copy this alias to the current header field"); X X if (i) { /* post names in a rectangular list */ X if (n % i == 0) hold = bw; X if ((n+1) % i == 0) { X left = hold; X bw = NULL; X } X } X } X } /* end - if some alias names exist */ X } /* end - if popup does not exist or was being destroyed */ X/* X** If the menu exists, set its x,y coordinates X*/ X SetCursor(0); X if (popup->core.being_destroyed) X XBell(XtDisplay(toplevel), 33); X else { X SetXY(popup, w, XMail.menuX, XMail.buttonHeight / 2); X } X} /* SetAliases */ X X X/* X** @(#)SetFolders() - create a menu list of folder names X*/ X/* ARGSUSED */ XXtActionProc XSetFolders(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; XCardinal *num_params; X{ X Arg args[8]; X Widget lw, above, this_one, to_left, popup; X int x, n; X char trans[BUFSIZ], tmp[BUFSIZ], *p, *List = NULL; X char foldir[BUFSIZ], *GetMailEnv(), *getenv(); X int foldlen, List_size, newline = 0; X DIR *dirp = NULL; X X#ifdef USE_DIRENT X struct dirent *dp; X#else X struct direct *dp; X#endif X X X static String dir_Trans = "\ X <Btn1Down>: SetDirectory(%s,%s,%s)"; X X static String l_Trans = "<Btn3Up>: MenuPopdown(popupList)"; X X static String fl_trans = "<EnterWindow>: set() \n\ X <LeaveWindow>: unset() \n\ X <Btn3Up>: notify() MenuPopdown(popupList)"; X X static XtCallbackRec fl_callbacks[] = { X { (XtCallbackProc) GetFolderName, NULL }, X { NULL, NULL } X }; X X X SetCursor(1); X popup = XtNameToWidget(w, "popupList"); X X if (! popup || popup->core.being_destroyed) { X p = GetMailEnv("folder"); /* returns NULL if none */ X if (p && strlen(p)) { X /* X * Don't prepend HOME if it starts with a slash or a . X */ X if (strchr("/.", *p)) X strcpy(foldir, p); X else X sprintf(foldir, "%s/%s", getenv("HOME"), p); X XtFree((char *)p); X /* X * Make sure it ends with (only one) slash X */ X if (LASTCH(foldir) != '/') X strcat(foldir, "/"); X } else X foldir[0] = '\0'; /* If no folder variable, then no folders */ X foldlen = strlen(foldir); X X XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(l_Trans)); X popup = XtCreatePopupShell("popupList",overrideShellWidgetClass,w,args,1); X X if (*foldir) { /* if folder variable exists */ X if (mailpid) X List = QueryMail("folders"); X else { X if (dirp = opendir(foldir)) { /* and folder is readable... */ X List_size = BUFSIZ; X List = XtMalloc(List_size); /* start with a BUFSIZ block */ X List[0] = '\0'; X x = 0; X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) X if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) { X if (strlen(List) + strlen(dp->d_name) + 2 > List_size) { X List_size += BUFSIZ; X List = XtRealloc(List, List_size); X } X strcat(List, " "); X strcat(List, dp->d_name); X if (++x % 4 == 0) { X x = 0; X strcat(List, "\n"); X } X } X List = XtRealloc(List, strlen(List) + 1); X closedir(dirp); X } /* end - if folder directory is readable */ X } /* end - if mail process is running */ X } /* end - if a folder value exists */ X X if (List) /* could be null if no current mail */ X if (O_BELL == match(&output_pattern, List)) { X strcat(List, "\n"); X Bell(List); X XtFree((char *)List); X List = NULL; X } X/* X** determine proper label width by finding longest word length X*/ X trans[0] = '\0'; X x = 0; X if (List) /* if folders exist and are readable */ X for (p = List; *p; p++) { X if (*p == ' ' || *p == '\n' || *p == '\t') { X if (x) { X tmp[x] = '\0'; X x = 0; X if (strlen(trans) < strlen(tmp)) X strcpy(trans, tmp); X } X } else tmp[x++] = *p; X } X X if (x) { X tmp[x] = '\0'; X if (strlen(trans) < strlen(tmp)) X strcpy(trans, tmp); X } X X if ((n = strlen(trans)) == 0) { /* if no folders set dummy width and */ X XtSetArg(args[0], XtNwidth, 1); /* height so MenuPopup() */ X XtSetArg(args[1], XtNheight, 1); /* won't complain about */ X XtSetValues(popup, (ArgList) args, 2); /* zero width or height */ X X XtDestroyWidget(popup); /* it would be nice if MenuPopup() cared */ X } else { X XtSetArg(args[0], XtNdefaultDistance, 1); X lw = XtCreateManagedWidget("list", formWidgetClass, popup, args, ONE); X/* X** Now, make equal width command buttons which contain the folder names X*/ X XtSetArg(args[0], XtNwidth, XTextWidth(XMail.buttonFont, trans, n) + 20); X XtSetArg(args[1], XtNfont, XMail.buttonFont); X XtSetArg(args[2], XtNtranslations, XtParseTranslationTable(fl_trans)); X XtSetArg(args[3], XtNcallback, fl_callbacks); X X above = this_one = to_left = NULL; X for (x = 0, p = List; *p; p++) { X if (*p == '\n') { X newline = 1; X } X if (*p == ' ' || *p == '\n' || *p == '\t') { X if (x) { X tmp[x] = '\0'; X/* X** If this 'folder' is really a directory, mark it with a trailing slash '/' X*/ X foldir[foldlen] = '\0'; X strcat(foldir, &tmp[1]); X if ((dirp = opendir(foldir)) != NULL) { X tmp[x++] = '/'; X tmp[x] = '\0'; X } X XtSetArg(args[4], XtNlabel, tmp); X XtSetArg(args[5], XtNfromHoriz, to_left); n = 6; X if (! to_left) XtSetArg(args[n], XtNfromVert, above); n++; X X this_one = XtCreateManagedWidget("listbutton", commandWidgetClass, X lw, args, n); X if (to_left == NULL) above = this_one; X to_left = this_one; X if (newline) { X newline = 0; X to_left = NULL; X } X x = 0; X/* X** If this 'folder' is a directory, add a button to popup a menu of filenames. X*/ X if (dirp) { X closedir(dirp); X sprintf(trans, dir_Trans, &tmp[1], foldir, "0"); X XtOverrideTranslations(this_one, XtParseTranslationTable(trans)); X AddInfoHandler(this_one, Folder_Info[2]); X } else X AddInfoHandler(this_one, Folder_Info[1]); X } X } else { X if (x == 0) tmp[x++] = '+'; /* start folder names with a 'plus' */ X tmp[x++] = *p; X } X } X X if (x) { X tmp[x] = '\0'; X foldir[foldlen] = '\0'; X strcat(foldir, &tmp[1]); X if ((dirp = opendir(foldir)) != NULL) { X tmp[x++] = '/'; X tmp[x] = '\0'; X } X XtSetArg(args[4], XtNlabel, tmp); X XtSetArg(args[5], XtNfromHoriz, to_left); n = 6; X if (! to_left) XtSetArg(args[n], XtNfromVert, above); n++; X X this_one = XtCreateManagedWidget("listbutton", commandWidgetClass, X lw, args, n); X if (dirp) { X closedir(dirp); X sprintf(trans, dir_Trans, &tmp[1], foldir, "0"); X XtOverrideTranslations(this_one, XtParseTranslationTable(trans)); X AddInfoHandler(this_one, Folder_Info[2]); X } else X AddInfoHandler(this_one, Folder_Info[1]); X } X } X } /* end - if some trans strlen */ X/* X** If folders menu exists, pop it up, after setting x,y coordinates X*/ X if (popup->core.being_destroyed) { X if (! *foldir) X Bell("No value set for \"folder\"\n"); X else { X if (dirp) { X if (! mailpid) { X Bell("No mail folders exist\n"); X } else { X foldir[foldlen - 1] = '\0'; X sprintf(tmp, "%s not found\n", foldir); X Bell(tmp); X } X } X } X } else { X if (! XtIsRealized(popup)) X XtRealizeWidget(popup); X /* X ** If folder list is small enough, anchor it to X ** the folder button instead of the commandPanel X */ X if (popup->core.width + (3 * (XMail.buttonWidth + 12)) <= XMail.shellWidth) X SetXY(popup, w, XMail.menuX, XMail.buttonHeight / 2); X else X SetXY(popup, XtNameToWidget(toplevel, "topBox.commandPanel"), X XMail.menuX, XMail.commandHeight / 2); X } X X if (List) X XtFree((char *)List); X X SetCursor(0); X} /* SetFolders */ X X X X/* X** @(#)SetMenu() - create a menu for toggling selected mail options X*/ XXtActionProc XSetMenu(parent, event, params, num_params) XWidget parent; XXEvent *event; /* unused */ XString *params; XCardinal *num_params; X{ X Arg args[6]; X Widget menu, layout, previous, next; X char *c, *info, label[BUFSIZ], name[BUFSIZ]; X int indx; X X static String b_Trans = X "<EnterWindow>: set() \n\ X <LeaveWindow>: reset() \n\ X <Btn3Up>: notify() unset()"; X X static String m_Trans = X "<Btn3Up>: MenuPopdown(set_menu)"; X X static String list[] = { "alwaysignore", "autoprint", "hold", "expert", NULL }; X X static String set_info[] = { X "Skip 'ignore'd header fields everywhere, not just during a print or read", X "Enable automatic printing of messages after delete and undelete commands", X "Preserve messages in the system mailbox after they have been read", X "Don't ask for confirmation when commiting changes or aborting a new letter", X NULL X }; X X static String unset_info[] = { X "Skip 'ignore'd header fields only when doing a print or read command", X "Disable automatic printing of messages after delete and undelete commands", X "Move system mailbox messages to the mbox save file after you read them", X "Ask for confirmation before commiting any changes or aborting a new letter", X NULL X }; X X X SetCursor(1); X menu = XtNameToWidget(parent, "set_menu"); X X if (! menu || menu->core.being_destroyed) { X XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(m_Trans)); X menu = XtCreatePopupShell("set_menu",overrideShellWidgetClass,parent,args,1); X X XtSetArg(args[0], XtNdefaultDistance, (XtArgVal) 1); X layout = XtCreateManagedWidget("menu", formWidgetClass, menu, args, ONE); X/* X** create the menu buttons X*/ X previous = NULL; X XtSetArg(args[0], XtNwidth, figureWidth(XMail.buttonFont) * 18 + 12); X XtSetArg(args[1], XtNfont, XMail.buttonFont); X XtSetArg(args[2], XtNjustify, XtJustifyLeft); X XtSetArg(args[3], XtNtranslations, XtParseTranslationTable(b_Trans)); X for (indx = 0; list[indx] != NULL; indx++) { X info = set_info[indx]; X strcpy(label, "set "); X if (strcmp(list[indx], "expert") == 0) { X if (XMail.expert) { X info = unset_info[indx]; X strcat(label, "no"); X } X } else { X if ((c = GetMailEnv(list[indx])) != NULL) { X info = unset_info[indx]; X strcat(label, "no"); X XtFree(c); X } X } X strcat(label, list[indx]); /* set window name by label */ X strcpy(name, &label[4]); X XtSetArg(args[4], XtNlabel, label); X XtSetArg(args[5], XtNfromVert, previous); X next = XtCreateManagedWidget(name, commandWidgetClass, layout, args, 6); X XtAddCallback(next, XtNcallback, (XtCallbackProc) DoSet, NULL); X AddInfoHandler(next, info); X previous = next; X } X } /* end - menu creation */ X SetXY(menu, parent, XMail.menuX, XMail.buttonHeight / 2); X SetCursor(0); X} /* SetMenu */ X X X/* X** @(#)SetPopup() - place named popup at menuX, menuY relative to Widget w. X*/ X/* ARGSUSED */ XXtActionProc XSetPopup(w, event, params, num_params) XWidget w; XXEvent *event; /* unused */ XString *params; XCardinal *num_params; X{ X Widget shell; X String p; X X X SetCursor(1); X if (*num_params == 0) X XtError("xmail had no name parameter passed to SetPopup()"); X X p = params[0]; X X if ((shell = XtNameToWidget(w, p)) == NULL) X XtError("xmail shell name passed to SetPopup() not found in list"); X X SetXY(shell, w, XMail.menuX, XMail.menuY); X SetCursor(0); X} /* SetPopup */ X X X/* ARGSUSED */ X/* X** @(#)SetSelect() - flag the index number of the selected message X*/ XXtActionProc XSetSelect(w, event, params, num_params) XWidget w; /* unused */ XXEvent *event; /* unused */ XString *params; /* unused */ XCardinal *num_params; /* unused */ X{ X markIndex(">"); X} /* SetSelect */ X X X/* X** @(#)ShowHelp() - set named string source as text for and popup help window. X*/ X/* ARGSUSED */ XXtActionProc XShowHelp(w, event, params, num_params) XWidget w; XXEvent *event; XString *params; /* unused */ XCardinal *num_params; /* unused */ X{ X String name; X Widget tb; X int x; X X X SetCursor(1); X name = w->core.name; X if (strcmp(name, "text") == 0 && event->type == KeyPress) X name = "text2"; X X for (x = 0; x < HelpList.indx; x++) X if (strcmp(name, HelpList.name[x]) == 0) { X tb = XtNameToWidget(toplevel, "topBox"); X XawTextSetSource(XtNameToWidget(tb, "help.helpWindow"), X HelpList.text[x], (XawTextPosition) 0); X X SetXY(XtNameToWidget(tb, "help"), X XtNameToWidget(tb, "textWindow.text"), X XMail.helpX, XMail.helpY); X X SetCursor(0); X XtPopup(XtNameToWidget(tb, "help"), XtGrabNone); X break; X } X} /* ShowHelp */ END_OF_FILE if test 28772 -ne `wc -c <'actions.c'`; then echo shar: \"'actions.c'\" unpacked with wrong size! fi # end of 'actions.c' fi echo shar: End of archive 8 \(of 11\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 11 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Dan Heller O'Reilly && Associates Z-Code Software Comp-sources-x: Senior Writer President comp-sources-x@uunet.uu.net argv@ora.com argv@zipcode.com