TSViewerImpl.mesa
Michael Plass, May 2, 1983 9:55 am
DIRECTORY
Ascii,
Atom,
Buttons,
CIFS,
Commander,
Containers,
Convert,
EditSpanSupport,
FileIO,
IO,
Icons,
Labels,
Menus,
NodeStyle,
PieViewers,
PressPrinter,
PressScreen,
Process,
PseudoCursors,
PutGet,
Rope,
SafeStorage,
SirPress,
TEditDocument,
TEditInput,
TextNode,
TSTranslate,
TSGlue,
TSJaMPageBuilder,
TSObject,
TSOutput,
TSOutputPress,
TSViewer,
UserCredentials,
UserProfile,
ViewerClasses,
ViewerOps,
ViewerSpecs,
ViewerTools;
TSViewerImpl: CEDAR MONITOR
IMPORTS Buttons, CIFS, Commander, Containers, Convert, EditSpanSupport, FileIO, Icons, IO, Labels, Menus, PieViewers, PressPrinter, PressScreen, Process, PutGet, PseudoCursors, Rope, SafeStorage, TEditInput, TextNode, TSJaMPageBuilder, TSTranslate, TSObject, TSOutput, TSOutputPress, UserCredentials, UserProfile, ViewerOps, ViewerTools EXPORTS TSViewer =
BEGIN
ROPE: TYPE = Rope.ROPE;
indent: INTEGER = 4;
baseline: INTEGER = 16;
rightIcon: Icons.IconFlavor ← Icons.NewIconFromFile["TSetter.icons", 0];
leftIcon: Icons.IconFlavor ← Icons.NewIconFromFile["TSetter.icons", 2];
Tool: PUBLIC TYPE = REF ToolRec;
ToolRec:
PUBLIC
TYPE =
RECORD [
stop: BOOLEAN ← FALSE,
stopSending: BOOLEAN ← FALSE,
selfDestruct: BOOLEAN ← FALSE,
pause: BOOLEAN ← FALSE,
idle: CONDITION,
process: PROCESS ← NIL,
nameButton: ViewerClasses.Viewer ← NIL,
nameBox: ViewerClasses.Viewer ← NIL,
currentName: ROPE,
prunedCurrentName: ROPE,
pressName: ROPE,
messageBox: ViewerClasses.Viewer ← NIL,
messageRope: ROPE ← NIL,
messageLog: ROPE ← NIL,
miniDisplay: PseudoCursors.PseudoCursor ← NIL,
pie: PieViewers.PieViewer ← NIL,
singleOutputFile: BOOLEAN ← FALSE,
debug: BOOLEAN ← FALSE,
tempPressLabel: ViewerClasses.Viewer ← NIL,
tempPress: BOOLEAN ← FALSE,
serverName: ROPE,
serverPie: PieViewers.PieViewer ← NIL,
serverMsg: ViewerClasses.Viewer ← NIL,
serverProcess: PROCESS ← NIL,
serverIdle: CONDITION,
copiesBox: ViewerClasses.Viewer ← NIL
];
NewButton: Menus.MenuProc = {
IF mouseButton=yellow THEN ShowMessage[NARROW[clientData], doc[New]]
ELSE {
selectedViewer: ViewerClasses.Viewer ← ViewerTools.GetSelectedViewer[];
server:
ROPE ←
IF selectedViewer = NIL OR selectedViewer.class.get = NIL THEN NIL
ELSE NARROW[selectedViewer.class.get[selectedViewer, $SelChars]];
IF server.Length < 2 THEN server ← NIL;
[] ← NewTool[server];
};
};
doc: REF ARRAY MenuCode OF ROPE ← InitDoc[];
MenuCode: TYPE = {New, RightScreen, Screen, LeftScreen, All, Print, Get, StopSending, Stop, Pause};
InitDoc:
PROC
RETURNS [d:
REF ARRAY MenuCode
OF
ROPE] = {
d ← NEW[ARRAY MenuCode OF ROPE];
d[New] ← "New: Create a new typesetter tool for selected server.";
d[RightScreen] ← ">: Print the right side of the screen.";
d[Screen] ← "Screen: Print the whole screen.";
d[LeftScreen] ← "<: Print the left side of the screen.";
d[All] ← "All: Print all the documents in one press file.";
d[Print] ← "Print: Print the documents named above.";
d[Get] ← "Get: Add selected documents to the document queue.";
d[StopSending] ← "StopSending: Abort transmission to the printer.";
d[Stop] ← "Stop: Stop typesetting as soon as possible.";
d[Pause] ← "Pause: Stop typesetting at end of current document.";
};
NewTool:
PUBLIC
ENTRY
PROCEDURE [server:
ROPE]
RETURNS [data: Tool ←
NEW [ToolRec]] =
BEGIN ENABLE UNWIND => NULL;
curY: INTEGER ← indent/2;
NextY: PROC RETURNS [y:NAT] = {y ← curY ← curY+baseline};
container: ViewerClasses.Viewer ←
ViewerOps.CreateViewer[
flavor: $TSetter,
info: [name:
IF server.Length = 0
THEN "TSetter"
ELSE server,
column: right, scrollable: FALSE
],
paint: FALSE
];
menu: Menus.Menu ← MakeMenu[];
MakeMenu:
PROC
RETURNS [m: Menus.Menu] = {
m ← Menus.CreateMenu[];
InsertMenuEntry[
menu: m,
name: "New",
proc: NewButton,
fork: FALSE,
clientData: data,
documentation: doc[New]
];
InsertMenuEntry[
menu: m,
name: ">",
proc: RightScreenButton,
fork: TRUE,
clientData: data,
documentation: doc[RightScreen]
];
InsertMenuEntry[
menu: m,
name: "Screen",
proc: ScreenButton,
fork: TRUE,
clientData: data,
documentation: doc[Screen]
];
InsertMenuEntry[
menu: m,
name: "<",
proc: LeftScreenButton,
fork: TRUE,
clientData: data,
documentation: doc[LeftScreen]
];
InsertMenuEntry[
menu: m,
name: "All",
proc: AllButton,
fork: FALSE,
clientData: data,
documentation: doc[All]
];
InsertMenuEntry[
menu: m,
name: "Print",
proc: PrintButton,
fork: FALSE,
clientData: data,
documentation: doc[Print]
];
InsertMenuEntry[
menu: m,
name: "Get",
proc: GetSelectionButton,
fork: FALSE,
clientData: data,
documentation: doc[Get]
];
InsertMenuEntry[
menu: m,
name: "StopSending",
proc: StopSendingButton,
fork: FALSE,
clientData: data,
documentation: doc[StopSending]
];
InsertMenuEntry[
menu: m,
name: "Stop",
proc: StopButton,
fork: FALSE,
clientData: data,
documentation: doc[Stop]
];
InsertMenuEntry[
menu: m,
name: "Pause",
proc: PauseButton,
fork: FALSE,
clientData: data,
documentation: doc[Pause]
];
};
InsertMenuEntry:
PROC [menu: Menus.Menu, name: Rope.
ROPE, proc: Menus.MenuProc, fork:
BOOL ←
FALSE, row:
INTEGER ← 0, clientData:
REF
ANY ←
NIL, copy:
BOOL ←
FALSE, documentation: Rope.
ROPE ←
NIL, guarded:
BOOL ←
FALSE] = {
menuEntry: Menus.MenuEntry ← Menus.CreateEntry[name: name, proc: proc, clientData: clientData, documentation: documentation, fork: fork, guarded: guarded];
Menus.InsertMenuEntry[menu, menuEntry];
};
ViewerOps.SetMenu[container, menu];
data.nameButton ← Buttons.Create[
info:[name: "Documents: ", wx: indent, wy: curY, parent: container, border: FALSE],
clientData: data,
proc: NameButton,
fork: FALSE,
paint: FALSE,
documentation: "Select the document name window. The right button empties it first."
];
PlaceChild[data.nameButton, 0, 0, TRUE];
data.nameBox ← ViewerTools.MakeNewTextViewer[
info:[wx: data.nameButton.wx + data.nameButton.ww, wy: curY+1, ww: 4*72, wh: data.nameButton.wh,
parent: container, scrollable: TRUE, border: FALSE],
paint: FALSE
];
PlaceChild[data.nameBox, 0, 0, FALSE];
Containers.ChildXBound[container, data.nameBox]; -- Let the text box grow to the right
data.pie ← PieViewers.Create[parent: container, x: indent, y: NextY[]];
PlaceChild[data.pie, 1, 0, TRUE];
data.miniDisplay ← PseudoCursors.Create[parent: container, x: indent+20, y: curY];
PlaceChild[data.miniDisplay, 1, 0, TRUE];
data.messageBox ← ViewerTools.MakeNewTextViewer[
info: [wx: indent + 40, wy: curY, ww: 350, wh: 16, parent: container, scrollable: TRUE, border: TRUE],
paint: FALSE
];
PlaceChild[data.messageBox, 1, 0, FALSE];
ViewerTools.InhibitUserEdits[data.messageBox];
data.serverName ← server;
data.serverPie ← PieViewers.Create[parent: container, x: indent, y: NextY[], total: 1.0];
PlaceChild[data.serverPie, 2, 0, TRUE];
data.serverMsg ← ViewerTools.MakeNewTextViewer[
info: [wx: indent + 40, wy: curY, ww: 350, wh: 16, parent: container, scrollable: TRUE, border: TRUE],
paint: FALSE
];
PlaceChild[data.serverMsg, 2, 0, FALSE];
ViewerTools.InhibitUserEdits[data.serverMsg];
data.copiesBox ← Buttons.Create[
info:[name: "Copies: ", wx: indent, wy: NextY[], parent: container, border: FALSE],
clientData: data,
proc: CopiesButton,
fork: FALSE,
paint: FALSE,
documentation: "Set the number of copies. Gets reset to 1 after each file is sent."
];
PlaceChild[data.copiesBox, 3, 0, TRUE];
data.copiesBox ← ViewerTools.MakeNewTextViewer[
info:[wx: data.copiesBox.wx + data.copiesBox.ww, wy: curY+1, ww: 4*72, wh: data.nameButton.wh,
parent: container, scrollable: FALSE, border: FALSE],
paint: FALSE
];
PlaceChild[data.copiesBox, 3, 0, TRUE];
data.tempPressLabel ← Buttons.Create[
info:[name: "Temporary Press Files: ", wx: indent , wy: NextY[], parent: container, border: FALSE],
clientData: data,
proc: TempPressButton,
fork: FALSE,
paint: FALSE
];
PlaceChild[data.tempPressLabel, 3, 1, TRUE];
data.tempPressLabel ← Labels.Create[
info:[name: "FALSE", wx: data.tempPressLabel.wx+data.tempPressLabel.ww , wy: curY, parent: container, border: FALSE],
paint: FALSE
];
PlaceChild[data.tempPressLabel, 3, 1, TRUE];
TempPress[data, UserProfile.Boolean["Hardcopy.TemporaryPressFiles"]];
Containers.ChildXBound[container, data.copiesBox];
ViewerTools.SetContents[data.copiesBox, "1"];
ViewerOps.SetOpenHeight[container, curY+indent/2+baseline];
ViewerOps.PaintViewer[container, all];
ShowMessage[data, "Ready"];
END;
PositionInfoRec:
TYPE =
RECORD [
nVar: NAT, -- number of stretchy children above this one
nFixed: NAT, -- number of fixed-height children above this one
fixed: BOOLEAN -- true if this child is fixed in height
];
PlaceChild:
PROC [viewer: ViewerClasses.Viewer, nVar, nFixed:
NAT, fixed:
BOOLEAN ←
TRUE] = {
ViewerOps.AddProp[viewer, $TSViewerPositionInfo, NEW[PositionInfoRec ← [nVar, nFixed, fixed]]];
};
SetViewerPosition:
PROC [viewer: ViewerClasses.Viewer, x,y,w,h:
INTEGER] =
BEGIN OPEN viewer;
vbs: INTEGER = IF border THEN ViewerSpecs.windowBorderSize ELSE 0;
wx ← x; wy ← y; ww ← w; wh ← h;
ch ← wh - (vbs+vbs) - (IF column=static OR parent#NIL THEN 0 ELSE ViewerSpecs.captionHeight);
IF menu#NIL THEN ch ← ch - (Menus.GetNumberOfLines[menu]*ViewerSpecs.menuHeight);
cx ← wx + vbs + (IF scrollable THEN ViewerSpecs.scrollBarW ELSE 0);
cy ← wy + vbs;
cw ← ww - (cx-wx) - vbs;
END;
TSViewerPaint: ViewerClasses.PaintProc = {
IF self.iconic
THEN {
self.icon ← IF self.column = left THEN leftIcon ELSE rightIcon;
ViewerOps.PaintViewer[viewer: self, hint: all, clearClient: FALSE];
self.icon ← self.class.icon;
}
ELSE {
varbaseline: NAT ← MAX[baseline, (self.ch-indent-2*baseline)/3];
FOR v: ViewerClasses.Viewer ← self.child, v.sibling
UNTIL v=
NIL
DO
positionInfo: REF PositionInfoRec ← NARROW[ViewerOps.FetchProp[v,$TSViewerPositionInfo]];
IF positionInfo#
NIL
THEN SetViewerPosition[viewer: v, x: v.wx,
y: varbaseline*positionInfo.nVar + baseline*positionInfo.nFixed + indent/2,
w: v.ww,
h: IF positionInfo.fixed THEN baseline ELSE varbaseline
];
ENDLOOP;
depend on containerPaint to reset the paint cache, since there are bound children.
containerPaint[self, context, whatChanged, clear];
};
};
ShowMessage:
PROC [tool: Tool, msg:
ROPE] = {
tool.messageLog ← msg ← tool.messageLog.Cat["\n", msg];
ViewerTools.SetContents[tool.messageBox, msg];
[] ← tool.messageBox.class.scroll[tool.messageBox, thumb, 100];
};
StopButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[Stop]]
ELSE Stop[tool]
};
Stop:
PUBLIC
ENTRY
PROCEDURE [tool: Tool] = {
ENABLE
UNWIND =>
NULL;
tool.stop ← TRUE;
};
PauseButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[Pause]]
ELSE Pause[tool]
};
Pause:
PUBLIC
ENTRY
PROCEDURE [tool: Tool] = {
ENABLE
UNWIND =>
NULL;
tool.pause ← TRUE;
};
StopSendingButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[StopSending]]
ELSE StopSending[tool]
};
StopSending:
PUBLIC
ENTRY
PROCEDURE [tool: Tool] = {
ENABLE
UNWIND =>
NULL;
tool.stopSending ← TRUE;
};
NameButton:
ENTRY Buttons.ButtonProc = {
ENABLE
UNWIND =>
NULL;
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton = blue THEN ViewerTools.SetContents[tool.nameBox, ""];
ViewerTools.SetSelection[tool.nameBox];
};
Copies:
PUBLIC
PROCEDURE [tool: Tool, copies:
NAT] = {
ViewerTools.SetContents[tool.copiesBox, Convert.ValueToRope[[signed [copies]]]];
};
CopiesButton: Buttons.ButtonProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton = blue THEN ViewerTools.SetContents[tool.copiesBox, ""];
ViewerTools.SetSelection[tool.copiesBox];
};
TempPress:
PUBLIC
PROCEDURE [tool: Tool, temporaryPressFiles:
BOOLEAN] = {
tool.tempPress ← temporaryPressFiles;
Labels.Set[tool.tempPressLabel, IF tool.tempPress THEN "TRUE" ELSE "FALSE"];
};
TempPressButton: Buttons.ButtonProc = {
tool: Tool ← NARROW[clientData];
tool.tempPress ← NOT tool.tempPress;
tool.selfDestruct ← FALSE;
Labels.Set[tool.tempPressLabel, IF tool.tempPress THEN "TRUE" ELSE "FALSE"];
};
GetFirstName:
ENTRY
PROC [tool: Tool]
RETURNS [gotIt:
BOOLEAN ←
TRUE] = {
ENABLE UNWIND => NULL;
rope: ROPE ~ ViewerTools.GetContents[tool.nameBox];
length: NAT ~ rope.Length;
i, start: NAT ← 0;
c: CHAR;
IF tool.pause
OR tool.stop
THEN
{tool.process ← NIL; NOTIFY tool.idle; RETURN[FALSE]};
WHILE i<length
AND ((c ← rope.Fetch[i]) = Ascii.
SP
OR c=Ascii.
CR
OR c=Ascii.
TAB
OR c=',
OR c=';)
DO i ← i+1 ENDLOOP;
start ← i;
UNTIL i>=length
OR (c ← rope.Fetch[i]) = Ascii.
SP
OR c=Ascii.
CR
OR c=Ascii.
TAB
OR c=',
OR c=';
DO i ← i+1 ENDLOOP;
tool.currentName ← rope.Substr[start: start, len: i-start];
WHILE i<length
AND ((c ← rope.Fetch[i]) = Ascii.
SP
OR c=Ascii.
CR
OR c=Ascii.
TAB
OR c=',
OR c=';)
DO i ← i+1 ENDLOOP;
ViewerTools.SetContents[tool.nameBox, rope.Substr[start: i]];
IF tool.currentName.Length = 0
THEN
{tool.process ← NIL; NOTIFY tool.idle; RETURN[FALSE]};
};
GetDocument:
PROC [tool: Tool]
RETURNS [node: TextNode.Ref] =
BEGIN
viewer: ViewerClasses.Viewer;
errorMsg: ROPE ← NIL;
viewer ← ViewerOps.FindViewer[tool.currentName];
IF viewer =
NIL
OR
NOT
ISTYPE[viewer.data, TEditDocument.TEditDocumentData]
THEN
node ← PutGet.FromFile[tool.currentName ! CIFS.Error => TRUSTED {errorMsg ← error; CONTINUE}]
ELSE {
-- make a copy of the tree.
root: TextNode.Ref ← NARROW[viewer.data, TEditDocument.TEditDocumentData].text;
root ← TextNode.Root[
EditSpanSupport.CopySpan[
-- adds an extra root node
TextNode.MakeNodeSpan[
root,
TextNode.LastWithin[root]
]
]
.start.node
];
node ← TextNode.FirstChild[root]; -- get rid of the extra root node
node.next ← NIL; root.child ← NIL; -- to help out the garbage collector
};
IF errorMsg # NIL THEN ShowMessage[tool, errorMsg];
END;
LetterOrDigit:
PROC [c:
CHARACTER]
RETURNS [
BOOLEAN] =
{RETURN[c IN ['A .. 'Z] OR c IN ['a .. 'z] OR c IN ['0 .. '9] OR c='-]};
GetPressName:
PROC [tool: Tool]
RETURNS [pressName:
ROPE] =
BEGIN
nameLen: INT ← 0;
pressName ← tool.currentName;
FOR i:
NAT
DECREASING
IN [0..pressName.Length)
DO
c: CHAR ← pressName.Fetch[i];
IF c = '/
OR c = '>
THEN {
pressName ← pressName.Substr[i+1];
EXIT;
};
ENDLOOP;
WHILE nameLen<pressName.Length
AND LetterOrDigit[pressName.Fetch[nameLen]]
DO
nameLen ← nameLen+1 ENDLOOP;
IF nameLen = 0 THEN pressName ← "NoName";
IF tool.singleOutputFile THEN pressName ← pressName.Substr[0, nameLen].Concat[".etc"];
tool.prunedCurrentName ← pressName;
IF pressName.Substr[start: nameLen].Equal[".Tioga", FALSE] THEN pressName ← pressName.Substr[0, nameLen];
pressName ← pressName.Concat[".press"];
IF tool.tempPress THEN pressName ← pressName.Concat["$"];
IF pressName.Equal[tool.pressName]
THEN {
WaitForSendIdle[tool];
ViewerTools.SetContents[tool.serverMsg, ""]
}
END;
PrintButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[Print]]
ELSE Print[tool]
};
Print:
PUBLIC
ENTRY
PROCEDURE [tool: Tool] =
BEGIN ENABLE UNWIND => NULL;
tool.pause ← tool.stop ← tool.stopSending ← FALSE;
IF tool.process=NIL THEN TRUSTED {Process.Detach[tool.process ← FORK TypesetProcess[tool]]};
END;
AllButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[All]]
ELSE PrintAll[tool]};
PrintAll:
PUBLIC
PROCEDURE [tool: Tool] = {
tool.singleOutputFile ← TRUE;
Print[tool];
};
LeftScreenButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[LeftScreen]]
ELSE Screen[tool, leftSide]
};
ScreenButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[Screen]]
ELSE Screen[tool, bothSides]
};
RightScreenButton: Menus.MenuProc = {
tool: Tool ← NARROW[clientData];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[RightScreen]]
ELSE Screen[tool, rightSide]
};
Screen:
PUBLIC
ENTRY
PROCEDURE [tool: Tool, side: PressScreen.Side] = {
ENABLE
UNWIND =>
NULL;
pressName: ROPE;
TRUSTED {pressName ← PressScreen.NewPressName[]};
IF tool.tempPress THEN pressName ← pressName.Concat["$"];
TRUSTED {PressScreen.PressScreen[pressName, side]};
ShowMessage[tool, pressName.Concat[" completed"]];
IF
NOT tool.debug
AND
NOT tool.stop
AND tool.serverName.Length # 0
THEN {
UNTIL tool.serverProcess = NIL DO WAIT tool.serverIdle ENDLOOP;
tool.stopSending ← FALSE;
TRUSTED {Process.Detach[tool.serverProcess ← FORK SendingProcess[tool, pressName]]};
};
};
cursorProc: SirPress.CursorProc = CHECKED {PseudoCursors.Set[NARROW[clientData], bits]};
TypesetProcess:
PROC [tool: Tool] =
BEGIN
didNothing: BOOLEAN ← TRUE;
outputHandle: TSOutput.Handle ← NIL;
TRUSTED {Process.SetPriority[Process.priorityBackground]};
WHILE GetFirstName[tool]
DO
node: TextNode.Ref;
ShowMessage[tool, tool.currentName];
IF PressPrinter.IsAPressFile[tool.currentName]
THEN {
IF outputHandle # NIL THEN {FinishUp[tool, outputHandle]; outputHandle ← NIL};
tool.pressName ← tool.prunedCurrentName ← tool.currentName;
IF
NOT tool.debug
AND
NOT tool.stop
AND tool.serverName.Length # 0
THEN
StartSending[tool];
}
ELSE {
node ← GetDocument[tool];
IF node =
NIL
THEN {
tool.stop ← TRUE;
}
ELSE {
IF outputHandle = NIL THEN outputHandle ← CreateOutputHandle[tool, node, NEW[SirPress.CursorObjectRec ← [cursorProc: cursorProc, clientData: tool.miniDisplay]]];
FormatOneFile[tool, node, outputHandle ! ABORTED => CONTINUE];
IF NOT tool.singleOutputFile THEN {FinishUp[tool, outputHandle]; outputHandle ← NIL};
TEditInput.FreeTree[node];
};
};
didNothing ← FALSE;
ENDLOOP;
IF outputHandle # NIL THEN {FinishUp[tool, outputHandle]; outputHandle ← NIL};
tool.singleOutputFile ← FALSE;
SafeStorage.ReclaimCollectibleObjects[];
SafeStorage.TrimZone[TSObject.pZone];
SafeStorage.TrimZone[TSObject.qZone];
IF didNothing THEN ShowMessage[tool, "Ready"];
IF tool.selfDestruct THEN WaitForSendIdle[tool];
IF tool.stop OR tool.stopSending THEN tool.selfDestruct ← FALSE;
IF tool.selfDestruct THEN ViewerOps.DestroyViewer[tool.messageBox.parent];
END;
QueueRequest:
PUBLIC
ENTRY
PROCEDURE [tool: Tool, documentName:
ROPE] = {
ENABLE UNWIND => NULL;
queue: ROPE ← ViewerTools.GetContents[tool.nameBox];
IF queue.Length = 0 THEN queue ← documentName
ELSE queue ← queue.Cat[" ", documentName];
ViewerTools.SetContents[tool.nameBox, queue];
};
GetSelectionButton: Menus.MenuProc =
BEGIN
tool: Tool ← NARROW[clientData, Tool];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[Get]]
ELSE {
selectedViewer: ViewerClasses.Viewer ← ViewerTools.GetSelectedViewer[];
sourceName:
ROPE ←
IF selectedViewer = NIL OR selectedViewer.class.get = NIL THEN NIL
ELSE NARROW[selectedViewer.class.get[selectedViewer, $SelChars]];
IF sourceName.Length <=1
THEN {
IF (selectedViewer =
NIL)
THEN
{ShowMessage[tool, "Selection not in text viewer"]; sourceName ← NIL}
ELSE sourceName ← selectedViewer.name;
};
QueueRequest[tool, sourceName];
};
END;
CreateOutputHandle:
PROCEDURE [tool: Tool, node: TextNode.Ref, cursorObject: SirPress.CursorObject]
RETURNS [outputHandle: TSOutput.Handle] = {
stream: IO.STREAM ← FileIO.Open[tool.pressName ← GetPressName[tool], overwrite];
inputLength: INT ← TextNode.LocNumber[TextNode.LastLocWithin[node], 0];
stream.SetLength[MIN[1024, inputLength+inputLength-inputLength/3]];
IF node=NIL THEN ERROR;
outputHandle ← TSOutputPress.CreateWithCursor[
stream: stream,
documentName: tool.prunedCurrentName,
cursorObject: cursorObject
];
};
FinishUp:
PROC [tool: Tool, outputHandle: TSOutput.Handle] = {
msg: ROPE;
IF NOT tool.debug THEN msg ← tool.pressName ELSE msg ← NIL;
IF tool.stop THEN msg ← msg.Concat[" aborted"]
ELSE msg ← msg.Concat[" completed"];
outputHandle.Close;
ShowMessage[tool, msg];
IF NOT tool.debug AND NOT tool.stop AND tool.serverName.Length # 0 THEN StartSending[tool];
};
FormatOneFile:
PROC [tool: Tool, node: TextNode.Ref, outputHandle: TSOutput.Handle] = {
ENABLE TSTranslate.FontNotFound =>
TRUSTED {
ShowMessage[tool, Rope.Cat["Unable to find font ", fontName, "; position including comment nodes = ", Convert.ValueToRope[[signed [location]]]]];
tool.stop ← TRUE;
GOTO Quit
};
aborted: BOOLEAN;
isAborted: PROC RETURNS [BOOLEAN] = {RETURN[tool.stop]};
progressProc: TSTranslate.ProgressProc = {
PieViewers.Set[tool.pie, 100.0-progress];
IF tool.stop THEN ERROR Process.Aborted
};
galley: TSObject.ItemList;
style: NodeStyle.Ref;
IF tool.singleOutputFile
THEN
ShowMessage[tool, Rope.Concat["Typesetting member ", tool.currentName]]
ELSE ShowMessage[tool, Rope.Concat["Typesetting ", tool.currentName]];
TRUSTED {
[galley, style] ← TSTranslate.TreeToVlist[node, progressProc];
aborted ← TSJaMPageBuilder.RunPageBuilder[
galley: galley,
style: style,
output: outputHandle,
abortCheckProc: isAborted,
documentName: tool.currentName
]};
tool.stop ← tool.stop OR aborted;
EXITS Quit => {}
};
WaitForIdle:
PUBLIC
ENTRY
PROCEDURE [tool: Tool] = {
ENABLE UNWIND => NULL;
WHILE tool.process # NIL DO WAIT tool.idle ENDLOOP;
WHILE tool.serverProcess # NIL DO WAIT tool.serverIdle ENDLOOP;
};
WaitForSendIdle:
PUBLIC
ENTRY
PROCEDURE [tool: Tool] = {
ENABLE UNWIND => NULL;
WHILE tool.serverProcess # NIL DO WAIT tool.serverIdle ENDLOOP;
};
StartSending:
ENTRY
PROCEDURE [tool: Tool] = {
ENABLE UNWIND => NULL;
UNTIL tool.serverProcess = NIL DO WAIT tool.serverIdle ENDLOOP;
TRUSTED {Process.Detach[tool.serverProcess ← FORK SendingProcess[tool, tool.pressName]]};
};
FinishSending:
ENTRY
PROCEDURE [tool: Tool] = {
ENABLE UNWIND => NULL;
tool.serverProcess ← NIL;
BROADCAST tool.serverIdle;
ViewerTools.SetContents[tool.copiesBox, "1"];
};
SendingProcess:
PROCEDURE [tool: Tool, pressName:
ROPE] = {
ENABLE ABORTED => {FinishSending[tool]; GOTO Quit};
prevMsg: ROPE ← NIL;
progressProc: PressPrinter.ProgressProc =
TRUSTED {
newMsg: ROPE;
PieViewers.Set[tool.serverPie, 1.0-handle.CurrentProgress];
IF prevMsg # (newMsg←handle.CurrentStateMessage)
THEN
ViewerTools.SetContents[tool.serverMsg, ViewerTools.GetContents[tool.serverMsg].Cat["\n",newMsg]];
[] ← tool.serverMsg.class.scroll[tool.serverMsg, thumb, 100];
prevMsg ← newMsg;
IF tool.stopSending THEN handle.Abort;
};
copies: INT ← 1;
copies ← MAX[0, Convert.IntFromRope[ViewerTools.GetContents[tool.copiesBox] ! SafeStorage.NarrowFault => CONTINUE]];
IF copies > 0
THEN {
[] ← PressPrinter.SendPressFile[
fileName: pressName,
server: tool.serverName,
progressProc: progressProc,
copies: copies,
userName: UserCredentials.GetUserCredentials[].name
];
};
IF pressName.Fetch[pressName.Length-1] = '$
THEN {
CIFS.Delete[pressName];
};
FinishSending[tool];
EXITS Quit => {}
};
ExecCommand: Commander.CommandProc =
TRUSTED {
tool: Tool;
stream: IO.STREAM ← IO.RIS[cmd.commandLine];
serverName: ROPE ← IO.GetToken[stream, IO.IDProc];
rest: ROPE ← IO.GetSequence[stream];
IF serverName.Length=0 THEN serverName ← UserProfile.Token["Hardcopy.PressPrinter", ""];
tool ← NewTool[serverName];
IF rest.Length > 0 THEN {tool.selfDestruct ← TRUE; QueueRequest[tool, rest]};
Print[tool];
};
tSViewerClass: ViewerClasses.ViewerClass =
NEW[ViewerClasses.ViewerClassRec ← ViewerOps.FetchViewerClass[$Container]^];
containerPaint: ViewerClasses.PaintProc = tSViewerClass.paint;
tSViewerClass.paint ← TSViewerPaint;
tSViewerClass.icon ← private;
ViewerOps.RegisterViewerClass[$TSetter, tSViewerClass];
Commander.Register[
key: "TSetter",
proc: ExecCommand,
doc: "Create a typesetter viewer for specified server, and use it to print listed documents"
];
END.
Michael Plass, September 15, 1982 9:53 am. ENABLE UNWIND => NULL.
Michael Plass, September 15, 1982 10:51 am. Changed Rope.SP, etc, to refer to Ascii.
Michael Plass, September 15, 1982 10:51 am. Removed "Clover" default.
Michael Plass, September 15, 1982 11:54 am. Fixed it so unknown font message is not obliterated.
Michael Plass, September 15, 1982 12:07 pm. Revised calculation of press file names.
Michael Plass, September 15, 1982 12:13 pm. Replaced ! ANY with ! SafeStorage.NarrowFault.
Michael Plass, September 16, 1982 1:01 pm. Revised creation of press files.
Michael Plass, November 1, 1982 11:30 am. Converted to Tioga fomatting, made cursorProc and progressProc SAFE
Michael Plass, November 12, 1982 3:22 pm. Made some of the windows scrollable and growable.
Michael Plass, November 15, 1982 3:08 pm. Added StopSending and Screen buttons.
Michael Plass, November 17, 1982 9:28 am. Fixed screen buttons to reset the stopSending bit.
Michael Plass, November 17, 1982 11:35 am. Added calls to SafeStorage.
Michael Plass, November 18, 1982 10:45 am. Added yellow-button documentation.
Michael Plass, December 10, 1982 4:19 pm. Added clientData to New menu item.
Michael Plass, December 10, 1982 4:18 pm. Added ExecCommand.
Michael Plass, December 10, 1982 5:33 pm. Added selfDestuct
changes to: ToolRec, StopButton, PauseButton, StopSendingButton, NameButton, CopiesButton, TempPress, TempPressButton, GetFirstName, PrintButton, AllButton, LeftScreenButton, ScreenButton, RightScreenButton, TypesetProcess, GetSelectionButton, ExecCommand
Michael Plass, December 10, 1982 6:17 pm. Bug fix in TypesetProcess
John Maxwell, January 20, 1983 1:54 pm.
changes to: TSViewerImpl, Print, Screen, TypesetProcess, FormatOneFile, StartSending, ExecCommand
Michael Plass, March 10, 1983 8:30 am. changes to: rightIcon, leftIcon, InitDoc, NewTool
Michael Plass, May 2, 1983 9:05 am. Removed uses of UserExec, fixed bug in GetFirstName.
Michael Plass, May 2, 1983 9:55 am. Changed so foo.tioga produces foo.press.