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]]}; Process.Pause[Process.MsecToTicks[250]]; 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. >TEditMenuImpl.mesa Michael Plass, October 12, 1983 11:05 am Process forking mechanism. -- 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 Clear = Empty, New, or CloseAndNew Don't fork these operations since they change the selection; want to capture typein that follows calls on these. Get = Load, Open, or CloseAndOpen GetImpl = LoadImpl, OpenImpl, or CloseAndOpenImpl PrevFile = LoadPrevious, OpenPrevious, or CloseAndOpenPrevious Anonymous Loads -- into NoName viewers ÊߘJ™J™(šÏk ˜ Jšœ˜Jšœ ˜ J˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ J˜J˜Jšœ ˜ Jšœ˜Jšœ˜J˜ J˜Jšœ ˜ J˜—šœœ˜Jšœ¦˜­Jšœ˜Jšœ˜J˜—Jšœ œ˜+Jšœœ˜$šœœœ˜J˜—™š Ïn œœœ#œœ˜SJ˜šœœ˜9JšÏcI™I—˜(JšŸH™H—Jšœœ˜Jšœ˜—šž œœœ&˜CJšœœœ˜"Jšœ˜J˜——™"J™pšžœ˜Jšœ)˜)Jšœœ˜Jšœ˜J˜—šžœ˜Jšœ'˜'Jšœœ˜Jšœ˜J˜—šž œ˜Jšœ/˜/Jšœœ˜Jšœ˜J˜——šžœ˜šžœœ˜Jšœ'œ ˜6Jšœœ˜ Jšœœœœ˜Jšœ.Ÿ'˜UJšœ5˜5Jšœ˜Jšœ/œœ ˜?JšœœŸ,˜AJšœ˜—šžœœ˜Jšœ'œ ˜6Jšœœ˜Jšœœœœ˜Jšœ$œ˜FJšœ œ$˜3Jšœ˜Jšœœ˜!š œ œœœS˜mJšœ˜—Jšœ˜—Jšœ˜šœ œ˜Jšœ!œ œ œ˜I—J˜šœ œ˜Jšœ!œ œ œ˜G—Jšœœ˜Jšœ˜J˜—™!šžœ˜Jšœ%˜+Jšœ˜—šž œœ˜'Jšœ<œ˜CJšœ˜J˜—šžœ˜Jšœ%˜+Jšœ˜—šž œœ˜'Jšœ5˜5Jšœ˜J˜—šžœ˜Jšœ-˜3Jšœ˜—šžœœ˜/Jšœ=˜=Jšœ˜J˜——™1šž œ˜Jšœ)˜/Jšœ˜—šžœœ˜+Jšœ@œ˜GJšœ˜J˜—šž œ˜Jšœ)˜/Jšœ˜—šžœœ˜+Jšœ9˜9Jšœ˜J˜—šžœ˜#Jšœ1˜7Jšœ˜—šžœœ˜3JšœA˜AJšœ˜J˜——šœ>™>šžœ˜Jšœ>˜DJšœ˜J˜—šžœ˜Jšœ>˜DJšœ˜J˜—šžœ˜'JšœF˜LJšœ˜J˜——šžœ˜Jšœ&˜,Jšœ˜—šž œœ˜(Jšœ)˜)Jšœ˜J˜—šžœ˜J˜šœœ˜Jšœœ ˜A—Jšœœ˜Jšœ˜J˜—šž œ˜Jšœ'œ˜;Jšœœ(œ0˜gš œœœœœ˜"J˜"Jšœ"œ˜9Jšœ2œœ˜AJšœœ8œœ˜\—Jšœ1œ˜7J˜Jšœœ˜Jšœ˜J˜—šž œ˜Jšœ'œ˜;Jšœ œ1˜Wš œœœœœ!œ˜FJ˜š œœœ!œœ˜?Jšœœ'œ˜MJšœ˜#Jšœ˜—Jšœ˜Jšœ œ˜Jšœ˜J˜—šžœœœ5˜OJ˜—Jšœ˜Jšœ˜Jšœ&˜&šœ˜Jšœ]˜]—Jšœ˜Jšœ˜Jšœ(˜(šœ˜JšœW˜W—šœ˜Jšœ]˜]—Jšœ(˜(Jšœ(˜(Jšœ8˜8Jšœ2˜2Jšœ*˜*Jšœ ˜ Jšœ ˜ Jšœ0˜0Jšœ"˜"Jšœ ˜ J˜Jšœ˜J˜Jšœ˜—…—0'M