<<-- TEditDocuments3Impl.mesa; Edited by Paxton on June 6, 1983 1:58 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], TEditDocument, TEditDocumentPrivate, TEditInput USING [CheckSelection, CloseEvent, CommandProc, InterpretAtom, Register], TEditOps, TEditScrolling USING [AutoScroll], TEditSelection USING [MakeSelection], TextNode USING [Offset, Location, LocNumber, LocWithin, pZone], ViewerMenus USING [Restore, Save], ViewerClasses USING [Viewer, ViewerClass], ViewerTools USING [GetSelectionContents], ViewerOps USING [AddProp, EnumProc, FetchProp, PaintViewer], VirtualDesktops USING [EnumerateViewers]; TEditDocuments3Impl: CEDAR PROGRAM IMPORTS CedarSnapshot, InputFocus, MessageWindow, Process, Rope, TEditDocument, TEditDocumentPrivate, TEditInput, TEditScrolling, TEditSelection, TextNode, ViewerMenus, ViewerOps, ViewerTools, VirtualDesktops EXPORTS TEditDocumentPrivate = BEGIN OPEN TEditDocument, TEditDocumentPrivate, ViewerClasses; Do: PROC [viewer: REF ANY, atom: ATOM] = INLINE { TEditInput.InterpretAtom[NARROW[viewer], atom] }; Register: PROC [atom: ATOM, op: TEditInput.CommandProc] = { TEditInput.Register[atom, op] }; ForkViewerOp2: PROC [ proc: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL], parent: Viewer] RETURNS [BOOL] = { TEditInput.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] = { TEditInput.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: TEditDocumentData; 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: TEditInput.CommandProc = { SaveLoc: PROC [v: Viewer] = BEGIN tdd: TEditDocument.TEditDocumentData _ NARROW[v.data]; loc: INT; IF tdd = NIL THEN RETURN; [] _ SpinAndLock[tdd, "Reset"]; -- delay until after other op completes loc _ TextNode.LocNumber[tdd.lineTable.lines[0].pos]; Unlock[tdd]; ViewerOps.AddProp[v, $ResetLoc, TextNode.pZone.NEW[INT _ loc]]; v.newVersion _ TRUE; -- to force the init proc to reread the file END; DoOne: PROC [v: Viewer] = BEGIN tdd: TEditDocument.TEditDocumentData _ 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,TextNode.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: TEditInput.CommandProc = BEGIN TEditInput.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: 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.MenuProc = { MessageWindow.Clear[]; Do[parent, SelectMouse[mouseButton, $RedStore, $YellowStore, $BlueStore]] }; StoreOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[DoStoreFile,viewer]] }; <> <<>> PreviousFile: PUBLIC Menus.MenuProc = { 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.MenuProc = { Do[parent,$AnonymousLoadImpl] }; AnonymousLoadImplOp: TEditInput.CommandProc = { RETURN [ForkViewerOp[AnonymousLoadImplFile,viewer]] }; AnonymousLoad: PUBLIC Menus.MenuProc = { Do[parent,$AnonymousLoad] }; AnonymousLoadOp: TEditInput.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: TEditInput.CommandProc = { RETURN [ForkViewerOp2[LoadIt,viewer]] }; LoadIt: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoLoadFile[parent, fileName, FALSE] }; OpenOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[OpenIt,viewer]] }; OpenIt: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoOpenFile[fileName, parent] }; CloseAndOpenOp: TEditInput.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: TEditInput.CommandProc = { RETURN [ForkViewerOp2[LoadItImpl,viewer]] }; LoadItImpl: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoLoadImplFile[parent, fileName, FALSE] }; OpenImplOp: TEditInput.CommandProc = { RETURN [ForkViewerOp2[OpenItImpl,viewer]] }; OpenItImpl: PROC [parent: Viewer, fileName: Rope.ROPE _ NIL] = { [] _ DoOpenImplFile[fileName, parent] }; CloseAndOpenImplOp: TEditInput.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: 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.MenuProc = {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] }; 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]}; <