<> <> <> DIRECTORY Ascii, Atom, Buttons, CIFS, Commander, Containers, Convert, EditSpanSupport, FileIO, Graphics, IO, IconManager, Icons, Labels, Menus, NodeStyle, PieViewers, PressPrinter, PressScreen, Process, PseudoCursors, PutGet, Rope, SafeStorage, SirPress, TEditDocument, TEditInput, TEditSelection, 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, Graphics, IconManager, Icons, IO, Labels, Menus, PieViewers, PressPrinter, PressScreen, Process, PutGet, PseudoCursors, Rope, SafeStorage, TEditInput, TEditSelection, TextNode, TSJaMPageBuilder, TSTranslate, TSObject, TSOutput, TSOutputPress, UserCredentials, UserProfile, ViewerOps, ViewerTools EXPORTS TSViewer = { 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 _ NIL, prunedCurrentName: ROPE _ NIL, pressName: ROPE _ NIL, 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 _ NIL, 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: 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] RETURNS [data: Tool _ NEW[ToolRec]] = { ENABLE UNWIND => NULL; 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 _ MakeMenu[]; MakeMenu: PROCEDURE 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: PROCEDURE [menu: Menus.Menu, name: ROPE, proc: Menus.MenuProc, fork: BOOL _ FALSE, row: INTEGER _ 0, clientData: REF ANY _ NIL, copy: BOOL _ FALSE, documentation: 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"]; }; 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] = 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 { IF IconManager.selectedIcon=self THEN [] _ Graphics.Save[context]; Icons.DrawIcon[flavor: IF self.column = left THEN leftIcon ELSE rightIcon, context: context, x: 0, y: 0, label: self.name]; IF IconManager.selectedIcon=self THEN { Graphics.Restore[context]; [] _ Graphics.SetPaintMode[context, invert]; Graphics.DrawBox[context, [0, 0, ViewerSpecs.iconWidth, ViewerSpecs.iconHeight]]; }} ELSE { varbaseline: NAT _ MAX[baseline, (self.ch-indent-2*baseline)/3]; IF NOT clear THEN { Graphics.SetColor[context, Graphics.white]; Graphics.DrawBox[context, Graphics.GetBounds[context]]; }; 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; <> containerPaint[self, context, whatChanged, clear]; }; }; 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.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 PROCEDURE [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 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 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: PROCEDURE [c: CHARACTER] RETURNS [BOOLEAN] = {RETURN[c IN ['A .. 'Z] OR c IN ['a .. 'z] OR c IN ['0 .. '9] OR c='-]}; GetPressName: PROCEDURE [tool: Tool] RETURNS [pressName: ROPE] = BEGIN nameLen: INT _ 0; pressName _ tool.currentName; FOR i: INT 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 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: PROCEDURE [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: PROCEDURE [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: PROCEDURE [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: PROCEDURE 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]; <> <> TEditSelection.InvalidateLineCache[]; }; 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 { printedBy: ROPE _ UserProfile.Token["Hardcopy.PrintedBy", ""]; [] _ PressPrinter.SendPressFile[ fileName: pressName, server: tool.serverName, progressProc: progressProc, copies: copies, userName: IF printedBy.Length = 0 THEN UserCredentials.GetUserCredentials[].name ELSE printedBy ]; }; IF pressName.Fetch[pressName.Length-1] = '$ THEN { CIFS.Delete[pressName]; }; FinishSending[tool]; EXITS Quit => {} }; TSetterExecCommand: 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; tSViewerClass.bltContents _ 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" ]; }. < NULL.>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <<>> <<>> <> <> <<>> <<>> <<>> <<>> <<>> <<>> <<>> <<>> <<>> <> <> <> <> <> <> <<>>