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 ~ "Peanut for PCedar\n"; 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 = { PeanutWindow.AddCommand[name: "GetMail", proc: GetMail]; PeanutWindow.AddCommand[name: "NewMessage", proc: NewMessage]; PeanutWindow.AddCommand[name: "SaveAll", proc: SaveAll]; PeanutWindow.AddCommand[name: "NewMailFile", proc: NewMailFile]; PeanutWindow.AddCommand[name: "Answer", proc: AnswerMessage, data: $xns, lineNum: 1]; PeanutWindow.AddCommand[name: "Forward", proc: ForwardMessage, lineNum: 1]; PeanutWindow.AddCommand[name: "SendMessage", proc: SendMessage, data: $xns, lineNum: 1]; PeanutWindow.AddCommand[name: "AbortSend", proc: AbortSend, lineNum: 1]; UserProfile.CallWhenProfileChanges[NewProfile]; Commander.Register[key: "Peanut", proc: PeanutCommand, doc: "For retrieving and sending mail"]; }; DoInit[]; END. ¦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 herald: ROPE ~ IO.PutFR["Peanut of %g\n", IO.time[Loader.BCDBuildTime[StartPeanut]]]; PeanutCheckpointProc: Booting.CheckpointProc = { Sleep[] }; procsL: LIST OF MailSend.MailSendProcsRef = MailSend.GetRegisteredSendProcsList[]; guardedGV: BOOL _ TRUE; TRUSTED { guardedGV _ ( List.Length[LOOPHOLE[procsL]] > 1 ) }; 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; 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; Booting.RegisterProcs[c: PeanutCheckpointProc]; Κς•NewlineDelimiter –(cedarcode) style˜code– "Cedar" stylešœ™Kšœ ΟeœF™QK– "Cedar" stylešœ%™%Kšœ.™.K™-K™5K™,K™*K™2K™*K™*—K˜šΟk œœ žžœœœœœœ žžœ˜œ˜ϊK˜—KšΠln œžœž˜Kšžœ žœ?žœu˜ΜKšžœΟc˜'šœž˜K˜Kšœžœžœ ˜Kšœ žœžœ˜&K˜Kšœžœ˜$Kšžœžœžœ˜K˜šœ žœžœžœ ?˜XK˜—šΟn œ˜Kšœ˜Kšœ˜—K˜š‘ œ˜"Kšœ žœžœ ˜%KšœF˜FKšœ˜—K˜š‘œ˜#Kšœ˜Kšœ˜—K˜š‘ œ˜ Kšœ žœžœ ˜%Kšœ,˜,Kšœ˜—K˜š‘œ˜Kšœ˜Kšœ˜—K˜š‘ œ˜Kšœ˜Kšœ˜—K˜š‘œ˜K˜>Kšœ˜—K˜š‘ œ˜ Kšœžœ&˜0Kšœ žœ;˜IK˜šžœžœž˜KšœH˜H—šžœžœžœ žœžœžœžœ˜CKšœ;˜;—šžœ˜K˜:K˜K˜$K˜0šœžœ˜4šœžœ ˜KšœT˜TKšžœžœ˜ K˜——šœD˜DKšœ žœ˜—Kšœ žœ˜"Kšœ˜—šž˜Kšœ žœ˜—K˜—K˜š‘œ˜#Kšœžœžœ ˜ šžœ ž˜Kšœ3žœ˜:K˜?Kšœ4žœ˜:Kšžœ˜—K˜—K˜š‘œžœ žœžœ˜4Kšœ žœžœžœG˜^š ‘ œžœ  œž œ˜GKšœžœ4˜>Kšžœžœžœ2˜DKšžœ žœ˜K˜—Kšžœ:žœ$žœhžœ˜ΪK˜—K˜š‘œ˜0Kš œžœžœ žœžœ˜+Kšžœ$žœ  ˜YK˜K˜—š‘œžœžœ žœžœžœžœ˜>K˜CKš‘ œžœžœ'˜FK˜&šžœž˜ Kšœžœžœ˜.Kšœ žœ˜Kšžœ˜—K˜K˜—Kšœžœžœžœ)™UKšœžœ˜%K˜Kš‘œ'™;K˜š‘ œ/˜9K˜—Kšœžœžœ˜š‘œžœžœ˜Kšžœžœžœ˜K˜4K˜!Kš žœžœžœ žœžœžœ˜0Kšœ˜Kšœ žœ˜Kšœ˜K˜—š‘œžœžœ˜Kšžœžœžœ˜Kšžœžœžœžœ˜Kšœ˜Kšœ žœ˜Kšœ˜K˜—š‘ œžœžœ˜š‘œžœ˜š žœžœžœžœžœžœž˜BKšœžœ˜šœD˜DKšœžœ˜—Kšžœ˜—K˜K˜—Kšœ˜Kšœžœž˜šžœ!žœ ˜>K˜Kšœ˜Kšœ ˜ KšœL˜LKšœD˜DKšœE˜EKšœ˜—K˜K˜—Kš‘œžœ&˜0Kš‘œžœ-žœ˜?K˜š‘ œžœ˜.Kšžœžœžœ˜šžœ žœžœ #˜PK˜8Kšžœžœžœ˜-K˜—Kšœ˜Kšœ˜K˜—š‘œžœ˜KšœžœžœC™RKšœ žœžœ™Kšžœžœ™>K˜Kšœ8˜8Kšœ>˜>Kšœ8˜8Kšœ@˜@K˜š žœžœžœ0žœ žœž™VKšœžœ8™BKšœ^™^Kšžœ™—KšœU˜UKšœK˜Kš žœžœžœ0žœ žœž™VKšœžœ9™CKšœsžœ™ŽKšžœ™—KšœX˜XKšœH˜HK˜Kšœ/™/Kšœ/˜/K˜K˜_K˜—K˜K˜ K˜K˜—Kšžœ˜K˜—…—F$ή