DIRECTORY FileViewerOps USING [], FileViewerOpsBackdoor, FS, Icons, IO USING [PutF1, PutRope, ROS, STREAM], Menus USING [AppendMenuEntry, ClickProc, CreateEntry, FindEntry, MenuEntry, MouseButton, ReplaceMenuEntry], MessageWindow USING [Append], PFS, PFSCanonicalNames, Process USING [CheckForAbort, Pause, SecondsToTicks], RefTab USING [Fetch, Create, Delete, Ref, Store], Rope USING [Concat, Equal, Fetch, Find, Index, Length, Replace, ROPE, Run, Substr], TiogaMenuOps USING [DefaultMenus, Load, Open], ViewerClasses USING [Viewer], ViewerOps USING [BlinkIcon, CreateViewer, DestroyViewer, EnumerateViewers, EnumProc, OpenIcon, PaintViewer]; FileViewerOpsImpl: CEDAR PROGRAM IMPORTS IO, Menus, MessageWindow, PFSCanonicalNames, PFS, Process, RefTab, Rope, TiogaMenuOps, ViewerOps EXPORTS FileViewerOps, FileViewerOpsBackdoor = BEGIN OPEN FileViewerOpsBackdoor; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; Viewer: TYPE = ViewerClasses.Viewer; ViewerSaveStatus: TYPE = {none, old, new, saving}; ShowLog: PUBLIC PROC [fileName: ROPE, destroyIt: BOOL ¬ FALSE, createIconic: BOOL ¬ FALSE, blinkIfIconic: BOOL ¬ TRUE] = { logViewer: Viewer ¬ FindFileViewer[StripVersion[fileName]]; FOR v: Viewer ¬ logViewer, v.link UNTIL v = NIL DO [] ¬ RefTab.Delete[viewerTable, v]; IF v.link = logViewer THEN EXIT; ENDLOOP; IF destroyIt THEN {IF logViewer # NIL THEN ViewerOps.DestroyViewer[logViewer]} ELSE { icon: Icons.IconFlavor ~ SELECT TRUE FROM Rope.Find[fileName, ".errlog", 0, FALSE] # -1 => typescript, Rope.Find[fileName, ".log", 0, FALSE] # -1 => typescript, Rope.Find[fileName, ".mesa", 0, FALSE] # -1 => needsToBeCompiled, ENDCASE => document; IF logViewer = NIL THEN logViewer ¬ CreateLog[fileName, icon, createIconic] ELSE logViewer ¬ SetContents[logViewer, fileName, icon, createIconic]; IF logViewer # NIL AND logViewer.iconic AND blinkIfIconic THEN ViewerOps.BlinkIcon[logViewer]}; }; StripVersion: PROC [fileName: ROPE] RETURNS [ROPE] ~ { RETURN Rope.Substr[base: fileName, start: 0, len: fileName.Index[s2: "!"]]}; WaitUntilSaved: PUBLIC PROC [fileName: ROPE, feedBack: STREAM ¬ NIL] = { lastState: ViewerSaveStatus ¬ none; fileNameLen: INT ¬ Rope.Length[fileName ¬ ExpandName[fileName]]; IF feedBack = NIL THEN feedBack ¬ IO.ROS[]; DO state: ViewerSaveStatus ¬ none; vName: 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] = { viewer: Viewer ¬ FindFileViewer[sourceFileName]; IF viewer # NIL THEN { AppendMenuEntry[viewer, "ErrorLog", OpenErrorLog]; SetIcon[viewer: viewer, from: document, to: needsToBeCompiled]}; }; RemoveErrorLog: PUBLIC PROC [sourceFileName: ROPE] = { errlogName: 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 ¬ FindFileViewer[errlogName]) # NIL DO ViewerOps.DestroyViewer[errlog]; ENDLOOP; }; AppendMenuEntry: PROC [viewer: Viewer, name: 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] = { 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; procList: LIST OF ProcListItem; viewer: Viewer = NARROW[parent]; name: ROPE = ErrorLogName[viewer.name]; repeat: BOOLEAN; log ¬ FindFileViewer[name]; IF log = NIL THEN log ¬ CreateLog[name, typescript, FALSE] ELSE IF log.iconic THEN ViewerOps.OpenIcon[log] ELSE { FOR v: ViewerClasses.Viewer ¬ parent, v.link UNTIL v = NIL DO [found: repeat] ¬ RefTab.Fetch[viewerTable, v]; IF repeat OR v.link = parent THEN EXIT; ENDLOOP; procList ¬ GetProcList[]; FOR left: LIST OF ProcListItem ¬ procList, left.rest UNTIL left =NIL DO left.first.proc[log, repeat, left.first.data, parent, mouseButton, shift, control]; ENDLOOP; [] ¬ RefTab.Store[viewerTable, parent, parent]; } }; RegisterErrorLogProc: PUBLIC PROC[proc: ErrorLogProc, clientData: REF ANY] = { item: ProcListItem; item ¬ NEW[ProcListItemRec]; item.proc ¬ proc; item.data ¬ clientData; procList ¬ CONS[item, procList]; }; UnregisterErrorLogProc: PUBLIC PROC[proc: ErrorLogProc] = { prev: LIST OF ProcListItem; IF procList.first.proc = proc THEN procList ¬ procList.rest ELSE { prev ¬ procList; FOR left: LIST OF ProcListItem ¬ procList.rest, left.rest UNTIL left = NIL DO IF left.first.proc = proc THEN { prev.rest ¬ left.rest; EXIT; }; prev ¬ prev.rest; ENDLOOP; }; }; GetProcList: PUBLIC PROC RETURNS [LIST OF ProcListItem] = {RETURN [procList];}; ErrorLogName: PROC [file: ROPE] RETURNS [errlog: 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] RETURNS [viewer: Viewer] = { FindViewer: ViewerOps.EnumProc = { IF v.class # NIL AND v.class.flavor = $Text AND Rope.Run[s1: v.file, s2: file, case: FALSE] = file.Length THEN { viewer ¬ v; RETURN [FALSE]; }; RETURN [TRUE]; }; file ¬ ExpandName[file]; ViewerOps.EnumerateViewers[FindViewer]; RETURN}; CreateLog: PROC [fileName: ROPE, icon: Icons.IconFlavor, iconic: BOOL] RETURNS [viewer: Viewer] = { fullFName: ROPE ~ ResolveName[fileName]; IF fullFName=NIL THEN { MessageWindow.Append[Rope.Concat[fileName, " does not exist."], TRUE]; RETURN; }; IF iconic THEN { viewer ¬ ViewerOps.CreateViewer[flavor: $Text, info: [name: fullFName, file: fullFName, iconic: iconic, icon: icon]]; IF viewer # NIL THEN TiogaMenuOps.DefaultMenus[viewer]; } ELSE { viewer ¬ TiogaMenuOps.Open[fileName]; IF viewer # NIL THEN viewer.icon ¬ icon; }; }; SetContents: PROC [viewer: Viewer, fileName: ROPE, icon: Icons.IconFlavor, iconic: BOOL] RETURNS [Viewer] = { fullFName: ROPE ~ ResolveName[fileName]; IF fullFName=NIL THEN { MessageWindow.Append[Rope.Concat[fileName, " does not exist."], TRUE]; ViewerOps.DestroyViewer[viewer]; RETURN [NIL]; }; IF Rope.Equal[fullFName, viewer.file, FALSE] THEN RETURN [viewer]; IF iconic AND viewer.iconic THEN { ViewerOps.DestroyViewer[viewer: viewer]; viewer ¬ ViewerOps.CreateViewer[flavor: $Text, info: [name: fullFName, file: fullFName, iconic: iconic, icon: icon]]; IF viewer # NIL THEN TiogaMenuOps.DefaultMenus[viewer]; RETURN [viewer]; } ELSE { TiogaMenuOps.Load[viewer, IF iconic THEN fullFName ELSE fileName]; RETURN [viewer]; }; }; ResolveName: PROC [fileName: ROPE] RETURNS [fullFName: ROPE --NIL if file doesn't exist; otherwise has version--] ~ { bytes: INT ¬ -1; fullFNamePath: PFS.PATH; [fullFName: fullFNamePath, bytes: bytes] ¬ PFS.FileInfo[PFSCanonicalNames.ParseName[fileName] ! PFS.Error => CONTINUE]; RETURN [IF bytes >= 0 THEN PFSCanonicalNames.UnparseName[fullFNamePath] ELSE NIL]; }; ExpandName: PROC [fileName: ROPE] RETURNS [fullFileName: ROPE] = BEGIN RETURN [PFSCanonicalNames.UnparseName[PFS.AbsoluteName[PFSCanonicalNames.ParseName[fileName]]]]; END; 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: Viewer] RETURNS [ViewerSaveStatus] = { IF viewer # NIL AND NOT viewer.destroyed THEN { v: 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]; }; procList: LIST OF ProcListItem; viewerTable: RefTab.Ref; needsToBeCompiled: Icons.IconFlavor ¬ document; { viewerTable ¬ RefTab.Create[]; procList ¬ NIL; }; END. p FileViewerOpsImpl.mesa Copyright Σ 1984, 1985, 1986, 1987, 1991 by Xerox Corporation. All rights reserved. Bob Hagmann February 6, 1985 8:20:38 am PST Russ Atkinson (RRA) March 10, 1987 10:39:35 am PST Last tweaked by Mike Spreitzer on February 16, 1988 8:57:02 am PST David Goldberg April 27, 1989 6:48:23 pm PDT Theimer, March 13, 1990 10:28 pm PST Michael Plass, September 30, 1991 4:29 pm PDT Willie-s, October 31, 1991 1:00 pm PST A fresh compile occured, so remove viewer and all its splits from table [v: Viewer] RETURNS [BOOL _ TRUE] PROC[parent: ViewerClasses.Viewer, clientData: REF ANY _ NIL, mouseButton: ViewerClasses.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] icon: Icons.IconFlavor; icon _ Icons.NewIconFromFile["InterpreterTool.icons", 6 ! FS.Error => GO TO noGood]; IF icon # unInit THEN needsToBeCompiled _ icon; EXITS noGood => {}; Κ –(cedarcode) style•NewlineDelimiter ™code™Kšœ ΟeœI™TK™+K™2K™BK™,K™$K™-K™&K™šΟk ˜ Kšœžœ˜Kšœž˜Kšžœ˜Kšœ˜Kšžœžœžœžœ˜'Kšœžœ`˜kKšœžœ ˜K˜Kšœ˜Kšœžœ(˜5Kšœžœ%˜1Kšœžœ6žœ˜SKšœ žœ˜.Kšœžœ ˜Kšœ žœ]˜l——headšœžœž˜ Kšžœžœ_˜išžœ%˜,Kšœžœžœ˜#—K˜Kšžœžœžœ˜Kšžœžœžœžœ˜Kšœžœ˜$Kšœžœ˜2K˜—šΟnœž œ žœ žœžœžœžœžœžœ˜zKšœ;˜;KšœG™Gšžœžœžœž˜2Kšœ#˜#Kšžœžœžœ˜ Kšžœ˜—šžœ ˜ Kšžœžœ žœžœ$˜Ašžœ˜šœžœžœž˜)Kšœ"žœ˜šŸ œ˜"š žœ žœžœžœ&žœžœ˜pKšœ ˜ Kšžœžœ˜Kšœ˜—Kšžœžœ˜K˜—Kšœ˜K˜'Kšžœ˜K˜—š Ÿ œžœ žœ"žœžœ˜cKšœ žœ˜(šžœ žœžœ˜Kšœ@žœ˜FKšž˜Kšœ˜—šžœ˜ šžœ˜Kšœu˜uKšžœ žœžœ#˜7K˜—šžœ˜Kšœ%˜%Kšžœ žœžœ˜(Kšœ˜——K˜K˜—š Ÿ œžœžœ"žœžœ ˜mKšœ žœ˜(šžœ žœžœ˜Kšœ@žœ˜FKšœ ˜ Kšžœžœ˜ Kšœ˜—Kšžœ$žœžœžœ ˜Bšžœžœ˜šžœ˜Kšœ(˜(Kšœu˜uKšžœ žœžœ#˜7Kšžœ ˜K˜—šžœ˜Kšœžœžœ žœ ˜BKšžœ ˜Kšœ˜——K˜K˜—š Ÿ œžœ žœžœ žœ‘4œ˜uKšœžœ˜Kšœžœž˜Kšœ+žœ2žœ žœ˜wKš žœžœ žœ.žœžœ˜RK˜—K˜š Ÿ œžœ žœžœžœ˜@Kšž˜KšžœZ˜`Kšžœ˜K˜—šŸœžœ0˜>Kšžœ žœžœ˜šžœžœžœž˜/š žœžœžœžœ žœ˜