DIRECTORY
Ascii USING [CR, SP, TAB],
Buttons USING [ButtonProc, Create],
Commander USING [CommandProc, Handle, Register],
CommandTool USING [DoCommand],
Containers USING [ChildXBound],
Convert USING [Error, IntFromRope, RopeFromInt],
FileNames USING [CurrentWorkingDirectory],
FS USING [ComponentPositions, Delete, EnumerateForNames, Error, ExpandName, NameProc],
Icons USING [DrawIcon, IconFlavor, NewIconFromFile],
Imager USING [DoSaveAll, MaskRectangleI, SetColor],
ImagerBackdoor USING [invert],
IO USING [CharClass, EndOf, EndOfStream, GetLineRope, GetTokenRope, IDProc, PutChar, PutRope, RIS, STREAM],
Labels USING [Create, Set],
Menus USING [CreateEntry, CreateMenu, GetNumberOfLines, InsertMenuEntry, Menu, MenuEntry, MenuProc],
PieViewers USING [Create, Set],
PressPrinter USING [Abort, CurrentProgress, CurrentState, CurrentStateMessage, Handle, IsAPressFile, ProgressProc, SendPressFile, State],
PressScreen USING [NewPressName, PressScreen, Side],
PrincOps USING [],
PrincOpsUtils USING [],
Process USING [CheckForAbort, Detach, Pause, priorityBackground, SecondsToTicks, SetPriority, Ticks],
PseudoCursors USING [Create],
Rope USING [Cat, Concat, Equal, Fetch, Find, IsEmpty, Length, ROPE, Substr],
RuntimeError USING [UNCAUGHT],
SafeStorage USING [ReclaimCollectibleObjects],
TSFormat USING [FormatOneOutputFile],
TSGlue USING [],
TSOutput USING [Handle],
TSViewer USING [RemoteOrLocalState, Tool, ToolRec],
UserCredentials USING [Get],
UserProfile USING [Boolean, Token],
ViewerClasses USING [AdjustProc, PaintProc, Viewer, ViewerClass, ViewerClassRec],
ViewerOps USING [AddProp, CreateViewer, DestroyViewer, EnumerateViewers, EnumProc, EstablishViewerPosition, FetchProp, FetchViewerClass, PaintViewer, RegisterViewerClass, SetMenu, SetOpenHeight],
ViewerPrivate USING [selectedIcon],
ViewerSpecs USING [captionHeight, iconHeight, iconWidth, menuHeight, scrollBarW, windowBorderSize],
ViewerTools USING [GetContents, GetSelectedViewer, InhibitUserEdits, MakeNewTextViewer, SetContents, SetSelection];
=
BEGIN
OPEN TSViewer;
ROPE: TYPE = Rope.ROPE;
indent: INTEGER = 4;
longIndent: INTEGER = 128;
baseline: INTEGER = 16;
rightIcon: Icons.IconFlavor ← Icons.NewIconFromFile["TSetter.icons", 0];
leftIcon: Icons.IconFlavor ← Icons.NewIconFromFile["TSetter.icons", 2];
NewButton: Menus.MenuProc = {
IF mouseButton=yellow THEN ShowMessage[NARROW[clientData], doc[New]]
ELSE {
selectedViewer: ViewerClasses.Viewer ← ViewerTools.GetSelectedViewer[];
server: ROPE ← NIL;
server
← IF selectedViewer =
NIL
OR selectedViewer.class.get =
NIL
THEN
NIL
ELSE
NARROW[selectedViewer.class.get[selectedViewer, $SelChars !
RuntimeError.UNCAUGHT => CONTINUE]];
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:
PROCEDURE
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, feedBack:
IO.
STREAM ←
NIL]
RETURNS [Tool] = {
ENABLE UNWIND => NULL;
data: Tool ← NEW[ToolRec ← [stop: FALSE, feedBack: feedBack]];
curY: INTEGER ← indent/2;
NextY: PROCEDURE 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 ← Menus.CreateMenu[];
InsertMenuEntry:
PROCEDURE [name:
ROPE,
proc: Menus.MenuProc, fork:
BOOL ←
FALSE, row:
INTEGER ← 0,
copy:
BOOL ←
FALSE, documentation:
ROPE ←
NIL, guarded:
BOOL ←
FALSE] = {
menuEntry: Menus.MenuEntry ~ Menus.CreateEntry[name: name, proc: proc, clientData: data, documentation: documentation, fork: fork, guarded: guarded];
Menus.InsertMenuEntry[menu, menuEntry];
};
InsertMenuEntry[name: "New", proc: NewButton, fork: FALSE, documentation: doc[New]];
InsertMenuEntry[name: ">", proc: RightScreenButton, fork: TRUE,
documentation: doc[RightScreen]];
InsertMenuEntry[name: "Screen", proc: ScreenButton, fork: TRUE,
documentation: doc[Screen]];
InsertMenuEntry[name: "<", proc: LeftScreenButton, fork: TRUE,
documentation: doc[LeftScreen]];
InsertMenuEntry[name: "All", proc: AllButton, fork: FALSE, documentation: doc[All]];
InsertMenuEntry[name: "Print", proc: PrintButton, fork: FALSE, documentation: doc[Print]];
InsertMenuEntry[name: "Get", proc: GetSelectionButton, fork: FALSE,
documentation: doc[Get]];
InsertMenuEntry[name: "StopSending", proc: StopSendingButton, fork: FALSE, documentation: doc[StopSending]];
InsertMenuEntry[name: "Stop", proc: StopButton, fork: FALSE, documentation: doc[Stop] ];
InsertMenuEntry[name: "Pause", proc: PauseButton, fork: FALSE, documentation: doc[Pause]];
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: 72, wh: data.nameButton.wh,
parent: container, scrollable: FALSE, border: FALSE],
paint: FALSE
];
PlaceChild[data.copiesBox, 3, 0, TRUE];
data.remoteBox ← Buttons.Create[
info:[name: "Remote or Local: ", wx: longIndent , wy: curY, parent: container, border: FALSE],
clientData: data,
proc: RemoteOrLocalButton,
fork: FALSE,
paint: FALSE
];
PlaceChild[data.remoteBox, 3, 0, TRUE];
data.remoteBox ← Labels.Create[
info:[name: "best performance", wx: data.remoteBox.wx+data.remoteBox.ww , wy: curY, parent: container, border: FALSE],
paint: FALSE
];
data.remoteState ← bestPerformance;
PlaceChild[data.remoteBox, 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"];
RETURN [data]
};
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:
PROCEDURE [viewer: ViewerClasses.Viewer, nVar, nFixed:
NAT,
fixed:
BOOLEAN ←
TRUE] = {
ViewerOps.AddProp[viewer, $TSViewerPositionInfo, NEW[PositionInfoRec ←
[nVar, nFixed, fixed]]];
};
SetViewerPosition:
PROCEDURE [viewer: ViewerClasses.Viewer, x,y,w,h:
INTEGER] = {
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;
};
TSViewerAdjust: ViewerClasses.AdjustProc = {
varbaseline: NAT ← MAX[baseline, (self.ch-indent-2*baseline)/3];
FOR v: ViewerClasses.Viewer ← self.child, v.sibling
UNTIL v=
NIL
DO
WITH ViewerOps.FetchProp[v, $TSViewerPositionInfo]
SELECT
FROM
positionInfo:
REF PositionInfoRec => {
ViewerOps.EstablishViewerPosition[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
];
};
ENDCASE => NULL;
ENDLOOP;
};
TSViewerPaint: ViewerClasses.PaintProc = {
drawIcon:
PROC ~ {
Icons.DrawIcon[flavor:
IF self.column = left
THEN leftIcon
ELSE rightIcon,
context: context, x: 0, y: 0,
label: self.name];
};
IF self.iconic
THEN {
Imager.DoSaveAll[context, drawIcon];
IF ViewerPrivate.selectedIcon=self
THEN {
Imager.SetColor[context, ImagerBackdoor.invert];
Imager.MaskRectangleI[context, 0, 0, ViewerSpecs.iconWidth, ViewerSpecs.iconHeight];
}
};
};
ShowMessage:
PROCEDURE [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.RopeFromInt[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"];
};
RemoteOrLocalButton: Buttons.ButtonProc = {
tool: Tool ← NARROW[clientData];
currentOption: ROPE;
tool.selfDestruct ← FALSE;
currentOption ← ViewerTools.GetContents[tool.remoteBox];
tool.remoteState ← IF tool.remoteState = TSViewer.RemoteOrLocalState.LAST THEN TSViewer.RemoteOrLocalState.FIRST ELSE tool.remoteState.SUCC;
Labels.Set[tool.remoteBox,
SELECT tool.remoteState
FROM
bestPerformance => "best performance",
localOnly => "local only",
remoteOnly => "remote only"
ENDCASE => "???"];
};
GetNames:
ENTRY
PROCEDURE [tool: Tool]
RETURNS [gotIt:
BOOLEAN ←
TRUE, names:
LIST
OF
ROPE ← NIL] = {
ENABLE UNWIND => NULL;
rope: ROPE ~ ViewerTools.GetContents[tool.nameBox];
length: NAT ~ rope.Length;
i, start: NAT ← 0;
c: CHAR;
currentName: LIST OF ROPE;
IF tool.pause
OR tool.stop
THEN
{tool.process ← NIL; NOTIFY tool.idle; RETURN[FALSE, NIL]};
names ← CONS[NIL, NIL];
currentName ← names;
DO
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;
IF i-start <= 0 THEN EXIT;
currentName.rest ← CONS[rope.Substr[start: start, len: i-start], NIL];
currentName ← currentName.rest;
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;
IF i >= length OR ~tool.singleOutputFile THEN EXIT;
ENDLOOP;
ViewerTools.SetContents[tool.nameBox, rope.Substr[start: i]];
names ← names.rest;
IF names =
NIL
OR names.first.IsEmpty[]
THEN {
tool.process ← NIL;
NOTIFY tool.idle;
RETURN[FALSE, NIL];
};
};
FindFileViewer:
PROC[file: Rope.
ROPE]
RETURNS[viewer: ViewerClasses.Viewer] = {
FindViewer: ViewerOps.EnumProc = {
IF Rope.Find[v.file, file, 0,
FALSE] = 0
THEN {viewer ← v; RETURN[FALSE]}
ELSE RETURN[TRUE];
};
ViewerOps.EnumerateViewers[FindViewer];
};
WaitUntilSaved:
PROC [fileName: Rope.
ROPE, tool: Tool] = {
viewer: ViewerClasses.Viewer ← NIL;
viewer ← FindFileViewer[fileName];
IF viewer #
NIL
AND viewer.newVersion
THEN {
SomeSaveInProgress:
PROC
RETURNS[ans:
BOOL ←
FALSE] =
CHECKED {
v: ViewerClasses.Viewer ← viewer;
IF viewer.saveInProgress THEN RETURN[TRUE];
WHILE (v ← v.link) #
NIL
AND (v # viewer)
DO
IF v.saveInProgress THEN RETURN[TRUE];
ENDLOOP;
};
IF
NOT SomeSaveInProgress[]
THEN {
IF tool.feedBack =
NIL
THEN {
ShowMessage[tool, Rope.Cat["***Please save ", viewer.name, ". . . \n"]];
}
ELSE {
tool.feedBack.PutRope[Rope.Cat["***Please save ", viewer.name, ". . . \n"]];
};
};
UNTIL SomeSaveInProgress[]
DO
Process.Pause[Process.SecondsToTicks[1]];
Process.CheckForAbort[];
ENDLOOP;
IF SomeSaveInProgress[]
THEN {
IF tool.feedBack =
NIL
THEN {
ShowMessage[tool, Rope.Cat["***Waiting for ", viewer.name, " to finish being saved. . . "]];
}
ELSE {
tool.feedBack.PutRope[Rope.Cat["***Waiting for ", viewer.name, " to finish being saved. . . "]];
};
};
WHILE SomeSaveInProgress[]
DO
TRUSTED {
Process.Pause[Process.SecondsToTicks[1]];
Process.CheckForAbort[];
};
ENDLOOP;
IF tool.feedBack = NIL THEN ShowMessage[tool, "ok\n"]
ELSE tool.feedBack.PutRope["ok\n"];
};
};
InsureSaved:
PROC [tool: Tool, names:
LIST
OF
ROPE] = {
wDir: ROPE = FileNames.CurrentWorkingDirectory[];
FOR loopNames:
LIST
OF
ROPE ← names, loopNames.rest
UNTIL loopNames =
NIL
DO
currentName: ROPE = loopNames.first;
WaitUntilSaved[
IF Rope.Find[currentName, ">"] < 0
AND Rope.Find[currentName, "/"] < 0
THEN FS.ExpandName[currentName, wDir].fullFName
ELSE currentName,
tool];
ENDLOOP;
};
GetPressName:
PROCEDURE [tool: Tool]
RETURNS [pressName:
ROPE] = {
nameLen: INT ← 0;
cp: FS.ComponentPositions; dirOmitted: BOOLEAN;
[tool.currentName, cp, dirOmitted] ← FS.ExpandName[tool.currentName];
IF tool.currentName.Substr[cp.ext.start, cp.ext.length].Equal["Tioga",
FALSE]
THEN
pressName ← tool.currentName.Substr[cp.base.start, cp.base.length]
ELSE pressName ← tool.currentName.Substr[cp.base.start, cp.ext.start+cp.ext.length-cp.base.start];
IF tool.singleOutputFile THEN pressName ← pressName.Concat[".etc"];
pressName ← pressName.Concat[".press"];
IF cp.server.length = 0
THEN {
pressName ← tool.currentName.Substr[0, cp.base.start].Concat[pressName];
};
IF tool.tempPress THEN pressName ← pressName.Concat["$"];
IF pressName.Equal[tool.pressName]
THEN {
WaitForSendIdle[tool];
ViewerTools.SetContents[tool.serverMsg, ""]
}
};
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] = {
ENABLE UNWIND => NULL;
tool.pause ← tool.stop ← tool.stopSending ← FALSE;
IF tool.process=NIL THEN TRUSTED {Process.Detach[tool.process ← FORK TypesetProcess[tool]]};
};
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
PROCEDURE [tool: Tool, side: PressScreen.Side] = {
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 {
tool.pressName ← pressName;
StartSending[tool];
};
};
TypesetProcess:
PROCEDURE [tool: Tool] = {
didNothing: BOOLEAN ← TRUE;
gotIt: BOOLEAN;
names: LIST OF ROPE;
outputHandle: TSOutput.Handle ← NIL;
TRUSTED {Process.SetPriority[Process.priorityBackground]};
WHILE ([gotIt: gotIt, names: names] ← GetNames[tool]).gotIt
DO
didNothing ← FALSE;
IF tool.singleOutputFile
THEN {
tool.currentName ← names.first;
ShowMessage[tool, tool.currentName];
tool.pressName ← GetPressName[tool];
IF PressPrinter.IsAPressFile[tool.currentName]
THEN {
tool.pressName ← tool.currentName;
IF
NOT tool.debug
AND
NOT tool.stop
AND tool.serverName.Length # 0
THEN
StartSending[tool];
}
ELSE {
InsureSaved[tool, names];
TSFormat.FormatOneOutputFile[tool, names ! ABORTED => CONTINUE];
IF NOT tool.debug AND NOT tool.stop AND tool.serverName.Length # 0 THEN StartSending[tool];
};
}
ELSE {
-- the "All" button means to format to one output file
currentList: LIST OF ROPE ← CONS[NIL, NIL];
currentListTail: LIST OF ROPE ← currentList;
tool.pressName ← NIL ;
FOR n:
LIST
OF
ROPE ← names, n.rest
UNTIL n =
NIL
DO
tool.currentName ← n.first;
IF tool.pressName = NIL THEN tool.pressName ← GetPressName[tool];
ShowMessage[tool, tool.currentName];
IF PressPrinter.IsAPressFile[tool.currentName]
THEN {
IF currentList.rest #
NIL
THEN {
currentList ← currentList.rest;
TSFormat.FormatOneOutputFile[tool, currentList ! ABORTED => CONTINUE];
IF NOT tool.debug AND NOT tool.stop AND tool.serverName.Length # 0 THEN StartSending[tool];
};
currentList ← CONS[NIL, NIL];
currentListTail ← currentList;
ShowMessage[tool, tool.currentName];
tool.pressName ← tool.currentName;
IF
NOT tool.debug
AND
NOT tool.stop
AND tool.serverName.Length # 0
THEN
StartSending[tool];
tool.pressName ← NIL;
}
ELSE {
ShowMessage[tool, tool.currentName];
InsureSaved[tool, names];
currentListTail.rest ← CONS[n.first, NIL];
currentListTail ← currentListTail.rest;
};
ENDLOOP;
IF currentList.rest #
NIL
THEN {
currentList ← currentList.rest;
TSFormat.FormatOneOutputFile[tool, currentList ! ABORTED => CONTINUE];
IF NOT tool.debug AND NOT tool.stop AND tool.serverName.Length # 0 THEN StartSending[tool];
};
};
ENDLOOP;
SafeStorage.ReclaimCollectibleObjects[];
tool.singleOutputFile ← FALSE;
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];
};
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 = {
tool: Tool ← NARROW[clientData, Tool];
tool.selfDestruct ← FALSE;
IF mouseButton=yellow THEN ShowMessage[tool, doc[Get]]
ELSE {
selectedViewer: ViewerClasses.Viewer ← ViewerTools.GetSelectedViewer[];
sourceName: ROPE ← NIL;
sourceName
← IF selectedViewer =
NIL
OR selectedViewer.class.get =
NIL
THEN
NIL
ELSE
NARROW[selectedViewer.class.get[selectedViewer, $SelChars !
RuntimeError.UNCAUGHT => CONTINUE]];
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];
};
};
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:
PROCEDURE [tool: Tool] = {
IF tool.serverName.Equal["*"] THEN DoShowPress[tool.pressName]
ELSE MonitoredStartSending[tool];
};
MonitoredStartSending:
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"]; -- should set it to one here only if there is nothing more to print, but I didn't figure out how to determine that yet...
};
SendingProcess:
PROCEDURE [tool: Tool, pressName:
ROPE] = {
ENABLE ABORTED => {FinishSending[tool]; GOTO Quit};
prevMsg: ROPE ← NIL;
AbortablePause:
PROC [seconds:
CARDINAL] ~ {
oneSecond: Process.Ticks ~ Process.SecondsToTicks[1];
THROUGH [0..seconds]
DO
IF tool.stopSending THEN GO TO Aborted;
Process.Pause[oneSecond];
ENDLOOP;
EXITS
Aborted => DisplayMsg["Transmission aborted"];
};
DisplayMsg:
PROC [rope:
ROPE] ~ {
IF prevMsg # rope
THEN {
ViewerTools.SetContents[tool.serverMsg, ViewerTools.GetContents[tool.serverMsg].Cat["\n",rope]];
[] ← tool.serverMsg.class.scroll[tool.serverMsg, thumb, 100];
The line cache in Tioga 1 is global and used by both scrolling and selection.
Invalidate it as a good citizen (guess scrolling was never expected to be asynchronous)
TEditSelection.InvalidateLineCache[];
};
prevMsg ← rope;
};
tryAgain: BOOL ← FALSE;
progressProc: PressPrinter.ProgressProc = {
state: PressPrinter.State ~ handle.CurrentState;
PieViewers.Set[tool.serverPie, 1.0-handle.CurrentProgress];
IF tryAgain=FALSE OR state#aborted THEN DisplayMsg[handle.CurrentStateMessage];
IF state=serverBusy OR state=serverTimeout THEN {tryAgain ← TRUE; handle.Abort};
IF tool.stopSending THEN {tryAgain ← FALSE; handle.Abort};
};
copies: INT ← 1;
copies ← MAX[0, Convert.IntFromRope[ViewerTools.GetContents[tool.copiesBox] ! Convert.Error => CONTINUE]];
IF copies > 0
THEN {
printedBy: ROPE ← UserProfile.Token["Hardcopy.PrintedBy", ""];
DO
tryAgain ← FALSE;
[] ← PressPrinter.SendPressFile[
fileName: pressName,
server: tool.serverName,
progressProc: progressProc,
copies: copies,
userName: IF printedBy.Length = 0 THEN UserCredentials.Get[].name ELSE printedBy
];
IF NOT tryAgain THEN EXIT;
AbortablePause[30];
ENDLOOP;
};
IF TemporaryName[pressName]
THEN {
FS.Delete[pressName ! FS.Error => {
DisplayMsg[error.explanation];
CONTINUE
}];
};
FinishSending[tool];
EXITS Quit => {}
};
TemporaryName:
PROC [rope:
ROPE]
RETURNS [
BOOL] ~ {
fullFName: ROPE;
cp: FS.ComponentPositions;
[fullFName, cp] ← FS.ExpandName[rope];
RETURN [fullFName.Fetch[cp.ext.start+cp.ext.length-1] = '$]
};
GetName:
PROC [stream:
IO.
STREAM]
RETURNS [name:
ROPE] ~ {
name ← NIL;
name ← IO.GetTokenRope[stream, IO.IDProc ! IO.EndOfStream => CONTINUE].token;
};
FileNameBreakProc:
PROC [char:
CHAR]
RETURNS [
IO.CharClass] = {
IF char = ' OR char = ' OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
GetFileName:
PROC [stream:
IO.
STREAM]
RETURNS [name:
ROPE] ~ {
name ← NIL;
name ← IO.GetTokenRope[stream, FileNameBreakProc ! IO.EndOfStream => CONTINUE].token;
};
GetLine:
PROC [stream:
IO.
STREAM]
RETURNS [line:
ROPE] ~ {
line ← NIL;
line ← IO.GetLineRope[stream ! IO.EndOfStream => CONTINUE];
};
DoShowPress:
PROC [pressFileName:
ROPE] ~ {
[] ← CommandTool.DoCommand[Rope.Concat["ShowPress ", pressFileName], NIL];
};
TSetterExecCommand: Commander.CommandProc = {
tool: Tool;
stream: IO.STREAM ← IO.RIS[cmd.commandLine];
serverName: ROPE ← GetName[stream];
files: ROPE ← NIL;
WHILE
NOT
IO.EndOf[stream]
DO
token: ROPE ← GetFileName[stream];
IF token #
NIL
THEN {
ENABLE FS.Error => {IF error.group=user THEN {cmd.out.PutRope[error.explanation]; cmd.out.PutChar['\n]; CONTINUE} ELSE REJECT};
CatProc:
FS.NameProc = {
files ← files.Cat[" ", fullFName];
RETURN[TRUE];
};
IF token.Find["*"] = -1 THEN [] ← CatProc[FS.ExpandName[token].fullFName]
ELSE {
IF token.Find["!"] = -1 THEN token ← token.Concat["!H"];
FS.EnumerateForNames[pattern: token, proc: CatProc];
};
};
ENDLOOP;
IF serverName.Length=0 THEN serverName ← UserProfile.Token["Hardcopy.PressPrinter", ""];
tool ← NewTool[serverName];
IF files.Length > 0 THEN {tool.selfDestruct ← TRUE; QueueRequest[tool, files]};
Print[tool];
};
tSViewerClass: ViewerClasses.ViewerClass =
NEW[ViewerClasses.ViewerClassRec ← ViewerOps.FetchViewerClass[$Container]^];
tSViewerClass.paint ← TSViewerPaint;
tSViewerClass.adjust ← TSViewerAdjust;
tSViewerClass.icon ← private;
tSViewerClass.bltH ← none;
tSViewerClass.bltV ← none;
ViewerOps.RegisterViewerClass[$TSetter, tSViewerClass];
Commander.Register[
key: "TSetter",
proc: TSetterExecCommand,
doc: "Create a typesetter viewer for specified server, and use it to print listed documents"
];
CHANGE LOG
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 27, 1983 11:15 am. Changed so foo.tioga produces foo.press., IMPORTS
Edited on May 27, 1983 11:11 am, by Beach
changes to: TSViewerPaint to force a clear viewer when adjusting the viewer sizes.
Edited on June 1, 1983 9:40 am, by Beach
changes to: tSViewerClass, TSViewerPaint, TSViewerPaint
Edited on June 20, 1983 3:56 pm, by Beach
changes to: SendingProcess to use Hardcopy.PrintedBy if its defined in the user profile.
Edited on August 10, 1983 5:24 pm, by Beach
changes to: DIRECTORY, IMPORTS, TSViewerPaint
Edited on August 12, 1983 2:39 pm, by Beach
changes to: ToolRec, NewTool, TSetterExecCommand, PressScreenTool, PressScreenToolRec, NewPressScreenTool, NextY (local of NewPressScreenTool), FlashImageButton, SelectedImageButton, WholeScreenButton, RightColumnButton, LeftColumnButton, MagnificationFactorButton, SetCornersButton, BlackBorder, PageMarginButton, PressScreenExecCommand, Commander, Commander, mode, BoxAdjustNotify, Clip (local of BoxAdjustNotify), BlackBorder
Edited on August 15, 1983 2:52 pm, by Beach
changes to: DIRECTORY, IMPORTS, InsertMenuEntry, FlashImageButton, SelectedImageButton, WholeScreenButton, RightColumnButton, LeftColumnButton, ReadScreenCorners, ConvertRopeToReal, vaTIP, NewPressScreenTool, TSetterExecCommand, Commander, }, Screen, MenuCode, NewTool, NewTool, ToolRec, InsertMenuEntry (local of NewTool), ToolRec, GetPressName
Edited on August 18, 1983 12:46 pm, by Beach
changes to: TSViewerPaint
Edited on August 19, 1983 12:56 pm, by Beach
changes to: NewTool, InsertMenuEntry (local of NewTool)
Edited on October 26, 1983 9:08 am, by Beach
changes to: DIRECTORY, IMPORTS, progressProc (local of SendingProcess)
Michael Plass, December 7, 1983 12:36 pm: Cedar 5 conversion (FS, Convert, UserCredentials, IO.GetTokenRope, IO.GetLineRope)
Michael Plass, December 12, 1983 2:11 pm: Carried local directory name from input file to output file.
Michael Plass, February 21, 1984 9:46:50 am PST: Fixed file-name-on-header bug.