<> <> DIRECTORY FileIO, InputFocus, IO, Menus, MessageWindow, Process, Rope, RopeFrom, TEditDocument, TEditDocumentPrivate, TEditInput, TEditScrolling, TEditSelection, TextNode, ViewerClasses, ViewerOps ; TEditMenuImpl: CEDAR PROGRAM IMPORTS FileIO, InputFocus, IO, Menus, MessageWindow, Process, RopeFrom, TEditDocument, TEditDocumentPrivate, TEditInput, TEditScrolling, TEditSelection, TextNode, ViewerOps EXPORTS TEditDocumentPrivate ~ BEGIN CommandProc: TYPE ~ TEditInput.CommandProc; Viewer: TYPE ~ ViewerClasses.Viewer; ROPE: TYPE ~ Rope.ROPE; <> ForkViewerOp: PROC [proc: PROC [parent: Viewer], parent: Viewer] RETURNS [BOOL] = { TEditInput.CloseEvent[]; 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>> RETURN [FALSE] }; StackBottom: PROC [proc: PROC [parent: Viewer], parent: Viewer] = { proc[parent ! ABORTED => CONTINUE] }; <> <> EmptyOp: CommandProc = { TEditDocumentPrivate.EmptyViewer[viewer]; RETURN [FALSE] }; NewOp: CommandProc = { TEditDocumentPrivate.NewViewer[viewer]; RETURN [FALSE] }; CloseAndNewOp: CommandProc = { TEditDocumentPrivate.CloseAndNewViewer[viewer]; RETURN [FALSE] }; ResetOp: CommandProc ~ { SaveLoc: PROC [v: Viewer] ~ { tdd: TEditDocument.TEditDocumentData _ NARROW[v.data]; loc: INT; IF tdd = NIL THEN RETURN; [] _ TEditDocument.SpinAndLock[tdd, "Reset"]; -- delay until after other op completes loc _ TextNode.LocNumber[tdd.lineTable.lines[0].pos]; TEditDocument.Unlock[tdd]; ViewerOps.AddProp[v, $ResetLoc, TextNode.pZone.NEW[INT _ loc]]; v.newVersion _ TRUE; -- to force the init proc to reread the file }; DoOne: PROC [v: Viewer] ~ { 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 NOT TEditDocumentPrivate.PositionViewer[v,TextNode.LocWithin[tdd.text, locRef^], all] THEN ViewerOps.PaintViewer[v, all]; }; 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] }; <> LoadOp: CommandProc = { RETURN [ForkViewerOp[LoadImplicit, viewer]] }; LoadImplicit: PROC [parent: Viewer] ~ { [] _ TEditDocumentPrivate.DoLoadFile[parent: parent, close: FALSE]; }; OpenOp: CommandProc = { RETURN [ForkViewerOp[OpenImplicit, viewer]] }; OpenImplicit: PROC [parent: Viewer] ~ { [] _ TEditDocumentPrivate.DoOpenFile[parent: parent]; }; CloseAndOpenOp: CommandProc = { RETURN [ForkViewerOp[CloseAndOpenImplicit, viewer]] }; CloseAndOpenImplicit: PROC [parent: Viewer] ~ { [] _ TEditDocumentPrivate.DoCloseAndOpenFile[parent: parent]; }; <> LoadImplOp: CommandProc = { RETURN [ForkViewerOp[LoadImplImplicit, viewer]] }; LoadImplImplicit: PROC [parent: Viewer] ~ { [] _ TEditDocumentPrivate.DoLoadImplFile[parent: parent, close: FALSE]; }; OpenImplOp: CommandProc = { RETURN [ForkViewerOp[OpenImplImplicit, viewer]] }; OpenImplImplicit: PROC [parent: Viewer] ~ { [] _ TEditDocumentPrivate.DoOpenImplFile[parent: parent]; }; CloseAndOpenImplOp: CommandProc = { RETURN [ForkViewerOp[CloseAndOpenImplImplicit, viewer]] }; CloseAndOpenImplImplicit: PROC [parent: Viewer] ~ { [] _ TEditDocumentPrivate.DoCloseAndOpenImplFile[parent: parent]; }; <> LoadPreviousOp: CommandProc = { RETURN [ForkViewerOp[TEditDocumentPrivate.LoadPreviousFile, viewer]] }; OpenPreviousOp: CommandProc = { RETURN [ForkViewerOp[TEditDocumentPrivate.OpenPreviousFile, viewer]] }; CloseAndOpenPreviousOp: CommandProc = { RETURN [ForkViewerOp[TEditDocumentPrivate.CloseAndOpenPreviousFile, viewer]] }; StoreOp: CommandProc = { RETURN [ForkViewerOp[StoreImplicit, viewer]] }; StoreImplicit: PROC [parent: Viewer] ~ { TEditDocumentPrivate.DoStoreFile[parent]; }; SaveOp: CommandProc ~ { TEditInput.CloseEvent[]; IF ~viewer.saveInProgress THEN TRUSTED {[] _ Process.Detach[FORK ViewerOps.SaveViewer[viewer]]}; RETURN [FALSE]; }; PrevPlaceOp: CommandProc = { tdd: TEditDocument.TEditDocumentData _ NARROW[viewer.data]; prop: REF TEditDocumentPrivate.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 TEditDocumentPrivate.PositionViewer[viewer, loc] THEN RETURN; IF loc # prop.prev AND TEditDocumentPrivate.PositionViewer[viewer, prop.prev] THEN RETURN }; MessageWindow.Append["No previous place saved.", TRUE]; MessageWindow.Blink[]; RETURN [FALSE] }; ReselectOp: 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] }; <> AnonymousLoadOp: CommandProc = { RETURN [ForkViewerOp[AnonymousLoadIt, viewer]] }; AnonymousLoadIt: PROC [parent: Viewer] = { TEditDocumentPrivate.AnonymousLoadFile[parent] }; AnonymousLoadImplOp: CommandProc = { RETURN [ForkViewerOp[TEditDocumentPrivate.AnonymousLoadImplFile, viewer]] }; DefaultMenus: PUBLIC PROC [viewer: Viewer, paint: BOOL _ FALSE] ~ { menus: LIST OF ATOM _ viewer.class.menus; Menus.ClearMenus[viewer, paint AND menus = NIL]; FOR menu: LIST OF ATOM _ menus, menu.rest UNTIL menu = NIL DO Menus.AddMenu[viewer, menu.first, paint AND menu.rest = NIL]; ENDLOOP; }; RegisterTiogaMenu: PUBLIC PROC ~ { stream: IO.STREAM _ FileIO.Open["tioga.menu" ! FileIO.OpenFailed => GOTO Quit]; rope: ROPE _ RopeFrom.Stream[stream]; tiogaMenus: LIST OF Menus.Menu _ Menus.ParseDescription[rope]; FOR m: LIST OF Menus.Menu _ tiogaMenus, m.rest UNTIL m = NIL DO IF NOT Menus.AlreadyRegistered[m.first.name] THEN Menus.RegisterMenu[m.first] ELSE Menus.ReRegisterMenu[m.first]; ENDLOOP; stream.Close[]; EXITS Quit => NULL; }; Register: PROC [atom: ATOM, op: CommandProc] ~ {TEditInput.Register[atom, op]}; Register[$Empty, EmptyOp]; Register[$New, NewOp]; Register[$CloseAndNew, CloseAndNewOp]; Register[$Reset, ResetOp]; Register[$RedReset, ResetOp]; Register[$YellowReset, ResetOp]; Register[$BlueReset, ResetOp]; Register[$Load, LoadOp]; Register[$Open, OpenOp]; Register[$CloseAndOpen, CloseAndOpenOp]; Register[$Save, SaveOp]; Register[$RedSave, SaveOp]; Register[$YellowSave, SaveOp]; Register[$BlueSave, SaveOp]; Register[$Store, StoreOp]; 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[$LoadImpl, LoadImplOp]; Register[$OpenImpl, OpenImplOp]; Register[$CloseAndOpenImpl, CloseAndOpenImplOp]; Register[$PrevPlace, PrevPlaceOp]; Register[$Reselect, ReselectOp]; RegisterTiogaMenu[]; END.