DIRECTORY FileViewerOps USING [], FS USING [Error, ExpandName, FileInfo], Icons USING [IconFlavor, NewIconFromFile], IO USING [PutF1, PutRope, ROS, STREAM], Menus USING [AppendMenuEntry, ClickProc, CreateEntry, FindEntry, MenuEntry, ReplaceMenuEntry], MessageWindow USING [Append], Process USING [CheckForAbort, Pause, SecondsToTicks], Rope USING [Cat, Concat, Fetch, Find, Length, Replace, ROPE, Run], TiogaMenuOps USING [DefaultMenus, Open], ViewerClasses USING [Viewer], ViewerOps USING [BlinkIcon, CreateViewer, DestroyViewer, EnumerateViewers, EnumProc, FindViewer, OpenIcon, PaintViewer]; FileViewerOpsImpl: CEDAR PROGRAM IMPORTS FS, Icons, IO, Menus, MessageWindow, Process, Rope, TiogaMenuOps, ViewerOps EXPORTS FileViewerOps = BEGIN Viewer: TYPE = ViewerClasses.Viewer; ViewerSaveStatus: TYPE = {none, old, new, saving}; ShowLog: PUBLIC PROC [fileName: Rope.ROPE, destroyIt: BOOL _ FALSE, createIconic: BOOL _ FALSE, blinkIfIconic: BOOL _ TRUE] = { logViewer: ViewerClasses.Viewer _ FindFileViewer[fileName]; IF destroyIt THEN {IF logViewer # NIL THEN ViewerOps.DestroyViewer[logViewer]} ELSE { IF logViewer = NIL THEN { icon: Icons.IconFlavor; SELECT TRUE FROM Rope.Find[fileName, ".errlog", 0, FALSE] # -1 => icon _ typescript; Rope.Find[fileName, ".log", 0, FALSE] # -1 => icon _ typescript; Rope.Find[fileName, ".mesa", 0, FALSE] # -1 => icon _ needsToBeCompiled; ENDCASE => icon _ document; logViewer _ CreateLog[fileName, icon, createIconic]}; IF logViewer # NIL AND logViewer.iconic AND blinkIfIconic THEN ViewerOps.BlinkIcon[logViewer]}; }; WaitUntilSaved: PUBLIC PROC [fileName: Rope.ROPE, feedBack: IO.STREAM _ NIL] = { lastState: ViewerSaveStatus _ none; fileNameLen: INT _ Rope.Length[fileName _ FS.ExpandName[fileName].fullFName]; IF feedBack = NIL THEN feedBack _ IO.ROS[]; DO state: ViewerSaveStatus _ none; vName: Rope.ROPE _ NIL; innerCheck: ViewerOps.EnumProc = { IF Rope.Run[fileName, 0, v.file, 0, FALSE] # fileNameLen THEN RETURN; vName _ v.file; state _ CheckViewer[v]; SELECT state FROM new, saving => {vName _ v.file; RETURN [FALSE]}; ENDCASE => RETURN [TRUE]; }; Process.CheckForAbort[]; state _ none; vName _ NIL; ViewerOps.EnumerateViewers[innerCheck]; IF lastState # none AND state # lastState THEN IO.PutRope[feedBack, "\n"]; SELECT state FROM none => RETURN; lastState => {}; new => IO.PutF1[feedBack, "** Please save %g ...", [rope[vName]] ]; saving => IO.PutF1[feedBack, "** Saving %g ...", [rope[vName]] ]; ENDCASE => RETURN; Process.CheckForAbort[! ABORTED => IO.PutRope[feedBack, "\n"]]; lastState _ state; Process.Pause[Process.SecondsToTicks[1]]; ENDLOOP; }; AttachErrorLog: PUBLIC PROC [sourceFileName: Rope.ROPE] = { viewer: Viewer _ FindFileViewer[sourceFileName]; IF viewer # NIL THEN { AppendMenuEntry[viewer, "ErrorLog", OpenErrorLog]; SetIcon[viewer: viewer, from: document, to: needsToBeCompiled]}; }; RemoveErrorLog: PUBLIC PROC [sourceFileName: Rope.ROPE] = { errlogName: Rope.ROPE; errlog: Viewer; viewer: Viewer _ FindFileViewer[sourceFileName]; IF viewer # NIL THEN { RemoveMenuEntry[viewer, "ErrorLog"]; SetIcon[viewer: viewer, from: needsToBeCompiled, to: document]; }; errlogName _ ErrorLogName[sourceFileName]; WHILE (errlog _ ViewerOps.FindViewer[errlogName]) # NIL DO ViewerOps.DestroyViewer[errlog]; ENDLOOP; }; AppendMenuEntry: PROC [viewer: Viewer, name: Rope.ROPE, proc: Menus.ClickProc] = { FOR v: Viewer _ viewer, v.link WHILE v # NIL DO entry: Menus.MenuEntry _ Menus.FindEntry[v.menu, name]; IF entry = NIL THEN { entry _ Menus.CreateEntry[name: name, proc: proc, fork: FALSE]; Menus.AppendMenuEntry[menu: v.menu, line: 0, entry: entry]; IF NOT v.iconic THEN ViewerOps.PaintViewer[v, menu]; }; IF v.link = viewer THEN EXIT; ENDLOOP; }; RemoveMenuEntry: PROC [viewer: Viewer, name: Rope.ROPE] = { FOR v: Viewer _ viewer, v.link WHILE v # NIL DO entry: Menus.MenuEntry _ Menus.FindEntry[v.menu, name]; IF entry # NIL THEN { Menus.ReplaceMenuEntry[v.menu, entry]; -- deletes it IF NOT v.iconic THEN ViewerOps.PaintViewer[v, menu]; }; IF v.link = viewer THEN EXIT; ENDLOOP; }; OpenErrorLog: Menus.ClickProc = { log: Viewer; viewer: Viewer = NARROW[parent]; name: Rope.ROPE = ErrorLogName[viewer.name]; log _ ViewerOps.FindViewer[name]; IF log = NIL THEN log _ CreateLog[name, typescript, FALSE] ELSE IF log.iconic THEN ViewerOps.OpenIcon[log] ELSE ViewerOps.PaintViewer[log, client]; }; ErrorLogName: PROC [file: Rope.ROPE] RETURNS [errlog: Rope.ROPE] = { pos: INT _ Rope.Length[file]; WHILE (pos _ pos - 1) > 0 DO SELECT Rope.Fetch[file, pos] FROM '. => RETURN [Rope.Replace[base: file, start: pos+1, with: "errlog"]]; '>, '], '/ => EXIT; ENDCASE; ENDLOOP; RETURN [Rope.Concat[file, ".errlog"]]; }; FindFileViewer: PROC [file: Rope.ROPE] RETURNS [viewer: Viewer] = { FindViewer: ViewerOps.EnumProc = { IF Rope.Find[v.file, file, 0, FALSE] = 0 THEN {viewer _ v; RETURN [FALSE]} ELSE RETURN [TRUE]; }; ViewerOps.EnumerateViewers[FindViewer]; }; CreateLog: PROC [fileName: Rope.ROPE, icon: Icons.IconFlavor, iconic: BOOL] RETURNS [viewer: ViewerClasses.Viewer] = { IF ~FileExists[fileName] THEN { MessageWindow.Append[Rope.Cat[fileName, " does not exist."], TRUE]; RETURN; }; IF iconic THEN { viewer _ ViewerOps.CreateViewer[flavor: $Text, info: [name: fileName, file: fileName, iconic: iconic, icon: icon]]; IF viewer # NIL THEN TiogaMenuOps.DefaultMenus[viewer]; } ELSE { viewer _ TiogaMenuOps.Open[fileName]; IF viewer # NIL THEN viewer.icon _ icon; }; }; FileExists: PROC [fileName: Rope.ROPE] RETURNS [BOOL] = { bytes: INT _ -1; [bytes: bytes] _ FS.FileInfo[fileName ! FS.Error => CONTINUE]; RETURN [bytes >= 0]; }; SetIcon: PROC [viewer: Viewer, from, to: Icons.IconFlavor] = { IF to = unInit THEN RETURN; FOR v: Viewer _ viewer, v.link WHILE v # NIL DO IF from = unInit OR v.icon = from THEN IF v.icon # to THEN { v.icon _ to; IF v.iconic THEN ViewerOps.PaintViewer[v, all]; }; IF v.link = viewer THEN EXIT; ENDLOOP; }; CheckViewer: PROC [viewer: ViewerClasses.Viewer] RETURNS [ViewerSaveStatus] = { IF viewer # NIL AND NOT viewer.destroyed THEN { v: ViewerClasses.Viewer _ viewer; IF viewer.saveInProgress THEN RETURN [saving]; WHILE (v _ v.link) # NIL AND (v # viewer) DO IF v.saveInProgress THEN RETURN [saving]; ENDLOOP; IF viewer.newVersion THEN RETURN [new]; RETURN [old]; }; RETURN [none]; }; needsToBeCompiled: Icons.IconFlavor _ document; needsToBeCompiled _ Icons.NewIconFromFile["///UserExec.icons", 9 ! FS.Error => CONTINUE]; END. φFileViewerOpsImpl.mesa Copyright c 1984, 1985, 1986 by Xerox Corporation. All rights reserved. Bob Hagmann February 6, 1985 8:20:38 am PST Russ Atkinson (RRA) March 11, 1986 2:57:59 pm PST [v: ViewerClasses.Viewer] RETURNS [BOOL _ TRUE] Κ΄˜code™Kšœ Οmœ=™HK™+K™1K™šΟk ˜ Kšœžœ˜Kšžœžœ˜'Kšœžœ˜*Kšžœžœžœžœ˜'KšœžœS˜^Kšœžœ ˜Kšœžœ(˜5Kšœžœ-žœ˜BKšœ žœ˜(Kšœžœ ˜Kšœ žœi˜x——headšœžœž˜ Kšžœžœ žœ>˜SKšžœž˜K˜Kšœžœ˜$Kšœžœ˜2K˜—šΟnœž œžœ žœžœžœžœžœžœ˜Kšœ;˜;šžœ ˜ Kšžœžœ žœžœ$˜Ašžœ˜šžœ žœžœ˜Kšœ˜šžœžœž˜Kšœ"žœ˜CKšœžœ˜@Kšœ žœ#˜HKšžœ˜—Kšœ5˜5—Kš žœ žœžœžœžœ!˜_——K˜K˜—šŸœžœžœžœ žœžœžœ˜PKšœ#˜#Kšœ žœžœ!˜MKš žœ žœžœ žœžœ˜+šž˜Kšœ˜Kšœ žœžœ˜•StartOfExpansion3 -- [v: ViewerClasses.Viewer] RETURNS [BOOL _ TRUE]˜"KšΠck/™/Kšžœ"žœžœžœ˜EKšœ˜Kšœ˜šžœž˜Kšœ žœžœ˜0Kšžœžœžœ˜—K˜—Kšœ˜Kšœ ˜ Kšœžœ˜ K˜'Kšžœžœžœžœ˜Jšžœž˜Kšœžœ˜Kšœ˜Kšœžœ:˜CKšœ žœ5˜AKšžœžœ˜—Kšœžœžœ˜?K˜Kšœ)˜)Kšžœ˜—K˜K˜—šŸœžœžœžœ˜;Kšœ0˜0šžœ žœžœ˜Kšœ2˜2K˜@—K˜K˜—šŸœžœžœžœ˜;Kšœžœ˜K˜Kšœ0˜0šžœ žœžœ˜Kšœ$˜$K˜?K˜—Kšœ*˜*šžœ/žœž˜:Kšœ ˜ Kšžœ˜—K˜K˜—šŸœžœžœ˜Ršžœžœžœž˜/Kšœ7˜7šžœ žœžœ˜Kšœ8žœ˜?Kšœ;˜;Kšžœžœ žœ ˜4K˜—Kšžœžœžœ˜Kšžœ˜—K˜K˜—šŸœžœžœ˜;šžœžœžœž˜/Kšœ7˜7šžœ žœžœ˜Kšœ'Οc ˜4Kšžœžœ žœ ˜4K˜—Kšžœžœžœ˜Kšžœ˜—K˜K˜—šŸ œ˜!K˜ Kšœžœ ˜ Kšœ žœ˜,K˜!šžœžœ˜ Kšžœ#žœ˜-šžœžœ ˜Kšžœ˜Kšžœ$˜(——K˜K˜—š Ÿ œžœ žœžœžœ˜DKšœžœ˜šžœž˜šžœž˜!Kšœžœ:˜FKšœžœ˜Kšžœ˜—Kšžœ˜—Kšžœ ˜&Kšœ˜K˜—šŸœžœ žœžœ˜C˜"šžœžœ˜)Kšžœžœžœ˜!Kšžœžœžœ˜—K˜—K˜'K˜K˜—š Ÿ œžœžœ"žœžœ#˜všžœžœ˜Kšœ=žœ˜CKšž˜Kšœ˜—šžœ˜ šžœ˜Kšœs˜sKšžœ žœžœ#˜7K˜—šžœ˜Kšœ%˜%Kšžœ žœžœ˜(Kšœ˜——K˜K˜—š Ÿ œžœžœžœžœ˜9Kšœžœ˜Kšœžœžœ žœ˜>Kšžœ˜K˜K˜—šŸœžœ0˜>Kšžœ žœžœ˜šžœžœžœž˜/š žœžœžœžœ žœ˜