DIRECTORY Buttons USING [ButtonProc], CedarSnapshot USING [After, Register], InputFocus USING [GetInputFocus, SetInputFocus], Menus USING [MenuProc, MouseButton], MessageWindow USING [Append, Blink, Clear], Process USING [Detach, MsecToTicks, Pause], Rope USING [Concat, ROPE], TiogaDocument, TiogaDocumentPrivate, TiogaInput USING [CheckSelection, CloseEvent, CommandProc, InterpretAtom, Register], TiogaOps, TiogaScrolling USING [AutoScroll], TiogaSelection USING [MakeSelection], TiogaNode USING [Offset, Location], TiogaNodeOps USING [LocNumber, LocWithin], ViewerMenus USING [Restore, Save], ViewerClasses USING [Viewer, ViewerClass], ViewerTools USING [GetSelectionContents], ViewerOps USING [AddProp, EnumProc, FetchProp, PaintViewer], VirtualDesktops USING [EnumerateViewers]; TiogaDocuments3Impl: CEDAR PROGRAM IMPORTS CedarSnapshot, InputFocus, MessageWindow, Process, Rope, TiogaDocument, TiogaDocumentPrivate, TiogaInput, TiogaScrolling, TiogaSelection, TiogaNodeOps, ViewerMenus, ViewerOps, ViewerTools, VirtualDesktops EXPORTS TiogaDocumentPrivate = BEGIN OPEN TiogaDocument, TiogaDocumentPrivate, ViewerClasses; Do: PROC [viewer: REF ANY, atom: ATOM] = INLINE { TiogaInput.InterpretAtom[NARROW[viewer], atom] }; Register: PROC [atom: ATOM, op: TiogaInput.CommandProc] = { TiogaInput.Register[atom, op] }; ForkViewerOp2: PROC [ proc: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL], parent: Viewer] RETURNS [BOOL] = { TiogaInput.CloseEvent[]; ForkCall2[proc, parent, ViewerTools.GetSelectionContents[]]; RETURN [FALSE] }; StackBottom2: PROC [ proc: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL], parent: Viewer, fileName: Rope.ROPE] = { proc[parent, fileName ! ABORTED => CONTINUE] }; ForkCall2: PROC [ proc: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL], parent: Viewer, fileName: Rope.ROPE] = { TRUSTED {Process.Detach[FORK StackBottom2[proc, parent, fileName]]}; Process.Pause[Process.MsecToTicks[250]]; }; ForkViewerOp: PROC [proc: PROC [parent: Viewer], parent: Viewer] RETURNS [BOOL] = { TiogaInput.CloseEvent[]; ForkCall[proc, parent]; RETURN [FALSE] }; StackBottom: PROC [proc: PROC [parent: Viewer], parent: Viewer] = { proc[parent ! ABORTED => CONTINUE] }; ForkCall: PROC [proc: PROC [parent: Viewer], parent: Viewer] = { TRUSTED {Process.Detach[FORK StackBottom[proc, parent]]}; Process.Pause[Process.MsecToTicks[250]]; }; CheckFilesAfterRollback: PROC [when: CedarSnapshot.After] = { Check: ViewerOps.EnumProc --PROC [v: Viewer] RETURNS [BOOL _ TRUE]-- = { tdd: TiogaDocumentData; IF v.class.flavor # $Text THEN RETURN [TRUE]; -- only interested in text viewers tdd _ NARROW[v.data]; IF tdd = NIL THEN RETURN [TRUE]; IF ~FileIsMoreRecent[tdd.text, v.file] THEN RETURN [TRUE]; MessageWindow.Append[Rope.Concat["Loading newer version of ", v.file], TRUE]; ViewerMenus.Restore[v]; -- reload the file RETURN [TRUE] --continue enumeration-- }; IF when=checkpoint THEN RETURN; -- only do this after return from Rollback VirtualDesktops.EnumerateViewers[Check]; -- Check each top level viewer }; PreReset: PUBLIC Menus.MenuProc = { viewer: ViewerClasses.Viewer = NARROW[parent]; IF viewer.file = NIL THEN MessageWindow.Append["Confirm clearing viewer", TRUE] ELSE MessageWindow.Append[Rope.Concat["Confirm reloading of ", viewer.file], TRUE] }; Reset: PUBLIC Menus.MenuProc = { MessageWindow.Clear[]; Do[parent, SelectMouse[mouseButton, $RedReset, $YellowReset, $BlueReset]] }; ResetOp: TiogaInput.CommandProc = { SaveLoc: PROC [v: Viewer] = BEGIN tdd: TiogaDocument.TiogaDocumentData _ NARROW[v.data]; loc: INT; IF tdd = NIL THEN RETURN; [] _ SpinAndLock[tdd, "Reset"]; -- delay until after other op completes loc _ TiogaNodeOps.LocNumber[tdd.lineTable.lines[0].pos]; Unlock[tdd]; ViewerOps.AddProp[v, $ResetLoc, NEW[INT _ loc]]; v.newVersion _ TRUE; -- to force the init proc to reread the file END; DoOne: PROC [v: Viewer] = BEGIN tdd: TiogaDocument.TiogaDocumentData _ NARROW[v.data]; locRef: REF INT; IF tdd = NIL THEN RETURN; IF InputFocus.GetInputFocus[].owner=v THEN InputFocus.SetInputFocus[]; locRef _ NARROW[ViewerOps.FetchProp[v, $ResetLoc]]; v.class.init[v]; v.newVersion _ v.newFile _ FALSE; IF locRef = NIL OR ~PositionViewer[v,TiogaNodeOps.LocWithin[tdd.text,locRef^],all] THEN ViewerOps.PaintViewer[v, all]; END; SaveLoc[viewer]; IF viewer.link#NIL THEN FOR v: Viewer _ viewer.link, v.link UNTIL v=viewer DO SaveLoc[v]; ENDLOOP; DoOne[viewer]; IF viewer.link#NIL THEN FOR v: Viewer _ viewer.link, v.link UNTIL v=viewer DO DoOne[v]; ENDLOOP; RETURN [FALSE] }; Save: PUBLIC Menus.MenuProc = { MessageWindow.Clear[]; Do[parent, SelectMouse[mouseButton, $RedSave, $YellowSave, $BlueSave]] }; SaveOp: TiogaInput.CommandProc = BEGIN TiogaInput.CloseEvent[]; IF ~viewer.saveInProgress THEN TRUSTED {[] _ Process.Detach[FORK ViewerMenus.Save[viewer]]}; RETURN [FALSE]; END; PreClear: PUBLIC Menus.MenuProc = { -- called when Clear menu item becomes unguarded MessageWindow.Append[clearFirst: TRUE, message: "Click LEFT to empty this viewer, MIDDLE to make new viewer, RIGHT for close & new"] }; Clear: PUBLIC Menus.MenuProc = { --PreClear[parent]; Do[parent, SelectMouse[mouseButton, $Empty, $New, $CloseAndNew]]}; EmptyOp: TiogaInput.CommandProc = { EmptyViewer[viewer]; RETURN [FALSE] }; NewOp: TiogaInput.CommandProc = { NewViewer[viewer]; RETURN [FALSE] }; NewButton: PUBLIC Buttons.ButtonProc = { NewViewer[NIL] }; CloseAndNewOp: TiogaInput.CommandProc = { CloseAndNewViewer[viewer]; RETURN [FALSE] }; Store: PUBLIC Menus.MenuProc = { MessageWindow.Clear[]; Do[parent, SelectMouse[mouseButton, $RedStore, $YellowStore, $BlueStore]] }; StoreOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp2[DoStoreFile,viewer]] }; PreviousFile: PUBLIC Menus.MenuProc = { PreLoadPrevious[parent]; Do[parent, SelectMouse[mouseButton, $LoadPrevious, $OpenPrevious, $CloseAndOpenPrevious]]}; LoadPreviousOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp[LoadPreviousFile,viewer]] }; OpenPreviousOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp[OpenPreviousFile,viewer]] }; CloseAndOpenPreviousOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp[CloseAndOpenPreviousFile,viewer]] }; AnonymousLoadImpl: PUBLIC Menus.MenuProc = { Do[parent,$AnonymousLoadImpl] }; AnonymousLoadImplOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp[AnonymousLoadImplFile,viewer]] }; AnonymousLoad: PUBLIC Menus.MenuProc = { Do[parent,$AnonymousLoad] }; AnonymousLoadOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp[AnonymousLoadIt,viewer]] }; AnonymousLoadIt: PROC [parent: Viewer] = { AnonymousLoadFile[parent] }; PreGet, PreGetImpl: PUBLIC Menus.MenuProc = { viewer: ViewerClasses.Viewer = NARROW[parent]; MessageWindow.Append[ "Click LEFT to load in this viewer, MIDDLE for new viewer, RIGHT for close & new", TRUE] }; Get: PUBLIC Menus.MenuProc = { --PreGet[parent]; Do[parent, SelectMouse[mouseButton, $Load, $Open, $CloseAndOpen]]}; LoadOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp2[LoadIt,viewer]] }; LoadIt: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoLoadFile[parent, fileName, FALSE] }; OpenOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp2[OpenIt,viewer]] }; OpenIt: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoOpenFile[fileName, parent] }; CloseAndOpenOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp2[CloseAndOpenIt,viewer]] }; CloseAndOpenIt: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoCloseAndOpenFile[parent, fileName] }; GetImpl: PUBLIC Menus.MenuProc = { --PreGetImpl[parent]; Do[parent, SelectMouse[mouseButton, $LoadImpl, $OpenImpl, $CloseAndOpenImpl]]}; LoadImplOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp2[LoadItImpl,viewer]] }; LoadItImpl: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoLoadImplFile[parent, fileName, FALSE] }; OpenImplOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp2[OpenItImpl,viewer]] }; OpenItImpl: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoOpenImplFile[fileName, parent] }; CloseAndOpenImplOp: TiogaInput.CommandProc = { RETURN [ForkViewerOp2[CloseAndOpenItImpl,viewer]] }; CloseAndOpenItImpl: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoCloseAndOpenImplFile[parent, fileName] }; OpenButton: PUBLIC Buttons.ButtonProc = { [] _ ForkViewerOp2[OpenIt,NIL] }; Normalize: PUBLIC Menus.MenuProc = { Do[parent, SelectMouse[mouseButton, $NormalizeToStart, $NormalizeToCaret, $NormalizeToEnd]]}; Position: PUBLIC Menus.MenuProc = {Do[parent,$Position]}; JumpToPrevious: PUBLIC Menus.MenuProc = {Do[parent,$PrevPlace]}; PrevPlaceOp: TiogaInput.CommandProc = { tdd: TiogaDocument.TiogaDocumentData _ NARROW[viewer.data]; prop: REF PositionHistory _ NARROW[ViewerOps.FetchProp[viewer, $PositionHistory]]; IF tdd # NIL AND prop # NIL THEN { loc: TiogaNode.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.MenuProc = {Do[parent,$Reselect]}; ReselectOp: TiogaInput.CommandProc = { tdd: TiogaDocument.TiogaDocumentData _ NARROW[viewer.data]; prop: TiogaDocument.Selection _ NARROW[ViewerOps.FetchProp[viewer, $SelectionHistory]]; IF tdd # NIL AND prop # NIL AND TiogaInput.CheckSelection[prop] THEN { TiogaSelection.MakeSelection[selection: primary, new: prop]; TiogaScrolling.AutoScroll[viewer,FALSE] } ELSE { MessageWindow.Append["No saved selection.", TRUE]; MessageWindow.Blink[] }; RETURN [FALSE] }; SelectMouse: PROC [mouseButton: Menus.MouseButton, redOp, yellowOp, blueOp: ATOM] RETURNS [ATOM] = { RETURN [SELECT mouseButton FROM red => redOp, yellow => yellowOp, blue => blueOp, ENDCASE => ERROR] }; Find: PUBLIC Menus.MenuProc = { Do[parent, SelectMouse[mouseButton, $FindNext, $FindAny, $FindPrev]]}; FindDef: PUBLIC Menus.MenuProc = { Do[parent, SelectMouse[mouseButton, $FindNextDef, $FindAnyDef, $FindPrevDef]]}; FindWord: PUBLIC Menus.MenuProc = { Do[parent, SelectMouse[mouseButton, $FindNextWord, $FindAnyWord, $FindPrevWord]]}; FewerLevels: PUBLIC Menus.MenuProc = {Do[parent,$FewerLevels]}; MoreLevels: PUBLIC Menus.MenuProc = {Do[parent,$MoreLevels]}; AllLevels: PUBLIC Menus.MenuProc = {Do[parent,$AllLevels]}; FirstLevelOnly: PUBLIC Menus.MenuProc = {Do[parent,$FirstLevelOnly]}; FewerLines: PUBLIC Menus.MenuProc = {Do[parent,$FewerLines]}; MoreLines: PUBLIC Menus.MenuProc = {Do[parent,$MoreLines]}; AllLines: PUBLIC Menus.MenuProc = {Do[parent,$AllLines]}; FirstLineOnly: PUBLIC Menus.MenuProc = {Do[parent,$FirstLineOnly]}; Time: PUBLIC Menus.MenuProc = {Do[parent,$Time]}; Split: PUBLIC Menus.MenuProc = {Do[parent, SelectMouse[mouseButton, $RedSplit, $YellowSplit, $BlueSplit]]}; TRUSTED {CedarSnapshot.Register[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.... Þ-- TiogaDocuments3Impl.mesa; Edited by Paxton on June 13, 1983 4:24 pm -- Edited by McGregor on August 26, 1982 2:52 pm Last Edited by: Maxwell, January 6, 1983 11:11 am Last Edited by: Plass, April 15, 1983 1:43 pm -- fork so can release input monitor without waiting for call to complete -- HACK: wait 1/4 sec to let other process lock the tdd before we return This is called after Rollback to see if any viewers need to be Reset. Reset Save Clear = Empty, New, or CloseAndNew 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 GetImpl = LoadImpl, OpenImpl, or CloseAndOpenImpl This is the Open button in the upper left corner of the screen. Places menu commands Levels menu commands Lines menu commands Time Split Ê ˜JšÏcF™FJš0™0J™1J™-J˜šÏk ˜ Jšœžœ˜Jšœžœ˜&Jšœ žœ ˜0Jšœžœ˜$Jšœžœ˜+Jšœžœ˜+Jšœžœ žœ˜J˜J˜Jšœ žœD˜TJ˜ Jšœžœ˜"Jšœžœ˜%Jšœ žœ˜#Jšœ žœ˜*Jšœ žœ˜"Jšœžœ˜*Jšœ žœ˜)Jšœ žœ-˜J˜š Ïnœžœ žœžœžœžœ˜1Jšœžœ˜1—J˜šŸœžœžœB˜\J˜—šŸ œžœ˜Jšœžœ!žœžœ˜GJšžœžœ˜J˜Jšœ<˜