PeanutTopImpl.mesa
Copyright Ó 1983, 1984, 1989, 1990, 1992 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: Gasbarro June 24, 1986 1:16:19 pm PDT
Willie-Sue, December 13, 1989 4:58:24 pm PST
Michael Plass, January 9, 1992 3:19 pm PST
Last changed by Pavel on March 8, 1990 3:20 pm PST
Doug Wyatt, September 13, 1990 1:42 pm PDT
Jules Bloomenthal July 1, 1992 1:41 pm PDT
DIRECTORY Commander, IO, Menus, PeanutProfile, PeanutRetrieve, PeanutSendMail, PeanutWindow, PFS, PFSNames, PriorityQueue, Rope, Tioga, TiogaFileOps, TiogaIO, TiogaOps, TiogaOpsDefs, UserProfile, ViewerClasses, ViewerOps, ViewerTools, XNSCredentials;
PeanutTopImpl: CEDAR MONITOR
IMPORTS Commander, IO, PeanutProfile, PeanutRetrieve, PeanutSendMail, PeanutWindow, PFS, PFSNames, PriorityQueue, TiogaIO, Rope, TiogaFileOps, TiogaOps, UserProfile, ViewerOps, ViewerTools, XNSCredentials
EXPORTS TiogaFileOps -- for opaque type
= BEGIN
Node: TYPE = REF NodeBody;
NodeBody: PUBLIC TYPE = Tioga.NodeRep;
Viewer: TYPE = ViewerClasses.Viewer;
ROPE: TYPE = Rope.ROPE;
mailFiles: LIST OF ROPE; -- short names of mail files, e.g. "Active" (not "Active.mail")
NewMessage: Menus.ClickProc = {
PeanutSendMail.NewMsgForm[];
};
AnswerMessage: Menus.ClickProc = {
transport: ATOM ¬ NARROW[clientData];
PeanutSendMail.AnswerMsg[includeOriginal: shift, transport: transport]
};
ForwardMessage: Menus.ClickProc = {
PeanutSendMail.ForwardMsg[];
};
SendMessage: Menus.ClickProc = {
transport: ATOM ¬ NARROW[clientData];
PeanutSendMail.SendMsg[transport: transport]
};
GetMail: Menus.ClickProc = {
PeanutRetrieve.GetNewMsgs[];
};
AbortSend: Menus.ClickProc = {
PeanutSendMail.AbortSend[];
};
SaveAll: Menus.ClickProc = {
PeanutWindow.SaveAllMailFiles[mailFiles, mouseButton = $blue];
};
NewMailFile: Menus.ClickProc ~ {
name: ROPE ~ ViewerTools.GetSelectionContents[];
fileName: ROPE ~ Rope.Cat[PeanutProfile.workingDirectory, name, ".mail"];
IF name = NIL THEN
PeanutWindow.OutputRope["\nPlease select a name for the new mail file."]
ELSE IF PFS.FileLookup[PFS.PathFromRope[fileName], NIL] # NIL THEN
PeanutWindow.OutputRope["\nThat mail file already exists."]
ELSE {
root: Node ~ TiogaIO.FromRope[Rope.Concat[name, ".mail"]];
TiogaFileOps.SetStyle[root, "Mail"];
TiogaOps.PutProp[root, $NewlineDelimiter, "\r"];
[] ¬ TiogaIO.ToFile[PFS.PathFromRope[fileName], root
! PFS.Error => {
PeanutWindow.OutputRope[Rope.Concat["\nUnexpected PFS.Error: ", error.explanation]];
GO TO Return;
}];
PeanutWindow.AddButton[name: name, proc: MailFileButton, data: name,
redisplay: TRUE];
mailFiles ¬ CONS[name, mailFiles];
};
EXITS
Return => RETURN;
};
MailFileButton: Menus.ClickProc = {
name: ROPE = NARROW[clientData];
SELECT mouseButton FROM
red => PeanutWindow.CopyMessages[to: name, delete: FALSE];
yellow => ViewerOps.OpenIcon[PeanutWindow.GetMailViewer[name]];
blue => PeanutWindow.CopyMessages[to: name, delete: TRUE];
ENDCASE;
};
EnumerateMailFileNames: PROC[action: PROC[ROPE]] = {
pattern: PFS.PATH ¬ PFS.PathFromRope[Rope.Concat[PeanutProfile.workingDirectory, "*.mail!H"]];
MailFileProc: PFS.NameProc --[name: PATH] RETURNS[continue: BOOL]-- = {
base: ROPE ¬ PFSNames.ComponentRope[PFSNames.ShortName[name]];
IF base # NIL THEN action[ base.Substr[0, base.FindBackward["."]] ];
RETURN[continue: TRUE];
};
PFS.EnumerateForNames[pattern: pattern, proc: MailFileProc ! PFS.Error => { PeanutWindow.OutputRope[IO.PutFR["PFS.Error for %g : %g\n", [rope[PeanutProfile.workingDirectory]], [rope[error.explanation]] ]]; CONTINUE} ];
};
MailFileListSortPred: PriorityQueue.SortPred ~ {
s1: ROPE ~ NARROW[x]; s2: ROPE ~ NARROW[y];
RETURN[Rope.Compare[s1: s1, s2: s2, case: FALSE]=greater]; -- the last shall be first ...
};
GetMailFileList: PROC RETURNS [result: LIST OF ROPE ¬ NIL] = {
pq: PriorityQueue.Ref ~ PriorityQueue.Create[MailFileListSortPred];
AddNameToList: PROC [name: ROPE] = { PriorityQueue.Insert[pq, name] };
EnumerateMailFileNames[AddNameToList];
UNTIL PriorityQueue.Empty[pq] DO
name: ROPE ~ NARROW[PriorityQueue.Remove[pq]];
result ¬ CONS[name, result];
ENDLOOP;
};
herald: ROPE ~ IO.PutFR["Peanut of %g\n", IO.time[Loader.BCDBuildTime[StartPeanut]]];
herald: ROPE ~ "Peanut for PCedar\n";
PeanutCheckpointProc: Booting.CheckpointProc = { 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[];
PeanutRetrieve.NewUser[NIL];
IF PeanutWindow.Create[Quit, Save] 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"];
};
};
Quit: PROC ~ {PeanutRetrieve.CloseConnection[]};
Save: PROC ~ {PeanutWindow.SaveAllMailFiles[mailFiles, FALSE]};
PeanutCommand: ENTRY Commander.CommandProc = {
ENABLE UNWIND => NULL;
IF XNSCredentials.GetIdentity[] = NIL THEN { -- User hasn't logged in to XNS yet
cmd.out.PutRope["Please enter your XNS credentials:\n"];
UNTIL XNSCredentials.DoLogin[cmd] DO ENDLOOP;
};
StartPeanut[];
};
DoInit: PROC = {
procsL: LIST OF MailSend.MailSendProcsRef = MailSend.GetRegisteredSendProcsList[];
guardedGV: BOOLTRUE;
TRUSTED { guardedGV ← ( List.Length[LOOPHOLE[procsL]] > 1 ) };
PeanutWindow.AddCommand[name: "GetMail", proc: GetMail];
PeanutWindow.AddCommand[name: "NewMessage", proc: NewMessage];
PeanutWindow.AddCommand[name: "SaveAll", proc: SaveAll];
PeanutWindow.AddCommand[name: "NewMailFile", proc: NewMailFile];
FOR procs: LIST OF MailSend.MailSendProcsRef ← procsL, procs.rest UNTIL procs = NIL DO
name: ROPE ← Rope.Concat[Atom.GetPName[procs.first.which], "Ans"];
PeanutWindow.AddCommand[name: name, proc: AnswerMessage, data: procs.first.which, lineNum: 1];
ENDLOOP;
PeanutWindow.AddCommand[name: "Answer", proc: AnswerMessage, data: $xns, lineNum: 1];
PeanutWindow.AddCommand[name: "Forward", proc: ForwardMessage, lineNum: 1];
FOR procs: LIST OF MailSend.MailSendProcsRef ← procsL, procs.rest UNTIL procs = NIL DO
name: ROPE ← Rope.Concat[Atom.GetPName[procs.first.which], "Send"];
PeanutWindow.AddCommand[name: name, proc: SendMessage, data: procs.first.which, guarded: (procs.first.which = $gv) AND guardedGV, lineNum: 1];
ENDLOOP;
PeanutWindow.AddCommand[name: "SendMessage", proc: SendMessage, data: $xns, lineNum: 1];
PeanutWindow.AddCommand[name: "AbortSend", proc: AbortSend, lineNum: 1];
Booting.RegisterProcs[c: PeanutCheckpointProc];
UserProfile.CallWhenProfileChanges[NewProfile];
Commander.Register[key: "Peanut", proc: PeanutCommand, doc: "For retrieving and sending mail"];
};
DoInit[];
END.