<<-- TiogaDocuments3Impl.mesa; Edited by Paxton on June 13, 1983 4:24 pm>> <<-- Edited by McGregor on August 26, 1982 2:52 pm>> <> <> 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]]}; <<-- fork so can release input monitor without waiting for call to complete>> Process.Pause[Process.MsecToTicks[250]]; <<-- HACK: wait 1/4 sec to let other process lock the tdd before we return>> }; 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]}; <