v13i050: xmail, Part08/11
Michael Wagnitz
stratus!voder!nsc!berlioz.nsc.com!michael at uunet.UU.NET
Sun Jun 16 05:44:53 AEST 1991
Submitted-by: stratus!voder!nsc!berlioz.nsc.com!michael at 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 at 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 at uunet.uu.net
argv at ora.com argv at zipcode.com
More information about the Comp.sources.x
mailing list