-- EditToolBuilderImpl.mesa; Edited by Paxton on November 5, 1982 2:07 pm
-- Edited by McGregor on September 1, 1982 3:56 pm
Last Edited by: Plass, April 15, 1983 12:53 pm
DIRECTORY
EditToolBuilder,
EditToolPrivate,
Buttons,
Containers,
IO,
Labels,
MessageWindow,
Rope,
Rules,
TEditDocument,
TEditInput,
TEditOps,
TEditSelection,
TextEdit,
TextLooks,
TextNode,
VFonts,
ViewerClasses,
ViewerOps,
ViewerSpecs,
ViewerTools;
EditToolBuilderImpl: CEDAR PROGRAM
IMPORTS EditToolPrivate, Buttons, Containers, IO, Labels, MessageWindow, Rope, Rules, TEditInput, TEditOps, TEditSelection, TextEdit, TextNode, VFonts, ViewerOps, ViewerSpecs, ViewerTools
EXPORTS EditToolBuilder, EditToolPrivate =
{ OPEN ViewerSpecs, EditToolBuilder, EditToolPrivate;
----------------------------
ToNext:
PUBLIC
PROC [info: Layout, bigGap:
BOOLEAN ←
FALSE] = {
OPEN info;
-- change entryLeft and heightSoFar to next "line" in container
entryLeft ← initLeft;
heightSoFar ← heightSoFar + entryHeight + entryVSpace;
IF bigGap THEN heightSoFar ← heightSoFar + entryVSpace/2 };
ToMiddle:
PUBLIC
PROC [info: Layout] = {
OPEN info;
-- change entryLeft to middle of container
entryLeft ← 190 };
BuildBox:
PROC [info: Layout, proc: Buttons.ButtonProc, clientData:
REF
ANY ←
NIL, fork:
BOOL ←
FALSE, gapAfter:
BOOL ←
TRUE, border:
BOOL ←
FALSE]
RETURNS [button: Buttons.Button] = { OPEN info;
button ← Buttons.Create[
info: [name:
NIL, parent: container, wx: entryLeft, wy: heightSoFar+2,
ww: entryHeight-2, wh: entryHeight-2, border: border],
proc: proc, clientData: clientData, fork: fork, paint: FALSE];
entryLeft ← entryLeft + button.ww;
IF gapAfter THEN entryLeft ← entryLeft + gapSize;
};
BuildButton:
PUBLIC
PROC [info: Layout, name: Rope.
ROPE, proc: Buttons.ButtonProc,
clientData:
REF
ANY ←
NIL, fork:
BOOL ←
FALSE, gapAfter:
BOOL ←
TRUE, border:
BOOL ←
FALSE]
RETURNS [button: Buttons.Button] = { OPEN info;
button ← Buttons.Create[
info: [name: name, parent: container, wx: entryLeft, wy: heightSoFar, border: border],
proc: proc, clientData: clientData, fork: fork, paint: FALSE];
entryLeft ← entryLeft + button.ww;
IF gapAfter THEN entryLeft ← entryLeft + gapSize;
};
BuildLabel:
PUBLIC
PROC [info: Layout, name: Rope.
ROPE, width:
INTEGER ← 0]
RETURNS [label: Labels.Label] = { OPEN info;
label ← Labels.Create[info: [name: name, parent: container, border:
FALSE,
wx: entryLeft, wy: heightSoFar+1, ww: width, wh: entryHeight], paint: FALSE];
entryLeft ← entryLeft + label.ww;
};
----------------------------
BuildPair:
PUBLIC
PROC [info: Layout, proc: Buttons.ButtonProc, flag:
BOOL, l1, l2: Rope.
ROPE,
clientData: REF ANY ← NIL, fork: BOOL ← FALSE]
RETURNS [label: Labels.Label, button: Buttons.Button] = { OPEN info;
w:
INTEGER =
MAX[
VFonts.StringWidth[l1],
VFonts.StringWidth[l2]];
button ← BuildBox[info, proc, clientData, fork, FALSE, TRUE];
label ← BuildLabel[info, IF flag THEN l1 ELSE l2, w+15];
};
----------------------------
BuildTriple:
PUBLIC
PROC [info: Layout, proc: Buttons.ButtonProc, state: [0..2], l0, l1, l2: Rope.
ROPE,
clientData: REF ANY ← NIL, fork: BOOLEAN ← FALSE]
RETURNS [label: Labels.Label, button: Buttons.Button] = { OPEN info;
w:
INTEGER =
MAX[
VFonts.StringWidth[l0],
VFonts.StringWidth[l1],
VFonts.StringWidth[l2]];
labelRopes: ARRAY [0..2] OF Rope.ROPE = [l0,l1,l2];
button ← BuildBox[info, proc, clientData, fork, FALSE, TRUE];
label ← BuildLabel[info, labelRopes[state], w+15];
};
----------------------------
DataFieldButton:
PUBLIC
PROC [arg: ViewerClasses.Viewer, clear:
BOOLEAN] = {
IF clear THEN ViewerTools.SetContents[arg, NIL]; -- clear contents of field
ViewerTools.SetSelection[arg, NIL]; -- make pending delete selection of field contents
};
SavePSel:
PUBLIC
PROC = {
IF ~EditToolPSel[] THEN prior^ ← TEditOps.GetSelData[]^ }; -- save it for later
FixPSel:
PUBLIC
PROC = {
-- if pSel is in data field, restore prior
IF EditToolPSel[]
AND TEditInput.CheckSelection[prior]
THEN
TEditSelection.MakeSelection[prior, primary] };
EditToolPSel:
PROC
RETURNS [
BOOL] = {
pSel: TEditDocument.Selection = TEditOps.GetSelData[];
RETURN [pSel # NIL AND pSel.viewer # NIL AND pSel.viewer.parent=editTool] };
prior: TEditDocument.Selection ← NEW [TEditDocument.SelectionRec];
BuildDataFieldPair:
PUBLIC
PROC [info: Layout, buttonRope: Rope.
ROPE, buttonProc: Buttons.ButtonProc,
clientData: REF ANY ← NIL, lines: CARDINAL ← 2]
RETURNS [button: Buttons.Button, arg: ViewerClasses.Viewer] = { OPEN info;
fudge: CARDINAL = 1;
button ← BuildButton[info: info, name: buttonRope, proc: buttonProc, clientData: clientData,
fork: FALSE, gapAfter: FALSE];
arg ← ViewerOps.CreateViewer[flavor: $Text, info: [parent: container,
wx: entryLeft, wy: heightSoFar+fudge,
ww: openRightWidth-entryLeft-5,
wh: entryHeight*lines,
border: FALSE], paint: FALSE];
heightSoFar ← heightSoFar + entryHeight*lines;
entryLeft ← initLeft;
Containers.ChildXBound[container, arg];
};
----------------------------
GetDataNode:
PUBLIC
PROC [arg: ViewerClasses.Viewer]
RETURNS [TextNode.RefTextNode] = {
tdd: TEditDocument.TEditDocumentData = NARROW[arg.data];
IF tdd=NIL THEN RETURN [NIL];
RETURN [TextNode.NarrowToTextNode[TextNode.FirstChild[tdd.text]]] };
GetDataLooks:
PUBLIC
PROC [arg: ViewerClasses.Viewer, name: Rope.
ROPE]
RETURNS [looks: TextLooks.Looks] = {
node: TextNode.RefTextNode ← GetDataNode[arg];
size: TextNode.Offset = TextEdit.Size[node];
IF size=0 THEN RETURN [TextLooks.noLooks];
looks ← TextEdit.FetchLooks[node,0];
FOR i: TextNode.Offset
IN [1..size)
DO
IF TextEdit.FetchLooks[node,i]#looks
THEN {
OPEN MessageWindow;
Append[name,TRUE];
Append[" does not have uniform looks. Using looks from first char."];
Blink[]; EXIT };
ENDLOOP };
BadNumber: PUBLIC SIGNAL = CODE;
GetInt:
PUBLIC
PROC [arg: ViewerClasses.Viewer]
RETURNS [num:
INT] = {
rope: Rope.ROPE ← TextEdit.GetRope[GetDataNode[arg]];
h: IO.Handle ← IO.CreateInputStreamFromRope[rope];
num ← IO.GetInt[h ! IO.Error => GOTO BadNum];
EXITS BadNum => SIGNAL BadNumber
};
SetInt:
PUBLIC
PROC [arg: ViewerClasses.Viewer, num:
INT] = {
h: IO.Handle ← IO.CreateOutputStreamToRope[];
IO.Put[h,IO.int[num]];
TEditOps.SetTextContents[arg, IO.GetOutputStreamRope[h]];
};
ConvertList:
PUBLIC
PROC [list:
LIST
OF
REF
ANY]
RETURNS [Rope.
ROPE] = {
OPEN
IO;
h: IO.Handle ← CreateOutputStreamToRope[];
doingChars: BOOLEAN ← FALSE;
nospace: BOOLEAN ← TRUE;
Space:
PROC = {
IF doingChars
THEN {
-- end of string
PutChar[h, '"]; doingChars ← FALSE };
IF nospace THEN nospace ← FALSE ELSE PutChar[h,' ] };
AddChar:
PROC [c:
CHARACTER] = {
IF ~doingChars
THEN {
-- start of string
Space[]; PutChar[h, '"]; doingChars ← TRUE };
SELECT c
FROM
'', '", '\\ => PutChar[h, '\\];
ENDCASE;
PutChar[h, c] };
{ ENABLE UNWIND => h.Close[];
FOR l:
LIST
OF
REF
ANY ← list, l.rest
UNTIL l=
NIL
DO
WITH l.first
SELECT
FROM
x: ATOM => { Space[]; Put[h,atom[x]] };
x: REF INT => { Space[]; Put[h,int[x^]] };
x: REF CHARACTER => AddChar[x^];
x:
ROPE => {
AddC:
SAFE
PROC [c:
CHAR]
RETURNS [
BOOL] = {
AddChar[c]; RETURN [FALSE] };
[] ← Rope.Map[base: x, action: AddC] };
x:
REF
TEXT => {
FOR i: NAT IN [0..x.length) DO AddChar[x[i]]; ENDLOOP };
ENDCASE;
ENDLOOP;
IF doingChars THEN PutChar[h, '"];
RETURN [GetOutputStreamRope[h]];
}};
----------------------------
HRule:
PUBLIC
PROC [info: Layout, thickness:
CARDINAL ← 1, gapAbove, gapBelow:
BOOLEAN ←
TRUE] = {
OPEN info;
IF gapAbove THEN heightSoFar ← heightSoFar + entryVSpace*2;
[] ← Rules.Create[info: [parent: container, wx: 0, wy: heightSoFar, ww: openRightWidth,
wh: thickness], paint: FALSE];
heightSoFar ← heightSoFar + thickness;
IF gapBelow THEN heightSoFar ← heightSoFar + entryVSpace*2;
};
}.
..