EditToolOpsImpl.mesa
Copyright Ó 1985, 1986, 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Russ Atkinson, September 28, 1983 2:21 pm
Russ Atkinson (RRA) June 18, 1985 4:59:53 pm PDT
Alison Lee June 11, 1986 8:44:11 pm PDT
Swinehart, November 14, 1986 10:01:23 am PST
Pier, January 7, 1989 4:13:44 pm PST
Michael Plass, January 8, 1990 12:19:02 pm PST
Doug Wyatt, March 14, 1992 6:04 pm PST
DIRECTORY
Buttons USING [ButtonProc],
EditToolBuilder USING [ToNext, BadNumber, BuildButton, BuildDataFieldPair, ConvertList, DataFieldButton, GetInt, HGap, VGap],
EditToolPrivate USING [CheckPSel, DoButton, GetRopeArg, Info, mainToolInfo, Register, TrySearch],
FS USING [Error, FileInfo, nullOpenFile, Open, OpenFile, StreamFromOpenFile],
IO USING [Close, EndOfStream, GetChar, GetLength, GetRefAny, RIS, STREAM],
List USING [Append, Nconc1],
MessageWindow USING [Append, Blink],
Rope USING [Cat, Concat, Fetch, FromProc, ROPE, Size, Substr],
TEditDocument USING [Selection],
TEditHistory USING [CurrentEventNumber, GetRepeatList, SliceSize],
TEditInput USING [CloseEvent, CommandProc, CurrentEvent, GetCommand, GetRepeatSequence, Interpret, SetCommand],
TEditOps USING [GetSelData, SetTextContents],
TEditProfile USING [GetToken],
TEditSelection USING [LockSel, UnlockSel],
TiogaMenuOps USING [CloseAndNewViewer, Empty, Load, New],
Tioga USING [],
TiogaOps USING [FirstChild, SelectDocument, SetSelection, ViewerDoc],
TiogaOpsDefs USING [Ref],
TypeScript USING [IsATypeScript],
UndoEvent USING [Event, EventRep, Reset],
ViewerClasses USING [Viewer],
ViewerOps USING [DestroyViewer, SaveViewer];
EditToolOpsImpl:
CEDAR
PROGRAM
IMPORTS EditToolPrivate, EditToolBuilder, FS, IO, List, MessageWindow, Rope, TEditInput, TEditOps, TEditHistory, TEditSelection, TiogaMenuOps, TiogaOps, TEditProfile, TypeScript, UndoEvent, ViewerOps
EXPORTS EditToolPrivate, Tioga
= { OPEN ViewerClasses, EditToolBuilder, EditToolPrivate;
ROPE: TYPE = Rope.ROPE;
EventRep: PUBLIC TYPE ~ UndoEvent.EventRep; -- concrete type of Tioga.EventRep
--------------------------
Flash:
PROC[message, message2, message3:
ROPE ¬
NIL] = {
MessageWindow.Append[message, TRUE];
IF message2#NIL THEN MessageWindow.Append[message2];
IF message3#NIL THEN MessageWindow.Append[message3];
MessageWindow.Blink[];
};
--------------------------
opsAtom: LIST OF REF = Register[$Operations,OpsArgOp];
clearOpsAtom: LIST OF REF = Register[$ClearOperations,ClearOpsArgOp];
OpsButton: Buttons.ButtonProc = {
DoButton[opsAtom,clearOpsAtom, mouseButton=red] };
OpsArgOp: TEditInput.CommandProc = { OpsArg[mainToolInfo] };
OpsArg: PROC [info: Info] = { DataFieldButton[info.opsArg,FALSE] };
ClearOpsArgOp: TEditInput.CommandProc = { ClearOpsArg[mainToolInfo] };
ClearOpsArg: PROC [info: Info] = { DataFieldButton[info.opsArg,TRUE] };
BuildOperationField:
PUBLIC
PROC [info: Info] = {
OPEN info;
[,opsArg] ¬ BuildDataFieldPair[layout, "Operations:", OpsButton, info, 2] };
GetOps:
PUBLIC
PROC [info: Info]
RETURNS [list:
LIST
OF
REF
ANY] = {
OPEN
IO, info;
rope: ROPE ¬ GetRopeArg[opsArg];
h: IO.STREAM ¬ IO.RIS[rope];
item: REF ANY ¬ NIL;
DO
item ¬ IO.GetRefAny[h ! IO.EndOfStream => { item ¬ NIL; CONTINUE}];
IF item = NIL THEN EXIT;
list ¬ List.Nconc1[list, item];
ENDLOOP;
};
--------------------------
BuildRealFileListEntries:
PUBLIC
PROC [info: EditToolPrivate.Info] = {
OPEN info;
[] ¬ BuildButton[layout, "DoForEachFile", DoFilesListButton, info, TRUE];
[] ¬ BuildButton[layout, "SearchEachFile", SearchFilesListButton, info, TRUE];
HGap[layout];
EditToolBuilder.ToNext[layout];
[,filesArg] ¬ BuildDataFieldPair[layout, "FilesList:", FilesListButton, info, 1];
VGap[layout];
[,wdirArg] ¬ BuildDataFieldPair[layout, "WDir:", WDirButton, info, 1];
BuildFileListEntries:
PUBLIC
PROC [info: EditToolPrivate.Info] = {
OPEN info;
[] ¬ BuildButton[layout, "DoForEachFile", DoFilesListButton, info, TRUE];
[] ¬ BuildButton[layout, "SearchEachFile", SearchFilesListButton, info, TRUE];
HGap[layout];
[,filesArg] ¬ BuildDataFieldPair[layout, "Files:", FilesListButton, info, 1];
VGap[layout];
[,wdirArg] ¬ BuildDataFieldPair[layout, "Working Directory:", WDirButton, info, 1];
--------------------------
filesListAtom: LIST OF REF = Register[$FilesList,FilesListOp];
clearFilesListAtom: LIST OF REF = Register[$ClearFilesList,ClearFilesListOp];
FilesListButton: Buttons.ButtonProc = {
DoButton[filesListAtom,clearFilesListAtom, mouseButton=red] };
FilesListOp: TEditInput.CommandProc = { FilesList[mainToolInfo] };
FilesList: PROC [info: Info] = { DataFieldButton[info.filesArg,FALSE] };
ClearFilesListOp: TEditInput.CommandProc = { ClearFilesList[mainToolInfo] };
ClearFilesList: PROC [info: Info] = { DataFieldButton[info.filesArg,TRUE] };
--------------------------
wDirAtom: LIST OF REF = Register[$WDir,WDirOp];
clearWDirAtom: LIST OF REF = Register[$ClearWDir,ClearWDirOp];
WDirButton: Buttons.ButtonProc = {
DoButton[wDirAtom,clearWDirAtom, mouseButton=red] };
WDirOp: TEditInput.CommandProc = { WDir[mainToolInfo] };
WDir: PROC [info: Info] = { DataFieldButton[info.wdirArg,FALSE] };
ClearWDirOp: TEditInput.CommandProc = { ClearWDir[mainToolInfo] };
ClearWDir: PROC [info: Info] = { DataFieldButton[info.wdirArg,TRUE] };
--------------------------
searchFilesListAtom: LIST OF REF = Register[$SearchEachFile,SearchFilesListOp];
SearchFilesListButton: Buttons.ButtonProc = { DoButton[searchFilesListAtom] };
SearchFilesListOp: TEditInput.CommandProc = { SearchFilesListCom[mainToolInfo] };
SearchFilesListCom: PROC [info: Info] = { DoFilesList[info, FALSE] };
--------------------------
doFilesListAtom: LIST OF REF = Register[$DoForEachFile,DoFilesListOp];
DoFilesListButton: Buttons.ButtonProc = { DoButton[doFilesListAtom] };
DoFilesListOp: TEditInput.CommandProc = { DoFilesListCom[mainToolInfo] };
DoFilesListCom: PROC [info: Info] = { DoFilesList[info, TRUE] };
DoFilesList:
PROC [info: Info, do:
BOOL] = {
params: LIST OF REF ANY;
pSel: TEditDocument.Selection;
viewer: Viewer;
found: BOOL ¬ FALSE;
event: UndoEvent.Event = TEditInput.CurrentEvent[];
fileList: ROPE ¬ GetRopeArg[info.filesArg];
wDir: ROPE ¬ GetRopeArg[info.wdirArg];
GetFilesList:
PROC [fileName:
ROPE]
RETURNS [filesList:
ROPE] = {
len: INT;
s: IO.STREAM;
readChar: PROC RETURNS [CHAR] = { RETURN [IO.GetChar[s]] };
file: FS.OpenFile ¬ FS.nullOpenFile;
file ¬
FS.Open[name: fileName, wDir: wDir
!
FS.Error =>
IF error.group=$user THEN CONTINUE
ELSE { Flash[error.explanation]; GOTO Quit }
];
IF file=
FS.nullOpenFile
THEN file ¬
FS.Open[name: fileName.Concat[".cm"], wDir: wDir
!
FS.Error =>
IF error.group=$user THEN CONTINUE
ELSE { Flash[error.explanation]; GOTO Quit }
];
IF file=FS.nullOpenFile THEN { Flash[fileName, " not found"]; GOTO Quit };
s ¬ FS.StreamFromOpenFile[file];
len ¬ IO.GetLength[s];
filesList ¬ Rope.FromProc[len, readChar];
IO.Close[s];
EXITS Quit => { filesList ¬ NIL };
};
DoEachInList:
PROC [list:
ROPE]
RETURNS [remainder:
ROPE] = {
offset: INT ¬ 0;
DO
-- process each file
filename: ROPE;
IF info.interrupt THEN RETURN [Rope.Substr[list, offset]];
[filename, offset] ¬ TEditProfile.GetToken[list, offset];
IF Rope.Size[filename]=0 THEN RETURN [NIL];
IF Rope.Fetch[filename,0]='@
THEN {
-- process list
sub: ROPE = DoEachInList[GetFilesList[Rope.Substr[filename,1]]];
IF sub=NIL THEN LOOP; -- finished the sublist
RETURN [Rope.Cat[sub, " ", Rope.Substr[list, offset]]] };
IF viewer.newVersion
THEN viewer ¬ TiogaMenuOps.CloseAndNewViewer[viewer]
ELSE TiogaMenuOps.Empty[viewer];
KAP for PCedar January 7, 1989
[fullFName: filename] ← TFS.ExpandName[name: filename, wDir: wDir
! TFS.Error => { Flash[error.explanation]; filename ← NIL; CONTINUE }];
[fullFName: filename] ¬
FS.FileInfo[name: filename, wDir: wDir
!
FS.Error =>
IF error.group=$user
THEN {
Flash[error.explanation];
filename ¬ NIL;
CONTINUE;
}
];
IF filename=
NIL
THEN Flash[filename, " does not exist"]
ELSE TiogaMenuOps.Load[viewer, filename];
IF viewer.file#
NIL
THEN {
-- got the file
IF do
THEN {
TiogaOps.SelectDocument[viewer];
TEditInput.Interpret[viewer, params];
IF viewer.newVersion THEN [] ← ViewerOps.SaveViewer[viewer];
UndoEvent.Reset[event] } -- so we don't fill up VM with trash
ELSE {
-- search
node: TiogaOpsDefs.Ref = TiogaOps.FirstChild[TiogaOps.ViewerDoc[viewer]];
TiogaOps.SetSelection[viewer, [node,0], [node,0], point];
make point selection at start of document
IF TrySearch[forwards, info]
THEN
found ¬ info.interrupt ¬ TRUE; -- so will stop after this one
}};
ENDLOOP
};
info.interrupt ¬ FALSE;
IF do AND (params ¬ GetOps[info])=NIL THEN { Flash["Enter operations."]; RETURN };
IF fileList=NIL THEN { Flash["Enter list of files."]; RETURN };
TEditInput.CloseEvent[];
TEditSelection.LockSel[primary, "DoFilesList"];
pSel ¬ TEditOps.GetSelData[];
viewer ¬
IF pSel.viewer#
NIL
AND pSel.viewer.parent=
NIL
AND ~TypeScript.IsATypeScript[pSel.viewer]
THEN
IF pSel.viewer.file=
NIL
THEN pSel.viewer
ELSE TiogaMenuOps.CloseAndNewViewer[pSel.viewer]
ELSE TiogaMenuOps.New[];
TEditOps.SetTextContents[info.filesArg, DoEachInList[fileList]];
TEditSelection.UnlockSel[primary];
IF do OR (~found AND ~viewer.newVersion) THEN ViewerOps.DestroyViewer[viewer];
};
--------------------------
BuildRealGetAndSetOpsEntries:
PUBLIC
PROC [info: EditToolPrivate.Info] = {
OPEN info;
[] ¬ BuildButton[layout, "DoGetLastOps", DoGetLastOpsButton, info];
[] ¬ BuildButton[layout, "DoOps", DoOpsButton, info];
[] ¬ BuildButton[layout, "DoBegin", DoBeginButton, info];
[] ¬ BuildButton[layout, "DoEnd", DoEndButton, info];
[] ¬ BuildButton[layout, "DoSetOps", DoSetOpsButton, info];
[] ¬ BuildButton[layout, "DoGetOps", DoGetOpsButton, info];
HGap[layout]
EditToolBuilder.ToNext[ layout];
BuildRealComNumField[info];
-- "Command number [0..9]:" field
};
BuildGetAndSetOpsEntries:
PUBLIC
PROC [info: EditToolPrivate.Info] = {
OPEN info;
[] ¬ BuildButton[layout, "GetLast", DoGetLastOpsButton, info];
[] ¬ BuildButton[layout, "Do", DoOpsButton, info];
[] ¬ BuildButton[layout, "Begin", DoBeginButton, info];
[] ¬ BuildButton[layout, "End", DoEndButton, info];
[] ¬ BuildButton[layout, "SetCom", DoSetOpsButton, info];
[] ¬ BuildButton[layout, "GetCom", DoGetOpsButton, info];
HGap[layout];
BuildComNumField[info];
-- "Command number [0..9]:" field
};
doGetLastOpsAtom: LIST OF REF = Register[$DoGetLastOps,DoGetLastOpsOp];
DoGetLastOpsButton: Buttons.ButtonProc = {
DoButton[doGetLastOpsAtom] };
DoGetLastOpsOp: TEditInput.CommandProc = {
DoGetLastOpsCom[mainToolInfo]; RETURN [FALSE] };
DoGetLastOpsCom:
PROC [info: Info] = {
ShowOps[TEditInput.GetRepeatSequence[],info] };
ShowOps:
PROC [list:
LIST
OF
REF
ANY, info: Info] = {
TEditOps.SetTextContents[info.opsArg, ConvertList[list]] };
doOpsAtom: LIST OF REF = Register[$DoOps,DoOpsOp];
DoOpsButton: Buttons.ButtonProc = {
DoButton[doOpsAtom] };
DoOpsOp: TEditInput.CommandProc = { DoOpsCom[mainToolInfo] };
DoOpsCom:
PUBLIC
PROC [info: Info] = {
pSel: TEditDocument.Selection ¬ TEditOps.GetSelData[];
params: LIST OF REF ANY;
IF ~CheckPSel[pSel] THEN { Flash["Make a selection."]; RETURN };
IF (params ¬ GetOps[info])=NIL THEN { Flash["Enter operations."]; RETURN };
TEditSelection.LockSel[primary, "DoOpsCom"];
TEditInput.Interpret[pSel.viewer, params];
TEditSelection.UnlockSel[primary] };
SetCom:
PROC [num: [0..9], info: Info] = {
list: LIST OF REF ANY ¬ GetOps[info];
TEditInput.SetCommand[num,list];
};
doSetOpsAtom: LIST OF REF = Register[$DoSetOps,DoSetOpsOp];
DoSetOpsButton: Buttons.ButtonProc = {
DoButton[doSetOpsAtom] };
DoSetOpsOp: TEditInput.CommandProc = { DoSetOpsCom[mainToolInfo] };
DoSetOpsCom:
PROC [info: Info] = {
num: INT ¬ GetInt[info.comArg ! BadNumber => GOTO BadNum];
IF num NOT IN [0..9] THEN GOTO BadNum;
SetCom[num,info];
EXITS BadNum => { Flash["Enter number from 0 to 9 in Command Number field"] }
doGetOpsAtom: LIST OF REF = Register[$DoGetOps,DoGetOpsOp];
DoGetOpsButton: Buttons.ButtonProc = {
DoButton[doGetOpsAtom] };
DoGetOpsOp: TEditInput.CommandProc = { DoGetOpsCom[mainToolInfo] };
DoGetOpsCom:
PROC [info: Info] = {
num: INT ¬ GetInt[info.comArg ! BadNumber => GOTO BadNum];
IF num NOT IN [0..9] THEN GOTO BadNum;
ShowOps[TEditInput.GetCommand[num],info];
EXITS BadNum => { Flash["Enter number from 0 to 9 in Command Number field"] }
doBeginAtom: LIST OF REF = Register[$DoBegin,DoBeginOp];
DoBeginButton: Buttons.ButtonProc = {
DoButton[doBeginAtom] };
DoBeginOp: TEditInput.CommandProc = { DoBeginCom[mainToolInfo] };
beginEvent: INT ¬ 0;
DoBeginCom:
PROC [info: Info] = {
[] ¬ TEditInput.GetRepeatSequence[]; -- to make sure the event is terminated
beginEvent ¬ TEditHistory.CurrentEventNumber[];
TEditInput.CloseEvent[] };
doEndAtom: LIST OF REF = Register[$DoEnd,DoEndOp];
DoEndButton: Buttons.ButtonProc = {
DoButton[doEndAtom] };
DoEndOp: TEditInput.CommandProc = { DoEndCom[mainToolInfo] };
DoEndCom:
PROC [info: Info] = {
list: LIST OF REF ANY;
endEvent: INT;
[] ¬ TEditInput.GetRepeatSequence[]; -- to make sure the event is terminated
endEvent ¬ TEditHistory.CurrentEventNumber[];
IF endEvent-beginEvent > TEditHistory.SliceSize[]
THEN {
Flash["Not all events still recorded. Some missing at start."];
};
FOR i:
INT ¬ beginEvent+1, i+1
UNTIL i > endEvent
DO
list ¬ List.Append[list, TEditHistory.GetRepeatList[i]];
ENDLOOP;
ShowOps[list,info] };
--------------------------
comNumAtom: LIST OF REF = Register[$CommandNumber,DoComNumOp];
clearComNumAtom: LIST OF REF = Register[$ClearCommandNumber,ClearComNumOp];
ComNumButton: Buttons.ButtonProc = {
DoButton[comNumAtom,clearComNumAtom, mouseButton=red] };
DoComNumOp: TEditInput.CommandProc = { DoComNum[mainToolInfo] };
DoComNum: PROC [info: Info] = { DataFieldButton[info.comArg,FALSE] };
ClearComNumOp: TEditInput.CommandProc = { ClearComNum[mainToolInfo] };
ClearComNum: PROC [info: Info] = { DataFieldButton[info.comArg,TRUE] };
BuildRealComNumField:
PUBLIC
PROC [info: EditToolPrivate.Info] = {
OPEN info;
[,comArg] ¬ BuildDataFieldPair[layout, "CommandNumber [0..9]:", ComNumButton, info, 1];
TEditOps.SetTextContents[comArg, "1 "]; };
BuildComNumField:
PUBLIC
PROC [info: EditToolPrivate.Info] = {
OPEN info;
[,comArg] ¬ BuildDataFieldPair[layout, "Command [0..9]:", ComNumButton, info, 1];
TEditOps.SetTextContents[comArg, "1 "]; };
--------------------------
}...