-- NewCalcImpl.mesa
-- last edit July 30, 1984 10:17:41 am PDT Sturgis

DIRECTORY
 ButtonCells USING[ForceNoteBCellSelection],
Commander USING[CommandProc, Register],
 Convert USING[RopeFromCard],
Dependencies USING[CreateDependencySet, DependencySet, LoopInDependencyGraph, MultipleAssignmentToOneDataItem, PerformDirtyActions, Verify],
Displayer USING[BuildDisplayer, ButtonDefiningProc, PaintDisplayerContents, ResetDisplayerName, SetDisplayerContents],
EncryptedIOStream USING[CreateDecryptedInStream, CreateEncryptedOutStream],
FS USING[ExpandName, StreamOpen],
Expressions USING[HCellIdSet, IdTable, MakeHCellIdSet, MakeIdTable],
GCell USING[ConnectInstalledItemArraysInColumnOfRows, ConnectLoadedItemArraysInColumnOfRows, CountOpenSlotsInColumnOfRows, CreateColumnOfRows, GenerateSummaryArraysInColumnOfRows, GetColumnOfRows, GetHCellArrayAtSlotInColumnOfRows, ForceNoteItemSelection, InstallHCellArrayAtAnOpenSlotInColumnOfRows, InstallHCellArrayAtOpenSlotInColumnOfRows, LoadColumnOfRows, ResetPageNameOfColumnOfRows, SetAColumnOfRowsProc, SetColumnOfRows, SlotCase],
HCells USING[ForceNoteHCellSelection, WriteCellText],
IO USING[atom, char, Close, CR, EndOf, GetChar, GetInt, GetTokenRope, STREAM, int, Put, PutChar, rope, SetIndex],
List USING[AList, Assoc],
MessageWindow USING[Append, Blink],
NewCalcGlobal USING[Displayer, Document, DocumentProcs, DocumentPublicBody,
 AbandonPageList, CheckForDirtyDataInPages, ControlRopeType, CreatePageList, LoadPageList, RepaintAllOpenPages, SavePageList, ShowPageList,
 PageMode],
ProcessProps USING[GetPropList],
Rope USING[Cat, Equal, Length, ROPE],
StructureNodes USING[Action, BadFormatLoadFile, StructureNode, StructureNodeProcs],
TiogaOps USING[CommandProc, RegisterCommand],
ViewerClasses USING[Viewer],
ViewerOps USING[DestroyViewer, FetchProp],
ViewerTools USING[GetContents, GetSelectedViewer, SetContents];


NewCalcImpl: MONITOR IMPORTS ButtonCells, Commander, Convert, Displayer, Dependencies, EncryptedIOStream, Expressions, FS, GCell, HCells, IO, List, MessageWindow, NewCalcGlobal, Rope, ProcessProps, StructureNodes, TiogaOps, ViewerOps, ViewerTools EXPORTS GCell, NewCalcGlobal =



-- NOTE NOTE NOTE NOTE NOTE NOTE

-- NOTE: !!!!! WHEN CONVERTING TO OBJECT MONITOR, Set and Get Selection must also be entry procedures. !!!! NOTE NOTE

-- ALSO, Array tool will have to set entry TRUE on calls to Get and Set GCellArray.



BEGIN OPEN Dependencies, EncryptedIOStream, IO, ViewerClasses;

-- control stuff

VersionForSave: CARDINAL = 2;

DocumentPrivateBody: TYPE = RECORD[
displayer: NewCalcGlobal.Displayer,
container: Viewer,
structure: Viewer,
newPageId: Viewer,
workingDirBox: Viewer,
saveFileBox: Viewer,
key: Rope.ROPE,
keyBox: Viewer,
zvt: Viewer,
newArrayIdText: Viewer,

 rootsn: StructureNodes.StructureNode ← NIL -- this holds the page buttons

];

DocumentDisplayerProcs: REF NewCalcGlobal.DocumentProcs ← NEW[NewCalcGlobal.DocumentProcs ← [ExecuteInDocumentMonitor, ComputeDocumentTotals, DoDocumentOperatorOrStructureAct, AdjustDocument, GetDocumentControlRope]];

BuildDocument: ENTRY Commander.CommandProc = TRUSTED
BEGIN ENABLE UNWIND => NULL;
dSet: DependencySet ← CreateDependencySet[];
ids: Expressions.IdTable ← Expressions.MakeIdTable[];
hCellIds: Expressions.HCellIdSet ← Expressions.MakeHCellIdSet[];
documentPrivate: REF DocumentPrivateBody ← NEW[DocumentPrivateBody];
documentPublic: NewCalcGlobal.Document ← NEW[NewCalcGlobal.DocumentPublicBody←[dSet, ids, hCellIds, documentPrivate, DocumentDisplayerProcs]];


[documentPrivate.displayer, documentPrivate.container, documentPrivate.structure] ← Displayer.BuildDisplayer[documentPublic, documentPublic, "newCalc", DefineButtons];



documentPrivate.rootsn ← NewCalcGlobal.CreatePageList[documentPublic, documentPrivate.displayer, documentPrivate.structure];

Displayer.SetDisplayerContents[documentPrivate.displayer, "document", documentPrivate.rootsn];
AdjustDocument[documentPublic];
END;


DefineButtons: Displayer.ButtonDefiningProc =
BEGIN
document: NewCalcGlobal.Document ← NARROW[owner];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
wDir: Rope.ROPE ← NARROW[List.Assoc[$WorkingDirectory, ProcessProps.GetPropList[]]];

defineProcButton[name: "adjust", proc: Adjust];
defineProcButton[name: "verify", proc: Verify];
defineProcButton[name: "Show", proc: Show];
defineProcButton[name: "save", proc: Save];
defineProcButton[name: "load", proc: Load];
newLine[];
[] ← defineLabel["save File Name: ", "save File Name: "];
documentPrivate.saveFileBox ← defineText["logical.calc", "****************************"];
newLine[];
[] ← defineLabel["working dir: ", "working dir: "];
documentPrivate.workingDirBox ← defineText[wDir, "***********************************"];
newLine[];
defineProcButton["setEncryptionKey : ", SetEncryptionKey];
documentPrivate.keyBox ← defineText["+ +", "******************"];
newLine[]; [] ← defineLabel[" ", " "]; -- to force a 1 line gap
newLine[];
defineStructureOpButton[InsertPage];
defineStructureOpButton[AppendPage];
defineStructureOpButton[DeletePage];
defineStructureOpButton[SetPageId];
newLine[];
[] ← defineLabel[" newPageId: ", " newPageId: "];
documentPrivate.newPageId ← defineText["pageName", "****************************"];
newLine[];
defineStructureOpButton[MakeSummaryPage];
defineStructureOpButton[CreateSummaryHCellArray];
newLine[]; [] ← defineLabel[" ", " "]; -- to force a 1 line gap
newLine[];
defineStructureOpButton[InsertSlot];
defineStructureOpButton[AppendSlot];
defineStructureOpButton[DeleteSlot];
newLine[]; [] ← defineLabel[" ", " "]; -- to force a 1 line gap
newLine[];
defineStructureOpButton[InsertColumn];
defineStructureOpButton[AppendColumn];
defineStructureOpButton[DeleteColumn];
newLine[];
defineStructureOpButton[InsertRow];
defineStructureOpButton[AppendRow];
defineStructureOpButton[DeleteRow];
newLine[];
[] ← defineLabel["SetRow", "SetColumn"];
defineStructureOpButton[SetRowControlToControl];
defineStructureOpButton[SetRowControlToText];
defineStructureOpButton[SetRowControlToAddItem];
defineStructureOpButton[SetRowControlToSum];
newLine[];
[] ← defineLabel["SetColumn", "SetColumn"];
defineStructureOpButton[SetColControlToControl];
defineStructureOpButton[SetColControlToText];
defineStructureOpButton[SetColControlToAddZero];
defineStructureOpButton[SetColControlToAddItem];
defineStructureOpButton[SetColControlToSubItem];
defineStructureOpButton[SetColControlToLeftValTimesExp];
defineStructureOpButton[SetColControlToLeftVal];
defineStructureOpButton[SetColControlToSum];
defineStructureOpButton[SetColControlToTotal];
newLine[];
[] ← defineLabel[" ", "SetColumn" ];
defineStructureOpButton[SetColControlToIdGetsTotal];
defineStructureOpButton[SetColControlToIdGetsSum];
defineStructureOpButton[SetColControlToIdGetsLv];
newLine[]; [] ← defineLabel[" ", " "]; -- to force a 1 line gap
newLine[];
defineProcButton["setZvt", SetZVT];
documentPrivate.zvt ← defineText["0.00", "*******"];
newLine[];
defineProcButton["CreateTable", CreateHCellArray];
defineProcButton["SetTableId ", SetArrayId];
documentPrivate.newArrayIdText ← defineText["newTableId", "****************************"];
newLine[];
 defineStructureOpButton[ToggleControlVisibility];
 newLine[];
 newLine[];
 defineStructureOpButton[MarkCellInteresting];
END;

Verify: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
Dependencies.Verify[document.dSet];
documentPrivate.rootsn.procs.Verify[documentPrivate.rootsn];
END;

ComputeTotals: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 document: NewCalcGlobal.Document ← NARROW[arg];
 ComputeDocumentTotals[document];
 END;

Adjust: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 document: NewCalcGlobal.Document ← NARROW[arg];
 AdjustDocument[document];
 END;

Show: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
outFileName: Rope.ROPE ← FS.ExpandName["print.calc", ViewerTools.GetContents[documentPrivate.workingDirBox]].fullFName;
out: IO.STREAM ← FS.StreamOpen[outFileName, create];
NewCalcGlobal.ShowPageList[documentPrivate.rootsn, out];
out.Close[];
END;

Save: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
fileName: Rope.ROPE;
out: IO.STREAM;
encryptedOut: IO.STREAM;
fileName ← FS.ExpandName[ViewerTools.GetContents[documentPrivate.saveFileBox], ViewerTools.GetContents[documentPrivate.workingDirBox]].fullFName;

out ← FS.StreamOpen[fileName: fileName, accessOptions: create, keep: 3];
out.SetIndex[0];

encryptedOut ← IF documentPrivate.key = NIL OR Rope.Length[documentPrivate.key] = 0 THEN out ELSE CreateEncryptedOutStream[out, documentPrivate.key];
Put[out, int[VersionForSave], char[' ]]; -- version number not encrypted, so that changes in encryption can be noted in version number
IF documentPrivate.key = NIL OR Rope.Length[documentPrivate.key] = 0 THEN
Put[out, rope["NoEncryption "]]
ELSE
BEGIN
Put[out, rope["Encrypted x"]]; -- the x is to precisely mark the beginning of the encrypted chars
Put[encryptedOut, rope[documentPrivate.key], char[' ]];
END;
NewCalcGlobal.SavePageList[documentPrivate.rootsn, encryptedOut];
encryptedOut.Put[IO.rope["(End)"]];
out.Close[];
END;

Load: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
fileName: Rope.ROPE;
in: IO.STREAM;
decryptedIn: IO.STREAM;
encryptionToken: Rope.ROPE;
keyToken: Rope.ROPE;
version: CARDINAL;

fileName ← FS.ExpandName[ViewerTools.GetContents[documentPrivate.saveFileBox], ViewerTools.GetContents[documentPrivate.workingDirBox]].fullFName;
in ← FS.StreamOpen[fileName, read];
decryptedIn ← IF documentPrivate.key = NIL OR Rope.Length[documentPrivate.key] = 0 THEN in ELSE CreateDecryptedInStream[in, documentPrivate.key];
version ← GetInt[in];
IF version # 1 AND version # 2 THEN StructureNodes.BadFormatLoadFile; -- version number mismatch
encryptionToken ← GetTokenRope[in].token;
SELECT TRUE FROM
Rope.Equal[encryptionToken, "NoEncryption"] => IF documentPrivate.key # NIL AND Rope.Length[documentPrivate.key] # 0 THEN StructureNodes.BadFormatLoadFile;
Rope.Equal[encryptionToken, "Encrypted"] =>
BEGIN
  WHILE in.GetChar[] # 'x DO ENDLOOP; -- spin to the x marking the beginning of encrypted chars
  keyToken ← GetTokenRope[decryptedIn].token;
  IF NOT Rope.Equal[keyToken, documentPrivate.key] THEN StructureNodes.BadFormatLoadFile;
  END;
ENDCASE => StructureNodes.BadFormatLoadFile;

NewCalcGlobal.AbandonPageList[documentPrivate.rootsn];
documentPrivate.rootsn ← NewCalcGlobal.LoadPageList[document, documentPrivate.displayer, documentPrivate.structure, decryptedIn, version];


in.Close[];

Displayer.SetDisplayerContents[documentPrivate.displayer, "document", documentPrivate.rootsn];
AdjustDocument[document];
END;

SetEncryptionKey: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
fakeKey: Rope.ROPE ← "";
IF NOT documentPrivate.keyBox.newVersion THEN RETURN;
documentPrivate.keyBox.newVersion ← FALSE;
documentPrivate.key ← ViewerTools.GetContents[documentPrivate.keyBox];
FOR I: INT IN [1..Rope.Length[documentPrivate.key]] DO
fakeKey ← Rope.Cat[fakeKey, "*"];
ENDLOOP;
ViewerTools.SetContents[documentPrivate.keyBox, fakeKey];
END;

SetZVT: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
DoDocumentOperatorOrStructureAct[document, SetZeroValueText, ViewerTools.GetContents[documentPrivate.zvt], NIL];
AdjustDocument[document];
END;

CreateHCellArray: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
DoDocumentOperatorOrStructureAct[document, CreateHCellArray, ViewerTools.GetContents[documentPrivate.newArrayIdText], NIL];
AdjustDocument[document];
END;

SetArrayId: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
document: NewCalcGlobal.Document ← NARROW[arg];
documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
DoDocumentOperatorOrStructureAct[document, SetArrayId, ViewerTools.GetContents[documentPrivate.newArrayIdText], NIL];
AdjustDocument[document];
END;

-- this procedure is to be executed from an interpreter
CopyDecrypted: PROCEDURE[from: Rope.ROPE, to: Rope.ROPE, key: Rope.ROPE] =
 BEGIN
 fromStream: IO.STREAM ← FS.StreamOpen[FS.ExpandName[from, ""].fullFName, read];
 toStream: IO.STREAM ← FS.StreamOpen[FS.ExpandName[to, ""].fullFName, create];
 decrypted: IO.STREAM ← CreateDecryptedInStream[fromStream, key];
 encryptionToken: Rope.ROPE;
 Put[toStream, int[GetInt[fromStream]], char[' ]];
 encryptionToken ← GetTokenRope[fromStream].token;
 IF NOT Rope.Equal[encryptionToken, "Encrypted"] THEN ERROR;
 Put[toStream, rope["NoEncryption "]];
 WHILE fromStream.GetChar[] # 'x DO ENDLOOP;

 WHILE NOT decrypted.EndOf[] DO toStream.PutChar[decrypted.GetChar[]] ENDLOOP;
 toStream.Close[];
 END;

ExecuteInDocumentMonitor: ENTRY PROCEDURE[document: NewCalcGlobal.Document, p: PROC] =
 {ENABLE UNWIND => NULL; p[]};

ComputeDocumentTotals: PROCEDURE[document: NewCalcGlobal.Document] =
 BEGIN
 documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
BEGIN
ENABLE 
   BEGIN
   LoopInDependencyGraph =>
     BEGIN
     MessageWindow.Append[
       message: "loop in dependency graph",
       clearFirst: TRUE];
     MessageWindow.Blink[];
     GO TO abortAction;
     END;
   
   MultipleAssignmentToOneDataItem =>
     BEGIN
     MessageWindow.Append[
       message: "multiple assignment to one data item",
       clearFirst: TRUE];
     MessageWindow.Blink[];
     GO TO abortAction;
     END;
   END;
   
IF documentPrivate.rootsn # NIL THEN documentPrivate.rootsn.procs.CheckForDirtyData[documentPrivate.rootsn];    
IF documentPrivate.rootsn # NIL THEN NewCalcGlobal.CheckForDirtyDataInPages[documentPrivate.rootsn];
PerformDirtyActions[document.dSet];
EXITS
abortAction => NULL
END;
 END;

DoDocumentOperatorOrStructureAct: PROCEDURE[document: NewCalcGlobal.Document, act: StructureNodes.Action, p1, p2: REF ANY] =
 BEGIN
 documentPrivate: REF DocumentPrivateBody ← IF document = NIL THEN NIL
     ELSE NARROW[document.private];
 disp: NewCalcGlobal.Displayer;
sn: StructureNodes.StructureNode;
I, J: CARDINAL;

 [disp, sn, J] ← GetItemSelection[];

 IF sn = NIL THEN RETURN;
 I ← 0; --for first call
  
WHILE sn # NIL DO
 [sn, I, J] ← sn.procs.Act[sn, I, J, act, p1, p2];
 ENDLOOP;

END;

AdjustDocument: PROCEDURE[document: NewCalcGlobal.Document] =
 BEGIN
 documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
 ComputeDocumentTotals[document];
 Displayer.PaintDisplayerContents[documentPrivate.displayer];
 NewCalcGlobal.RepaintAllOpenPages[documentPrivate.rootsn];
END;

GetDocumentControlRope: PROCEDURE[document: NewCalcGlobal.Document, type: NewCalcGlobal.ControlRopeType] RETURNS[Rope.ROPE] =
 BEGIN
 documentPrivate: REF DocumentPrivateBody ← NARROW[document.private];
 SELECT type FROM
  newPageId => RETURN[ViewerTools.GetContents[documentPrivate.newPageId]];
  ENDCASE => ERROR;
 END;




-- page displayer, temporary home

PageDisplayer: TYPE = REF PageDisplayerBody;
PageDisplayerBody: PUBLIC TYPE = RECORD[
document: NewCalcGlobal.Document,
pageIds: Expressions.IdTable ← NIL,
pageNumber: CARDINAL ← 0,
pageName: Rope.ROPE ← NIL,
pageMode: NewCalcGlobal.PageMode ← individual,
displayer: NewCalcGlobal.Displayer ← NIL,
rootsn: StructureNodes.StructureNode ← NIL,
container: Viewer ← NIL,
structure: Viewer ← NIL,
zvt: Viewer ← NIL,
newArrayIdText: Viewer ← NIL,
newText, oldText: Viewer ← NIL
];


LoadPageDisplayer: PUBLIC PROCEDURE[document: NewCalcGlobal.Document, pageNumber: CARDINAL, pageName: Rope.ROPE, mode: NewCalcGlobal.PageMode, from: IO.STREAM, version: CARDINAL] RETURNS[PageDisplayer] =
BEGIN ENABLE UNWIND => NULL;
page: PageDisplayer ← NEW[PageDisplayerBody ← [document: document, pageNumber: pageNumber, pageName: pageName, pageMode: mode]];

page.pageIds ← Expressions.MakeIdTable[];
[page.displayer, page.container, page.structure] ← Displayer.BuildDisplayer[document, page, "page", DefinePageButtons];


page.rootsn ← GCell.LoadColumnOfRows[document, page.displayer, page.structure, pageName, from, version];
Displayer.SetDisplayerContents[page.displayer, Rope.Cat["page ", Convert.RopeFromCard[pageNumber]], page.rootsn];

AdjustDocument[page.document];

RETURN[page]
END;

CreatePageDisplayer: PUBLIC PROCEDURE[document: NewCalcGlobal.Document, pageNumber: CARDINAL, pageName: Rope.ROPE, mode: NewCalcGlobal.PageMode] RETURNS[PageDisplayer] =
BEGIN ENABLE UNWIND => NULL;
page: PageDisplayer ← NEW[PageDisplayerBody ← [document: document, pageNumber: pageNumber, pageName: pageName, pageMode: mode]];

page.pageIds ← Expressions.MakeIdTable[];
[page.displayer, page.container, page.structure] ← Displayer.BuildDisplayer[document, page, "page", DefinePageButtons];


page.rootsn ← GCell.CreateColumnOfRows[document, page.displayer, page.structure, page.pageName];

Displayer.SetDisplayerContents[page.displayer, page.pageName, page.rootsn];

SetPageDisplayerHeader[page];


AdjustDocument[page.document];

RETURN[page]
END;

ShowPageDisplayer: PUBLIC PROCEDURE[page: PageDisplayer, out: IO.STREAM] =
 BEGIN
 nLines: CARDINAL;
L, R, W: CARDINAL;
[ , nLines, , L, , , R, W] ← page.rootsn.procs.PreShow[page.rootsn];
FOR I: CARDINAL IN [1..nLines] DO
page.rootsn.procs.ShowLine[page.rootsn, L, R, W, I, out];
out.PutChar[IO.CR];
ENDLOOP;
 END;

SavePageDisplayer: PUBLIC PROCEDURE[page: PageDisplayer, to: IO.STREAM] =
 BEGIN
 to.PutChar[' ];
 HCells.WriteCellText[to, page.pageName]; -- "(" must immediately follow the text, no intermediate blanks. This is a requirement of LoadPageList.
Put[to, char['(], atom[$ColumnOfRows]];
 page.rootsn.procs.Save[page.rootsn, to];
Put[to, char[')]];
 END;

DestroyPageDisplayer: PUBLIC PROCEDURE[page: PageDisplayer] RETURNS[PageDisplayer] = -- always returns NIL
 BEGIN
 page.rootsn.procs.Abandon[page.rootsn];
 ViewerOps.DestroyViewer[page.container];
 RETURN[NIL]
 END;


NoteNewPageNumber: PUBLIC PROCEDURE[page: PageDisplayer, newNumber: CARDINAL] =
 {page.pageNumber ← newNumber; SetPageDisplayerHeader[page]};

NoteNewPageName: PUBLIC PROCEDURE[page: PageDisplayer, newName: Rope.ROPE] =
 BEGIN
 page.pageName ← newName;
 SetPageDisplayerHeader[page];
 GCell.ResetPageNameOfColumnOfRows[page.rootsn, newName];
 END;

NoteNewPageMode: PUBLIC PROCEDURE[page: PageDisplayer, newMode: NewCalcGlobal.PageMode] =
 BEGIN
 IF page.pageMode # individual THEN ERROR;
 page.pageMode ← newMode;
 END;

CheckForDirtyDataInPage: PUBLIC PROCEDURE[page: PageDisplayer] =
 {page.rootsn.procs.CheckForDirtyData[page.rootsn]};

SetPageDisplayerHeader: PROCEDURE[page: PageDisplayer] =
 BEGIN
 Displayer.ResetDisplayerName[page.displayer, Rope.Cat["page ", Convert.RopeFromCard[page.pageNumber], " ", page.pageName]];
 END;

DefinePageButtons: Displayer.ButtonDefiningProc =
BEGIN
page: PageDisplayer ← NARROW[owner];

defineProcButton[name: "adjust", proc: PDAdjust];
IF TRUE THEN RETURN; -- only "adjust"
newLine[];
newLine[];
defineStructureOpButton[InsertColumn];
defineStructureOpButton[AppendColumn];
defineStructureOpButton[DeleteColumn];
newLine[];
defineStructureOpButton[InsertRow];
defineStructureOpButton[AppendRow];
defineStructureOpButton[DeleteRow];
newLine[];
defineStructureOpButton[InsertSlot];
defineStructureOpButton[AppendSlot];
defineStructureOpButton[DeleteSlot];
newLine[];
defineStructureOpButton[CreateGCellArray];
defineStructureOpButton[CreateHCellArray];
newLine[];
[] ← defineLabel["SetRow", "SetColumn"];
defineStructureOpButton[SetRowControlToControl];
defineStructureOpButton[SetRowControlToText];
defineStructureOpButton[SetRowControlToAddItem];
defineStructureOpButton[SetRowControlToSum];
newLine[];
[] ← defineLabel["SetColumn", "SetColumn"];
defineStructureOpButton[SetColControlToControl];
defineStructureOpButton[SetColControlToText];
defineStructureOpButton[SetColControlToAddZero];
defineStructureOpButton[SetColControlToAddItem];
defineStructureOpButton[SetColControlToSubItem];
defineStructureOpButton[SetColControlToLeftValTimesExp];
defineStructureOpButton[SetColControlToLeftVal];
defineStructureOpButton[SetColControlToSum];
defineStructureOpButton[SetColControlToTotal];
defineStructureOpButton[SetColControlToIdGetsTotal];
defineStructureOpButton[SetColControlToIdGetsSum];
defineStructureOpButton[SetColControlToIdGetsLv];
newLine[];
defineStructureOpButton[ToggleControlVisibility];
newLine[];
defineProcButton["setZvt", PDSetZVT];
page.zvt ← defineText["0.00", "*******"];
newLine[];
defineProcButton["SetTableId", PDSetArrayId];
page.newArrayIdText ← defineText["newTableId", "****************************"];
newLine[];
newLine[];
defineProcButton["SubstituteOnPage", PDSubstituteOnPage];
defineProcButton["SubstituteInTable", PDSubstituteInArray];
defineProcButton["SubstituteInRow", PDSubstituteInRow];
defineProcButton["SubstituteInColumn", PDSubstituteInColumn];
newLine[];
[] ← defineLabel["new Text: ", "new Text: "];
page.newText ← defineText["newText", "****************************"];
newLine[];
[] ← defineLabel["old Text: ", "old Text: "];
page.oldText ← defineText["oldText", "****************************"];
newLine[];
newLine[];
defineProcButton["GetPage", PDGetPage];
END;

PDAdjust: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 AdjustDocument[page.document];
 END;

PDSetZVT: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 DoDocumentOperatorOrStructureAct[page.document, SetZeroValueText, ViewerTools.GetContents[page.zvt], NIL];
 AdjustDocument[page.document];
 END;

PDSetArrayId: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 DoDocumentOperatorOrStructureAct[page.document, SetArrayId, ViewerTools.GetContents[page.newArrayIdText], NIL];
 AdjustDocument[page.document];
 END;

PDSubstituteOnPage: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 page.rootsn.procs.Substitute[page.rootsn, ViewerTools.GetContents[page.newText], ViewerTools.GetContents[page.oldText]];
 AdjustDocument[page.document];
 END;

PDSubstituteInArray: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 DoDocumentOperatorOrStructureAct[page.document, SubstituteInArray, ViewerTools.GetContents[page.newText], ViewerTools.GetContents[page.oldText]];
 AdjustDocument[page.document];
 END;

PDSubstituteInRow: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 DoDocumentOperatorOrStructureAct[page.document, SubstituteInRow, ViewerTools.GetContents[page.newText], ViewerTools.GetContents[page.oldText]];
 AdjustDocument[page.document];
 END;

PDSubstituteInColumn: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 DoDocumentOperatorOrStructureAct[page.document, SubstituteInColumn, ViewerTools.GetContents[page.newText], ViewerTools.GetContents[page.oldText]];
 AdjustDocument[page.document];
 END;

PDGetPage: ENTRY PROCEDURE[arg: REF ANY] =
BEGIN ENABLE UNWIND => NULL;
 page: PageDisplayer ← NARROW[arg];
 otherDisplayer: NewCalcGlobal.Displayer;

 otherPageSn: StructureNodes.StructureNode ← NIL;
 nextSn: StructureNodes.StructureNode;

 SetOurPage: GCell.SetAColumnOfRowsProc =
  {GCell.SetColumnOfRows[page.rootsn, nRows, GetOneRow, FALSE]};

 [otherDisplayer, nextSn, ] ← GetItemSelection[];
 IF otherDisplayer = page.displayer THEN RETURN;

 WHILE nextSn # NIL DO -- scans up the logical node tree to the root
  otherPageSn ← nextSn;
  [nextSn, , ] ← otherPageSn.procs.Act[otherPageSn, 0, 0, NullAction, NIL, NIL];
  ENDLOOP;

 IF otherPageSn = NIL THEN RETURN;

 GCell.GetColumnOfRows[otherPageSn, SetOurPage, FALSE]; -- When we get object procs, this false will become true??

 AdjustDocument[page.document];


 END;

CountOpenSlotsInPage: PUBLIC PROCEDURE[page: PageDisplayer] RETURNS[CARDINAL] =
 {RETURN[GCell.CountOpenSlotsInColumnOfRows[page.rootsn]]};

InstallHCellArrayAtOpenSlot: PUBLIC PROCEDURE[page: PageDisplayer, rowNumber, colNumber: CARDINAL, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE] RETURNS[StructureNodes.StructureNode]] =
 BEGIN
 case: GCell.SlotCase ← SELECT page.pageMode FROM
  individual => ERROR,
  groupItem => itemHCellArray,
  groupSummary => summaryHCellArray,
  ENDCASE => ERROR;

 GCell.InstallHCellArrayAtOpenSlotInColumnOfRows[page.rootsn, rowNumber, colNumber, case, createIt];
 END;

InstallHCellArrayAtAnOpenSlot: PUBLIC PROCEDURE[page: PageDisplayer, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE, rowNumber, colNumber: CARDINAL] RETURNS[StructureNodes.StructureNode]] =
 BEGIN
 case: GCell.SlotCase ← SELECT page.pageMode FROM
  individual => ERROR,
  groupItem => itemHCellArray,
  groupSummary => summaryHCellArray,
  ENDCASE => ERROR;

 GCell.InstallHCellArrayAtAnOpenSlotInColumnOfRows[page.rootsn, case, createIt];
 END;

GetHCellArrayAtSlot: PUBLIC PROCEDURE[page: PageDisplayer, rowNumber, colNumber: CARDINAL] RETURNS[StructureNodes.StructureNode] =
 {RETURN[GCell.GetHCellArrayAtSlotInColumnOfRows[page.rootsn, rowNumber, colNumber]]};

ConnectInstalledItemArrays: PUBLIC PROCEDURE[page: PageDisplayer, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, row, col: CARDINAL]] =
 {GCell.ConnectInstalledItemArraysInColumnOfRows[page.rootsn, connectOneItemArray]};

GenerateSummaryArrays: PUBLIC PROCEDURE[page: PageDisplayer, seeOneArray: PROCEDURE[summaryHcaSn: StructureNodes.StructureNode, summaryKey: LONG CARDINAL] RETURNS[continue: BOOLEAN]] =
 {GCell.GenerateSummaryArraysInColumnOfRows[page.rootsn, seeOneArray]};

ConnectLoadedItemArrays: PUBLIC PROCEDURE[page: PageDisplayer, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, itemKey: LONG CARDINAL, atRow: CARDINAL]] =
 {GCell.ConnectLoadedItemArraysInColumnOfRows[page.rootsn, connectOneItemArray]};



RepaintOpenPage: PUBLIC PROCEDURE[page: PageDisplayer] =
 {Displayer.PaintDisplayerContents[page.displayer]};

VerifyPageDisplayer: PUBLIC PROCEDURE[page: PageDisplayer, mode: NewCalcGlobal.PageMode] =
 {page.rootsn.procs.Verify[page.rootsn]};

-- exported to GCell

selectedDisplayer: NewCalcGlobal.Displayer ← NIL;
selectedGCA: StructureNodes.StructureNode ← NIL;
selectedSn: StructureNodes.StructureNode ← NIL;
selectedI, selectedJ: CARDINAL ← 0;


NoteItemSelection: PUBLIC PROCEDURE[displayer: NewCalcGlobal.Displayer, sn: StructureNodes.StructureNode, itemX: CARDINAL] =
 BEGIN
 selectedDisplayer ← displayer;
 selectedGCA ← NIL;
 selectedSn ← sn;
 selectedI ← 0;
 selectedJ ← itemX;
 END;

GetItemSelection: PUBLIC PROCEDURE RETURNS[displayer: NewCalcGlobal.Displayer, sn: StructureNodes.StructureNode, itemX: CARDINAL] =
 BEGIN
 viewer: Viewer ← ViewerTools.GetSelectedViewer[];
 itemRef: REF ANY;

 selectedDisplayer ← NIL;
 selectedGCA ← NIL;
 selectedSn ← NIL;
 selectedI ← selectedJ ← 0;

 IF viewer = NIL THEN RETURN[NIL, NIL, 0];
 IF (itemRef ← ViewerOps.FetchProp[viewer, $HCell]) # NIL THEN
  HCells.ForceNoteHCellSelection[itemRef]
  ELSE IF (itemRef ← ViewerOps.FetchProp[viewer, $GCellItem]) # NIL THEN
  GCell.ForceNoteItemSelection[itemRef]
  ELSE IF (itemRef ← ViewerOps.FetchProp[viewer, $BCell]) # NIL THEN
   ButtonCells.ForceNoteBCellSelection[itemRef]
  ELSE RETURN[NIL, NIL, 0];



 IF selectedSn # NIL THEN RETURN[selectedDisplayer, selectedSn, selectedJ]
  ELSE RETURN[NIL, NIL, 0];
 END;


NoteArraySelection: PUBLIC PROCEDURE[displayer: NewCalcGlobal.Displayer, gcaSn: StructureNodes.StructureNode, I, J: CARDINAL] =
 BEGIN
 selectedDisplayer ← displayer;
 selectedGCA ← gcaSn;
 selectedSn ← NIL;
 selectedI ← I;
 selectedJ ← J;
 END;

GetArraySelection: PUBLIC PROCEDURE RETURNS[displayer: NewCalcGlobal.Displayer, gcaSn: StructureNodes.StructureNode, I, J: CARDINAL] =
 BEGIN
  
 selectedDisplayer ← NIL;
 selectedGCA ← NIL;
 selectedSn ← NIL;
 selectedI ← selectedJ ← 0;

 DoDocumentOperatorOrStructureAct[NIL, NoteArraySelection, NIL, NIL];

 IF selectedDisplayer # NIL AND selectedGCA # NIL THEN RETURN[selectedDisplayer, selectedGCA, selectedI, selectedJ]
  ELSE RETURN[NIL, NIL, 0, 0];
 END;

MoveToPreviousCell: TiogaOps.CommandProc = TRUSTED
 {ok: BOOLEAN ← MoveToCell[viewer, previous]; RETURN[FALSE, ok]};

MoveToNextCell: TiogaOps.CommandProc = TRUSTED
 {ok: BOOLEAN ← MoveToCell[viewer, next]; RETURN[FALSE, ok]};

MoveToCell: ENTRY PROCEDURE[viewer: Viewer, direction: {next, previous}] RETURNS[didIt: BOOLEAN] =
 BEGIN ENABLE UNWIND => NULL;
   
 SELECT direction FROM
  next => DoDocumentOperatorOrStructureAct[NIL, MoveSelectionToNext, NIL, NIL];
  previous => DoDocumentOperatorOrStructureAct[NIL, MoveSelectionToPrevious, NIL, NIL];
  ENDCASE => ERROR;

 END;



-- main code

-- IF TiogaOps.IsRegistered[$PreviousCell] THEN TiogaOps.UnRegister[$PreviousCell];
TiogaOps.RegisterCommand[$PreviousPlaceholder, MoveToPreviousCell];
-- IF TiogaOps.IsRegistered[$NextCell] THEN TiogaOps.UnRegister[$NextCell];
TiogaOps.RegisterCommand[$NextPlaceholder, MoveToNextCell];

Commander.Register[key: "NewCalc", proc: BuildDocument, doc: "a new calculator window"];
--GCell.MakeAGCellToolInstance[NIL];
--GCell.BuildArrayTool[];



END..


-- 17-Feb-82 11:16:14: Sturgis, started SimpleMatrixImpl.mesa
-- RTE: 19-Feb-82 12:37:35: a run time type error using NARROW, would have been caught with parameterized types. i.e. pulled a REF ANY out of a matrix and then supplied it to the wrong procedure. The matrix could have been declared as a paramaterized type.
-- RTE: 19-Feb-82 12:51:19: row and column creation did so at 1, rather than intended index.
-- RTE: 19-Feb-82 12:58:12: the matrices that hold column and row info needed 1 row (or column) to contain the actual elements (as well as the n columns (or rows)).
-- REMARK: 19-Feb-82 13:03:26: screen now comes up, next step is to get the arithmetic to work.
-- RTE: 19-Feb-82 13:05:11: forgot to install the menu into the container.
-- RTE: 19-Feb-82 13:57:51: ComputeRowSum called GetElement with row number before column number, should have been the other way around. Needed painted cardinals here.
-- REMARK: 19-Feb-82 14:05:53: basic arithmetic works. Assorted issues remain: block edit f dependent values, or reset them to correct values; correct handling of badly edited values, etc.
-- REMARK: 22-Feb-82 17:24:37: Print (onto a.listing), Save (onto a.logical), and load (from a.logical) seem to work!! Have yet to remove some debugging output.
-- change: 26-Feb-82 16:28:07: remove data cell code.
-- REMARK: 26-Feb-82 16:45:10: works with DataCell moved out.
-- REMARK: 28-Feb-82 16:46:44: renamed: NewCalc.mesa, removed all except world control info. begin edit
-- REMARK: 1-Mar-82 18:47:40: compiles
-- change: 4-Mar-82 13:11:03: change module name to NewCalc (forgot to change it while editing before), change zero point for structure to 20,20, to see if this makes things visible. (currently 0,0).
-- change: 4-Mar-82 17:57:05: add verify
-- change: 5-Mar-82 11:58:16: verify now calls dependencies.verify
-- RTE?: 5-Mar-82 14:08:23: add a call to perform dirty actions during structure actions.
RTE: 6-Mar-82 14:51:04:change action name from print to Show, add a CR between lines.
-- 6-Mar-82 17:50:30: top level becomes column of rows.
-- 6-Mar-82 18:14:31: add slot menu items, and createsimplematrixA
-- 7-Mar-82 17:06:53: modify to use buttons, since menu was too full
-- RTE: 7-Mar-82 17:37:26: all buttons overlapped, buttons comments were wrong, so add code to compute appropritae positions.
-- RTE: 7-Mar-82 17:48:30: taking several steps to get things unoverlapped.
change: 8-Mar-82 15:28:07: convert to new load and save conventions
-- RTE: 8-Mar-82 17:21:17: load should have tested for the leading "(" inside the loop.
-- change: 9-Mar-82 14:18:05: change the names of the save and print files
-- change: 11-Mar-82 14:07:13: add the operator actions of set+, set- and set=. add GeneralOperator action, add the actoin of creating an AdditiveMatrix.
-- change: 13-Mar-82 12:04:18: install editable text box to hold svae file name. started at 11:00, lost :15 when Wasp died. Also restructured button creation code, and added button for requesting encryption key, but have yed to add the code.
-- RTE: 13-Mar-82 12:29:54: while attempt code to input encryption key, found that MessageWIndow.ReadFrom hung. SO converted to a text box to hold the key, and set key will replace contents of box wieh *s.
-- remark: 13-Mar-82 12:35:11: simple mode of getting encryption key is fundamentally working.
-- remark: 13-Mar-82 12:40:20: decided to add a test to be sure key had been edited before using it.
-- remark: 14-Mar-82 12:30:46: add version numbers and encrytion to save files. about 1/2 hour of initial editing.
-- remark: 14-Mar-82 13:05:54: In load, move KeyToken out a level of nesting or so so that I can see it with bugbane. Cant se it with COPilot because it is a variant record.
-- RTE: 14-Mar-82 13:47:35: did not have the start of reading decrypted exactly synchronized with the encrypted chars in the file (having to do with skipping over blanks etc). insert a synchronizing char.
-- remark: 18-Mar-82 16:26:11: add Adjust, check for dirty data more often, add sub viewers to hold data, so it can be scrolled independently of the buttons.
RTE: 18-Mar-82 16:57:25: had "move" the buttons viewer in order to set its height to structureY (rather than 0).
RTE: 18-Mar-82 17:04:57: did not step a line at end of CreateButtons, so data viewer ended up overlapping last row of buttons. added 2 StepLines. (note: these chagnes today have taken about 2 hours).
-- remark: 25-Mar-82 16:17:35: add another level of container nesting to keep scrolling from changing the wy values of the individual screeen elements. Thus "adjust" won't undo the effect of previous scrolling. (required due to a somewhat unreasonable scrolling implementation by viewers.)
-- RTE: March 25, 1982 4:29 pm: had to change the Child?BOund calls to name correct parent.

-- July 31, 1982 2:19 pm: convert to cedar 3.2
-- change: August 1, 1982 5:46 pm: add assignmentcells
-- change: August 2, 1982 11:14 am: convert to a monitor, fork all button procs, put entry on all button procs.
-- RTE: August 4, 1982 10:35 am: add unwind catches to entry procedures.
-- change: August 4, 1982 10:35 am: add version to subsequent load calls., remove assignmentcell from top level
-- RTE: August 4, 1982 11:09 am: forgot to output new version number during save.
-- change: August 7, 1982 4:00 pm: register build document procedure as a command "NewCalc".
-- August 7, 1982 6:02 pm: convert to using NCGlobal.
-- August 8, 1982 3:25 pm: add code to catch loop in dependency graph error.
-- August 8, 1982 3:49 pm: various changes, remove excess calls on performdirtyactions, remove redundant call on sort dependency graph, etc. Thus the dependency error catches need be in only one place.
-- August 8, 1982 5:27 pm: catch multiple assignment to one data itme.
-- October 1, 1982 2:37 pm: add create GCell array operation and button
-- October 2, 1982 2:54 pm: Rename NewCalcImpl
-- October 2, 1982 5:24 pm: add logic to try old style selection, then new style selection.
-- October 2, 1982 6:28 pm: note selection needs to be an entry procedure as it will be called by a forked process. eventually the caller should use a monitor lock procedure to be supplied by NeCalcImpl.
-- October 3, 1982 1:57 pm: add ExecuteInMonitor, a procedure to be called with a proc param, so that proc executes inside the monitor.
-- RTE: October 3, 1982 2:21 pm: NoteSelection remained an ENTRY procedure, leading to instant monitor lock.
-- change: October 5, 1982 5:07 pm: modify load to set button to black on grey while in execution.
-- change: October 5, 1982 5:15 pm: and all the rest of the action buttons.
-- change: October 6, 1982 5:47 pm: export get and note selection to GCell, call MakeAGCellToolInstance.
-- October 8, 1982 1:31 pm: convert entirely to new node structure.
-- change: October 10, 1982 11:58 am: convert to 3.4. 1) IO.CreateFileStream => FileIO.Open. 2) viewer in a button prc becomes NARROW[parent, Viewer].
-- October 10, 1982 2:21 pm: get Action and BadFormatLoadFile from StructureNodes rather than StructureNode. Also remove the recently de implemented actions (e.g. set operator +, createAdditiveMatrix.).
-- October 10, 1982 3:51 pm: add code to copy from an encrypted file to a decrypted one.
-- track restructuring of NewCalcGlobal.World.
-- October 13, 1982 11:43 am: move selection data into global frame.
-- October 13, 1982 2:57 pm: convert to using displayer
-- change: October 14, 1982 5:19 pm: Create and Load colukn of rows has changed interfaces and parameters.
-- change: October 14, 1982 5:24 pm: selection mechanism changed slightly.
-- October 14, 1982 6:08 pm: add ArrayTool code.
-- RTE: October 14, 1982 6:37 pm: need adjust and total procedures unique to the array tool. Also, must adjust the displayer in which the array lands.
-- October 15, 1982 2:20 pm: begin adding page displayer code.
-- October 16, 1982 3:47 pm: add comment about when converting to Object monitor.
-- RTE: October 16, 1982 4:10 pm: refuse to set array tool from self, or get from self.
-- change: October 18, 1982 2:01 pm: begin adding mult page document code.
-- RTE: October 18, 1982 4:33 pm: forgot to increment nActivePages when inserting a page, or to set new page active. Also, need to correctly set label of new pages.
-- RTE: October 18, 1982 4:51 pm: forgot to set the first page created active.
-- change: October 19, 1982 3:13 pm: add buttonCell code, so as to have nice buttons to represent page structure.
-- RTE: October 19, 1982 5:13 pm: no page buttons showed up, need to add first page. CreateColumns used indices 0 and 1, rather than 1 and 2.
-- RTE: October 19, 1982 5:19 pm: can not DestroyViewer on NIL.
-- RTE: October 19, 1982 5:26 pm: selection mechanism was rejecting non GCell selections.
-- RTE: October 19, 1982 5:32 pm: page label numbering confused, forgot to put a number on when page installed, but put a number on the title name.
-- October 20, 1982 4:00 pm: convert to newly defined PageActions (from RowActions).
-- October 20, 1982 4:35 pm: begin activiation of new page action machinary, to refer to real pages.
-- RTE: October 20, 1982 5:16 pm: two pages got created at beginning of world, because of change in convention for InstallPGSPageAt
-- RTE: October 20, 1982 5:40 pm: load was not expecting bracketing parenthesis around a colulnofrows.
-- October 21, 1982 1:17 pm: Export document body, and export a global procedure to compute totals.
-- RTE: October 21, 1982 2:26 pm: ComputeDocumentTotals gets called during creation, before document.rootdn has been installed. Fix is to not call CheckForDirtyData if rootdn = NIL.
-- RTE: October 21, 1982 3:04 pm: loaded pages did not have page number in caption.
-- change: October 25, 1982 4:42 pm: put line feeds between pages, and add a page number on each page
-- RTEs: October 25, 1982 4:58 pm: took several times to learn to use FF and not LF, and to put it at the end of the page, except the last page.
-- change: October 26, 1982 3:06 pm: begin adding code to handle next and previous cell ops, also change the selection algorithm to the current viewer with the tioga selection, that is also a GCellItemViewer.
-- RTE: October 28, 1982 2:41 pm: add a conditional unregister of $NextCell etc, so as to be able to reload NewCalc.
-- RTE: October 28, 1982 4:07 pm: modify button cell code to convert to text box when selected. i.e. should follow new selection conventions as implemented in GCellImpl.
-- RTE: October 30, 1982 4:47 pm: PrePaintBCell forgot to record lastPrePaintX.
-- change: October 31, 1982 3:28 pm: add code to copy a file on which we are about to save, to a file with same name except for an additional '$ at the end.
-- RTE: October 31, 1982 3:35 pm: copied file was length 0, so change open of old file from overwrite, to write.i
-- RTE: November 2, 1982 3:34 pm: 1) make MoveToCell an ENTRY procedure. 2) remove the DeSelect code.
-- T: add 2 ref any params to ActPageList and ActBCell.
-- November 2, 1982 4:57 pm: add code to put up the substitute commands, place to hold the text, and porcedures to request the actions.
-- RTE: November 2, 1982 5:22 pm: got the contents of the vieweres for onecase, but forgot to for the other case.
-- November 3, 1982 3:54 pm: add substitute actions for logical nodes for PageLists and BCells. Add substituteonpage, and substituteinarray buttons and procs.
-- November 3, 1982 5:56 pm: add GetPage.
-- RTE: November 3, 1982 6:08 pm: needed to do the equivalent of an adjust at finish of the GetPageCode.
-- change: November 5, 1982 11:31 am: add button to kill ref counting.
-- CTE: November 5, 1982 12:56 pm: overflow in pass 4, so remove ButtonCell code.
-- RTE: November 5, 1982 1:51 pm: well, LAST[LONG CARDINAL] does not appear to be the correct constant. try Mitchells 40000000.
-- November 14, 1982 2:08 pm: begin conversion to new selection mechanism.
-- November 14, 1982 3:35 pm: add Get/Set row/Column
-- CTE: December 15, 1982 7:33 pm: does not compile under 3.5. The tioga next cell feature iscausing the trouble, so I will comment it out.
-- RTE: December 15, 1982 7:50 pm: LoadPageList was expecting a '(, but it found a ' , followed by the expected '(. Not sure why, except that GetRope (called by Load just before calling LoadPageList) may have changed semantics. Add a leading "spin on blank" to LoadPageList.
CTE: February 11, 1983 11:27 am: convert to 4.0 (BuildDocument, a UserExec.CommandProc, wants a new parameter, feed it NIL)
RTE: February 11, 1983 1:52 pm change call on GetRope to GetToken.
RTE: February 11, 1983 2:16 pm: have to change GetAtom to NARROW[GetRefAny[]].
-- February 27, 1983 4:18 pm: replace LogicalNode and DisplayNode etc with StrucutreNode. February 27, 1983 5:14 pm: compiles, almost an hour. I suspect that the page list mechanism and the selection mechanisms havebeen garbled, due to throwing too much info away (it all looked like the same type ...).
-- RTE: February 28, 1983 10:04 am: forgot to put in the dummy displaynode routines for page list that call the associated display array structure node routines.
-- RTE: February 28, 1983 10:41 am: the array tool now must use the structure node of the contained gca too refer to the gca.
-- February 28, 1983 2:23 pm: add dummy NoteCoordinates procedures.
-- March 8, 1983 11:45 am: add UnPaint
-- Change: June 22, 1984 4:32:59 pm PDT: convert to Cedar 5.2
-- Change: June 24, 1984 12:19:31 pm PDT: add working directory features, and keep.
-- Change: June 28, 1984 3:44:16 pm PDT: add CreateHCellArray op button
-- Change: June 29, 1984 11:10:01 am PDT: add $HCells to selection mechanism.
-- Change: July 2, 1984 10:09:03 am PDT: add the row and coliumn control buttons for HCellArrays
-- Change: July 2, 1984 5:35:45 pm PDT: try to turn on Next and Shift Next.
-- Change: July 10, 1984 9:12:32 am PDT: add SetZVT.
-- RTE: July 10, 1984 9:44:11 am PDT: assorted commands, including the new SetZVT, needed "AfterStructureOp".
-- RTEs: Remark: July 11, 1984 9:11:10 am PDT: some considerable time spent on trying to put identifiers on pages, and then making sure that when changes occured on one page, all pages were updated on the screen. (two days?) This led to numerous confusions, e.g. recursive call loops, etc. I also removed the old NCGlobal and WOrld and Displayer.Owner, and rearanged the associated stuff into a more(?) coherent order.
-- Remark: July 19, 1984 4:24:17 pm PDT: started this morning to install the new page/array group machinary.
-- Remark: July 20, 1984 8:36:16 am PDT: remove page list stuff, palce in PageListImpl. However, keep pageDisplayer for time being.
-- Remark: July 23, 1984 2:22:27 pm PDT: page group and array group stuff working. Now starting on moving allmost all of the action buttons to the document displayer. Later, I hopw to move them to some sort of tool displayer.
-- remark: July 30, 1984 10:18:44 am PDT: add MarkCellInteresting