PeanutTopImpl.mesa
Copyright © 1983, 1984 Xerox Corporation. All rights reserved.
Written by Bill Paxton, February 1983
Last edited by Paxton on April 4, 1983 9:10 am
Last Edited by: Pausch, July 18, 1983 1:37 pm
Last Edited by: Wyatt, September 10, 1984 2:07:45 pm PDT
DIRECTORY
Booting USING [CheckpointProc, RegisterProcs, RollbackProc],
Commander USING [CommandProc, Register],
FS USING [ComponentPositions, EnumerateForNames, ExpandName, NameProc],
IO USING [PutFR, time],
Loader USING [BCDBuildTime],
Menus USING [ClickProc, MenuProc],
PeanutProfile USING [activeMailFile, killViewersOnSaveAll, outgoingMailFile, workingDirectory],
PeanutRetrieve USING [CloseConnection, CopyMessages, FindMailViewer, GetMailViewer, GetNewMsgs, NewUser],
PeanutSendMail USING [AnswerMsg, AuthenticateUser, ForwardMsg, NewMsgForm, SendMsg, userRName],
PeanutWindow USING [abortFlag, AddButton, AddCommand, Create, Destroy, OutputRope],
Process USING [Detach],
Rope USING [Equal, ROPE, Substr],
ViewerClasses USING [Viewer],
ViewerOps USING [CloseViewer, DestroyViewer, OpenIcon, SaveViewer];
PeanutTopImpl: CEDAR PROGRAM
IMPORTS Booting, Commander, FS, IO, Loader, PeanutProfile, PeanutRetrieve, PeanutSendMail, PeanutWindow, Process, Rope, ViewerOps
= BEGIN
Viewer: TYPE = ViewerClasses.Viewer;
ROPE: TYPE = Rope.ROPE;
mailFiles: LIST OF ROPE; -- short names of mail files, e.g. "Active" (not "Active.mail")
NewForm: Menus.MenuProc = {
PeanutSendMail.NewMsgForm[mouseButton, shift, control] };
AnswerMessage: Menus.MenuProc = {
PeanutSendMail.AnswerMsg[mouseButton, shift, control] };
ForwardMessage: Menus.MenuProc = {
PeanutSendMail.ForwardMsg[mouseButton, shift, control] };
SendMessage: Menus.MenuProc = {
PeanutSendMail.SendMsg[mouseButton, shift, control] };
NewMail: Menus.MenuProc = {
PeanutRetrieve.GetNewMsgs[] };
Abort: Menus.MenuProc = {
PeanutWindow.abortFlag ← TRUE };
SaveAll: Menus.MenuProc = {
killThem: BOOL ← PeanutProfile.killViewersOnSaveAll;
activeName: ROPE ← PeanutProfile.activeMailFile;
outgoingName: ROPE ← PeanutProfile.outgoingMailFile;
PeanutWindow.OutputRope["\nSaving all message sets:"];
FOR files: LIST OF ROPE ← mailFiles, files.rest UNTIL files=NIL DO
name: ROPE = files.first;
viewer: Viewer ← PeanutRetrieve.FindMailViewer[name];
IF viewer # NIL THEN {
IF viewer.newVersion THEN {
PeanutWindow.OutputRope["\nSaving "];
PeanutWindow.OutputRope[name];
ViewerOps.SaveViewer[viewer];
};
IF killThem THEN {
IF Rope.Equal[name, activeName, FALSE]
OR Rope.Equal[name, outgoingName, FALSE] THEN ViewerOps.CloseViewer[viewer]
ELSE ViewerOps.DestroyViewer[viewer];
};
};
ENDLOOP;
PeanutWindow.OutputRope["\nDone saving all message sets."];
};
MailFileButton: Menus.ClickProc = {
name: ROPE = NARROW[clientData];
SELECT mouseButton FROM
red => PeanutRetrieve.CopyMessages[to: name, delete: FALSE];
yellow => ViewerOps.OpenIcon[PeanutRetrieve.GetMailViewer[name]];
blue => PeanutRetrieve.CopyMessages[to: name, delete: TRUE];
ENDCASE;
};
restartAfterRollback: BOOLFALSE;
PeanutCheckpointProc: Booting.CheckpointProc = {
CloseDown[]; restartAfterRollback ← TRUE };
PeanutRollbackProc: Booting.RollbackProc = {
IF restartAfterRollback THEN TRUSTED {Process.Detach[FORK StartPeanut[]]}};
CloseDown: PROC = {
PeanutRetrieve.CloseConnection[] };
EnumerateMailFileNames: PROC[action: PROC[ROPE]] = {
MailFileProc: FS.NameProc --[fullFName: ROPE] RETURNS[continue: BOOL]-- = {
name, base: ROPE; cp: FS.ComponentPositions;
[fullFName: name, cp: cp] ← FS.ExpandName[fullFName];
base ← Rope.Substr[base: name, start: cp.base.start, len: cp.base.length];
action[base]; RETURN[continue: TRUE];
};
FS.EnumerateForNames[pattern: "*.mail!H", proc: MailFileProc,
wDir: PeanutProfile.workingDirectory];
};
GetMailFileList: PROC RETURNS[LIST OF ROPE] = {
head, tail: LIST OF ROPENIL;
AddNameToList: PROC[name: ROPE] = {
item: LIST OF ROPE = LIST[name];
IF head=NIL THEN head ← item ELSE tail.rest ← item;
tail ← item;
};
EnumerateMailFileNames[AddNameToList];
RETURN[head];
};
herald: ROPE ~ IO.PutFR["Peanut of %g\n", IO.time[Loader.BCDBuildTime[StartPeanut]]];
StartPeanut: PROC = {
AddMailFileButtons: PROC = {
FOR names: LIST OF ROPE ← mailFiles, names.rest UNTIL names=NIL DO
name: ROPE = names.first;
PeanutWindow.AddButton[name: name, proc: MailFileButton, data: name,
redisplay: names.rest=NIL];
ENDLOOP;
};
IF PeanutSendMail.AuthenticateUser[] THEN
[] ← PeanutRetrieve.NewUser[PeanutSendMail.userRName];
IF PeanutWindow.Create[] THEN { -- created a new one
mailFiles ← GetMailFileList[];
AddMailFileButtons[];
PeanutWindow.OutputRope[herald];
PeanutWindow.OutputRope["MIDDLE click mail file button to open the file\n"];
PeanutWindow.OutputRope["LEFT click to copy selected message(s)\n"];
PeanutWindow.OutputRope["RIGHT click to move selected message(s)\n"];
}
ELSE { -- restarting, probably after Rollback; check for new Mail files
MatchLists: PROC[a, b: LIST OF ROPE] RETURNS[BOOL] = {
UNTIL a=NIL OR b=NIL DO
IF NOT Rope.Equal[a.first, b.first, FALSE] THEN RETURN[FALSE];
a ← a.rest; b ← b.rest;
ENDLOOP;
RETURN[a=NIL AND b=NIL];
};
oldMailFiles: LIST OF ROPE = mailFiles;
mailFiles ← GetMailFileList[];
IF NOT MatchLists[oldMailFiles, mailFiles] THEN {
PeanutWindow.Destroy[];
[] ← PeanutWindow.Create[];
AddMailFileButtons[];
};
};
};
PeanutCommand: Commander.CommandProc = { StartPeanut[] };
PeanutWindow.AddCommand[name: "NewMail", proc: NewMail];
PeanutWindow.AddCommand[name: "NewForm", proc: NewForm];
PeanutWindow.AddCommand[name: "Answer", proc: AnswerMessage];
PeanutWindow.AddCommand[name: "Forward", proc: ForwardMessage];
PeanutWindow.AddCommand[name: "Send", proc: SendMessage];
PeanutWindow.AddCommand[name: "Abort", proc: Abort];
PeanutWindow.AddCommand[name: "SaveAll", proc: SaveAll];
Booting.RegisterProcs[c: PeanutCheckpointProc, r: PeanutRollbackProc];
Commander.Register[key: "Peanut", proc: PeanutCommand, doc: "For retrieving and sending mail"];
END.