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
Last Edited by: Gasbarro June 24, 1986 1:16:19 pm PDT
Michael Plass, June 24, 1986 2:47:37 pm PDT
DIRECTORY
Booting USING [CheckpointProc, RegisterProcs],
Commander USING [CommandProc, Register],
FS USING [ComponentPositions, EnumerateForNames, ExpandName, NameProc],
Idle,
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, peanutParent],
Rope USING [ROPE, Substr],
UserProfile,
ViewerClasses USING [Viewer],
ViewerOps USING [CloseViewer, DestroyViewer, OpenIcon, SaveViewer];
PeanutTopImpl: CEDAR MONITOR
IMPORTS Booting, Commander, FS, Idle, IO, Loader, PeanutProfile, PeanutRetrieve, PeanutSendMail, PeanutWindow, Rope, UserProfile, 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 ViewerOps.DestroyViewer[viewer];
};
ENDLOOP;
PeanutWindow.OutputRope["\nDone saving all message sets."];
IF killThem THEN ViewerOps.CloseViewer[PeanutWindow.peanutParent];
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;
};
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 ROPE ← NIL;
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]]];
PeanutCheckpointProc: Booting.CheckpointProc = { Sleep[] };
IdleHandler: Idle.IdleHandler ~ {
IF reason = becomingIdle
THEN Sleep[] };
NewProfile: UserProfile.ProfileChangedProc ~ { Awake[] };
asleep: BOOL ← FALSE;
Sleep:
ENTRY
PROC = {
ENABLE UNWIND => NULL;
w: ViewerClasses.Viewer ← PeanutWindow.peanutParent;
PeanutRetrieve.CloseConnection[];
IF w = NIL OR w.destroyed OR asleep THEN RETURN;
PeanutWindow.Destroy[];
asleep ← TRUE;
};
Awake:
ENTRY
PROC = {
ENABLE UNWIND => NULL;
IF NOT asleep THEN RETURN;
StartPeanut[];
asleep ← FALSE;
};
StartPeanut:
INTERNAL
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;
};
PeanutWindow.Destroy[];
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"];
};
};
PeanutCommand:
ENTRY Commander.CommandProc = {
ENABLE UNWIND => NULL;
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];
UserProfile.CallWhenProfileChanges[NewProfile];
[] ← Idle.RegisterIdleHandler[IdleHandler];
Commander.Register[key: "Peanut", proc: PeanutCommand, doc: "For retrieving and sending mail"];
END.