DIRECTORY Booting USING [RegisterProcs, RollbackProc], Buttons USING [ButtonProc], InputFocus USING [GetInputFocus, SetInputFocus], Menus USING [ClickProc, MouseButton], MessageWindow USING [Append, Blink, Clear], Process USING [Detach], Rope USING [Concat, ROPE], TEditDocument USING [Selection, SpinAndLock, TEditDocumentData, Unlock], TEditDocumentPrivate USING [AnonymousLoadFile, AnonymousLoadImplFile, CloseAndNewViewer, CloseAndOpenPreviousFile, DoCloseAndOpenFile, DoCloseAndOpenImplFile, DoLoadFile, DoLoadImplFile, DoOpenFile, DoOpenImplFile, DoStoreFile, EmptyViewer, FileIsMoreRecent, LoadPreviousFile, NewViewer, OpenPreviousFile, PositionHistory, PositionViewer, PreLoadPrevious], TEditInput USING [CheckSelection, CloseEvent, CommandProc, InterpretAtom, Register], TEditScrolling USING [AutoScroll], TEditSelection USING [MakeSelection], TextNode USING [Location, LocNumber, LocWithin], ViewerClasses USING [Viewer], ViewerForkers USING [CallBack, ForkCall], ViewerGroupLocks USING [CallRootAndLinksUnderWriteLock], ViewerMenus USING [Restore, Save], ViewerOps USING [AddProp, EnumerateViewers, EnumProc, FetchProp, PaintViewer], ViewerTools USING [GetSelectionContents]; TEditDocuments3Impl: CEDAR PROGRAM IMPORTS Booting, InputFocus, MessageWindow, Process, Rope, TEditDocument, TEditDocumentPrivate, TEditInput, TEditScrolling, TEditSelection, TextNode, ViewerForkers, ViewerGroupLocks, ViewerMenus, ViewerOps, ViewerTools EXPORTS TEditDocumentPrivate = BEGIN OPEN TEditDocumentPrivate; ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ ViewerClasses.Viewer; Do: PROC [viewer: REF ANY, atom: ATOM] = { TEditInput.InterpretAtom[NARROW[viewer], atom]; }; Register: PROC [atom: ATOM, op: TEditInput.CommandProc] = { TEditInput.Register[atom, op]; }; ForkViewerOp2: PROC [proc: PROC [parent: Viewer, fileName: ROPE _ NIL], parent: Viewer] RETURNS [BOOL _ FALSE] = { TEditInput.CloseEvent[]; ViewerForkers.ForkCall[parent, StackBase, NEW[Data2 _ [proc, parent, ViewerTools.GetSelectionContents[]]]]; }; ForkViewerOp: PROC [proc: PROC [parent: Viewer], parent: Viewer] RETURNS [BOOL _ FALSE] = { TEditInput.CloseEvent[]; ViewerForkers.ForkCall[parent, StackBase, NEW[Data1 _ [proc, parent]]]; }; Data1: TYPE = RECORD [ proc: PROC [parent: Viewer], viewer: Viewer]; Data2: TYPE = RECORD [ proc: PROC [parent: Viewer, fileName: ROPE], viewer: Viewer, fileName: ROPE]; StackBase: ViewerForkers.CallBack = { WITH data SELECT FROM data1: REF Data1 => { data1.proc[data1.viewer ! ABORTED => CONTINUE]; }; data2: REF Data2 => { data2.proc[data2.viewer, data2.fileName ! ABORTED => CONTINUE]; }; ENDCASE; }; CheckFilesAfterRollback: Booting.RollbackProc = { Check: ViewerOps.EnumProc = { WITH v.data SELECT FROM tdd: TEditDocument.TEditDocumentData => { IF FileIsMoreRecent[tdd.text, v.file] THEN { MessageWindow.Append[Rope.Concat["Loading newer version of ", v.file], TRUE]; ViewerMenus.Restore[v]; -- reload the file }; }; ENDCASE; RETURN [TRUE] --continue enumeration-- }; ViewerOps.EnumerateViewers[Check]; -- Check each top level viewer }; SelectMouse: PROC [mouseButton: Menus.MouseButton, redOp, yellowOp, blueOp: ATOM] RETURNS [ATOM] = { RETURN [SELECT mouseButton FROM red => redOp, yellow => yellowOp, blue => blueOp, ENDCASE => ERROR]; }; PreReset: PUBLIC Menus.ClickProc = { WITH parent SELECT FROM viewer: Viewer => MessageWindow.Append[ IF viewer.file = NIL THEN "Confirm clearing viewer" ELSE Rope.Concat["Confirm reloading of ", viewer.file], TRUE]; ENDCASE; }; Reset: PUBLIC Menus.ClickProc = { MessageWindow.Clear[]; Do[parent, SelectMouse[mouseButton, $RedReset, $YellowReset, $BlueReset]]; }; ResetOp: TEditInput.CommandProc = { inner: PROC = { FOR v: Viewer _ viewer, v.link UNTIL v = NIL DO WITH v.data SELECT FROM tdd: TEditDocument.TEditDocumentData => { [] _ TEditDocument.SpinAndLock[tdd, "Reset"]; ViewerOps.AddProp[v, $ResetLoc, NEW[INT _ TextNode.LocNumber[tdd.lineTable.lines[0].pos]]]; v.newVersion _ TRUE; -- to force the init proc to reread the file TEditDocument.Unlock[tdd]; }; ENDCASE; IF v.link=viewer THEN EXIT; ENDLOOP; FOR v: Viewer _ viewer, v.link UNTIL v = NIL DO WITH v.data SELECT FROM tdd: TEditDocument.TEditDocumentData => { IF InputFocus.GetInputFocus[].owner=v THEN InputFocus.SetInputFocus[]; WITH ViewerOps.FetchProp[v, $ResetLoc] SELECT FROM locRef: REF INT => { v.class.init[v]; v.newVersion _ v.newFile _ FALSE; [] _ TEditDocument.SpinAndLock[tdd, "Reset"]; IF ~PositionViewer[v,TextNode.LocWithin[tdd.text,locRef^],all] THEN ViewerOps.PaintViewer[v, all]; TEditDocument.Unlock[tdd]; }; ENDCASE; }; ENDCASE; IF v.link=viewer THEN EXIT; ENDLOOP; }; ViewerGroupLocks.CallRootAndLinksUnderWriteLock[inner, viewer]; }; Save: PUBLIC Menus.ClickProc = { MessageWindow.Clear[]; Do[parent, SelectMouse[mouseButton, $RedSave, $YellowSave, $BlueSave]]; }; SaveOp: TEditInput.CommandProc = { TEditInput.CloseEvent[]; IF ~viewer.saveInProgress THEN TRUSTED { [] _ Process.Detach[FORK ViewerMenus.Save[viewer]]; }; RETURN [FALSE]; }; PreClear: PUBLIC Menus.ClickProc = { MessageWindow.Append[clearFirst: TRUE, message: "Click LEFT to empty this viewer, MIDDLE to make new viewer, RIGHT for close & new"]; }; Clear: PUBLIC Menus.ClickProc = { Do[parent, SelectMouse[mouseButton, $Empty, $New, $CloseAndNew]]; }; EmptyOp: TEditInput.CommandProc = { EmptyViewer[viewer]; RETURN [FALSE] }; NewOp: TEditInput.CommandProc = { NewViewer[viewer]; RETURN [FALSE] }; NewButton: PUBLIC Buttons.ButtonProc = { NewViewer[NIL] }; CloseAndNewOp: TEditInput.CommandProc = { CloseAndNewViewer[viewer]; RETURN [FALSE] }; Store: PUBLIC Menus.ClickProc = { MessageWindow.Clear[]; Do[parent, SelectMouse[mouseButton, $RedStore, $YellowStore, $BlueStore]]; }; StoreOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[DoStoreFile,viewer]] }; PreviousFile: PUBLIC Menus.ClickProc = { PreLoadPrevious[parent]; Do[parent, SelectMouse[mouseButton, $LoadPrevious, $OpenPrevious, $CloseAndOpenPrevious]]; }; LoadPreviousOp: TEditInput.CommandProc = { RETURN [ForkViewerOp[LoadPreviousFile,viewer]]; }; OpenPreviousOp: TEditInput.CommandProc = { RETURN [ForkViewerOp[OpenPreviousFile,viewer]]; }; CloseAndOpenPreviousOp: TEditInput.CommandProc = { RETURN [ForkViewerOp[CloseAndOpenPreviousFile,viewer]]; }; AnonymousLoadImpl: PUBLIC Menus.ClickProc = { Do[parent,$AnonymousLoadImpl]; }; AnonymousLoadImplOp: TEditInput.CommandProc = { RETURN [ForkViewerOp[AnonymousLoadImplFile,viewer]]; }; AnonymousLoad: PUBLIC Menus.ClickProc = { Do[parent,$AnonymousLoad]; }; AnonymousLoadOp: TEditInput.CommandProc = { RETURN [ForkViewerOp[AnonymousLoadIt,viewer]]; }; AnonymousLoadIt: PROC [parent: Viewer] = { AnonymousLoadFile[parent]; }; PreGet, PreGetImpl: PUBLIC Menus.ClickProc = { viewer: Viewer = NARROW[parent]; MessageWindow.Append["Click LEFT to load in this viewer, MIDDLE for new viewer, RIGHT for close & new", TRUE]; }; Get: PUBLIC Menus.ClickProc = { Do[parent, SelectMouse[mouseButton, $Load, $Open, $CloseAndOpen]]; }; LoadOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[LoadIt,viewer]] }; LoadIt: PROC [parent: Viewer, fileName: ROPE _ NIL] = { [] _ DoLoadFile[parent, fileName, FALSE]; }; OpenOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[OpenIt,viewer]]; }; OpenIt: PROC [parent: Viewer, fileName: ROPE _ NIL] = { [] _ DoOpenFile[fileName, parent]; }; CloseAndOpenOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[CloseAndOpenIt,viewer]]; }; CloseAndOpenIt: PROC [parent: Viewer, fileName: ROPE _ NIL] = { [] _ DoCloseAndOpenFile[parent, fileName]; }; GetImpl: PUBLIC Menus.ClickProc = { Do[parent, SelectMouse[mouseButton, $LoadImpl, $OpenImpl, $CloseAndOpenImpl]]; }; LoadImplOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[LoadItImpl,viewer]]; }; LoadItImpl: PROC [parent: Viewer, fileName: ROPE _ NIL] = { [] _ DoLoadImplFile[parent, fileName, FALSE]; }; OpenImplOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[OpenItImpl,viewer]]; }; OpenItImpl: PROC [parent: Viewer, fileName: ROPE _ NIL] = { [] _ DoOpenImplFile[fileName, parent]; }; CloseAndOpenImplOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[CloseAndOpenItImpl,viewer]]; }; CloseAndOpenItImpl: PROC [parent: Viewer, fileName: ROPE _ NIL] = { [] _ DoCloseAndOpenImplFile[parent, fileName]; }; OpenButton: PUBLIC Buttons.ButtonProc = { [] _ ForkViewerOp2[OpenIt, NIL]; }; Normalize: PUBLIC Menus.ClickProc = { Do[parent, SelectMouse[mouseButton, $NormalizeToStart, $NormalizeToCaret, $NormalizeToEnd]]; }; Position: PUBLIC Menus.ClickProc = {Do[parent, IF shift THEN $PositionIncludingComments ELSE $Position]; }; JumpToPrevious: PUBLIC Menus.ClickProc = {Do[parent,$PrevPlace]}; PrevPlaceOp: TEditInput.CommandProc = { tdd: TEditDocument.TEditDocumentData _ NARROW[viewer.data]; prop: REF PositionHistory _ NARROW[ViewerOps.FetchProp[viewer, $PositionHistory]]; IF tdd # NIL AND prop # NIL THEN { loc: TextNode.Location _ prop.pos; IF loc = tdd.lineTable.lines[0].pos THEN loc _ prop.prev; IF PositionViewer[viewer, loc] THEN RETURN; IF loc # prop.prev AND PositionViewer[viewer, prop.prev] THEN RETURN }; MessageWindow.Append["No previous place saved.", TRUE]; MessageWindow.Blink[]; RETURN [FALSE]; }; Reselect: PUBLIC Menus.ClickProc = {Do[parent,$Reselect]}; ReselectOp: TEditInput.CommandProc = { tdd: TEditDocument.TEditDocumentData _ NARROW[viewer.data]; prop: TEditDocument.Selection _ NARROW[ViewerOps.FetchProp[viewer, $SelectionHistory]]; IF tdd # NIL AND prop # NIL AND TEditInput.CheckSelection[prop] THEN { TEditSelection.MakeSelection[selection: primary, new: prop]; TEditScrolling.AutoScroll[viewer,FALSE] } ELSE { MessageWindow.Append["No saved selection.", TRUE]; MessageWindow.Blink[] }; RETURN [FALSE]; }; Find: PUBLIC Menus.ClickProc = { Do[parent, SELECT mouseButton FROM red => IF shift THEN $FindNextCaseless ELSE $FindNext, yellow => IF shift THEN $FindAnyCaseless ELSE $FindAny, blue => IF shift THEN $FindPrevCaseless ELSE $FindPrev, ENDCASE => ERROR]; }; FindDef: PUBLIC Menus.ClickProc = { Do[parent, SELECT mouseButton FROM red => IF shift THEN $FindNextDefCaseless ELSE $FindNextDef, yellow => IF shift THEN $FindAnyDefCaseless ELSE $FindAnyDef, blue => IF shift THEN $FindPrevDefCaseless ELSE $FindPrevDef, ENDCASE => ERROR]; }; FindWord: PUBLIC Menus.ClickProc = { Do[parent, SELECT mouseButton FROM red => IF shift THEN $FindNextWordCaseless ELSE $FindNextWord, yellow => IF shift THEN $FindAnyWordCaseless ELSE $FindAnyWord, blue => IF shift THEN $FindPrevWordCaseless ELSE $FindPrevWord, ENDCASE => ERROR]; }; FewerLevels: PUBLIC Menus.ClickProc = {Do[parent,$FewerLevels]}; MoreLevels: PUBLIC Menus.ClickProc = {Do[parent,$MoreLevels]}; AllLevels: PUBLIC Menus.ClickProc = {Do[parent,$AllLevels]}; FirstLevelOnly: PUBLIC Menus.ClickProc = {Do[parent,$FirstLevelOnly]}; FewerLines: PUBLIC Menus.ClickProc = {Do[parent,$FewerLines]}; MoreLines: PUBLIC Menus.ClickProc = {Do[parent,$MoreLines]}; AllLines: PUBLIC Menus.ClickProc = {Do[parent,$AllLines]}; FirstLineOnly: PUBLIC Menus.ClickProc = {Do[parent,$FirstLineOnly]}; Time: PUBLIC Menus.ClickProc = {Do[parent,$Time]}; Split: PUBLIC Menus.ClickProc = {Do[parent, SelectMouse[mouseButton, $RedSplit, $YellowSplit, $BlueSplit]]; }; Booting.RegisterProcs[r: CheckFilesAfterRollback]; Register[$RedReset,ResetOp]; Register[$YellowReset,ResetOp]; Register[$BlueReset,ResetOp]; Register[$RedSave,SaveOp]; Register[$YellowSave,SaveOp]; Register[$BlueSave,SaveOp]; Register[$Empty,EmptyOp]; Register[$New,NewOp]; Register[$CloseAndNew,CloseAndNewOp]; Register[$RedStore, StoreOp]; Register[$YellowStore, StoreOp]; Register[$BlueStore, StoreOp]; Register[$LoadPrevious,LoadPreviousOp]; Register[$OpenPrevious,OpenPreviousOp]; Register[$CloseAndOpenPrevious,CloseAndOpenPreviousOp]; Register[$AnonymousLoadImpl,AnonymousLoadImplOp]; Register[$AnonymousLoad,AnonymousLoadOp]; Register[$Load,LoadOp]; Register[$Open,OpenOp]; Register[$CloseAndOpen,CloseAndOpenOp]; Register[$LoadImpl,LoadImplOp]; Register[$OpenImpl,OpenImplOp]; Register[$CloseAndOpenImpl,CloseAndOpenImplOp]; Register[$PrevPlace,PrevPlaceOp]; Register[$Reselect,ReselectOp]; END. JTEditDocuments3Impl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Plass, March 29, 1985 3:36:43 pm PST Doug Wyatt, April 5, 1985 5:49:28 pm PST Russ Atkinson (RRA) August 19, 1985 4:05:04 pm PDT [data: REF ANY] This is called after Rollback to see if any viewers need to be Reset. [v: ViewerClasses.Viewer] RETURNS [BOOL _ TRUE] Reset [viewer: ViewerClasses.Viewer _ NIL] RETURNS [recordAtom: BOOL _ TRUE, quit: BOOL _ FALSE] Save Clear = Empty, New, or CloseAndNew called when Clear menu item becomes unguarded PreClear[parent]; Don't fork these operations since they change the selection; want to capture typein that follows calls on these. This is the button in the upper left corner. Store PreviousFile = LoadPrevious, OpenPrevious, or CloseAndOpenPrevious Anonymous Loads -- into NoName viewers Get = Load, Open, or CloseAndOpen PreGet[parent]; GetImpl = LoadImpl, OpenImpl, or CloseAndOpenImpl PreGetImpl[parent]; This is the Open button in the upper right corner of the screen. Places menu commands Levels menu commands Lines menu commands Time Split Ê ˜codešœ™Kšœ Ïmœ1™˜kKšœ˜K˜—š   œžœžœ#žœžœžœ˜[K˜Kšœ*žœ˜GKšœ˜K˜—šœžœžœ˜Kšœžœ˜Kšœ˜K˜—šœžœžœ˜Kšœžœžœ˜,Kšœ˜Kšœ žœ˜K˜—•StartOfExpansion -- [data: REF ANY]šœ%˜%KšÐck™šžœžœž˜šœžœ ˜Kšœžœžœ˜/K˜—šœžœ ˜Kšœ*žœžœ˜?K˜—Kšžœ˜—K˜—˜K˜—šœ1˜1K™E–3 -- [v: ViewerClasses.Viewer] RETURNS [BOOL _ TRUE]šœ˜Kš¡/™/šžœžœž˜šœ)˜)šžœ$žœ˜,KšœGžœ˜MKšœÏc˜*K˜—K˜—Kšžœ˜—Kšžœžœ¢˜&Kšœ˜—Kšœ#¢˜AK˜K˜—™K™š   œžœ;žœžœžœ˜dšžœžœ ž˜Kšœ1˜1Kšžœžœ˜—šœ˜K˜——šœ žœ˜$šžœžœž˜šœ˜šœ˜Kšžœžœžœžœ3˜kKšžœ˜——Kšžœ˜—Kšœ˜K˜—šœžœ˜!Kšœ˜KšœJ˜JKšœ˜—K˜–^ -- [viewer: ViewerClasses.Viewer _ NIL] RETURNS [recordAtom: BOOL _ TRUE, quit: BOOL _ FALSE]šœ#˜#Kš¡Z™Zšœžœ˜šžœžœžœž˜/šžœžœž˜šœ)˜)Kšœ-˜-Kšœ žœžœ4˜[Kšœžœ¢,˜AKšœ˜K˜—Kšžœ˜—Kšžœžœžœ˜Kšžœ˜—šžœžœžœž˜/šžœžœž˜šœ)˜)Kšžœ$žœ˜Fšžœ#žœž˜2šœžœžœ˜Kšœ˜Kšœžœ˜!Kšœ-˜-šžœ=ž˜CKšœ˜—Kšœ˜K˜—Kšžœ˜—K˜—Kšžœ˜—Kšžœžœžœ˜Kšžœ˜—K˜—Kšœ?˜?Kšœ˜K˜——™K™šœžœ˜ Kšœ˜KšœG˜GKšœ˜—K˜šœ"˜"K˜šžœžœžœ˜)Kšœžœ˜3Kšœ˜—Kšžœžœ˜Kšœ˜K˜——™"K™šœ žœ˜$Kšœ-™-šœ!žœ ˜/K˜U—K˜K˜—šœžœ˜"Kšœ™KšœA˜AKšœ˜K˜—K™pK™šœ9žœžœ˜JK˜—šœ5žœžœ˜FK˜—šœ žœ"žœ˜:K™,K˜—šœ)˜)Kšœžœžœ˜,K˜——™K™šœžœ˜"Kšœ˜KšœJ˜JKšœ˜—K˜šœ$žœ'˜QK˜——™BK™šœžœ˜)K˜KšœZ˜ZKšœ˜K˜—šœ*˜*Kšžœ)˜/Kšœ˜K˜—šœ*˜*Kšžœ)˜/Kšœ˜K˜—šœ2˜2Kšžœ1˜7Kšœ˜—K˜—™&K™šœžœ˜-Kšœ˜Kšœ˜K˜—˜/Kšžœ.˜4Kšœ˜K˜—šœžœ˜*Kšœ˜Kšœ˜K˜—˜+Kšžœ(˜.Kšœ˜—˜š œžœ˜*Kšœ˜Kšœ˜———K˜™!K™šœžœ˜.Kšœžœ ˜ Kšœhžœ˜nKšœ˜K˜—šœžœ˜ Kšœ™KšœB˜BKšœ˜K˜—šœ#žœ"˜KK˜š œžœžœžœ˜7Kšœ"žœ˜)Kšœ˜——K˜šœ"˜"Kšžœ ˜&Kšœ˜K˜š œžœžœžœ˜7Kšœ"˜"Kšœ˜K˜——˜*Kšžœ(˜.Kšœ˜K˜š œžœžœžœ˜?Kšœ*˜*Kšœ˜—K˜—K˜—™1K™šœ žœ˜$Kšœ™KšœN˜NKšœ˜K˜—šœ&˜&Kšžœ$˜*Kšœ˜K˜š  œžœžœžœ˜;Kšœ&žœ˜-Kšœ˜K˜——šœ&˜&Kšžœ$˜*Kšœ˜K˜š  œžœžœžœ˜;Kšœ&˜&Kšœ˜K˜——šœ.˜.Kšžœ,˜2Kšœ˜K˜š œžœžœžœ˜CKšœ.˜.Kšœ˜—K˜——šœ žœ˜)K™@Kšœžœ˜ Kšœ˜K˜—™K™šœ žœ˜%Kšœ\˜\Kšœ˜—K˜šœ žœ˜.Kšžœžœžœ ˜9Kšœ˜—K˜Kšœžœ+˜Ašœ'˜'Kšœ'žœ˜;Kšœžœžœ0˜Rš žœžœžœžœžœ˜"K˜"Kšžœ"žœ˜9Kšžœžœžœ˜,Kšžœžœ#žœžœ˜G—Kšœ1žœ˜7K˜Kšžœžœ˜Kšœ˜—K˜Kšœ žœ*˜:šœ&˜&Kšœ'žœ˜;Kšœ žœ1˜Wš žœžœžœžœžœ!žœ˜FK˜Kšœ žœžœžœ˜?Kšœžœžœžœ˜?Kšžœžœ˜Kšœ˜K˜—K˜—™K˜Kšœ žœ-˜@K˜Kšœ žœ,˜>K˜Kšœ žœ+˜K˜Kšœ žœ+˜