TEditMenuImpl.mesa
Michael Plass, October 12, 1983 11:05 am
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;
Process forking mechanism.
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]
};
Clear = Empty, New, or CloseAndNew
Don't fork these operations since they change the selection; want to capture typein that follows calls on these.
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]
};
Get = Load, Open, or CloseAndOpen
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];
};
GetImpl = LoadImpl, OpenImpl, or CloseAndOpenImpl
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];
};
PrevFile = LoadPrevious, OpenPrevious, or CloseAndOpenPrevious
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]
};
Anonymous Loads -- into NoName viewers
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: BOOLFALSE] ~ {
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.