DIRECTORY Containers, Icons USING [IconFlavor], FS USING [Error, OpenFile, Create, SetKeep, StreamFromOpenFile], IO, Labels USING [Set], Menus, MessageWindow USING [Append], Process USING [Detach, Pause, SecondsToTicks], Rope, TypeScript USING [Create], UserProfile USING [Boolean], ViewerClasses USING [Viewer], ViewerEvents USING [EventRegistration, UnRegisterEventProc], ViewerOps, ViewerIO USING [CreateViewerStreams], ViewerSpecs, WalnutOps USING [ServerInfo, ActiveMsgSetName, AcceptNewMail, GetNewMail, RecordNewMailInfo, RegisterReporter, Shutdown, StartNewMail, UnregisterReporter], WalnutNewMail USING [DisableMailRetrieval, EnableMailRetrieval], WalnutSendOps USING [userRName, RegisterReporter, UnregisterReporter], WalnutControlInternal USING [ mailNotifyLabel, mustQuitWalnut, WaitCallOutcome, walnutMenu, workingMenu, ChangeMenu, DoWaitCall], WalnutDisplayerInternal USING [AddNewMsgsToActive], WalnutWindowInternal USING [MailState, MsgSetButton, firstMsgSetButton, selectedMsgSetButtons, msgSetsTViewer, personalMailDB, newMailIcon, walnut, walnutEventReg, walnutIcon, walnutTS, GetButton], WalnutWindow USING []; WalnutWindowInternalImpl: CEDAR PROGRAM IMPORTS Labels, MessageWindow, FS, IO, Process, Rope, UserProfile, TypeScript, ViewerEvents, ViewerOps, ViewerIO, WalnutOps, WalnutControlInternal, WalnutNewMail, WalnutSendOps, WalnutDisplayerInternal, WalnutWindowInternal EXPORTS WalnutWindowInternal, WalnutWindow = BEGIN OPEN WalnutControlInternal, WalnutWindowInternal; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; Viewer: TYPE = ViewerClasses.Viewer; wtsOut: IO.STREAM _ NIL; Report: PUBLIC PROC[msg1, msg2, msg3: ROPE _ NIL] = { DoReport[msg1, msg2, msg3, TRUE] }; ReportRope: PUBLIC PROC[msg1, msg2, msg3: ROPE _ NIL] = { DoReport[msg1, msg2, msg3, FALSE] }; DoReport: PROC[msg1, msg2, msg3: ROPE _ NIL, doCR: BOOL] = { IF wtsOut = NIL THEN { IF msg1#NIL THEN MessageWindow.Append[msg1]; IF msg2#NIL THEN MessageWindow.Append[msg2]; IF msg3#NIL THEN MessageWindow.Append[msg3]; RETURN }; IF msg1#NIL THEN wtsOut.PutRope[msg1]; IF msg2#NIL THEN wtsOut.PutRope[msg2]; IF msg3#NIL THEN wtsOut.PutRope[msg3]; IF doCR THEN wtsOut.PutChar['\n]; wtsOut.Flush[]; }; RetrieveNewMail: PUBLIC PROC = { Rnm: PROC = { ENABLE UNWIND => { ChangeMenu[walnutMenu, FALSE] }; responses: LIST OF WalnutOps.ServerInfo; complete: BOOL; numNew, total: INT _ 0; msB: MsgSetButton _ GetButton[WalnutOps.ActiveMsgSetName]; ChangeMenu[workingMenu, TRUE]; IF msB.msViewer # NIL THEN IF msB.msViewer.destroyed THEN msB.msViewer _ NIL; IF msB.msViewer = NIL THEN { -- not displayed [responses, complete] _ WalnutOps.GetNewMail[msB.msgSet.version, NIL]; numNew _ -1; WalnutOps.AcceptNewMail[msB.msgSet.version]; } ELSE [responses, complete, numNew] _ WalnutDisplayerInternal.AddNewMsgsToActive[msB]; IF ~complete THEN { Report[" There were problems with GetNewMail - some messages not available; try again"]; ChangeMenu[walnutMenu, FALSE]; RETURN }; FOR rL: LIST OF WalnutOps.ServerInfo _ responses, rL.rest UNTIL rL = NIL DO total _ total + rL.first.num; ENDLOOP; IF total = 0 THEN Report["No messages were on the newMailLog"] ELSE { FOR rL: LIST OF WalnutOps.ServerInfo _ responses, rL.rest UNTIL rL = NIL DO ReportRope[rL.first.server]; IF rL.first.num = 0 THEN Report[" ... empty"] ELSE { IF rL.first.num = 1 THEN Report[" delivered 1 message"] ELSE Report[IO.PutFR[" delivered %g messages", IO.int[rL.first.num]]]; }; ENDLOOP; IF (numNew >= 0) AND (total # numNew) THEN { IF numNew = 0 THEN Report["\nNo new messages added to database"] ELSE Report[IO.PutFR["\nOnly %g messages were new", IO.int[numNew]] ]; }; }; SetMailState[noMail]; ChangeMenu[walnutMenu, FALSE]; }; [] _ DoWaitCall[Rnm]; }; EnableNewMail: PUBLIC PROC = { progress: BOOL = UserProfile.Boolean[key: "Walnut.ReportNewMailProgress", default: FALSE]; progressLog: ROPE = Rope.Cat["///Users/", WalnutSendOps.userRName, "/WalnutNewMailProgress.log"]; FS.SetKeep[progressLog, 5 ! FS.Error => CONTINUE]; IF newMailProgressStream = NIL THEN IF progress THEN { newMailProgressTS _ TypeScript.Create[ info: [name: "NewMail Retrieval", iconic: FALSE, column: right, openHeight: 64], paint: FALSE]; ViewerOps.TopViewer[viewer: newMailProgressTS, paint: TRUE]; newMailProgressTS.inhibitDestroy _ TRUE; newMailProgressStream _ ViewerIO.CreateViewerStreams[ name: NIL, viewer: newMailProgressTS, backingFile: progressLog].out; } ELSE { of: FS.OpenFile = FS.Create[progressLog, TRUE, 2, TRUE, 5]; newMailProgressStream _ FS.StreamFromOpenFile[of, $write]; }; WalnutNewMail.EnableMailRetrieval[ reportProc: ReportProc, progressProc: ProgressReport, getMailLog: GetMailLog, recordMailInfo: RecordNewMailInfo, notifyWhenMailRetrieved: NotifyWhenMailRetrieved]; IF newMailProgressTS # NIL THEN newMailProgressTS.inhibitDestroy _ FALSE; }; DisableNewMail: PUBLIC PROC = { WalnutNewMail.DisableMailRetrieval[]; IF newMailProgressStream # NIL THEN { IF newMailProgressTS = NIL THEN newMailProgressStream.Close[] ELSE IF ~newMailProgressTS.destroyed THEN { newMailProgressStream.Close[]; ViewerOps.DestroyViewer[newMailProgressTS]; }; newMailProgressStream _ NIL; newMailProgressTS _ NIL; }; }; tsLogName: ROPE = "///Temp/Walnut/Walnut.TypescriptLog"; OpenTS: PUBLIC PROC[r: ROPE _ NIL, doRegister: BOOL _ TRUE] = { FS.SetKeep[tsLogName, 10 ! FS.Error => CONTINUE]; -- if tsLogName doesn't exist IF wtsOut = NIL THEN { wtsOut _ ViewerIO.CreateViewerStreams[NIL, walnutTS, tsLogName].out; IF r # NIL THEN wtsOut.PutRope[r]; IF doRegister THEN { WalnutSendOps.RegisterReporter[wtsOut]; WalnutOps.RegisterReporter[wtsOut]; }; }; }; CloseTS: PUBLIC PROC = { IF wtsOut # NIL THEN wtsOut.Close[]; WalnutSendOps.UnregisterReporter[wtsOut]; WalnutOps.UnregisterReporter[wtsOut]; wtsOut _ NIL; }; GetTSStream: PUBLIC PROC RETURNS[IO.STREAM] = { RETURN[wtsOut] }; CloseDownWalnut: PUBLIC PROC = { v: Viewer _ walnut; IF walnut = NIL THEN RETURN; -- not running walnut.inhibitDestroy _ TRUE; DisableNewMail[]; ChangeMenu[workingMenu, FALSE]; selectedMsgSetButtons _ firstMsgSetButton _ NIL; TakeDownWalnutViewers[]; ReportRope["Closing database and saving log ..."]; WalnutOps.Shutdown[]; IF walnutEventReg # NIL THEN ViewerEvents.UnRegisterEventProc[walnutEventReg, destroy]; walnutEventReg _ NIL; walnut _ NIL; -- don't let others try to use Report mailNotifyLabel _ NIL; WalnutSendOps.UnregisterReporter[wtsOut]; WalnutOps.UnregisterReporter[wtsOut]; wtsOut.Close[]; wtsOut _ NIL; mustQuitWalnut _ NIL; v.inhibitDestroy _ FALSE; msgSetsTViewer _ NIL; ViewerOps.DestroyViewer[v]; }; EnumWalnutViewers: PUBLIC PROC[keepSeparate: BOOL] RETURNS [msgSetList, msgList: LIST OF Viewer] = { Enum: ViewerOps.EnumProc = { IF ViewerOps.FetchProp[v, $WalnutMsgSetName] # NIL THEN { msgSetList_ CONS[v, msgSetList]; RETURN[TRUE] }; IF ViewerOps.FetchProp[v, $WalnutMsgName] # NIL THEN { IF keepSeparate THEN msgList_ CONS[v, msgList] ELSE msgSetList_ CONS[v, msgSetList]; RETURN[TRUE] }; }; ViewerOps.EnumerateViewers[Enum] }; TakeDownWalnutViewers: PUBLIC PROC = { msgSetL, msgL: LIST OF Viewer; [msgSetL, msgL] _ EnumWalnutViewers[TRUE]; FOR vL: LIST OF Viewer _ msgL, vL.rest UNTIL vL=NIL DO IF ViewerOps.FetchProp[vL.first, $Frozen] = NIL THEN ViewerOps.DestroyViewer[vL.first]; ENDLOOP; FOR vL: LIST OF Viewer _ msgSetL, vL.rest UNTIL vL=NIL DO ViewerOps.DestroyViewer[vL.first]; ENDLOOP; }; newMailProgressTS: Viewer; newMailProgressStream: STREAM _ NIL; ReportProc: PROC[r: ROPE] = { Report[r] }; ProgressReport: PROC[r: ROPE] = { IF newMailProgressTS # NIL THEN IF newMailProgressTS.destroyed THEN { newMailProgressTS _ NIL; newMailProgressStream _ NIL; }; IF newMailProgressStream # NIL THEN { newMailProgressStream.PutRope[r]; newMailProgressStream.Flush[]; }; }; GetMailLog: PROC RETURNS[strm: STREAM] = { outcome: WalnutControlInternal.WaitCallOutcome; Gml: PROC = { strm _ WalnutOps.StartNewMail[] }; IF (outcome _ DoWaitCall[Gml]) = ok THEN { SetMailState[retrieving]; RETURN; }; IF outcome = notRunning THEN Process.Pause[Process.SecondsToTicks[20]]; outcome _ DoWaitCall[Gml]; -- try again IF outcome = ok THEN SetMailState[retrieving]; }; RecordNewMailInfo: PROC[logLen: INT, server: ROPE, num: INT] RETURNS[ok: BOOL] = { Rnml: PROC = { ok _ FALSE; WalnutOps.RecordNewMailInfo[logLen, server, num]; ok _ TRUE; }; [] _ DoWaitCall[Rnml]; }; NotifyWhenMailRetrieved: PROC[ok: BOOL, someMail: BOOL] = { IF ~someMail THEN { SetMailState[noMail]; RETURN}; SetMailState[thereIsMail]; IF personalMailDB THEN { autoNewMail: BOOL _ UserProfile.Boolean[key: "Walnut.AutoNewMail", default: FALSE]; IF autoNewMail THEN TRUSTED { Process.Detach[FORK RetrieveNewMail[] ] }; }; }; SetMailState: PUBLIC PROC[mailState: MailState] = { status: ROPE; icon: Icons.IconFlavor _ walnutIcon; IF walnut = NIL THEN RETURN; SELECT mailState FROM noMail => status _ "There is no new mail at %g"; retrieving => status _ "Mail is being retrieved at %g"; thereIsMail => { icon _ newMailIcon; status _ "You have new mail at %g"; }; gvWaiting => status _ "Waiting (15 sec) for initial grapevine response at %g"; noGV => status _ "No mailbox state reported from grapevine at %g"; noServers => status _ "All of the mail servers are down at %g"; gvMail => status _ "Mail on grapevine at %g"; ENDCASE => NULL; IF walnut.icon # icon THEN { walnut.icon_ icon; IF walnut.iconic THEN ViewerOps.PaintViewer[walnut, all]; }; Labels.Set[mailNotifyLabel, IO.PutFR[status, IO.time[]] ]; }; END. ÔWalnutWindowInternalImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Willie-Sue, September 29, 1986 1:24:26 pm PDT Contents: (Internal communication for) Top level Viewer for Walnut Last edit by: Willie-Sue on: January 7, 1985 9:22:19 am PST Donahue, January 2, 1985 3:42:26 pm PST Walnut Viewers types and global data * * * * * * * * * * * * exported to WalnutWindowInternal clean up after Walnut * * * * * * * * * * support for new mail Ê ã˜šÏb™Jšœ Ïmœ1™