home *** CD-ROM | disk | FTP | other *** search
- /*
- * $XConsortium: msg.c,v 2.49 91/07/24 20:28:31 converse Exp $
- *
- *
- * COPYRIGHT 1987, 1989
- * DIGITAL EQUIPMENT CORPORATION
- * MAYNARD, MASSACHUSETTS
- * ALL RIGHTS RESERVED.
- *
- * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
- * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
- * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
- * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
- *
- * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
- * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
- * ADDITION TO THAT SET FORTH ABOVE.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Digital Equipment Corporation not be
- * used in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission.
- */
-
- /* msgs.c -- handle operations on messages. */
-
- #include <X11/Xaw/Cardinals.h>
-
- #include "xmh.h"
- #include "tocintrnl.h"
-
- static int SetScrn();
-
- /* Function Name: SetEditable
- * Description: Sets the editable flag for this message.
- * Arguments: msg - the message.
- * edit - set editable to this.
- * Returns: none
- */
-
- static void
- SetEditable(msg, edit)
- Msg msg;
- Boolean edit;
- {
- Arg args[1];
-
- if (edit)
- XtSetArg(args[0], XtNeditType, XawtextEdit);
- else
- XtSetArg(args[0], XtNeditType, XawtextRead);
-
- XtSetValues(msg->source, args, ONE);
- }
-
- /* Function Name: IsEditable
- * Description: Returns true if this is an editable message.
- * Arguments: msg - the message to edit.
- * Returns: TRUE if editable.
- */
-
- static Boolean
- IsEditable(msg)
- Msg msg;
- {
- Arg args[1];
- XawTextEditType type;
-
- XtSetArg(args[0], XtNeditType, &type);
- XtGetValues(msg->source, args, ONE);
-
- return(type == XawtextEdit);
- }
-
- /* Return the user-viewable name of the given message. */
-
- static char *NameOfMsg(msg)
- Msg msg;
- {
- static char result[100];
- (void) sprintf(result, "%s:%d", msg->toc->foldername, msg->msgid);
- return result;
- }
-
-
- /* Update the message titlebar in the given scrn. */
-
- static void ResetMsgLabel(scrn)
- Scrn scrn;
- {
- Msg msg;
- char str[200];
- if (scrn) {
- msg = scrn->msg;
- if (msg == NULL) (void) strcpy(str, app_resources.banner);
- else {
- (void) strcpy(str, NameOfMsg(msg));
- switch (msg->fate) {
- case Fdelete:
- (void) strcat(str, " -> *Delete*");
- break;
- case Fcopy:
- case Fmove:
- (void) strcat(str, " -> ");
- (void) strcat(str, msg->desttoc->foldername);
- if (msg->fate == Fcopy)
- (void) strcat(str, " (Copy)");
- break;
- }
- if (msg->temporary) (void)strcat(str, " [Temporary]");
- }
- ChangeLabel((Widget) scrn->viewlabel, str);
- }
- }
-
-
- /* A major msg change has occured; redisplay it. (This also should
- work even if we now have a new source to display stuff from.) This
- routine arranges to hide boring headers, and also will set the text
- insertion point to the proper place if this is a composition and we're
- viewing it for the first time. */
-
- static void RedisplayMsg(scrn)
- Scrn scrn;
- {
- Msg msg;
- XawTextPosition startPos, lastPos, nextPos;
- int length; char str[100];
- XawTextBlock block;
- if (scrn) {
- msg = scrn->msg;
- if (msg) {
- startPos = 0;
- if (app_resources.hide_boring_headers && scrn->kind != STcomp) {
- lastPos = XawTextSourceScan(msg->source, (XawTextPosition) 0,
- XawstAll, XawsdRight, 1, FALSE);
- while (startPos < lastPos) {
- nextPos = startPos;
- length = 0;
- while (length < 8 && nextPos < lastPos) {
- nextPos = XawTextSourceRead(msg->source, nextPos,
- &block, 8 - length);
- (void) strncpy(str + length, block.ptr, block.length);
- length += block.length;
- }
- if (length == 8) {
- if (strncmp(str, "From:", 5) == 0 ||
- strncmp(str, "To:", 3) == 0 ||
- strncmp(str, "Date:", 5) == 0 ||
- strncmp(str, "Subject:", 8) == 0) break;
- }
- startPos = XawTextSourceScan(msg->source, startPos,
- XawstEOL, XawsdRight, 1, TRUE);
- }
- if (startPos >= lastPos) startPos = 0;
- }
- XawTextSetSource(scrn->viewwidget, msg->source, startPos);
- if (msg->startPos > 0) {
- XawTextSetInsertionPoint(scrn->viewwidget, msg->startPos);
- msg->startPos = 0; /* Start in magic place only once. */
- }
- } else {
- XawTextSetSource(scrn->viewwidget, PNullSource,
- (XawTextPosition)0);
- }
- }
- }
-
-
-
- static char tempDraftFile[100] = "";
-
- /* Temporarily move the draftfile somewhere else, so we can exec an mh
- command that affects it. */
-
- static void TempMoveDraft()
- {
- char *ptr;
- if (FileExists(draftFile)) {
- do {
- ptr = MakeNewTempFileName();
- (void) strcpy(tempDraftFile, draftFile);
- (void) strcpy(rindex(tempDraftFile, '/'), rindex(ptr, '/'));
- } while (FileExists(tempDraftFile));
- RenameAndCheck(draftFile, tempDraftFile);
- }
- }
-
-
-
- /* Restore the draftfile from its temporary hiding place. */
-
- static void RestoreDraft()
- {
- if (*tempDraftFile) {
- RenameAndCheck(tempDraftFile, draftFile);
- *tempDraftFile = 0;
- }
- }
-
-
-
- /* Public routines */
-
-
- /* Given a message, return the corresponding filename. */
-
- char *MsgFileName(msg)
- Msg msg;
- {
- static char result[500];
- (void) sprintf(result, "%s/%d", msg->toc->path, msg->msgid);
- return result;
- }
-
-
-
- /* Save any changes to a message. Also calls the toc routine to update the
- scanline for this msg. Returns True if saved, false otherwise. */
-
- MsgSaveChanges(msg)
- Msg msg;
- {
- int i;
- if (msg->source) {
- if (XawAsciiSave(msg->source)) {
- for (i=0; i < (int) msg->num_scrns; i++)
- EnableProperButtons(msg->scrn[i]);
- if (!msg->temporary)
- TocMsgChanged(msg->toc, msg);
- return True;
- }
- else {
- char str[256];
- (void) sprintf(str, "Cannot save changes to \"%s/%d\"!",
- msg->toc->foldername, msg->msgid);
- PopupError((Widget)NULL, str);
- return False;
- }
- }
- Feep();
- return False;
- }
-
-
- /*
- * Show the given message in the given scrn. If a message is changed, and we
- * are removing it from any scrn, then ask for confirmation first. If the
- * scrn was showing a temporary msg that is not being shown in any other scrn,
- * it is deleted. If scrn is NULL, then remove the message from every scrn
- * that's showing it.
- */
-
-
- /*ARGSUSED*/
- static void ConfirmedNoScrn(widget, client_data, call_data)
- Widget widget; /* unused */
- XtPointer client_data;
- XtPointer call_data; /* unused */
- {
- Msg msg = (Msg) client_data;
- register int i;
-
- for (i=msg->num_scrns - 1 ; i >= 0 ; i--)
- SetScrn((Msg)NULL, msg->scrn[i], TRUE, (XtCallbackList) NULL,
- (XtCallbackList) NULL);
- }
-
-
- static void RemoveMsgConfirmed(scrn)
- Scrn scrn;
- {
- if (scrn->kind == STtocAndView && MsgChanged(scrn->msg)) {
- Arg args[1];
- XtSetArg(args[0], XtNtranslations, scrn->read_translations);
- XtSetValues(scrn->viewwidget, args, (Cardinal) 1);
- }
- scrn->msg->scrn[0] = NULL;
- scrn->msg->num_scrns = 0;
- XawTextSetSource(scrn->viewwidget, PNullSource, (XawTextPosition) 0);
- XtDestroyWidget(scrn->msg->source);
- scrn->msg->source = NULL;
- if (scrn->msg->temporary) {
- (void) unlink(MsgFileName(scrn->msg));
- TocRemoveMsg(scrn->msg->toc, scrn->msg);
- MsgFree(scrn->msg);
- }
- }
-
-
- static void SetScrnNewMsg(msg, scrn)
- Msg msg;
- Scrn scrn;
- {
- scrn->msg = msg;
- if (msg == NULL) {
- XawTextSetSource(scrn->viewwidget, PNullSource, (XawTextPosition) 0);
- ResetMsgLabel(scrn);
- EnableProperButtons(scrn);
- if (scrn->kind != STtocAndView)
- StoreWindowName(scrn, progName);
- } else {
- msg->num_scrns++;
- msg->scrn = (Scrn *) XtRealloc((char *)msg->scrn,
- (unsigned) sizeof(Scrn)*msg->num_scrns);
- msg->scrn[msg->num_scrns - 1] = scrn;
- if (msg->source == NULL)
- msg->source = CreateFileSource(scrn->viewwidget, MsgFileName(msg),
- scrn->kind == STcomp);
- ResetMsgLabel(scrn);
- RedisplayMsg(scrn);
- EnableProperButtons(scrn);
- if (scrn->kind != STtocAndView)
- StoreWindowName(scrn, NameOfMsg(msg));
- }
- }
-
- typedef struct _MsgAndScrn {
- Msg msg;
- Scrn scrn;
- } MsgAndScrnRec, *MsgAndScrn;
-
- /*ARGSUSED*/
- static void ConfirmedWithScrn(widget, client_data, call_data)
- Widget widget; /* unused */
- XtPointer client_data;
- XtPointer call_data; /* unused */
- {
- MsgAndScrn mas = (MsgAndScrn) client_data;
- RemoveMsgConfirmed(mas->scrn);
- SetScrnNewMsg(mas->msg, mas->scrn);
- XtFree((char *) mas);
- }
-
-
- static int SetScrn(msg, scrn, force, confirms, cancels)
- Msg msg;
- Scrn scrn;
- Boolean force; /* if true, force msg set scrn */
- XtCallbackList confirms; /* callbacks upon confirmation */
- XtCallbackList cancels; /* callbacks upon cancellation */
- {
- register int i, num_scrns;
- static XtCallbackRec yes_callbacks[] = {
- {(XtCallbackProc) NULL, (XtPointer) NULL},
- {(XtCallbackProc) NULL, (XtPointer) NULL},
- {(XtCallbackProc) NULL, (XtPointer) NULL}
- };
-
- if (scrn == NULL) {
- if (msg == NULL || msg->num_scrns == 0) return 0;
- if (!force && XawAsciiSourceChanged(msg->source)) {
- char str[100];
- (void) sprintf(str,
- "Are you sure you want to remove changes to %s?",
- NameOfMsg(msg));
-
- yes_callbacks[0].callback = ConfirmedNoScrn;
- yes_callbacks[0].closure = (XtPointer) msg;
- yes_callbacks[1].callback = confirms[0].callback;
- yes_callbacks[1].closure = confirms[0].closure;
-
- PopupConfirm((Widget) NULL, str, yes_callbacks, cancels);
- return NEEDS_CONFIRMATION;
- }
- ConfirmedNoScrn((Widget)NULL, (XtPointer) msg, (XtPointer) NULL);
- return 0;
- }
-
- if (scrn->msg == msg) return 0;
-
- if (scrn->msg) {
- num_scrns = scrn->msg->num_scrns;
- for (i=0 ; i<num_scrns ; i++)
- if (scrn->msg->scrn[i] == scrn) break;
- if (i >= num_scrns) Punt("Couldn't find scrn in SetScrn!");
- if (num_scrns > 1)
- scrn->msg->scrn[i] = scrn->msg->scrn[--(scrn->msg->num_scrns)];
- else {
- if (!force && XawAsciiSourceChanged(scrn->msg->source)) {
- char str[100];
- MsgAndScrn cb_data;
-
- cb_data = XtNew(MsgAndScrnRec);
- cb_data->msg = msg;
- cb_data->scrn = scrn;
- (void)sprintf(str,
- "Are you sure you want to remove changes to %s?",
- NameOfMsg(scrn->msg));
- yes_callbacks[0].callback = ConfirmedWithScrn;
- yes_callbacks[0].closure = (XtPointer) cb_data;
- yes_callbacks[1].callback = confirms[0].callback;
- yes_callbacks[1].closure = confirms[0].closure;
- PopupConfirm(scrn->viewwidget, str, yes_callbacks, cancels);
- return NEEDS_CONFIRMATION;
- }
- RemoveMsgConfirmed(scrn);
- }
- }
- SetScrnNewMsg(msg, scrn);
- return 0;
- }
-
-
-
- /* Associate the given msg and scrn, asking for confirmation if necessary. */
-
- int MsgSetScrn(msg, scrn, confirms, cancels)
- Msg msg;
- Scrn scrn;
- XtCallbackList confirms;
- XtCallbackList cancels;
- {
- return SetScrn(msg, scrn, FALSE, confirms, cancels);
- }
-
-
- /* Same as above, but with the extra information that the message is actually
- a composition. (Nothing currently takes advantage of that extra fact.) */
-
- void MsgSetScrnForComp(msg, scrn)
- Msg msg;
- Scrn scrn;
- {
- (void) SetScrn(msg, scrn, FALSE, (XtCallbackList) NULL,
- (XtCallbackList) NULL);
- }
-
-
- /* Associate the given msg and scrn, even if it means losing some unsaved
- changes. */
-
- void MsgSetScrnForce(msg, scrn)
- Msg msg;
- Scrn scrn;
- {
- (void) SetScrn(msg, scrn, TRUE, (XtCallbackList) NULL,
- (XtCallbackList) NULL);
- }
-
-
-
- /* Set the fate of the given message. */
-
- void MsgSetFate(msg, fate, desttoc)
- Msg msg;
- FateType fate;
- Toc desttoc;
- {
- Toc toc = msg->toc;
- XawTextBlock block;
- int i;
- msg->fate = fate;
- msg->desttoc = desttoc;
- if (fate == Fignore && msg == msg->toc->curmsg)
- block.ptr = "+";
- else {
- switch (fate) {
- case Fignore: block.ptr = " "; break;
- case Fcopy: block.ptr = "C"; break;
- case Fmove: block.ptr = "^"; break;
- case Fdelete: block.ptr = "D"; break;
- }
- }
- block.firstPos = 0;
- block.format = FMT8BIT;
- block.length = 1;
- if (toc->stopupdate)
- toc->needsrepaint = TRUE;
- if (toc->num_scrns && msg->visible && !toc->needsrepaint &&
- *block.ptr != msg->buf[MARKPOS])
- (void)XawTextReplace(msg->toc->scrn[0]->tocwidget, /*%%%SourceReplace*/
- msg->position + MARKPOS,
- msg->position + MARKPOS + 1, &block);
- else
- msg->buf[MARKPOS] = *block.ptr;
- for (i=0; i < (int) msg->num_scrns; i++)
- ResetMsgLabel(msg->scrn[i]);
- }
-
-
-
- /* Get the fate of this message. */
-
- FateType MsgGetFate(msg, toc)
- Msg msg;
- Toc *toc; /* RETURN */
- {
- if (toc) *toc = msg->desttoc;
- return msg->fate;
- }
-
-
- /* Make this a temporary message. */
-
- void MsgSetTemporary(msg)
- Msg msg;
- {
- int i;
- msg->temporary = TRUE;
- for (i=0; i < (int) msg->num_scrns; i++)
- ResetMsgLabel(msg->scrn[i]);
- }
-
-
- /* Make this a permanent message. */
-
- void MsgSetPermanent(msg)
- Msg msg;
- {
- int i;
- msg->temporary = FALSE;
- for (i=0; i < (int) msg->num_scrns; i++)
- ResetMsgLabel(msg->scrn[i]);
- }
-
-
-
- /* Return the id# of this message. */
-
- int MsgGetId(msg)
- Msg msg;
- {
- return msg->msgid;
- }
-
-
- /* Return the scanline for this message. */
-
- char *MsgGetScanLine(msg)
- Msg msg;
- {
- return msg->buf;
- }
-
-
-
- /* Return the toc this message is in. */
-
- Toc MsgGetToc(msg)
- Msg msg;
- {
- return msg->toc;
- }
-
-
- /* Set the reapable flag for this msg. */
-
- void MsgSetReapable(msg)
- Msg msg;
- {
- int i;
- msg->reapable = TRUE;
- for (i=0; i < (int) msg->num_scrns; i++)
- EnableProperButtons(msg->scrn[i]);
- }
-
-
-
- /* Clear the reapable flag for this msg. */
-
- void MsgClearReapable(msg)
- Msg msg;
- {
- int i;
- msg->reapable = FALSE;
- for (i=0; i < (int) msg->num_scrns; i++)
- EnableProperButtons(msg->scrn[i]);
- }
-
-
- /* Get the reapable value for this msg. Returns TRUE iff the reapable flag
- is set AND no changes have been made. */
-
- int MsgGetReapable(msg)
- Msg msg;
- {
- return msg == NULL || (msg->reapable &&
- (msg->source == NULL ||
- !XawAsciiSourceChanged(msg->source)));
- }
-
-
- /* Make it possible to edit the given msg. */
- void MsgSetEditable(msg)
- Msg msg;
- {
- int i;
- if (msg && msg->source) {
- SetEditable(msg, TRUE);
- for (i=0; i < (int) msg->num_scrns; i++)
- EnableProperButtons(msg->scrn[i]);
- }
- }
-
-
-
- /* Turn off editing for the given msg. */
-
- void MsgClearEditable(msg)
- Msg msg;
- {
- int i;
- if (msg && msg->source) {
- SetEditable(msg, FALSE);
- for (i=0; i < (int) msg->num_scrns; i++)
- EnableProperButtons(msg->scrn[i]);
- }
- }
-
-
-
- /* Get whether the msg is editable. */
-
- int MsgGetEditable(msg)
- Msg msg;
- {
- return msg && msg->source && IsEditable(msg);
- }
-
-
- /* Get whether the msg has changed since last saved. */
-
- int MsgChanged(msg)
- Msg msg;
- {
- return msg && msg->source && XawAsciiSourceChanged(msg->source);
- }
-
- /* Call the given function when the msg changes. */
-
- void
- MsgSetCallOnChange(msg, func, param)
- Msg msg;
- void (*func)();
- XtPointer param;
- {
- Arg args[1];
- static XtCallbackRec cb[] = { {NULL, NULL}, {NULL, NULL} };
-
- if (func != NULL) {
- cb[0].callback = func;
- cb[0].closure = param;
- XtSetArg(args[0], XtNcallback, cb);
- }
- else
- XtSetArg(args[0], XtNcallback, NULL);
-
- XtSetValues(msg->source, args, (Cardinal) 1);
-
- }
-
- /* Send (i.e., mail) the given message as is. First break it up into lines,
- and copy it to a new file in the process. The new file is one of 10
- possible draft files; we rotate amoung the 10 so that the user can have up
- to 10 messages being sent at once. (Using a file in /tmp is a bad idea
- because these files never actually get deleted, but renamed with some
- prefix. Also, these should stay in an area private to the user for
- security.) */
-
- void MsgSend(msg)
- Msg msg;
- {
- FILEPTR from;
- FILEPTR to;
- int p, c, l, inheader, sendwidth, sendbreakwidth;
- char *ptr, *ptr2, **argv, str[100];
- static sendcount = -1;
- (void) MsgSaveChanges(msg);
- from = FOpenAndCheck(MsgFileName(msg), "r");
- sendcount = (sendcount + 1) % 10;
- (void) sprintf(str, "%s%d", xmhDraftFile, sendcount);
- to = FOpenAndCheck(str, "w");
- sendwidth = app_resources.send_line_width;
- sendbreakwidth = app_resources.break_send_line_width;
- inheader = TRUE;
- while (ptr = ReadLine(from)) {
- if (inheader) {
- if (strncmpIgnoringCase(ptr, "sendwidth:", 10) == 0) {
- if (atoi(ptr+10) > 0) sendwidth = atoi(ptr+10);
- continue;
- }
- if (strncmpIgnoringCase(ptr, "sendbreakwidth:", 15) == 0) {
- if (atoi(ptr+15) > 0) sendbreakwidth = atoi(ptr+15);
- continue;
- }
- for (l = 0, ptr2 = ptr ; *ptr2 && !l ; ptr2++)
- l = (*ptr2 != ' ' && *ptr2 != '\t' && *ptr != '-');
- if (l) {
- (void) fprintf(to, "%s\n", ptr);
- continue;
- }
- inheader = FALSE;
- if (sendbreakwidth < sendwidth) sendbreakwidth = sendwidth;
- }
- do {
- for (p = c = l = 0, ptr2 = ptr;
- *ptr2 && c < sendbreakwidth;
- p++, ptr2++) {
- if (*ptr2 == ' ' && c < sendwidth)
- l = p;
- if (*ptr2 == '\t') {
- if (c < sendwidth) l = p;
- c += 8 - (c % 8);
- }
- else
- c++;
- }
- if (c < sendbreakwidth) {
- (void) fprintf(to, "%s\n", ptr);
- *ptr = 0;
- }
- else
- if (l) {
- ptr[l] = 0;
- (void) fprintf(to, "%s\n", ptr);
- ptr += l + 1;
- }
- else {
- for (c = 0; c < sendwidth; ) {
- if (*ptr == '\t') c += 8 - (c % 8);
- else c++;
- (void) fputc(*ptr++, to);
- }
- (void) fputc('\n', to);
- }
- } while (*ptr);
- }
- (void) myfclose(from);
- (void) myfclose(to);
- argv = MakeArgv(3);
- argv[0] = "send";
- argv[1] = "-push";
- argv[2] = str;
- DoCommand(argv, (char *) NULL, (char *) NULL);
- XtFree((char *) argv);
- }
-
-
- /* Make the msg into the form for a generic composition. Set msg->startPos
- so that the text insertion point will be placed at the end of the first
- line (which is usually the "To:" field). */
-
- void MsgLoadComposition(msg)
- Msg msg;
- {
- static char *blankcomp = NULL; /* Array containing comp template */
- static int compsize = 0;
- static XawTextPosition startPos;
- char *file, **argv;
- int fid;
- if (blankcomp == NULL) {
- file = MakeNewTempFileName();
- argv = MakeArgv(5);
- argv[0] = "comp";
- argv[1] = "-file";
- argv[2] = file;
- argv[3] = "-nowhatnowproc";
- argv[4] = "-nodraftfolder";
- DoCommand(argv, (char *) NULL, (char *) NULL);
- XtFree((char *) argv);
- compsize = GetFileLength(file);
- if (compsize > 0) {
- blankcomp = XtMalloc((Cardinal) compsize);
- fid = myopen(file, O_RDONLY, 0666);
- if (compsize != read(fid, blankcomp, compsize))
- Punt("Error reading in MsgLoadComposition!");
- (void) myclose(fid);
- DeleteFileAndCheck(file);
- } else {
- blankcomp = "To: \n--------\n";
- compsize = strlen(blankcomp);
- }
- startPos = index(blankcomp, '\n') - blankcomp;
- }
- fid = myopen(MsgFileName(msg), O_WRONLY | O_TRUNC | O_CREAT, 0666);
- if (compsize != write(fid, blankcomp, compsize))
- Punt("Error writing in MsgLoadComposition!");
- (void) myclose(fid);
- TocSetCacheValid(msg->toc);
- msg->startPos = startPos;
- }
-
-
-
- /* Load a msg with a template of a reply to frommsg. Set msg->startPos so
- that the text insertion point will be placed at the beginning of the
- message body. */
-
- void MsgLoadReply(msg, frommsg)
- Msg msg, frommsg;
- {
- char **argv;
- char str[100];
- int status;
-
- TempMoveDraft();
- argv = MakeArgv(5);
- argv[0] = "repl";
- argv[1] = TocMakeFolderName(frommsg->toc);
- (void) sprintf(str, "%d", frommsg->msgid);
- argv[2] = str;
- argv[3] = "-nowhatnowproc";
- argv[4] = "-nodraftfolder";
- status = DoCommand(argv, (char *) NULL, (char *) NULL);
- XtFree(argv[1]);
- XtFree((char*)argv);
- if (!status) {
- RenameAndCheck(draftFile, MsgFileName(msg));
- RestoreDraft();
- TocSetCacheValid(frommsg->toc); /* If -anno is set, this keeps us from
- rescanning folder. */
- TocSetCacheValid(msg->toc);
- msg->startPos = GetFileLength(MsgFileName(msg));
- }
- }
-
-
-
- /* Load a msg with a template of forwarding a list of messages. Set
- msg->startPos so that the text insertion point will be placed at the end
- of the first line (which is usually a "To:" field). */
-
- void MsgLoadForward(scrn, msg, mlist)
- Scrn scrn;
- Msg msg;
- MsgList mlist;
- {
- char **argv, str[100];
- int i;
- TempMoveDraft();
- argv = MakeArgv(4 + mlist->nummsgs);
- argv[0] = "forw";
- argv[1] = TocMakeFolderName(mlist->msglist[0]->toc);
- for (i = 0; i < mlist->nummsgs; i++) {
- (void) sprintf(str, "%d", mlist->msglist[i]->msgid);
- argv[2 + i] = XtNewString(str);
- }
- argv[2 + i] = "-nowhatnowproc";
- argv[3 + i] = "-nodraftfolder";
- DoCommand(argv, (char *) NULL, (char *) NULL);
- for (i = 1; i < 2 + mlist->nummsgs; i++)
- XtFree((char *) argv[i]);
- XtFree((char *) argv);
- RenameAndCheck(draftFile, MsgFileName(msg));
- RestoreDraft();
- TocSetCacheValid(msg->toc);
- msg->source = CreateFileSource(scrn->viewlabel, MsgFileName(msg), True);
- msg->startPos = XawTextSourceScan(msg->source, (XawTextPosition) 0,
- XawstEOL, XawsdRight, 1, False);
- }
-
-
- /* Load msg with a copy of frommsg. */
-
- void MsgLoadCopy(msg, frommsg)
- Msg msg, frommsg;
- {
- char str[500];
- (void)strcpy(str, MsgFileName(msg));
- CopyFileAndCheck(MsgFileName(frommsg), str);
- TocSetCacheValid(msg->toc);
- }
-
- /* Checkpoint the given message if it contains unsaved edits. */
-
- void MsgCheckPoint(msg)
- Msg msg;
- {
- int len;
- char file[500];
-
- if (!msg || !msg->source || !IsEditable(msg) ||
- !XawAsciiSourceChanged(msg->source))
- return;
-
- if (*app_resources.checkpoint_name_format == '/') {
- (void) sprintf(file, app_resources.checkpoint_name_format, msg->msgid);
- } else {
- (void) sprintf(file, "%s/", msg->toc->path);
- len = strlen(file);
- (void) sprintf(file + len, app_resources.checkpoint_name_format,
- msg->msgid);
- }
- if (!XawAsciiSaveAsFile(msg->source, file)) {
- char str[256];
- (void) sprintf(str, "Unsaved edits cannot be checkpointed to %s.",
- file);
- PopupError((Widget)NULL, str);
- }
- TocSetCacheValid(msg->toc);
- }
-
- /* Free the storage being used by the given msg. */
-
- void MsgFree(msg)
- Msg msg;
- {
- XtFree(msg->buf);
- XtFree((char *)msg);
- }
-
- /* Insert the associated message, if any, filtering it first */
-
- /*ARGSUSED*/
- void XmhInsert(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- Scrn scrn = ScrnFromWidget(w);
- Msg msg = scrn->msg;
- XawTextPosition pos;
- XawTextBlock block;
-
- if (msg == NULL || scrn->assocmsg == NULL) return;
-
- if (app_resources.insert_filter && *app_resources.insert_filter) {
- char command[1024];
- char *argv[4];
- argv[0] = "/bin/sh";
- argv[1] = "-c";
- sprintf(command, "%s %s", app_resources.insert_filter,
- MsgFileName(scrn->assocmsg));
- argv[2] = command;
- argv[3] = 0;
- block.ptr = DoCommandToString(argv);
- block.length = strlen(block.ptr);
- }
- else {
- /* default filter is equivalent to 'echo "<filename>"' */
- block.ptr = XtNewString(MsgFileName(scrn->assocmsg));
- block.length = strlen(block.ptr);
- }
- block.firstPos = 0;
- block.format = FMT8BIT;
- pos = XawTextGetInsertionPoint(scrn->viewwidget);
- if (XawTextReplace(scrn->viewwidget, pos, pos, &block) != XawEditDone)
- PopupError(scrn->parent, "Insertion failed!");
- XtFree(block.ptr);
- }
-
- /* Function Name: CreateFileSource
- * Description: Creates an AsciiSource for a file.
- * Arguments: w - the widget to create the source for.
- * filename - the file to assign to this source.
- * edit - if TRUE then this disk source is editable.
- * Returns: the source.
- */
-
- Widget
- CreateFileSource(w, filename, edit)
- Widget w;
- String filename;
- Boolean edit;
- {
- Arg arglist[10];
- Cardinal num_args = 0;
-
- XtSetArg(arglist[num_args], XtNtype, XawAsciiFile); num_args++;
- XtSetArg(arglist[num_args], XtNstring, filename); num_args++;
- if (edit)
- XtSetArg(arglist[num_args], XtNeditType, XawtextEdit);
- else
- XtSetArg(arglist[num_args], XtNeditType, XawtextRead);
- num_args++;
-
- return(XtCreateWidget("textSource", asciiSrcObjectClass, w,
- arglist, num_args));
- }
-
-