-- ColumnOfRows.mesa
-- last edit July 23, 1984 9:59:01 am PDT Sturgis
DIRECTORY
GCell USING[CreateGCell, CreateGCellArray, GetGCellArray, LoadGCellArray, SetAColumnOfRowsProc, SetAGCellArrayProc, SetARowOfSlotsProc, SetASlotProc, SetGCellArray, SlotCase],
HCells USING[CreateHCell, CreateHCellArray, GetSummaryArray, HCell, LoadHCellArray, ResetPageNameOfHCellArray, SetHCellParameters, SetHCellText],
IO USING[atom, card, char, GetCard, GetInt, GetRefAny, GetTokenRope, STREAM, int, Put],
NewCalcGlobal USING[Displayer, Document],
Rope USING[Equal, ROPE],
StructureNodes USING[Action, AddColumnAt, AddRowAt, BadFormatLoadFile, CreateDisplayArray, DACell, DeleteColumnAt, DeleteRowAt, DisplayArray, GetContextDA, GetElementAt, PrePaintPass, SetElementAt, StructureNode, StructureNodeBody, StructureNodeProcs],
ViewerClasses USING[Viewer];
ColumnOfRows: PROGRAM IMPORTS GCell, HCells, IO, Rope, StructureNodes EXPORTS GCell =
BEGIN OPEN IO, StructureNodes, ViewerClasses;
-- column of rows
Column: TYPE = REF ColumnBody;
ColumnBody: TYPE = RECORD[
daSn: StructureNodes.StructureNode,
da: StructureNodes.DisplayArray,
nRows: CARDINAL,
document: NewCalcGlobal.Document,
displayer: NewCalcGlobal.Displayer,
vParent: Viewer,
pageName: Rope.ROPE];
ColOfRowsStructureNodeProcs: REF StructureNodes.StructureNodeProcs ← NEW[StructureNodes.StructureNodeProcs ← [ColumnOfRowsCheckForDirtyData, ColumnOfRowsPreShow, ColumnOfRowsShowLine, ColumnOfRowsPrePrePaint, ColumnOfRowsPrePaint, ColumnOfRowsPaint, ColumnOfRowsUnPaint, ColumnOfRowsNoteEnclosingCell, ColumnOfRowsNoteCoordinates, SaveColumnOfRows, ActColumnOfRows, SubstituteInColumnOfRows, AbandonColumnOfRows, VerifyColumnOfRows]];
LoadColumnOfRows: PUBLIC PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, name: Rope.ROPE, from: IO.STREAM, version: CARDINAL] RETURNS[StructureNode] =
BEGIN -- note: column of rows atom has been read
col: Column;
colSn: StructureNode;
[col, colSn] ← BasicCreateColumnOfRows[document, displayer, vParent, name];
IF name # NIL THEN InstallRowAtColumnOfRows[col, 1, name, displayPageName];
col.nRows ← GetInt[from]+ (IF name # NIL THEN 1 ELSE 0);
FOR J: CARDINAL IN [(IF name # NIL THEN 2 ELSE 1)..col.nRows] DO
rssn: StructureNode; -- holds the row of slots
IF NOT Rope.Equal[GetTokenRope[from].token, "("] THEN BadFormatLoadFile;
IF NARROW[GetRefAny[from], ATOM] # $RowOfSlots THEN BadFormatLoadFile;
rssn ← LoadRowOfSlots[document, displayer, vParent, name, from, version];
IF NOT Rope.Equal[GetTokenRope[from].token, ")"] THEN BadFormatLoadFile;
StructureNodes.AddRowAt[col.da, J];
StructureNodes.SetElementAt[col.da, 1, J, rssn, NIL];
ENDLOOP;
RETURN[colSn]
END;
CreateColumnOfRows: PUBLIC PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, pageName: Rope.ROPE] RETURNS[StructureNode] =
BEGIN
col: Column;
colSn: StructureNode;
[col, colSn] ← BasicCreateColumnOfRows[document, displayer, vParent, pageName];
InstallRowAtColumnOfRows[col, 1, pageName, displayPageName];
InstallRowAtColumnOfRows[col, 2, pageName, clientRow];
RETURN[colSn]
END;
ResetPageNameOfColumnOfRows: PUBLIC PROCEDURE[info: StructureNode, pageName: Rope.ROPE] =
BEGIN
col: Column ← NARROW[info.ref];
col.pageName ← pageName;
FOR J: CARDINAL IN [1..col.nRows] DO
ResetPageNameOfRow[StructureNodes.GetElementAt[col.da, 1, J].sn, pageName];
ENDLOOP;
END;
GetColumnOfRows: PUBLIC PROCEDURE[info: StructureNode, send: GCell.SetAColumnOfRowsProc, entry: BOOLEAN] =
BEGIN
column: Column ← NARROW[info.ref];
GCS: PROCEDURE =
BEGIN
J: CARDINAL ← 1;
GetOneRow: PROCEDURE[sendIt: GCell.SetARowOfSlotsProc] =
BEGIN
ssn: StructureNodes.StructureNode ← StructureNodes.GetElementAt[column.da, 1, J].sn;
GetRowOfSlots[ssn, sendIt, FALSE];
J ← J + 1;
END;
send[column.nRows, GetOneRow];
END;
IF entry THEN column.document.procs.executeInMonitor[column.document, GCS] ELSE GCS[];
END;
SetColumnOfRows: PUBLIC PROCEDURE[sn: StructureNode, nRows: CARDINAL, getOneRow: PROCEDURE[GCell.SetARowOfSlotsProc], entry: BOOLEAN] =
BEGIN
column: Column ← NARROW[sn.ref];
SCS: PROCEDURE =
BEGIN
WHILE column.nRows # 0 DO RemoveRowAtColumnOfRows[column, column.nRows] ENDLOOP;
column.nRows ← nRows;
FOR J: CARDINAL IN [1..nRows] DO
rssn: StructureNode; -- holds the row
SetTheRow: GCell.SetARowOfSlotsProc =
{SetRowOfSlots[rssn, nSlots, GetOneSlot, FALSE]};
rssn ← CreateRowOfSlots[column.document, column.displayer, column.vParent, NIL, clientRow];
StructureNodes.AddRowAt[column.da, J];
StructureNodes.SetElementAt[column.da, 1, J, rssn, NIL];
getOneRow[SetTheRow];
ENDLOOP;
END;
IF entry THEN column.document.procs.executeInMonitor[column.document, SCS] ELSE SCS[];
END;
CountOpenSlotsInColumnOfRows: PUBLIC PROCEDURE[node: StructureNode] RETURNS[CARDINAL] =
BEGIN
column: Column ← NARROW[node.ref];
count: CARDINAL ← 0;
FOR J: CARDINAL IN [1..column.nRows] DO
count ← count + CountOpenSlotsInRowOfSlots[StructureNodes.GetElementAt[column.da, 1, J].sn];
ENDLOOP;
RETURN[count];
END;
InstallHCellArrayAtOpenSlotInColumnOfRows: PUBLIC PROCEDURE[sn: StructureNode, rowNumber, colNumber: CARDINAL, case: GCell.SlotCase, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE] RETURNS[StructureNode]] =
BEGIN
column: Column ← NARROW[sn.ref];
row: StructureNode ← StructureNodes.GetElementAt[column.da, 1, rowNumber].sn;
InstallHCellArrayAtOpenSlotInRowOfSlots[row, colNumber, case, createIt];
END;
InstallHCellArrayAtAnOpenSlotInColumnOfRows: PUBLIC PROCEDURE[sn: StructureNode, case: GCell.SlotCase, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE, rowNumber, colNumber: CARDINAL] RETURNS[StructureNode]] =
BEGIN
column: Column ← NARROW[sn.ref];
FOR J: CARDINAL IN [1..column.nRows] DO
IF InstallHCellArrayAtAnOpenSlotInRowOfSlots[StructureNodes.GetElementAt[column.da, 1, J].sn, J, case, createIt] THEN RETURN;
ENDLOOP;
END;
GetHCellArrayAtSlotInColumnOfRows: PUBLIC PROCEDURE[sn: StructureNode, rowNumber, colNumber: CARDINAL] RETURNS[StructureNode] =
BEGIN
column: Column ← NARROW[sn.ref];
row: StructureNode ← StructureNodes.GetElementAt[column.da, 1, rowNumber].sn;
RETURN[GetHCellArrayAtSlotInRowOfSlots[row, colNumber]];
END;
ConnectInstalledItemArraysInColumnOfRows: PUBLIC PROCEDURE[sn: StructureNode, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, row, col: CARDINAL]] =
BEGIN
column: Column ← NARROW[sn.ref];
FOR J: CARDINAL IN [1..column.nRows] DO
ConnectInstalledItemArraysInRowOfSlots[StructureNodes.GetElementAt[column.da, 1, J].sn, J, connectOneItemArray];
ENDLOOP;
END;
GenerateSummaryArraysInColumnOfRows: PUBLIC PROCEDURE[sn: StructureNode, seeOneArray: PROCEDURE[summaryHcaSn: StructureNodes.StructureNode, summaryKey: LONG CARDINAL] RETURNS[continue: BOOLEAN]] =
BEGIN
column: Column ← NARROW[sn.ref];
FOR J: CARDINAL IN [1..column.nRows] DO
IF NOT GenerateSummaryArraysInRowOfSlots[StructureNodes.GetElementAt[column.da, 1, J].sn, seeOneArray] THEN EXIT;
ENDLOOP;
END;
ConnectLoadedItemArraysInColumnOfRows: PUBLIC PROCEDURE[sn: StructureNode, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, itemKey: LONG CARDINAL, atRow: CARDINAL]] =
BEGIN
column: Column ← NARROW[sn.ref];
FOR J: CARDINAL IN [1..column.nRows] DO
ConnectLoadedItemArraysInRowOfSlots[StructureNodes.GetElementAt[column.da, 1, J].sn, connectOneItemArray];
ENDLOOP;
END;
ColumnOfRowsCheckForDirtyData: PROCEDURE[node: StructureNode] =
BEGIN
column: Column ← NARROW[node.ref];
column.daSn.procs.CheckForDirtyData[column.daSn];
END;
ColumnOfRowsPreShow: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
BEGIN
column: Column ← NARROW[node.ref];
[lead, height, space, L, A, B, R, W] ← column.daSn.procs.PreShow[column.daSn];
END;
ColumnOfRowsShowLine: PROCEDURE[node: StructureNode, L, R, W: INTEGER, lineX: INTEGER, to: STREAM] =
BEGIN
column: Column ← NARROW[node.ref];
column.daSn.procs.ShowLine[column.daSn, L, R, W, lineX, to];
END;
ColumnOfRowsPrePrePaint: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
BEGIN
column: Column ← NARROW[node.ref];
[lead, height, space, L, A, B, R, W] ← column.daSn.procs.PrePrePaint[column.daSn];
END;
ColumnOfRowsPrePaint: PROCEDURE[node: StructureNode, y, x, L, R, W: INTEGER, pass: PrePaintPass] =
BEGIN
column: Column ← NARROW[node.ref];
column.daSn.procs.PrePaint[column.daSn, y, x, L, R, W, pass];
END;
ColumnOfRowsPaint: PROCEDURE[node: StructureNode, dirtyOnly: BOOLEAN] =
BEGIN
column: Column ← NARROW[node.ref];
column.daSn.procs.Paint[column.daSn, dirtyOnly];
END;
ColumnOfRowsUnPaint: PROCEDURE[node: StructureNode] =
BEGIN
column: Column ← NARROW[node.ref];
column.daSn.procs.UnPaint[column.daSn];
END;
ColumnOfRowsNoteEnclosingCell: PROCEDURE[node: StructureNode, dac: DACell] =
BEGIN
column: Column ← NARROW[node.ref];
column.daSn.procs.NoteEnclosingCell[column.daSn, dac];
END;
ColumnOfRowsNoteCoordinates: PROCEDURE[node: StructureNode, da: DisplayArray, I, J: CARDINAL] =
BEGIN
column: Column ← NARROW[node.ref];
column.daSn.procs.NoteCoordinates[column.daSn, da, I, J];
END;
SaveColumnOfRows: PROCEDURE[info: StructureNode, to: IO.STREAM] =
BEGIN
col: Column ← NARROW[info.ref];
Put[to, char[' ], int[col.nRows-1]];
FOR J: CARDINAL IN (1..col.nRows] DO
rssn: StructureNodes.StructureNode ← StructureNodes.GetElementAt[col.da, 1, J].sn;
Put[to, char['(], char[' ], atom[$RowOfSlots]];
rssn.procs.Save[rssn, to];
Put[to, char[')]];
ENDLOOP;
END;
SubstituteInColumnOfRows: PROCEDURE[info: StructureNode, newText, oldText: Rope.ROPE] =
BEGIN
col: Column ← NARROW[info.ref];
FOR J: CARDINAL IN [1..col.nRows] DO
rssn: StructureNodes.StructureNode ← StructureNodes.GetElementAt[col.da, 1, J].sn;
rssn.procs.Substitute[rssn, newText, oldText];
ENDLOOP;
END;
AbandonColumnOfRows: PROCEDURE[info: StructureNode] =
BEGIN
col: Column ← NARROW[info.ref];
WHILE col.nRows # 0 DO RemoveRowAtColumnOfRows[col, col.nRows] ENDLOOP;
StructureNodes.DeleteColumnAt[col.da, 1];
END;
ActColumnOfRows: PROCEDURE[info: StructureNode, I, J: CARDINAL, action: StructureNodes.Action, p1, p2: REF ANY] RETURNS[StructureNode, CARDINAL, CARDINAL] =
BEGIN
col: Column ← NARROW[info.ref];
SELECT action FROM
InsertRow => IF J # 1 THEN InstallRowAtColumnOfRows[col, J, col.pageName, clientRow];
AppendRow => InstallRowAtColumnOfRows[col, J+1, col.pageName, clientRow];
DeleteRow => IF J # 1 THEN RemoveRowAtColumnOfRows[col, J];
ENDCASE =>
BEGIN
cSn: StructureNode; cI, cJ: CARDINAL;
[cSn, cI, cJ] ← GetContextDA[col.da];
RETURN[cSn, cI, cJ];
END;
RETURN[NIL, 0, 0];
END;
VerifyColumnOfRows: PROCEDURE[info: StructureNode] =
BEGIN
col: Column ← NARROW[info.ref];
FOR J: CARDINAL IN (1..col.nRows] DO
rssn: StructureNodes.StructureNode ← StructureNodes.GetElementAt[col.da, 1, J].sn;
rssn.procs.Verify[rssn];
ENDLOOP;
END;
-- support routines for Column of rows
BasicCreateColumnOfRows: PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, pageName: Rope.ROPE] RETURNS[Column, StructureNode] =
BEGIN
col: Column ← NEW[ColumnBody ← [NIL, NIL, 0, document, displayer, vParent, pageName]];
colSn: StructureNode ← NEW[StructureNodeBody ← [col, ColOfRowsStructureNodeProcs]];
[col.daSn, col.da] ← CreateDisplayArray[colSn];
StructureNodes.AddColumnAt[col.da, 1];
RETURN[col, colSn]
END;
InstallRowAtColumnOfRows: PROCEDURE[col: Column, J: CARDINAL, pageName: Rope.ROPE, rowCase: RowCase] =
BEGIN
rssn: StructureNode; -- holds the row of slots
IF J = 0 OR J > col.nRows+1 THEN ERROR;
col.nRows ← col.nRows+1;
StructureNodes.AddRowAt[col.da, J];
rssn ← CreateRowOfSlots[col.document, col.displayer, col.vParent, pageName, rowCase];
StructureNodes.SetElementAt[col.da, 1, J, rssn, NIL];
END;
RemoveRowAtColumnOfRows: PROCEDURE[col: Column, J: CARDINAL] =
BEGIN
IF J = 0 OR J > col.nRows THEN ERROR;
StructureNodes.DeleteRowAt[col.da, J];
col.nRows ← col.nRows-1;
END;
-- row of slots
CellWidth: INTEGER = 50;
CellHeight: INTEGER = 20;
RowCase: TYPE = {clientRow, displayPageName};
RowOfSlots: TYPE = REF RowOfSlotsBody;
RowOfSlotsBody: TYPE = RECORD[
daSn: StructureNodes.StructureNode,
da: StructureNodes.DisplayArray,
nSlots: CARDINAL,
document: NewCalcGlobal.Document,
displayer: NewCalcGlobal.Displayer,
vParent: Viewer,
pageName: Rope.ROPE,
rowCase: RowCase];
RowOfSlotsStructureNodeProcs: REF StructureNodes.StructureNodeProcs ← NEW[StructureNodes.StructureNodeProcs ← [RowOfSlotsCheckForDirtyData, RowOfSlotsPreShow, RowOfSlotsShowLine, RowOfSlotsPrePrePaint, RowOfSlotsPrePaint, RowOfSlotsPaint, RowOfSlotsUnPaint, RowOfSlotsNoteEnclosingCell, RowOfSlotsNoteCoordinates, SaveRowOfSlots, ActRowOfSlots, SubstituteInRowOfSlots, AbandonRowOfSlots, VerifyRowOfSlots]];
LoadRowOfSlots: PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, pageName: Rope.ROPE, from: IO.STREAM, version: CARDINAL] RETURNS[StructureNode] =
BEGIN -- the row of slots atom has been read
row: RowOfSlots;
rowSn: StructureNode;
[row, rowSn] ← BasicCreateRowOfSlots[document, displayer, vParent, pageName, clientRow];
row.nSlots ← GetInt[from];
FOR I: CARDINAL IN [1..row.nSlots] DO
rssn: StructureNode; -- holds the slot
IF NOT Rope.Equal[GetTokenRope[from].token, "("] THEN BadFormatLoadFile;
IF NARROW[GetRefAny[from], ATOM] # $Slot THEN BadFormatLoadFile;
rssn ← LoadSlot[document, displayer, vParent, pageName, from, version];
IF NOT Rope.Equal[GetTokenRope[from].token, ")"] THEN BadFormatLoadFile;
StructureNodes.AddColumnAt[row.da, I];
StructureNodes.SetElementAt[row.da, I, 1, rssn, NIL];
ENDLOOP;
RETURN[rowSn]
END;
CreateRowOfSlots: PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, pageName: Rope.ROPE, rowCase: RowCase] RETURNS[StructureNode] =
BEGIN
row: RowOfSlots;
rowSn: StructureNode;
[row, rowSn] ← BasicCreateRowOfSlots[document, displayer, vParent, pageName, rowCase];
InstallSlotAtRowOfSlots[row, 1];
RETURN[rowSn]
END;
ResetPageNameOfRow: PROCEDURE[rsn: StructureNode, name: Rope.ROPE] =
BEGIN
row: RowOfSlots ← NARROW[rsn.ref];
FOR I: CARDINAL IN [1..row.nSlots] DO
slotSn: StructureNode ← StructureNodes.GetElementAt[row.da, I, 1].sn;
ResetPageNameOfSlot[slotSn, name];
ENDLOOP;
END;
GetRowOfSlots: PROCEDURE[info: StructureNode, send: GCell.SetARowOfSlotsProc, entry: BOOLEAN] =
BEGIN
row: RowOfSlots ← NARROW[info.ref];
GRS: PROCEDURE =
BEGIN
I: CARDINAL ← 1;
GetOneSlot: PROCEDURE[sendIt: GCell.SetASlotProc] =
BEGIN
ssn: StructureNodes.StructureNode ← StructureNodes.GetElementAt[row.da, I, 1].sn;
GetSlot[ssn, sendIt, FALSE];
I ← I + 1;
END;
send[row.nSlots, GetOneSlot];
END;
IF entry THEN row.document.procs.executeInMonitor[row.document, GRS] ELSE GRS[];
END;
SetRowOfSlots: PROCEDURE[info: StructureNode, nSlots: CARDINAL, getOneSlot: PROCEDURE[GCell.SetASlotProc], entry: BOOLEAN] =
BEGIN
row: RowOfSlots ← NARROW[info.ref];
SRS: PROCEDURE =
BEGIN
WHILE row.nSlots # 0 DO RemoveSlotAtRowOfSlots[row, row.nSlots] ENDLOOP;
row.nSlots ← nSlots;
FOR I: CARDINAL IN [1..nSlots] DO
rssn: StructureNode; -- holds the slot
SetTheSlot: GCell.SetASlotProc =
{SetSlot[rssn, case, GetOneArray, FALSE]};
rssn ← CreateSlot[row.document, row.displayer, row.vParent, row.pageName, row.rowCase];
StructureNodes.AddColumnAt[row.da, I];
StructureNodes.SetElementAt[row.da, I, 1, rssn, NIL];
getOneSlot[SetTheSlot];
ENDLOOP;
END;
IF entry THEN row.document.procs.executeInMonitor[row.document, SRS] ELSE SRS[];
END;
CountOpenSlotsInRowOfSlots: PROCEDURE[node: StructureNode] RETURNS[CARDINAL] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
count: CARDINAL ← 0;
FOR I: CARDINAL IN [1..row.nSlots] DO
IF SlotCheckForOpenSlot[StructureNodes.GetElementAt[row.da, I, 1].sn] THEN
count ← count + 1;
ENDLOOP;
RETURN[count];
END;
InstallHCellArrayAtOpenSlotInRowOfSlots: PROCEDURE[sn: StructureNode, colNumber: CARDINAL, case: GCell.SlotCase, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE] RETURNS[StructureNode]] =
BEGIN
row: RowOfSlots ← NARROW[sn.ref];
SlotInstallHCellArrayAtOpenSlot[StructureNodes.GetElementAt[row.da, colNumber, 1].sn, case, createIt];
END;
InstallHCellArrayAtAnOpenSlotInRowOfSlots: PROCEDURE[sn: StructureNode, rowNumber: CARDINAL, case: GCell.SlotCase, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE, rowNumber, colNumber: CARDINAL] RETURNS[StructureNode]] RETURNS[didIt: BOOLEAN] =
BEGIN
row: RowOfSlots ← NARROW[sn.ref];
FOR I: CARDINAL IN [1..row.nSlots] DO
IF SlotInstallHCellArrayAtAnOpenSlot[StructureNodes.GetElementAt[row.da, I, 1].sn, rowNumber, I, case, createIt] THEN
RETURN[TRUE];
ENDLOOP;
RETURN[FALSE];
END;
GetHCellArrayAtSlotInRowOfSlots: PROCEDURE[sn: StructureNode, colNumber: CARDINAL] RETURNS[StructureNode] =
BEGIN
row: RowOfSlots ← NARROW[sn.ref];
RETURN[SlotGetHCellArrayAtSlot[StructureNodes.GetElementAt[row.da, colNumber, 1].sn]];
END;
ConnectInstalledItemArraysInRowOfSlots: PROCEDURE[sn: StructureNode, rowNumber: CARDINAL, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, row, col: CARDINAL]] =
BEGIN
row: RowOfSlots ← NARROW[sn.ref];
FOR I: CARDINAL IN [1..row.nSlots] DO
SlotConnectInstalledItemArrays[StructureNodes.GetElementAt[row.da, I, 1].sn, rowNumber, I, connectOneItemArray]
ENDLOOP;
END;
GenerateSummaryArraysInRowOfSlots: PROCEDURE[sn: StructureNode, seeOneArray: PROCEDURE[summaryHcaSn: StructureNodes.StructureNode, summaryKey: LONG CARDINAL] RETURNS[continue: BOOLEAN]] RETURNS[continue: BOOLEAN] =
BEGIN
row: RowOfSlots ← NARROW[sn.ref];
FOR I: CARDINAL IN [1..row.nSlots] DO
IF NOT SlotGenerateSummaryArrays[StructureNodes.GetElementAt[row.da, I, 1].sn, seeOneArray] THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE];
END;
ConnectLoadedItemArraysInRowOfSlots: PROCEDURE[sn: StructureNode, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, itemKey: LONG CARDINAL, atRow: CARDINAL]] =
BEGIN
row: RowOfSlots ← NARROW[sn.ref];
FOR I: CARDINAL IN [1..row.nSlots] DO
SlotConnectLoadedItemArrays[StructureNodes.GetElementAt[row.da, I, 1].sn, connectOneItemArray];
ENDLOOP;
END;
RowOfSlotsCheckForDirtyData: PROCEDURE[node: StructureNode] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
row.daSn.procs.CheckForDirtyData[row.daSn];
END;
RowOfSlotsPreShow: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
[lead, height, space, L, A, B, R, W] ← row.daSn.procs.PreShow[row.daSn];
END;
RowOfSlotsShowLine: PROCEDURE[node: StructureNode, L, R, W: INTEGER, lineX: INTEGER, to: STREAM] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
row.daSn.procs.ShowLine[row.daSn, L, R, W, lineX, to];
END;
RowOfSlotsPrePrePaint: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
[lead, height, space, L, A, B, R, W] ← row.daSn.procs.PrePrePaint[row.daSn];
END;
RowOfSlotsPrePaint: PROCEDURE[node: StructureNode, y, x, L, R, W: INTEGER, pass: PrePaintPass] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
row.daSn.procs.PrePaint[row.daSn, y, x, L, R, W, pass];
END;
RowOfSlotsPaint: PROCEDURE[node: StructureNode, dirtyOnly: BOOLEAN] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
row.daSn.procs.Paint[row.daSn, dirtyOnly];
END;
RowOfSlotsUnPaint: PROCEDURE[node: StructureNode] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
row.daSn.procs.UnPaint[row.daSn];
END;
RowOfSlotsNoteEnclosingCell: PROCEDURE[node: StructureNode, dac: DACell] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
row.daSn.procs.NoteEnclosingCell[row.daSn, dac];
END;
RowOfSlotsNoteCoordinates: PROCEDURE[node: StructureNode, da: DisplayArray, I, J: CARDINAL] =
BEGIN
row: RowOfSlots ← NARROW[node.ref];
row.daSn.procs.NoteCoordinates[row.daSn, da, I, J];
END;
SaveRowOfSlots: PROCEDURE[info: StructureNode, to: IO.STREAM] =
BEGIN
row: RowOfSlots ← NARROW[info.ref];
Put[to, char[' ], int[row.nSlots]];
FOR I: CARDINAL IN [1..row.nSlots] DO
ssn: StructureNodes.StructureNode ← StructureNodes.GetElementAt[row.da, I, 1].sn;
Put[to, char['(], char[' ], atom[$Slot]];
ssn.procs.Save[ssn, to];
Put[to, char[')]];
ENDLOOP;
END;
SubstituteInRowOfSlots: PROCEDURE[info: StructureNode, newText, oldText: Rope.ROPE] =
BEGIN
row: RowOfSlots ← NARROW[info.ref];
FOR I: CARDINAL IN [1..row.nSlots] DO
ssn: StructureNodes.StructureNode ← StructureNodes.GetElementAt[row.da, I, 1].sn;
ssn.procs.Substitute[ssn, newText, oldText];
ENDLOOP;
END;
AbandonRowOfSlots: PROCEDURE[info: StructureNode] =
BEGIN
row: RowOfSlots ← NARROW[info.ref];
WHILE row.nSlots # 0 DO RemoveSlotAtRowOfSlots[row, row.nSlots] ENDLOOP;
StructureNodes.DeleteRowAt[row.da, 1];
END;
ActRowOfSlots: PROCEDURE[info: StructureNode, I, J: CARDINAL, action: StructureNodes.Action, p1, p2: REF ANY] RETURNS[StructureNode, CARDINAL, CARDINAL] =
BEGIN
row: RowOfSlots ← NARROW[info.ref];
SELECT action FROM
InsertSlot => IF row.rowCase = clientRow THEN InstallSlotAtRowOfSlots[row, I];
AppendSlot => IF row.rowCase = clientRow THEN InstallSlotAtRowOfSlots[row, I+1];
DeleteSlot => IF row.rowCase = clientRow THEN RemoveSlotAtRowOfSlots[row, I];
ENDCASE =>
BEGIN
cSn: StructureNode; cI, cJ: CARDINAL;
[cSn, cI, cJ] ← GetContextDA[row.da];
RETURN[cSn, cI, cJ];
END;
RETURN[NIL, 0, 0];
END;
VerifyRowOfSlots: PROCEDURE[info: StructureNode] =
BEGIN
row: RowOfSlots ← NARROW[info.ref];
FOR I: CARDINAL IN [1..row.nSlots] DO
ssn: StructureNode ← StructureNodes.GetElementAt[row.da, I, 1].sn;
ssn.procs.Verify[ssn];
ENDLOOP;
END;
-- support routines for RowOfSlots
BasicCreateRowOfSlots: PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, pageName: Rope.ROPE, rowCase: RowCase] RETURNS[RowOfSlots, StructureNode] =
BEGIN
row: RowOfSlots ← NEW[RowOfSlotsBody ← [NIL, NIL, 0, document, displayer, vParent, pageName, rowCase]];
rowSn: StructureNode ← NEW[StructureNodeBody ← [row, RowOfSlotsStructureNodeProcs]];
[row.daSn, row.da] ← CreateDisplayArray[rowSn];
StructureNodes.AddRowAt[row.da, 1];
RETURN[row, rowSn]
END;
InstallSlotAtRowOfSlots: PROCEDURE[row: RowOfSlots, I: CARDINAL] =
BEGIN
ssn: StructureNode; -- holds the slot
IF I = 0 OR I > row.nSlots+1 THEN ERROR;
row.nSlots ← row.nSlots+1;
StructureNodes.AddColumnAt[row.da, I];
ssn ← CreateSlot[row.document, row.displayer, row.vParent, row.pageName, row.rowCase];
StructureNodes.SetElementAt[row.da, I, 1, ssn, NIL];
END;
RemoveSlotAtRowOfSlots: PROCEDURE[row: RowOfSlots, I: CARDINAL] =
BEGIN
IF I = 0 OR I > row.nSlots THEN ERROR;
StructureNodes.DeleteColumnAt[row.da, I];
row.nSlots ← row.nSlots-1;
END;
-- slots
Slot: TYPE = REF SlotBody;
SlotBody: TYPE = RECORD[
daSn: StructureNodes.StructureNode,
da: StructureNodes.DisplayArray,
document: NewCalcGlobal.Document,
displayer: NewCalcGlobal.Displayer,
vParent: Viewer,
pageName: Rope.ROPE,
case: GCell.SlotCase,
key: LONG CARDINAL, -- used during loading
rowInSummaryArray: CARDINAL -- used during loading
];
PageIdSlotInfo: TYPE = REF PageIdSlotInfoBody;
PageIdSlotInfoBody: TYPE = RECORD[hCell: HCells.HCell];
SlotStructureNodeProcs: REF StructureNodes.StructureNodeProcs ← NEW[StructureNodes.StructureNodeProcs ← [SlotCheckForDirtyData, SlotPreShow, SlotShowLine, SlotPrePrePaint, SlotPrePaint, SlotPaint, SlotUnPaint, SlotNoteEnclosingCell, SlotNoteCoordinates, SaveSlot, ActSlot, SubstituteInSlot, AbandonSlot, VerifySlot]];
LoadSlot: PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, pageName: Rope.ROPE, from: IO.STREAM, version: CARDINAL] RETURNS[StructureNode] =
BEGIN -- note: column of rows atom has been read
slot: Slot ← NEW[SlotBody ← [NIL, NIL, document, displayer, vParent, pageName, slot, 0, 0]];
type: ATOM;
badToken: Rope.ROPE ← NIL;
slotSn: StructureNode ← NEW[StructureNodeBody ← [slot, SlotStructureNodeProcs]];
[slot.daSn, slot.da] ← CreateDisplayArray[slotSn];
StructureNodes.AddColumnAt[slot.da, 1];
StructureNodes.AddRowAt[slot.da, 1];
IF NOT Rope.Equal[GetTokenRope[from].token, "("] THEN BadFormatLoadFile;
type ← NARROW[GetRefAny[from]];
SELECT type FROM
$Slot =>
BEGIN
gcSn: StructureNode;
gcSn ← GCell.CreateGCell[document, displayer, slotSn, vParent, slot];
StructureNodes.SetElementAt[slot.da, 1, 1, gcSn, NIL];
slot.case ← slot;
END;
$GCellArray =>
BEGIN
gcaSn: StructureNode ← GCell.LoadGCellArray[document, displayer, vParent, from, version];
StructureNodes.SetElementAt[slot.da, 1, 1, gcaSn, NIL];
slot.case ← GCellArray;
END;
$individualHCellArray =>
BEGIN
gcaSn: StructureNode ← HCells.LoadHCellArray[document, displayer, vParent, pageName, NIL, from, version, individual];
StructureNodes.SetElementAt[slot.da, 1, 1, gcaSn, NIL];
slot.case ← individualHCellArray;
END;
$itemHCellArray =>
BEGIN
gcaSn: StructureNode;
key: LONG CARDINAL ← GetCard[from];
row: CARDINAL ← GetCard[from];
gcaSn ← HCells.LoadHCellArray[document, displayer, vParent, pageName, NIL, from, version, individual]; -- will be converted to groupItem during connection
StructureNodes.SetElementAt[slot.da, 1, 1, gcaSn, NIL];
slot.case ← itemHCellArray;
slot.key ← key;
slot.rowInSummaryArray ← row;
END;
$summaryHCellArray =>
BEGIN
gcaSn: StructureNode;
key: LONG CARDINAL ← GetCard[from];
gcaSn ← HCells.LoadHCellArray[document, displayer, vParent, pageName, NIL, from, version, groupSummary];
StructureNodes.SetElementAt[slot.da, 1, 1, gcaSn, NIL];
slot.case ← summaryHCellArray;
slot.key ← key;
END;
ENDCASE => BadFormatLoadFile;
IF NOT Rope.Equal[badToken ← GetTokenRope[from].token, ")"] THEN BadFormatLoadFile;
RETURN[slotSn]
END;
CreateSlot: PUBLIC PROCEDURE[document: NewCalcGlobal.Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, pageName: Rope.ROPE, rowCase: RowCase] RETURNS[StructureNode] =
BEGIN
slot: Slot ← NEW[SlotBody ← [NIL, NIL, document, displayer, vParent, pageName, slot, 0, 0]];
slotSn: StructureNode ← NEW[StructureNodeBody ← [slot, SlotStructureNodeProcs]];
[slot.daSn, slot.da] ← CreateDisplayArray[slotSn];
StructureNodes.AddColumnAt[slot.da, 1];
StructureNodes.AddRowAt[slot.da, 1];
SELECT rowCase FROM
clientRow =>
BEGIN
slotGcSn: StructureNode;
slotGcSn ← GCell.CreateGCell[document, displayer, slotSn, vParent, slot];
StructureNodes.SetElementAt[slot.da, 1, 1, slotGcSn, NIL];
slot.case ← slot;
END;
displayPageName =>
BEGIN
slotHcSn: StructureNode;
hCell: HCells.HCell;
[slotHcSn, hCell] ← HCells.CreateHCell[document, displayer, slotSn, vParent];
StructureNodes.SetElementAt[slot.da, 1, 1, slotHcSn, NEW[PageIdSlotInfoBody ← [hCell]]];
HCells.SetHCellParameters[hCell, NIL, NIL, NIL, NIL, NIL, FALSE, pageName, none, none, none, none, text, left, "", NIL, NIL];
slot.case ← pageId;
END;
ENDCASE => ERROR;
RETURN[slotSn]
END;
ResetPageNameOfSlot: PROCEDURE[slotSn: StructureNode, name: Rope.ROPE] =
BEGIN
slot: Slot ← NARROW[slotSn.ref];
slot.pageName ← name;
SELECT slot.case FROM
pageId =>
BEGIN
info: PageIdSlotInfo ← NARROW[StructureNodes.GetElementAt[slot.da, 1, 1].info];
HCells.SetHCellText[info.hCell, name];
END;
$individualHCellArray, $itemHCellArray, $summaryHCellArray =>
BEGIN
hcaSn: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn;
HCells.ResetPageNameOfHCellArray[hcaSn, name];
END;
$slot, $GCellArray => NULL;
ENDCASE => ERROR;
END;
GetSlot: PROCEDURE[info: StructureNode, send: GCell.SetASlotProc, entry: BOOLEAN] =
BEGIN
slot: Slot ← NARROW[info.ref];
slotGca: StructureNode ← GetElementAt[slot.da, 1, 1].sn;
GAS: PROCEDURE =
BEGIN
GetTheArray: PROCEDURE[sendIt: GCell.SetAGCellArrayProc] =
{GCell.GetGCellArray[slotGca, sendIt, FALSE]};
send[slot.case, GetTheArray];
END;
IF entry THEN slot.document.procs.executeInMonitor[slot.document, GAS] ELSE GAS[];
END;
SetSlot: PROCEDURE[info: StructureNode, case: GCell.SlotCase, getOneArray: PROCEDURE[GCell.SetAGCellArrayProc], entry: BOOLEAN] =
BEGIN
slot: Slot ← NARROW[info.ref];
SAS: PROCEDURE =
BEGIN
sub: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn;
sub.procs.Abandon[sub];
StructureNodes.SetElementAt[slot.da, 1, 1, NIL, NIL];
SELECT case FROM
slot =>
BEGIN
slotGcSn: StructureNode ← GCell.CreateGCell[slot.document, slot.displayer, NIL, slot.vParent, slot];
StructureNodes.SetElementAt[slot.da, 1, 1, slotGcSn, NIL];
slot.case ← slot
END;
GCellArray =>
BEGIN
gcaSn: StructureNode;
SetTheArray: GCell.SetAGCellArrayProc =
{GCell.SetGCellArray[gcaSn, nColumns, nRows, GetOneCell, FALSE]};
gcaSn ← GCell.CreateGCellArray[slot.document, slot.displayer, slot.vParent];
StructureNodes.SetElementAt[slot.da, 1, 1, gcaSn, NIL];
slot.case ← GCellArray;
getOneArray[SetTheArray];
END;
individualHCellArray =>
BEGIN
hcaSn: StructureNode;
hcaSn ← HCells.CreateHCellArray[slot.document, slot.displayer, slot.vParent, NIL, NIL];
StructureNodes.SetElementAt[slot.da, 1, 1, hcaSn, NIL];
slot.case ← individualHCellArray;
END;
ENDCASE => ERROR;
END;
IF entry THEN slot.document.procs.executeInMonitor[slot.document, SAS] ELSE SAS[];
END;
SlotCheckForOpenSlot: PROCEDURE[node: StructureNode] RETURNS[BOOLEAN] =
BEGIN
slot: Slot ← NARROW[node.ref];
RETURN[slot.case = slot];
END;
SlotInstallHCellArrayAtOpenSlot: PROCEDURE[sn: StructureNode, case: GCell.SlotCase, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE] RETURNS[StructureNode]] =
BEGIN
slot: Slot ← NARROW[sn.ref];
hcaSn: StructureNode;
IF slot.case # slot THEN ERROR;
hcaSn ← createIt[slot.displayer, slot.vParent, slot.pageName];
StructureNodes.SetElementAt[slot.da, 1, 1, hcaSn, NIL];
slot.case ← case;
END;
SlotInstallHCellArrayAtAnOpenSlot: PROCEDURE[sn: StructureNode, rowNumber, colNumber: CARDINAL, case: GCell.SlotCase, createIt: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE, rowNumber, colNumber: CARDINAL] RETURNS[StructureNode]] RETURNS[didIt: BOOLEAN] =
BEGIN
slot: Slot ← NARROW[sn.ref];
hcaSn: StructureNode;
IF slot.case # slot THEN RETURN[FALSE];
hcaSn ← createIt[slot.displayer, slot.vParent, slot.pageName, rowNumber, colNumber];
StructureNodes.SetElementAt[slot.da, 1, 1, hcaSn, NIL];
slot.case ← case;
RETURN[TRUE];
END;
SlotGetHCellArrayAtSlot: PROCEDURE[sn: StructureNode] RETURNS[StructureNode] =
BEGIN
slot: Slot ← NARROW[sn.ref];
hcaSn: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn;
SELECT slot.case FROM
itemHCellArray, summaryHCellArray => RETURN[hcaSn];
slot => RETURN[NIL];
ENDCASE => ERROR;
END;
SlotConnectInstalledItemArrays: PROCEDURE[sn: StructureNode, rowNumber, colNumber: CARDINAL, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, row, col: CARDINAL]] =
BEGIN
slot: Slot ← NARROW[sn.ref];
hcaSn: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn;
IF slot.case # itemHCellArray THEN RETURN;
connectOneItemArray[hcaSn, rowNumber, colNumber];
END;
SlotGenerateSummaryArrays: PROCEDURE[sn: StructureNode, seeOneArray: PROCEDURE[summaryHcaSn: StructureNodes.StructureNode, summaryKey: LONG CARDINAL] RETURNS[continue: BOOLEAN]] RETURNS[continue: BOOLEAN] =
BEGIN
slot: Slot ← NARROW[sn.ref];
hcaSn: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn;
IF slot.case # summaryHCellArray THEN RETURN[TRUE];
RETURN[seeOneArray[hcaSn, slot.key]];
END;
SlotConnectLoadedItemArrays: PROCEDURE[sn: StructureNode, connectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, itemKey: LONG CARDINAL, atRow: CARDINAL]] =
BEGIN
slot: Slot ← NARROW[sn.ref];
hcaSn: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn;
IF slot.case # itemHCellArray THEN RETURN;
connectOneItemArray[hcaSn, slot.key, slot.rowInSummaryArray];
END;
SlotCheckForDirtyData: PROCEDURE[node: StructureNode] =
BEGIN
slot: Slot ← NARROW[node.ref];
slot.daSn.procs.CheckForDirtyData[slot.daSn];
END;
SlotPreShow: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
BEGIN
slot: Slot ← NARROW[node.ref];
[lead, height, space, L, A, B, R, W] ← slot.daSn.procs.PreShow[slot.daSn];
END;
SlotShowLine: PROCEDURE[node: StructureNode, L, R, W: INTEGER, lineX: INTEGER, to: STREAM] =
BEGIN
slot: Slot ← NARROW[node.ref];
slot.daSn.procs.ShowLine[slot.daSn, L, R, W, lineX, to];
END;
SlotPrePrePaint: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
BEGIN
slot: Slot ← NARROW[node.ref];
[lead, height, space, L, A, B, R, W] ← slot.daSn.procs.PrePrePaint[slot.daSn];
END;
SlotPrePaint: PROCEDURE[node: StructureNode, y, x, L, R, W: INTEGER, pass: PrePaintPass] =
BEGIN
slot: Slot ← NARROW[node.ref];
slot.daSn.procs.PrePaint[slot.daSn, y, x, L, R, W, pass];
END;
SlotPaint: PROCEDURE[node: StructureNode, dirtyOnly: BOOLEAN] =
BEGIN
slot: Slot ← NARROW[node.ref];
slot.daSn.procs.Paint[slot.daSn, dirtyOnly];
END;
SlotUnPaint: PROCEDURE[node: StructureNode] =
BEGIN
slot: Slot ← NARROW[node.ref];
slot.daSn.procs.UnPaint[slot.daSn];
END;
SlotNoteEnclosingCell: PROCEDURE[node: StructureNode, dac: DACell] =
BEGIN
slot: Slot ← NARROW[node.ref];
slot.daSn.procs.NoteEnclosingCell[slot.daSn, dac];
END;
SlotNoteCoordinates: PROCEDURE[node: StructureNode, da: DisplayArray, I, J: CARDINAL] =
BEGIN
slot: Slot ← NARROW[node.ref];
slot.daSn.procs.NoteCoordinates[slot.daSn, da, I, J];
END;
SaveSlot: PROCEDURE[info: StructureNode, to: IO.STREAM] =
BEGIN
slot: Slot ← NARROW[info.ref];
sub: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn; -- the sub structure
Put[to, char['(]];
SELECT slot.case FROM
slot => Put[to, char[' ], atom[$Slot]];
GCellArray =>
BEGIN
Put[to, char[' ], atom[$GCellArray]];
sub.procs.Save[sub, to];
END;
individualHCellArray =>
BEGIN
Put[to, char[' ], atom[$individualHCellArray]];
sub.procs.Save[sub, to];
END;
itemHCellArray =>
BEGIN
summaryArray: StructureNode;
row: CARDINAL;
[summaryArray, row] ← HCells.GetSummaryArray[sub];
Put[to, char[' ], atom[$itemHCellArray], char[' ]];
Put[to, card[LOOPHOLE[summaryArray]], char[' ]];
Put[to, card[row], char[' ]];
sub.procs.Save[sub, to];
END;
summaryHCellArray =>
BEGIN
Put[to, char[' ], atom[$summaryHCellArray], char[' ]];
Put[to, card[LOOPHOLE[sub]], char[' ]];
sub.procs.Save[sub, to];
END;
ENDCASE => ERROR;
Put[to, char[')]];
END;
SubstituteInSlot: PROCEDURE[info: StructureNode, newText, oldText: Rope.ROPE] =
BEGIN
slot: Slot ← NARROW[info.ref];
sub: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn; -- the sub structure
SELECT slot.case FROM
slot => NULL;
GCellArray => sub.procs.Substitute[sub, newText, oldText];
ENDCASE => ERROR;
END;
AbandonSlot: PROCEDURE[info: StructureNode] =
BEGIN
slot: Slot ← NARROW[info.ref];
StructureNodes.DeleteColumnAt[slot.da, 1];
StructureNodes.DeleteRowAt[slot.da, 1];
END;
ActSlot: PROCEDURE[info: StructureNode, I, J: CARDINAL, action: StructureNodes.Action, p1, p2: REF ANY] RETURNS[StructureNode, CARDINAL, CARDINAL] =
BEGIN
slot: Slot ← NARROW[info.ref];
SELECT action FROM
CreateGCellArray =>
IF slot.case = slot THEN
BEGIN
gcaSn: StructureNode ← GCell.CreateGCellArray[slot.document, slot.displayer, slot.vParent];
StructureNodes.SetElementAt[slot.da, 1, 1, gcaSn, NIL];
slot.case ← GCellArray;
END;
CreateHCellArray =>
IF slot.case = slot THEN
BEGIN
name: Rope.ROPE ← NARROW[p1];
hcaSn: StructureNode ← HCells.CreateHCellArray[slot.document, slot.displayer, slot.vParent, slot.pageName, name];
StructureNodes.SetElementAt[slot.da, 1, 1, hcaSn, NIL];
slot.case ← individualHCellArray;
END;
ENDCASE =>
BEGIN
cSn: StructureNode; cI, cJ: CARDINAL;
[cSn, cI, cJ] ← GetContextDA[slot.da];
RETURN[cSn, cI, cJ];
END;
RETURN[NIL, 0, 0];
END;
VerifySlot: PROCEDURE[info: StructureNode] =
BEGIN
slot: Slot ← NARROW[info.ref];
sub: StructureNode ← StructureNodes.GetElementAt[slot.da, 1, 1].sn; -- the sub structure;
SELECT slot.case FROM
slot => NULL;
GCellArray, individualHCellArray, itemHCellArray, summaryHCellArray => sub.procs.Verify[sub];
ENDCASE => ERROR;
END;
-- debugging routines
END..
-- 6-Mar-82 16:25:00: Sturgis, started ColumnOfRows.mesa
-- 6-Mar-82 17:46:45: initial edit completed.
-- 6-Mar-82 18:05:32: forgot to add the single row to the info matrix of a row of slots.
-- RTE: 6-Mar-82 18:20:27: forgot to replace an ERROR with a call on the appropriate routine that had been written after the ERROR installed.
-- change: 7-Mar-82 13:47:44: begin to add the new verions of save and load
-- remark: T: seemed adviasable to add a hole new layer of matrix to hold the slot???
-- RTE: 7-Mar-82 16:50:23: forgot to set the matirx element for the slot text cell.
-- remark: 7-Mar-82 16:54:31: basic structure still seems to work, i.e. can append slots, rows, and columns. However, menu is still too big, so can't test other actions. did not try any delete actions.
RTE: 7-Mar-82 18:00:31: could not append a slot to a simplematrix. modifed slot act to check for case only after seeing that it is a simplematrix create action. Thus, false will perculate up on appendslot.
-- change: 8-Mar-82 14:35:20: modify load and save to follow new conventions.
-- RTE: 8-Mar-82 16:54:07: remove row at column of rows was calling removal of last row an error.
-- RTE: 9-Mar-82 14:14:42: LoadSLot forgot to install the element in the MatrixNode.
-- change: 11-Mar-82 14:13:34: add knowledge of additivematrices to slot code.
-- July 31, 1982 2:12 pm: convert to cedar 3.2
-- August 1, 1982 5:30 pm: add AssignmentCell as a slot case, and necessary code
-- August 4, 1982 10:28 am: add version to load procedure and subsequent calls. remove assignment cell from top level structures.
-- August 7, 1982 5:10 pm: convert to NCGlobal
-- change: September 17, 1982 4:20 pm: add left justification
-- October 1, 1982 11:20 am: add code to splice in GCellArrays
change: October 3, 1982 3:10 pm: trouble during load, loading a slot does not see final ")". So, add code to save the actual token it sees to try to run down the problem.
-- October 8, 1982 11:01 am: begin to convert whole thing to use DisplayArrays, GCells, and only build GCellArrays.
-- BTE: October 8, 1982 1:44 pm: rename the module to be NewColumnOfRows, to match its new file name.
-- October 10, 1982 1:46 pm: rename as columnofrows.
-- October 10, 1982 2:07 pm: get action and badformatloadfile from structurenodes, rather than structurenode.
-- October 11, 1982 3:14 pm: CreateGGCellArray and LoadGCellArray now come from GCell.
-- October 14, 1982 3:58 pm: displayer now passed as an argument through crearte and load. Create and Load now exported through GCell.
-- T: add 2 ref any arguments to ActColumnOfRows, ActRowOfSlots, and ActSlot
-- November 3, 1982 3:29 pm: add Substitute to logical node procs.
-- November 3, 1982 5:33 pm: add Get Set, Column, Row, Slot.
-- RTE: February 11, 1983 2:21 pm: conversion to 4.0, change calls on GetAtom to NARROW[GetRefAny[]].
-- February 25, 1983 3:27 pm: replace displayNode and Logical node with StructureNode
-- February 27, 1983 1:00 pm: completed the change. Now only one reference to columns, rows, or slots; and that is a structure node. display actions on the structure node result in calls on the display routines of the associated display array structure node. Total time spent on this fix up about 2 hours. Note: still one back pointer from the associated display arrays.
-- February 27, 1983 3:27 pm: owing to discovery of the need for GCellarray to store two items in each displayArray crosspoint, have to change all calls on Get and SetElement from this module.
-- February 28, 1983 2:15 pm: add dummy note coordinates procedure.
-- RTE: March 1, 1983 9:48 am: slots must give their slotSn to the GCell holding the text of "slot", otherwise actions can not occur.
-- March 8, 1983 11:34 am: add UnPaint calls.
-- RTE: March 8, 1983 12:58 pm: nobody propogated NoteCoordinates to parallel display array.
-- Change: June 28, 1984 3:11:27 pm PDT: add HCellArrays
-- Change: July 3, 1984 9:39:23 am PDT: add code to save and load HCell arrays.
-- Change: July 10, 1984 11:06:47 am PDT: add code to handle page ids.
-- July 19, 1984 5:56:53 pm PDT: begin to install code to handle array groups.