DIRECTORY FS USING [ComponentPositions, Error, ExpandName], Rope USING [Flatten, Length, ROPE, Run, SkipTo], ViewerClasses USING [Viewer], ViewerEvents USING [EventProc, EventRegistration, ViewerEvent], UserCredentials USING [Get], UserProfile USING [GetProfileName, ProfileChanged]; ViewerEventsImpl: CEDAR PROGRAM IMPORTS FS, Rope, UserCredentials, UserProfile EXPORTS ViewerEvents = BEGIN ROPE: TYPE = Rope.ROPE; EventProcs: TYPE = LIST OF RECORD[proc: ViewerEvents.EventProc, filter: REF, before: BOOL] ; eventProcs: ARRAY ViewerEvents.ViewerEvent OF EventProcs ; RegisterEventProc: PUBLIC PROC [proc: ViewerEvents.EventProc, event: ViewerEvents.ViewerEvent, filter: REF _ NIL, before: BOOL _ TRUE] RETURNS [ViewerEvents.EventRegistration] = { RETURN [eventProcs[event] _ CONS[[proc, filter, before], eventProcs[event]]]; }; UnRegisterEventProc: PUBLIC PROC [proc: ViewerEvents.EventRegistration, event: ViewerEvents.ViewerEvent] = { prev: EventProcs _ eventProcs[event]; IF prev = NIL THEN RETURN; IF proc=prev THEN { -- its the first one on the list eventProcs[event] _ eventProcs[event].rest; RETURN }; FOR l: EventProcs _ prev.rest, l.rest UNTIL l=NIL DO IF l=proc THEN { prev.rest _ l.rest; RETURN }; prev _ l; ENDLOOP; }; ProcessEvent: PUBLIC PROC [event: ViewerEvents.ViewerEvent, viewer: ViewerClasses.Viewer, before: BOOL] RETURNS [abort: BOOL _ FALSE] = BEGIN FOR l: EventProcs _ eventProcs[event], l.rest UNTIL l=NIL DO IF l.first.before # before THEN LOOP; IF l.first.filter = NIL OR l.first.filter = viewer OR (viewer # NIL AND l.first.filter = viewer.class.flavor) THEN { abort _ l.first.proc[ viewer, event, before ! ABORTED => {abort _ TRUE; EXIT}].abort; IF abort THEN RETURN}; ENDLOOP; END; NoticeProfileChanges: ViewerEvents.EventProc = { IF viewer # NIL THEN { fileName: ROPE _ NIL; cp: FS.ComponentPositions; SubstrEqual: PROC[s1: ROPE, pos1, len1: INT, s2: ROPE] RETURNS[BOOL] = { RETURN[len1=s2.Length AND s1.Run[pos1: pos1, s2: s2, case: FALSE]=len1] }; BaseIs: PROC[x: ROPE] RETURNS[BOOL] = { RETURN[SubstrEqual[s1: fileName, pos1: cp.base.start, len1: cp.base.length, s2: x]] }; ExtensionIs: PROC[x: ROPE] RETURNS[BOOL] = { RETURN[SubstrEqual[s1: fileName, pos1: cp.ext.start, len1: cp.ext.length, s2: x]] }; SimpleNameIs: PROC[x: ROPE] RETURNS[BOOL] = { RETURN[SubstrEqual[s1: fileName, pos1: cp.base.start, len1: (cp.ext.start+cp.ext.length)-cp.base.start, s2: x]] }; [fullFName: fileName, cp: cp] _ FS.ExpandName[viewer.file ! FS.Error => GOTO GiveUp]; IF ExtensionIs["profile"] THEN { notify: BOOL _ FALSE; profileName: ROPE _ UserProfile.GetProfileName[]; profileName _ profileName.Flatten[0, profileName.SkipTo[0, "!"]]; IF SimpleNameIs[profileName] THEN notify _ TRUE ELSE { userName: ROPE _ UserCredentials.Get[].name; userName _ userName.Flatten[0, userName.SkipTo[0, "."]]; IF BaseIs[userName] THEN notify _ TRUE ELSE IF profileName.Length=0 AND BaseIs["user"] THEN notify _ TRUE; }; IF notify THEN UserProfile.ProfileChanged[edit]; }; EXITS GiveUp => NULL; }; }; [] _ RegisterEventProc[NoticeProfileChanges, save, $Text, FALSE]; END. ΦViewerEventsImpl.mesa; McGregor on August 2, 1982 11:44 am Maxwell, January 11, 1983 12:27 pm Russ Atkinson, September 30, 1983 12:16 pm Doug Wyatt, December 14, 1983 3:11 pm [viewer: ViewerClasses.Viewer, event: ViewerEvent, before: BOOL] RETURNS[abort: BOOL _ FALSE] remove the version info (if any), so profile name has the form "xxx.profile" changed file is NOT the current profile, but it MAY be the right profile to use next remove the registry information Κ„– "Mesa" style˜šΟc™Jš#™#Jšœ"™"J™*J™%—J˜šΟk ˜ Jšžœžœ)˜1Jšœžœžœ˜0Jšœžœ ˜Jšœ žœ-˜?Jšœžœ˜Jšœ žœ"˜3J˜—šœž ˜Jšžœžœ$˜.Jšžœ ˜Jšœž˜—J˜Jšžœžœžœ˜Jš œ žœžœžœžœ'žœ žœ˜\Jšœ žœžœ ˜:J˜šΟnœžœž˜Jš œHžœžœ žœžœ˜gJšžœ%˜,Jšžœžœ-˜MJšœ˜J˜—šŸœžœž˜ JšœK˜KJ˜%Jšžœžœžœžœ˜šžœ žœ ˜4J˜+Jšžœ˜ —šžœ#žœžœž˜4Jšžœžœžœ˜.J˜ Jšžœ˜—Jšœ˜J˜—šŸ œžœž˜JšœHžœ˜MJšžœžœžœž˜%šžœ+žœžœž˜