File: AdobeToolsE.mesa - created by JCS. Last edit:
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
JCS 2-Mar-86 15:15:08
RSF   11-Apr-86 10:27:02
RLC    8-Oct-87 10:52:12
Philip James, March 10, 1992 10:56 am PST
Christian Jacobi, April 7, 1992 5:51 pm PDT
Foote, June 24, 1992 9:15 am PDT
Copyright (C) 1985, 1986 by Xerox Corporation. All rights reserved.
Report
DIRECTORY
AccessCH USING [NSNameFromRope],
AdobeCommon,
AdobeCommonInternal USING [EntryBytes, InstanceData, InstanceDataHandle],
AdobeOps USING [ARSystemHandle, ARNumber, FieldItemHandle, FieldItemObject, FieldItemObjectRec, FieldList, FieldListArray, nilARNumber, QueryList, UserSpecifiedOrder, ArFIO, DateFIO, EnumFIO, FixFIO, NumFIO, StrFIO],
AdobeTool,
AdobeToolContext,
AdobeServer,
ARAccess USING [AppendChar, ARHandle, ARStorage, Error, ExamineAR, FreeAR, GetAR],
Ascii USING [CR, NUL, LF, SP, TAB],
BasicTime USING [Now, Unpacked],
Convert USING [Error, RopeFromCard, RopeFromChar, RopeFromTime, UnpackedTimeFromRope],
CrRPC USING [BulkDataXferProc],
IO,
PFS USING [Close, Delete, Error, Open, OpenFile, PathFromRope, StreamOpen],
Rope,
XNSAdobeClientOps USING [GetAcceleratorInfo];
AdobeToolImplE: CEDAR MONITOR
IMPORTS
AccessCH, AdobeCommon, AdobeToolContext, ARAccess, BasicTime, Convert, IO, PFS, Rope, XNSAdobeClientOps
EXPORTS AdobeTool =
BEGIN
globals for report
reportPos: CARDINAL = 0;
formatPos: CARDINAL = 1;
overwritePos: CARDINAL = 2;
resetPos: CARDINAL = 3;
setFieldsPos: CARDINAL = 4;
rptBkgdPos: CARDINAL = 5;
outFilePos: CARDINAL = 6;
tmpltFilePos: CARDINAL = 7;
rptQlNamePos: CARDINAL = 8;
nReportParams: CARDINAL = 9;
templateProblem: ERROR = CODE;
CreateReportSW: PUBLIC PROCEDURE [
w: Window.Handle, makeCmdSW: BOOLEANTRUE]
RETURNS [initialMsg: Rope.ROPENIL] =
BEGIN
data: AdobeCommon.DataHandle ← AdobeCommon.GetData[w];
instanceData: AdobeCommonInternal.InstanceDataHandle ←
data.instanceData;
IF makeCmdSW THEN { --there will be no instanceData hanging around
instanceData ← AdobeCommonInternal.AllocateInstanceData[data];
instanceData.cmdSW ← Tool.MakeFormSW[
window: w, formProc: ReportCmdSW, zone: data.heap]};
WITH instanceData SELECT FROM
report =>
IF data.context # NIL THEN
fieldsInReport ← NEW[AdobeCommon.ReportFieldsSeq[data.context.arSH.fieldList.len]];
ENDCASE;
IF data.knownSystems # NIL AND data.context # NIL THEN
instanceData.formSW ← Tool.MakeFormSW[
window: w, formProc: MakeFieldsInReportSW, zone: data.heap]
ELSE
instanceData.formSW ← Tool.MakeFormSW[
window: w, formProc: NilFormProc];
AdobeCommon.DisableAdobeAborts[w];
AdobeCommonInternal.SetWindowName[
w,
IF data.knownSystems # NIL AND data.context # NIL AND
data.system # LAST[CARDINAL] THEN
data.knownSystems[data.system] ELSE NIL,
AdobeCommonInternal.reportHeraldName];
END;
ReportCmdSW: FormSW.ClientItemsProcType =
BEGIN OPEN FormSW;
formatSeq: TYPE = RECORD [
seq: SEQUENCE length: CARDINAL OF Enumerated];
windowData: AdobeCommon.DataHandle ← AdobeCommon.GetDataSW[sw];
instanceData: AdobeCommonInternal.InstanceDataHandle ←
windowData.instanceData;
formats: REF formatSeq ← NEW[formatSeq [AdobeCommon.FormatType.LAST.ORD + 1]];
formats[ORD[AdobeCommon.FormatType.plain]] ← [
"plain", AdobeCommon.FormatType.plain];
formats[ORD[AdobeCommon.FormatType.columns]] ← [
"columns", AdobeCommon.FormatType.columns];
formats[ORD[AdobeCommon.FormatType.template]] ← [
"template", AdobeCommon.FormatType.template];
WITH reportToolData: instanceData SELECT FROM
report => {
items ← AllocateItemDescriptor[
nReportParams, windowData.heap];
freeDesc ← TRUE;
items[reportPos] ← CommandItem[
tag: "Report", place: [0, line0], proc: ReportCommandProc,
z: windowData.heap];
items[formatPos] ← EnumeratedItem[
tag: "Output format", feedback: one, copyChoices: TRUE,
--proc: ??,-- value: @reportToolData.format,
choices: DESCRIPTOR[formats], z: windowData.heap];
items[overwritePos] ← BooleanItem[
tag: "Overwrite", switch: @reportToolData.overwrite,
z: windowData.heap];
items[resetPos] ← CommandItem[
tag: "Reset", proc: ReportCommandProc, z: windowData.heap];
items[setFieldsPos] ← CommandItem[
tag: "Set Fields", proc: ReportCommandProc,
z: windowData.heap];
items[rptBkgdPos] ← BooleanItem[
tag: "Use background", switch: @reportToolData.background,
z: windowData.heap];
items[outFilePos] ← StringItem[
tag: "Output file", string: @reportToolData.outputFile,
place: [0, nextLine], z: windowData.heap, inHeap: TRUE];
items[tmpltFilePos] ← StringItem[
tag: "Template file", string: @reportToolData.templateFile,
place: [225, sameLine], z: windowData.heap, inHeap: TRUE];
items[rptQlNamePos] ← StringItem[
tag: "QL to use", string: @reportToolData.qlName,
place: [0, nextLine], menuProc: AdobeCommon.QLNameHints,
z: windowData.heap, inHeap: TRUE]};
ENDCASE => ERROR; --shouldn't happen
END;
SetUpReportTool: PUBLIC PROCEDURE [handle: AdobeCommon.Handle] ~ {
instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[handle.instanceData];
col: {left, right} ¬ left;
row: CARD ¬ 0;
buttonHeight: CARDINAL ¬ 14;
middle: CARD ¬ handle.getBoxGeometry[handle.fieldViewer.outer].w/2;
fl: AdobeOps.FieldList ¬ handle.systemHandle.fieldList;
bs: AdobeCommon.ButtonsSeq;
handle.fieldViewer.buttons ¬ NEW[AdobeCommon.ButtonSeqObject[fl.length+1]];
WITH instanceData SELECT FROM
id: REF AdobeCommonInternal.InstanceData.report => {
id.fieldsInReport ¬ NEW[AdobeCommon.ReportFieldsSeq[fl.length]];
FOR i: CARD IN [0..id.fieldsInReport.length) DO
id.fieldsInReport[i] ¬ FALSE;
ENDLOOP;
};
ENDCASE;
bs ¬ handle.fieldViewer.buttons;
bs[fl.length] ¬ NEW[AdobeCommon.EnumeratedTypesRec];
bs[fl.length].button ¬ handle.newLabelBox[
parent: handle.fieldViewer.outer,
x: middle - --VFonts.StringWidth["Fields in the Report"]--200 / 2,
y: row*(buttonHeight+1),
name: "Fields in the Report"
];
bs[fl.length].button ← Labels.Create[
info:[
parent: handle.fieldViewer.outer, wx: (middle - VFonts.StringWidth["Fields in the Report"]/2), wy: row*(buttonHeight+1), name: "Fields in the Report", border: FALSE]];
AdobeCommon.PostMessage[handle, TRUE, "about to increment row."];
row ¬ row + 1;
FOR i: CARDINAL IN [0..fl.length) DO
bs[i] ¬ NEW[AdobeCommon.EnumeratedTypesRec];
bs[i].mainViewer ¬ handle;
bs[i].fieldNum ¬ i;
bs[i].button ¬ handle.makeButton[
parent: handle.fieldViewer.outer, x: IF (col = left) THEN 0 ELSE middle, y: row*(buttonHeight+1), name: fl[i].name, --border: FALSE, --data: handle.fieldViewer.buttons[i], proc: $CheckField, cData: handle.fieldViewer.buttons[i]];
SELECT col FROM
left => col ¬ right;
right => {
col ¬ left;
row ¬ row + 1;
};
ENDCASE;
ENDLOOP;
};
MakeFieldsInReportSW: FormSW.ClientItemsProcType = {
OPEN FormSW;
windowData: AdobeCommon.DataHandle ← AdobeCommon.GetDataSW[sw];
instanceData: AdobeCommonInternal.InstanceDataHandle ←
windowData.instanceData;
WITH toolData: instanceData SELECT FROM
report => {
OPEN fl: windowData.context.arSH.fieldList;
items ← AllocateItemDescriptor[
toolData.fieldsInReport.length + 1, windowData.heap];
items[0] ← TagOnlyItem[
tag: "Fields in the Report", place: [100, line0],
z: windowData.heap];
FOR i: CARDINAL IN [0..toolData.fieldsInReport.length) DO
toolData.fieldsInReport[i] ← FALSE;
items[i + 1] ← BooleanItem[
tag: fl[i].name, place: [175 * (i MOD 2), line1 - i / 2],
switch: @toolData.fieldsInReport[i], proc: CheckField,
z: windowData.heap];
ENDLOOP}
ENDCASE};
backStr: Rope.ROPE ¬ NIL;
NilFormProc: FormSW.ClientItemsProcType = {
freeDesc ← TRUE;
items ← FormSW.AllocateItemDescriptor[1];
items[0] ← FormSW.StringItem[invisible: TRUE, string: @backStr]};
ReportCommandProc: PUBLIC PROCEDURE [h: AdobeCommon.Handle] = {
FormSW.ProcType = BEGIN
windowData: AdobeCommon.DataHandle ← AdobeCommon.GetDataSW[sw];
instanceData: AdobeCommonInternal.InstanceDataHandle ←
windowData.instanceData;
windowData: AdobeCommon.Handle ¬ h;
MsgSW.Clear[windowData.msgSW];
IF windowData.system = LAST[CARDINAL] --OR windowData.context = NIL --OR windowData.knownSystems = NIL OR windowData.knownSystems.next = 0 THEN {
AdobeCommon.PostMessage[windowData, TRUE, "No available systems"];
RETURN};
IF windowData.isBusy THEN
AdobeCommon.PostMessage[windowData, TRUE,
"Adobe system is Busy. Please try again later. "]
ELSE {
windowData.isBusy ¬ TRUE;
IF instanceData.background AND ~TajoMisc.toolDriverRunning THEN
Process.Detach[
windowData.processID ← FORK AdobeCommon.CatchErrors[
sw, item, index, windowData, ChooseReportCmd]]
ELSE {
windowData.processID ← Process.GetCurrent[];
AdobeCommon.CatchErrors[
--sw, item, index, --windowData, ChooseReportCmd]}--};
};
ChooseReportCmd: PROC[windowData: AdobeCommon.Handle] =
{
windowData: AdobeCommon.DataHandle ← AdobeCommon.GetDataSW[sw];
{ ENABLE UNWIND => windowData.isBusy ¬ FALSE;
SELECT index FROM
--reportPos => --ReportProc[windowData];
resetPos => ResetProc[windowData, TRUE];
setFieldsPos => SetProc[windowData];
ENDCASE => ERROR;
windowData.isBusy ¬ FALSE;
windowData.processID ← NIL;
};
};
SetProc: PUBLIC PROCEDURE [windowData: AdobeCommon.Handle] = {
templateList: AdobeCommon.Template;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬
NARROW[windowData.instanceData];
WITH instanceData SELECT FROM
reportData: REF AdobeCommonInternal.InstanceData.report => {
IF reportData.format # template THEN GOTO notTemplate;
SetFormSWFieldInvisible[windowData, instanceData.formSW, TRUE, , TRUE];
ResetProc[windowData, FALSE];
templateList ¬ ParseTemplate[windowData ! templateProblem => GOTO badTemplateFile];
templateList ¬ NIL;
FreeTemplateList[templateList, windowData.heap];
SetFormSWFieldInvisible[windowData, instanceData.formSW, FALSE, , TRUE];
FormSW.Display[reportData.formSW]
};
ENDCASE;
EXITS
badTemplateFile =>
AdobeCommon.PostMessage[windowData, TRUE, "Invalid template file specified!"];
notTemplate => NULL};
ResetProc: PUBLIC PROCEDURE [windowData: AdobeCommon.Handle, redisplay: BOOLEAN] = {
instanceData: AdobeCommonInternal.InstanceDataHandle ¬
NARROW[windowData.instanceData];
WITH instanceData SELECT FROM
reportData: REF AdobeCommonInternal.InstanceData.report => {
SetFormSWFieldInvisible[windowData, instanceData.formSW, TRUE, , TRUE];
FOR i: CARDINAL IN [0..reportData.fieldsInReport.length) DO
reportData.fieldsInReport[i] ¬ FALSE;
windowData.setDisplayStyle[windowData.fieldViewer.buttons[i].button, $BlackOnWhite];
ENDLOOP;
SetFormSWFieldInvisible[windowData, instanceData.formSW, FALSE, , TRUE];
IF redisplay THEN FormSW.Display[reportData.formSW]
};
ENDCASE};
ReportProc: PROCEDURE [windowData: AdobeCommon.Handle] = {
outputFH: PFS.OpenFile ¬ NIL;
outputFH: MFile.Handle ← NIL;
sortKeysFileName: Rope.ROPE ¬ NIL;
reportQL: AdobeOps.QueryList ¬ NIL;
index: INT ¬ 0;
newReportFile, success: BOOLEAN ¬ TRUE;
useAccels: BOOLEAN ¬ TRUE;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬
NARROW[windowData.instanceData];
WITH instanceData SELECT FROM
reportData: REF AdobeCommonInternal.InstanceData.report => {
BEGIN
ErrorCleanup: PROCEDURE = {
IF reportData.outSH # NIL THEN {
IO.Close[reportData.outSH];
Stream.Delete[reportData.outSH];
IF newReportFile THEN PFS.Delete[
PFS.PathFromRope[reportData.outputFile] !
PFS.Error => CONTINUE]
IF newReportFile THEN MFile.Delete[
MFile.Acquire[reportData.outputFile, delete, []] !
MFile.Error => CONTINUE]
};
IF reportData.sortKeysSH # NIL THEN {
IO.Close[reportData.sortKeysSH];
Stream.Delete[reportData.sortKeysSH];
IF newReportFile AND ~Rope.IsEmpty[sortKeysFileName] THEN PFS.Delete[
PFS.PathFromRope[sortKeysFileName] !
PFS.Error => CONTINUE]
IF newReportFile AND ~String.Empty[sortKeysFileName] THEN MFile.Delete[
MFile.Acquire[sortKeysFileName, delete, []] !
MFile.Error => CONTINUE]
}};
reportData.outputFile ¬ windowData.getContents[windowData.editors[1]];
{
ENABLE {
UNWIND => ErrorCleanup[];
templateProblem => {ErrorCleanup[]; GOTO badTemplateFile}};
AdobeCommon.PostMessage[windowData, FALSE, "Reporting..."];
verify all parameters
outputFH ¬ PFS.Open[
PFS.PathFromRope[reportData.outputFile] !
PFS.Error =>
IF error.code = $unknownFile THEN CONTINUE
ELSE GOTO outputFileProblem];
outputFH ← MFile.ReadOnly[
reportData.outputFile, [] !
MFile.Error =>
IF code = noSuchFile THEN CONTINUE
ELSE GOTO outputFileProblem];
IF outputFH # NIL THEN {
IF ~reportData.overwrite THEN {
AdobeCommon.PostMessage[windowData, TRUE,
"The output file specified already exists!"];
PFS.Close[outputFH];
MFile.Release[outputFH];
RETURN};
newReportFile ¬ FALSE;
PFS.Close[outputFH];
MFile.Release[outputFH]
};
reportQL ¬ AdobeCommon.FindThisQL[
windowData.getContents[windowData.editors[3]], windowData];
IF reportQL = NIL OR reportQL.list = NIL
OR reportQL.list.len = 0 THEN {
AdobeCommon.PostMessage[windowData, TRUE, "Empty QueryList!"];
RETURN};
reportData.outSH ¬ PFS.StreamOpen[PFS.PathFromRope[reportData.outputFile], create];
reportData.outSH ← MStream.WriteOnly[
reportData.outputFile, [], text !
MStream.Error => GOTO outputFileProblem];
sortKeysFileName ¬ NIL;
--String.MakeString[windowData.heap, reportData.outputFile.length + 9];
UNTIL index = reportData.outputFile.Length OR
reportData.outputFile.Fetch[index] = '. DO
sortKeysFileName ¬ sortKeysFileName.Concat[
Convert.RopeFromChar[reportData.outputFile.Fetch[index], FALSE]];
String.AppendChar[sortKeysFileName, reportData.outputFile[index]];
index ¬ index + 1;
ENDLOOP;
sortKeysFileName ¬ sortKeysFileName.Concat[".sortKeys"];
String.AppendString[sortKeysFileName, ".sortKeys"];
reportData.sortKeysSH ¬ PFS.StreamOpen[
PFS.PathFromRope[sortKeysFileName], create !
PFS.Error => GOTO sortKeysFileProblem];
reportData.sortKeysSH ← MStream.WriteOnly[
sortKeysFileName, [], text !
MStream.Error => GOTO sortKeysFileProblem];
success ¬ WriteReport[windowData, reportQL];}
END; --enable
IO.Close[reportData.outSH];
IO.Close[reportData.sortKeysSH];
Stream.Delete[reportData.outSH];
Stream.Delete[reportData.sortKeysSH];
IF ~success THEN {
PFS.Delete[
PFS.PathFromRope[reportData.outputFile] !
PFS.Error => CONTINUE];
PFS.Delete[
PFS.PathFromRope[sortKeysFileName] !
PFS.Error => CONTINUE]
MFile.Delete[
MFile.Acquire[reportData.outputFile, delete, []] !
MFile.Error => CONTINUE];
MFile.Delete[
MFile.Acquire[sortKeysFileName, delete, []] !
MFile.Error => CONTINUE]
};
AdobeCommon.PostMessage[windowData, TRUE, "Done."]};
ENDCASE => ERROR;
EXITS
outputFileProblem =>
AdobeCommon.PostMessage[
windowData, TRUE, "Cannot acquire the output file specified!"];
sortKeysFileProblem =>
AdobeCommon.PostMessage[windowData, TRUE,
"Cannot acquire sortKeys file for the output file specified!"];
badTemplateFile =>
AdobeCommon.PostMessage[
windowData, TRUE, "Invalid template file specified!"]};
WriteReport: PROCEDURE [data: AdobeCommon.Handle, ql: AdobeOps.QueryList]
RETURNS [success: BOOLEAN ¬ TRUE] = {
entryStartPos: LONG CARDINAL ¬ 0;
z: UNCOUNTED ZONE ← data.heap;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
qlStatus: AdobeCommon.SetStatus ¬ AdobeCommon.InitialSetStatus;
ar: AdobeOps.ARNumber;
arStream: ARAccess.ARStorage ¬ NIL;
arStream: Stream.Handle ← NIL;
fieldCount: CARDINAL ¬ 0;
useAccels: BOOLEAN ¬ TRUE;
template: AdobeCommon.Template ¬ NIL;
valueArray: REF AdobeCommon.StringArray ¬ NIL;
listOfFields: REF AdobeCommon.StringArray ¬ NIL;
options: Stream.InputOptions = [
TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE];
GetFromAccels: CrRPC.BulkDataXferProc = {
currentField, currentAR, len, b1, b2: CARD ¬ 0;
valueArray ¬ NEW[AdobeCommon.StringArray[listOfFields.length]];
IF checkAbort[h] THEN {
AdobeCommon.PostMessage[data, TRUE, "Instant Abort."];
RETURN[FALSE];
};
IF IO.EndOf[s] THEN {
AdobeCommon.PostMessage[data, TRUE, "Empty stream."];
RETURN[FALSE];
};
WHILE NOT IO.EndOf[s] DO
b1 ¬ ORD[IO.GetByte[s]];
b2 ¬ ORD[IO.GetByte[s]];
len ¬ (b1 * (ORD[LAST[CHAR]] + 1)) + b2;
FOR i: CARD IN [0..len) DO
valueArray[currentField] ¬ ARAccess.AppendChar[valueArray[currentField], IO.GetChar[s]];
ENDLOOP;
IF (len MOD 2) = 1 THEN
[] ¬ IO.GetChar[s];
currentField ¬ currentField + 1;
IF currentField >= listOfFields.length THEN {
entryStartPos ¬ PutValues[valueArray, data, template, entryStartPos];
FOR j: CARD IN [0..valueArray.length) DO
valueArray[j] ¬ NIL;
ENDLOOP;
currentField ¬ 0;
currentAR ¬ currentAR + 1;
};
ENDLOOP;
RETURN[FALSE];
};
WITH instanceData SELECT FROM
id: REF AdobeCommonInternal.InstanceData.report => {
id.entryBytes.eb ¬ 0;
IF id.format = template THEN {
SetFormSWFieldInvisible[data, instanceData.formSW, TRUE, , TRUE];
ResetProc[data, FALSE];
template ¬ ParseTemplate[data, TRUE];
SetFormSWFieldInvisible[data, instanceData.formSW, FALSE, , TRUE];
FormSW.Display[formSW]
}
ELSE id.orderInfo ¬ MakeOrderInfo[
id.fieldsInReport, data.systemHandle.fieldList,
data.systemHandle.formSWOrderArray[report]];
IF id.orderInfo.length = 0 THEN {
success ¬ FALSE; GOTO noFieldsSpecified};
WriteHeader[data, data.systemHandle.fieldList];
listOfFields ¬ NEW[AdobeCommon.StringArray[id.orderInfo.length]];
FOR i: CARDINAL IN [0..id.orderInfo.length) DO
WITH data.systemHandle.fieldList[id.orderInfo[i].flIndex] SELECT FROM
fio: AdobeOps.StrFIO => useAccels ¬ FALSE;
ENDCASE;
listOfFields[i] ¬ id.orderInfo[i].flName;
ENDLOOP;
valueArray ¬ NEW[AdobeCommon.StringArray[listOfFields.length]];
WriteSortHeader[data];
entryStartPos ¬ id.entryBytes.eb;
IF useAccels THEN {
fieldList: AdobeOps.FieldList ¬ NEW[AdobeOps.FieldListArray[listOfFields.length]];
FOR i: CARD IN [0..listOfFields.length) DO
fieldList[i] ¬ NEW[AdobeOps.FieldItemObjectRec.arId]; -- arId was chosen because it doesn't matter
fieldList[i].name ¬ listOfFields[i];
ENDLOOP;
XNSAdobeClientOps.GetAcceleratorInfo[
server: data.systemHandle.service,
system: AccessCH.NSNameFromRope[data.systemHandle.name].local,
version: data.systemHandle.version,
arSet: ql.list, fieldList: fieldList,
to: GetFromAccels];
}
ELSE {
arStream ¬ AdobeToolContext.CreateStream[
data.systemHandle.fieldList];
[ar, qlStatus] ¬ AdobeCommon.GetNextAR[ql.list, qlStatus];
WHILE ar # AdobeOps.nilARNumber DO
GetARVaues[
ar, listOfFields, valueArray, id.orderInfo, arStream,
data ! ARAccess.Error => {
SELECT why FROM
arNotFound => {
AdobeCommon.PostMessage[data, FALSE, "AR "];
AdobeCommon.PostNumber[data, FALSE, ar];
AdobeCommon.PostMessage[data, TRUE, " was not found."];
[ar, qlStatus] ¬ AdobeCommon.GetNextAR[ql.list, qlStatus]};
ENDCASE;
LOOP}
];
entryStartPos ¬ PutValues[valueArray, data, template, entryStartPos];
[ar, qlStatus] ¬ AdobeCommon.GetNextAR[ql.list, qlStatus];
ENDLOOP;
IO.Close[arStream]
Stream.Delete[arStream]
};
IF template # NIL THEN
template ¬ NIL;
template ← FreeTemplateList[template, data.heap];
};
ENDCASE;
z.FREE[@valueArray];
EXITS
noFieldsSpecified => {
AdobeCommon.PostMessage[data, TRUE, "Select the fields to be included in the report."];
}};
PutValues: PROCEDURE[valueArray: REF AdobeCommon.StringArray, data: AdobeCommon.Handle, template: AdobeCommon.Template, startPos: LONG CARDINAL]
RETURNS [entryStartPos: CARDINAL] = {
instanceData: AdobeCommonInternal.InstanceDataHandle ¬
NARROW[data.instanceData];
entryStartPos ¬ startPos;
WITH instanceData SELECT FROM
id: REF AdobeCommonInternal.InstanceData.report => {
id.entryBytes.eb ¬ 0;
SELECT id.format FROM
plain, columns =>
FOR i: CARDINAL IN [0..id.orderInfo.length) DO
SELECT id.format FROM
plain => WriteReportPair[
id.orderInfo[i], valueArray[i], instanceData,
data.systemHandle.fieldList];
columns => WriteColumnField[
id.orderInfo[i], valueArray[i], data];
ENDCASE;
ENDLOOP;
template => {
orderCount: CARDINAL ¬ 0;
i: INTEGER;
templateItem: AdobeCommon.Template ¬ template;
WHILE templateItem # NIL DO
WITH templateItem SELECT FROM
ti: REF AdobeCommon.TemplateObject.fixed => {
FOR i IN [0..ti.width) DO
WriteChar[id.outSH,
IF i < valueArray[orderCount].Length THEN
valueArray[orderCount].Fetch[i]
ELSE Ascii.SP, id.entryBytes];
ENDLOOP;
WriteSortEntry[
valueArray[orderCount],
NEW[AdobeOps.FieldItemObject ¬ --@--data.systemHandle.fieldList[
id.orderInfo[orderCount].flIndex]],
id.sortKeysSH];
orderCount ¬ orderCount + 1};
ti: REF AdobeCommon.TemplateObject.variable => {
WriteString[
id.outSH, valueArray[orderCount], id.entryBytes];
WriteSortEntry[
valueArray[orderCount],
NEW[AdobeOps.FieldItemObject ¬ --@-- data.systemHandle.fieldList[
id.orderInfo[orderCount].flIndex]],
id.sortKeysSH];
orderCount ¬ orderCount + 1};
ti: REF AdobeCommon.TemplateObject.string =>
IF ti.suppressFieldName THEN {
FOR i IN [0..ti.nameStart) DO
WriteChar[id.outSH, ti.s.Fetch[i], id.entryBytes]; ENDLOOP;
FOR i IN [ti.nameStart + ti.nameLength..ti.s.Length) DO
WriteChar[id.outSH, ti.s.Fetch[i], id.entryBytes]; ENDLOOP}
ELSE WriteString[id.outSH, ti.s, id.entryBytes];
ENDCASE;
templateItem ¬ templateItem.next;
ENDLOOP};
ENDCASE;
IF id.format = columns THEN ForceOutRow[instanceData];
IF id.format = plain THEN
WriteParagraphMark[id.outSH, id.format, id.entryBytes];
WriteSortPositions[id.sortKeysSH, entryStartPos, id.entryBytes.eb];
entryStartPos ¬ entryStartPos + id.entryBytes.eb};
ENDCASE};
WriteHeader: PROCEDURE [data: AdobeCommon.Handle, fl: AdobeOps.FieldList] = {
reportData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
date: Rope.ROPE ¬ Convert.RopeFromTime[BasicTime.Now[]];
date: Rope.ROPE ← Date.PackedToString[Time.Current[]];
WITH reportData SELECT FROM
rd: REF AdobeCommonInternal.InstanceData.report => {
WriteString[rd.outSH, "Report on file: ", rd.entryBytes];
WriteString[rd.outSH, rd.outputFile, rd.entryBytes];
WriteChar[rd.outSH, Ascii.SP, rd.entryBytes];
WriteLine[rd.outSH, date, rd.entryBytes];
WriteParagraphMark[rd.outSH, rd.format, rd.entryBytes];
Heap.systemZone.FREE[@date];
IF rd.format = columns THEN {
InitRowBuf[reportData];
FOR i: CARDINAL IN [0..rd.orderInfo.length) DO
WriteColumnField[
rd.orderInfo[i], rd.orderInfo[i].flName, data, TRUE]; -- oops set bool for coulumn heading
<< WriteReportPair[
orderInfo[i], orderInfo[i].flName, reportData, fl];>>
ENDLOOP;
ForceOutRow[reportData];
WriteDelimiter[rd.outSH, rd.format, rd.entryBytes];
WriteDelimiter[rd.outSH, rd.format, rd.entryBytes]}};
ENDCASE;
};
NotDoneYet: PROCEDURE [windowData: AdobeCommon.Handle] = {
AdobeCommon.PostMessage[windowData, TRUE, "Not Done Yet. "];
};
InitRowBuf: PROCEDURE [reportData: AdobeCommonInternal.InstanceDataHandle] = {
WITH reportData SELECT FROM
rd: REF AdobeCommonInternal.InstanceData.report => {
FOR i: CARDINAL IN [0..rd.orderInfo.length) DO
rd.rowLength ¬
rd.rowLength + rd.orderInfo[i].colWidth + AdobeCommon.ColSpace;
ENDLOOP;
rd.rowBuffer.s ¬ NIL; --String.MakeString[z, rowLength];
rd.rowBuffer.next ¬ NIL};
ENDCASE};
MakeOrderInfo: PROCEDURE [fieldsInReport: AdobeCommon.ReportFields, fl: AdobeOps.FieldList, reportOrderArray: AdobeOps.UserSpecifiedOrder]
RETURNS [orderInfo: AdobeCommon.OrderInfo] = {
itemCount: CARDINAL ¬ 0;
whichField, loopLen: CARD ¬ 0;
FOR i: CARDINAL IN [0..fieldsInReport.length) DO
IF fieldsInReport[i] THEN itemCount ¬ itemCount + 1; ENDLOOP;
orderInfo ¬ NEW[AdobeCommon.OrderInfoObject[itemCount]];
itemCount ¬ 0;
orderInfo is composed of entries only for those fields which are to appear in the report
IF reportOrderArray = NIL THEN
loopLen ¬ fl.length
ELSE
loopLen ¬ reportOrderArray.length;
FOR i: CARDINAL IN [0..loopLen) DO
IF reportOrderArray = NIL THEN
whichField ¬ i
ELSE
whichField ¬ reportOrderArray[i];
IF fieldsInReport[whichField] THEN {
orderInfo[itemCount].flName ¬ fl[whichField].name;
orderInfo[itemCount].flIndex ¬ whichField;
IF fl[whichField].defaultInfo[report].width # 0 THEN
orderInfo[itemCount].colWidth ¬ fl[
whichField].defaultInfo[report].width
ELSE
orderInfo[itemCount].colWidth ¬
WITH fl[whichField] SELECT FROM
fli: AdobeOps.ArFIO => MAX[5, fli.name.Length],
fli: AdobeOps.NumFIO => MAX[10, fli.name.Length],
fli: AdobeOps.FixFIO => MAX[
fli.maxLength / 2, fli.name.Length],
fli: AdobeOps.StrFIO => MAX[40, fli.name.Length],
fli: AdobeOps.DateFIO => MAX[9, fli.name.Length],
fli: AdobeOps.EnumFIO => MAX[10, fli.name.Length],
ENDCASE => 0;
IF itemCount # 0 THEN
orderInfo[itemCount].colIndex ¬
orderInfo[itemCount - 1].colIndex + orderInfo[
itemCount - 1].colWidth + AdobeCommon.ColSpace
ELSE orderInfo[itemCount].colIndex ¬ 0;
itemCount ¬ itemCount + 1};
ENDLOOP};
GetARVaues: PROCEDURE [ar: AdobeOps.ARNumber, fields: REF AdobeCommon.StringArray, valueArray: REF AdobeCommon.StringArray, orderInfo: AdobeCommon.OrderInfo, arStream: ARAccess.ARStorage, data: AdobeCommon.Handle] = {
arH: ARAccess.ARHandle;
must set the length of value in data table to 0 just in case the AR files don't have all the fields in the system
AdobeToolContext.ResetDataTableValues[arStream];
arH ¬ ARAccess.GetAR[data.systemHandle--.accessSession--, ar];
arStream ¬ ARAccess.ExamineAR[data.systemHandle--.accessSession--, arH];
contents must go into the array in the order they're to be used in the report
FOR i: CARDINAL IN [0..orderInfo.length) DO
valueArray[i] ¬ AdobeToolContext.GetValuePairFromTable[
orderInfo[i].flIndex, arStream];
ENDLOOP;
arH ¬ ARAccess.FreeAR[data.systemHandle--.accessSession--, arH]
};
ParseTemplate: PROCEDURE [data: AdobeCommon.Handle, setOrdering: BOOLEAN ¬ FALSE]
RETURNS [template: AdobeCommon.Template] = {
token: Rope.ROPE ¬ NIL; --String.MakeString[data.heap, 200];
sh: IO.STREAM ¬ NIL;
char: CHARACTER ¬ Ascii.NUL;
tail, next: AdobeCommon.Template ¬ NIL;
latestField: CARDINAL ¬ LAST[CARDINAL];
start, length: CARDINAL ¬ 0;
foundField: BOOLEAN ¬ FALSE;
suppress: BOOLEAN ¬ FALSE;
suppressionStart, suppressionEnd: CARDINAL ¬ 0;
orderIndex: CARDINAL ¬ 0;
tempOrder: AdobeCommon.OrderInfo ¬ NIL;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬
NARROW[data.instanceData];
GetToken: PROCEDURE = {
BEGIN OPEN String;
ENABLE IO.EndOfStream => {char ¬ Ascii.NUL; CONTINUE};
token ¬ NIL; --token.Length ¬ 0;
suppress ¬ FALSE;
suppressionEnd ¬ 0;
suppressionStart ¬ 0;
DO
ENABLE StringBoundsFault => GOTO Bounds;
SELECT char ¬
(IF char = Ascii.NUL THEN IO.GetChar[sh] ELSE char) FROM
'' => -- Don't interprete next char.
BEGIN
char ¬ IO.GetChar[sh];
token ¬ ARAccess.AppendChar[token, char];
token ← token.Concat[Convert.RopeFromChar[char, FALSE]];
AppendChar[token, char];
END;
'# =>
BEGIN
IF token.Length = 0 THEN
WHILE char = '# DO
token ¬ ARAccess.AppendChar[token, char];
token ← token.Concat[Convert.RopeFromChar[char, FALSE]];
AppendChar[token, char];
char ¬ IO.GetChar[sh];
ENDLOOP;
EXIT;
END;
'@ =>
BEGIN
IF token.Length = 0 THEN
WHILE char = '@ DO
token ¬ ARAccess.AppendChar[token, char];
token ← token.Concat[Convert.RopeFromChar[char, FALSE]];
AppendChar[token, char];
char ¬ IO.GetChar[sh];
ENDLOOP;
EXIT;
END;
'< => --assume start of field name
BEGIN
suppress ¬ TRUE;
suppressionStart ¬ token.Length;
END;
'> => --assume end of field name
suppressionEnd ¬ token.Length;
ENDCASE => token ¬ ARAccess.AppendChar[token, char];
token ← token.Concat[Convert.RopeFromChar[char, FALSE]];
AppendChar[token, char];
char ¬ IO.GetChar[sh];
ENDLOOP;
EXITS
Bounds =>
BEGIN
AdobeCommon.PostMessage[
data.msgSW, TRUE, "String too long in template file!"];
token.Length ← 0;
END;
};
template ¬ NIL;
WITH instanceData SELECT FROM
id: REF AdobeCommonInternal.InstanceData.report => {
id.templateFile ¬ data.getContents[data.editors[2]];
sh ¬ PFS.StreamOpen[PFS.PathFromRope[id.templateFile] ! PFS.Error => ERROR templateProblem];
MStream.ReadOnly[templateFile, [] ! MStream.Error => ERROR templateProblem];
};
ENDCASE;
IF setOrdering THEN
tempOrder ¬ NEW[AdobeCommon.OrderInfoObject[5]];
DO
GetToken[];
IF suppress THEN suppress ¬ suppressionEnd # 0;
IF token.Length > 0 THEN
BEGIN
next ← NEW[AdobeCommon.TemplateObject];
SELECT token.Fetch[0] FROM
'# =>
next ¬ NEW[AdobeCommon.TemplateObject.fixed ¬ [
NIL, fixed[width: token.Length]]];
'@ => next ¬ NEW[AdobeCommon.TemplateObject.variable ¬ [NIL, variable[]]];
ENDCASE =>
next ¬ NEW[AdobeCommon.TemplateObject.string ¬ [
NIL, string[s: token, suppressFieldName: suppress]]];
IF template = NIL THEN template ¬ next
ELSE
BEGIN
FOR tail ¬ template, tail.next UNTIL tail.next = NIL DO
ENDLOOP;
tail.next ¬ next;
END;
WITH next SELECT FROM
to: REF AdobeCommon.TemplateObject.string => {
name: Rope.ROPE ¬ NIL; --String.SubStringDescriptor;
[latestField, start, length] ¬ FindFieldNameInString[
token, data.systemHandle.fieldList];
to.nameStart ¬ start;
to.nameLength ¬ length;
IF suppressionStart # to.nameStart
OR suppressionEnd # to.nameStart + to.nameLength THEN
to.suppressFieldName ¬ FALSE;
IF setOrdering AND latestField # LAST[CARDINAL] THEN {
IF orderIndex = tempOrder.length THEN {
temp: AdobeCommon.OrderInfo ¬ NEW[
AdobeCommon.OrderInfoObject[tempOrder.length + 5]];
FOR i: CARDINAL IN [0..tempOrder.length) DO
temp[i] ¬ tempOrder[i]; ENDLOOP;
data.heap.FREE[@tempOrder];
tempOrder ¬ temp};
tempOrder[orderIndex].flIndex ¬ latestField;
tempOrder[orderIndex].flName ¬ NIL; -- String.MakeString[data.heap, length];
name ¬ Rope.Substr[token, start, length];
tempOrder[orderIndex].flName ¬ tempOrder[orderIndex].flName.Concat[name];
String.AppendSubString[tempOrder[orderIndex].flName, @name];
orderIndex ¬ orderIndex + 1}};
ENDCASE =>
WITH instanceData SELECT FROM
id: REF AdobeCommonInternal.InstanceData.report =>
IF latestField # LAST[CARDINAL] THEN {
data.setDisplayStyle[data.fieldViewer.buttons[latestField].button, $WhiteOnBlack];
id.fieldsInReport[latestField] ¬ foundField ¬ TRUE;
};
ENDCASE;
END
ELSE EXIT;
ENDLOOP;
IF ~foundField THEN
BEGIN
AdobeCommon.PostMessage[data, TRUE, "No field names recognized in template file!"];
template ← FreeTemplateList[template, data.heap];
END
ELSE
WITH instanceData SELECT FROM
reportData: REF AdobeCommonInternal.InstanceData.report => {
reportData.orderInfo ¬ NEW[AdobeCommon.OrderInfoObject[orderIndex]];
FOR i: CARDINAL IN [0..orderIndex) DO
reportData.orderInfo[i] ¬ tempOrder[i]; ENDLOOP;
data.heap.FREE[@tempOrder]
};
ENDCASE;
IO.Close[sh];
Stream.Delete[sh]
};
FreeTemplateList: PROCEDURE [
template: AdobeCommon.Template, z: UNCOUNTED ZONE]
RETURNS [nilTemplate: AdobeCommon.Template ← NIL] = {
Free: PROCEDURE [t: AdobeCommon.Template] = {
IF t.next # NIL THEN Free[t.next];
WITH t SELECT FROM string => z.FREE[@s]; ENDCASE;
z.FREE[@t]};
Free[template]};
FindFieldNameInString: PROCEDURE [s: Rope.ROPE, fl: AdobeOps.FieldList]
RETURNS [fli, start, length: CARDINAL] =
BEGIN -- Find longest field name that can.
i, astart: CARDINAL;
found: BOOLEAN;
fli ¬ LAST[CARDINAL];
length ¬ 0;
FOR i IN [0..fl.length) DO
[found, astart] ¬ SubString[s, fl[i].name];
IF found THEN
SELECT fli FROM
LAST[CARDINAL] => {
fli ¬ i; start ¬ astart; length ¬ fl[fli].name.Length};
ENDCASE =>
IF fl[fli].name.Length < fl[i].name.Length THEN {
fli ¬ i; start ¬ astart; length ¬ fl[fli].name.Length};
ENDLOOP;
END;
SubString: PROCEDURE [s1, s2: Rope.ROPE] RETURNS [found: BOOLEAN, start: CARDINAL] = {
TRUE IFF s2 is contained in s1
BEGIN OPEN String;
i: CARDINAL;
pos: INT ¬ 0;
s1ss, s2ss: SubStringDescriptor;
s2ss ← [base: s2, offset: 0, length: s2.length];
s1ss ← [base: s1, offset: 0, length: s2.length];
IF s2.length > s1.length THEN RETURN[FALSE, 0];
FOR i IN [0..s1.length - s2.length] DO
s1ss.offset ← i;
IF EquivalentSubString[@s1ss, @s2ss] THEN
RETURN[TRUE, s1ss.offset]
ENDLOOP;
pos ¬ Rope.Find[s1, s2, 0];
IF pos >= 0 THEN
RETURN[TRUE, pos];
RETURN[FALSE, 0]
};
Output Routines
WriteReportPair: PROCEDURE [orderItem: AdobeCommon.OrderItem, flValue: Rope.ROPE, reportData: AdobeCommonInternal.InstanceDataHandle, fieldList: AdobeOps.FieldList] = {
WITH reportData SELECT FROM
rd: REF AdobeCommonInternal.InstanceData.report => {
IF flValue = NIL THEN flValue ¬ "";
SELECT rd.format FROM
columns => {
used only for printing column headings.
sp: CARDINAL;
rd.rowBuffer.s ¬ rd.rowBuffer.s.Concat[flValue];
sp ¬ orderItem.colWidth - flValue.Length + AdobeCommon.ColSpace;
FOR i: CARDINAL IN [rd.rowBuffer.s.Length..rd.rowBuffer.s.Length + sp) DO
rd.rowBuffer.s ¬ rd.rowBuffer.s.Concat[" "];ENDLOOP;
rd.rowBuffer.s.length ← rd.rowBuffer.s.length + sp
};
plain => {
WriteString[rd.outSH, orderItem.flName, rd.entryBytes];
WriteString[rd.outSH, ": ", rd.entryBytes];
WriteLine[rd.outSH, flValue, rd.entryBytes];
WriteSortEntry[
flValue, NEW[AdobeOps.FieldItemObject ¬ --@--fieldList[orderItem.flIndex]], rd.sortKeysSH]};
ENDCASE};
ENDCASE;
};
Pad: PROCEDURE [sp: CARDINAL, str: Rope.ROPE] RETURNS [paddedstr: Rope.ROPE ¬ NIL] = {
paddedstr ¬ str;
FOR i: CARDINAL IN [str.Length..str.Length+sp) DO
str ¬ str.Concat[" "]; ENDLOOP;
str[i] ← Ascii.SP; ENDLOOP; --avoids overhead of AppendChar call
str.Length ← str.Length+sp;
RETURN[str];
};
GetWord: PROCEDURE [sH: IO.STREAM, options: Stream.InputOptions]
RETURNS [word: Stream.Word] = INLINE {
[] ← sH.get[sH, Stream.Block[LOOPHOLE[LONG[@word]], 0, 2], options]};
WriteColumnField: PROCEDURE [orderItem: AdobeCommon.OrderItem, flValue: Rope.ROPE,
data: AdobeCommon.Handle, columnHead: BOOLEAN ¬ FALSE] = {
totalSpaces: CARDINAL ¬ orderItem.colWidth + AdobeCommon.ColSpace;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬
NARROW[data.instanceData];
WITH instanceData SELECT FROM
id: REF AdobeCommonInternal.InstanceData.report => {
IF ~columnHead THEN WriteSortEntry[
flValue, NEW[AdobeOps.FieldItemObject ¬ data.systemHandle.fieldList[orderItem.flIndex]],
id.sortKeysSH];
IF Rope.IsEmpty[flValue] THEN {
id.rowBuffer.s ¬ Pad[totalSpaces, id.rowBuffer.s]; RETURN};
IF flValue.Length <= INT[orderItem.colWidth] THEN {
fits on one line
id.rowBuffer.s ¬ id.rowBuffer.s.Concat[flValue];
String.AppendString[rowBuffer.s, flValue];
id.rowBuffer.s ¬ Pad[totalSpaces - flValue.Length, id.rowBuffer.s]}
ELSE { --must be broken onto more than one line.
row: AdobeCommon.RowBuffer ¬ id.rowBuffer;
start, index, lastEnd: CARDINAL ¬ 0;
done: BOOLEAN ¬ FALSE;
str: Rope.ROPE ¬ NIL;
strnOffset, strnLen: CARD ¬ 0;
str: String.SubStringDescriptor;
str ¬ flValue;
WHILE ~done DO
lastEnd ¬ start + orderItem.colWidth - 1;
FOR index IN [start..start+orderItem.colWidth) DO
SELECT flValue.Fetch[index] FROM
Ascii.SP, Ascii.TAB => lastEnd ¬ index;
Ascii.CR, Ascii.LF => {lastEnd ¬ index;
IF index = flValue.Length - 1 THEN done ¬ TRUE;
EXIT};
ENDCASE => NULL;
IF index = flValue.Length - 1 THEN {
done ¬ TRUE; lastEnd ¬ index; EXIT};
ENDLOOP;
strnOffset ¬ start;
SELECT flValue.Fetch[lastEnd] FROM
Ascii.CR, Ascii.LF => {
strnLen ¬ lastEnd-start;--skip CR
start ¬ start + strnLen + 1};
ENDCASE => {
add 1 to length so SP break goes on same line unless
at end of flValue
IF done THEN strnLen ¬ lastEnd-start + 1
ELSE strnLen ¬ MIN[
lastEnd-start+1, orderItem.colWidth];
start ¬ start + strnLen};
str ¬ Rope.Substr[flValue, strnOffset, strnLen];
row.s ¬ row.s.Concat[str];
String.AppendSubString[row.s, @str];
row.s ¬ Pad[totalSpaces - str.Length, row.s];
IF ~done AND INT[index] < flValue.Length THEN
IF row.next # NIL THEN {
row ¬ row.next;
row.s ¬ Pad[orderItem.colIndex - row.s.Length, row.s]}
ELSE {
row.next ¬ NEW[AdobeCommon.RowBufferRec ¬ [NIL, NIL]];
String.MakeString[z, rowLength], NIL]];
row ¬ row.next;
row.s ¬ Pad[orderItem.colIndex, row.s]};
ENDLOOP}};
ENDCASE};
WriteLine: PROCEDURE [sh: IO.STREAM, s: Rope.ROPE, entryBytes: AdobeCommonInternal.EntryBytes] = {
WriteString[sh, s, entryBytes];
WriteChar[sh, Ascii.CR, entryBytes]};
WriteString: PROCEDURE [sh: IO.STREAM, s: Rope.ROPE, entryBytes: AdobeCommonInternal.EntryBytes] = {
IF s # NIL THEN {
IO.PutRope[sh, s]; entryBytes.eb ¬ entryBytes.eb + s.Length}};
WriteChar: PROCEDURE [sh: IO.STREAM, c: CHARACTER, entryBytes: AdobeCommonInternal.EntryBytes] = {
IF c = Ascii.CR OR c = Ascii.LF THEN
IO.PutRope[sh, "\n"]
IO.PutChar[sh, Ascii.CR]
IO.PutF[sh, "%g", IO.char[c]];
ELSE
IO.PutChar[sh, c];
entryBytes.eb ¬ entryBytes.eb + 1
};
WriteParagraphMark: PROCEDURE [sh: IO.STREAM, outType: AdobeCommon.FormatType,
entryBytes: AdobeCommonInternal.EntryBytes] = {
WriteChar[sh, Ascii.CR, entryBytes]};
<<seems to me that WriteParagraphMark appears in two places and all we want it to do is to output a CR
IF outType = template THEN {
WriteChar[sh, Ascii.ControlZ, entryBytes];
WriteChar[sh, Ascii.CR, entryBytes]}
ELSE WriteDelimiter[sh, outType, entryBytes]};>>
WriteDelimiter: PROCEDURE [sh: IO.STREAM, outType: AdobeCommon.FormatType,
entryBytes: AdobeCommonInternal.EntryBytes] = {
IF outType # template THEN WriteChar[sh, Ascii.CR, entryBytes]};
ForceOutRow: PROCEDURE [reportData: AdobeCommonInternal.InstanceDataHandle] = {
row: AdobeCommon.RowBuffer;
WITH reportData SELECT FROM
rd: REF AdobeCommonInternal.InstanceData.report => {
row ¬ rd.rowBuffer;
DO
IF row.s.Length # 0 THEN
WriteLine[rd.outSH, row.s, rd.entryBytes];
row.s ¬ NIL;
row.s.length ← 0;
IF row.next # NIL THEN row ¬ row.next ELSE EXIT;
ENDLOOP};
ENDCASE};
Sortkeys file routines
WriteSortHeader: PROCEDURE [data: AdobeCommon.Handle] = {
instanceData: AdobeCommonInternal.InstanceDataHandle ¬
NARROW[data.instanceData];
WITH instanceData SELECT FROM
reportData: REF AdobeCommonInternal.InstanceData.report => {
FOR i: CARDINAL IN [0..reportData.orderInfo.length) DO
WITH data.systemHandle.fieldList[reportData.orderInfo[i].flIndex] SELECT FROM
fli: AdobeOps.StrFIO => LOOP;
ENDCASE =>
WriteSortString[reportData.orderInfo[i].flName, TRUE, reportData.sortKeysSH];
ENDLOOP;
WriteSortEnd[reportData.sortKeysSH]};
ENDCASE};
WriteSortPositions: PROCEDURE [sortSH: IO.STREAM, start: CARDINAL, length: CARDINAL] = {
ln: CARDINAL ¬ LAST[CARD16] + 1;
ln: Inline.LongNumber;
ln.lc ← start;
copied from old, not sure this is all ok.
WriteSortNumber[start / ln --page-- , 0, TRUE, sortSH];
WriteSortNumber[start MOD ln --page-- , 0, TRUE, sortSH];
WriteSortNumber[ln.highbits --page-- , 0, TRUE, sortSH];
WriteSortNumber[ln.lowbits --byte-- , 0, TRUE, sortSH];
WriteSortNumber[length, 0, TRUE, sortSH];
IO.PutChar[sortSH, Ascii.CR]};
WriteSortEntry: PROCEDURE [value: Rope.ROPE, flItem: AdobeOps.FieldItemHandle, sortSH: IO.STREAM] = {
WITH flItem­ SELECT FROM
fio: AdobeOps.ArFIO => WriteARId[value, 5, TRUE, sortSH];
fio: AdobeOps.NumFIO => WriteNumeric[value, TRUE, sortSH];
fio: AdobeOps.DateFIO =>
BEGIN
u: BasicTime.Unpacked;
u ¬ Convert.UnpackedTimeFromRope[ --Time.Unpack[Date.StringToPacked[
value ! Convert.Error => {u.year ¬ 0; u.month ¬ LOOPHOLE[0]; u.day ¬ 0; u.hour ¬ 0; u.minute ¬ 0; u.second ¬ 0; CONTINUE}];--.dt];
WriteSortNumber[u.year, 4, FALSE, sortSH];
WriteSortNumber[LOOPHOLE[u.month, CARDINAL] + 1, 2, FALSE, sortSH];
WriteSortNumber[u.day, 2, FALSE, sortSH];
WriteSortNumber[u.hour, 2, FALSE, sortSH];
WriteSortNumber[u.minute, 2, FALSE, sortSH];
WriteSortNumber[u.second, 2, TRUE, sortSH];
END;
fio: AdobeOps.StrFIO => RETURN;
ENDCASE => WriteSortString[value, TRUE, sortSH];
};
WriteARId: PROCEDURE [val: Rope.ROPE, len: CARDINAL, nulToo: BOOLEAN,
sortSH: IO.STREAM] = {
i: CARDINAL;
str: Rope.ROPE ¬ NIL; -- = [10];
str.length ← len;
this is a workaround if ARIDs in the AR Files are bogus. should take this out eventually. workstation would freeze if val.length > len.
IF val.Length <= INT[len] THEN {
str ¬ val;
FOR i IN [0..len - val.Length) DO str ¬ Rope.Concat["0", str]; ENDLOOP;
FOR i IN [0..len - val.length) DO str[i] ← '0; ENDLOOP;
FOR i IN [len - val.length..len) DO
str[i] ← val[i - (len - val.length)]; ENDLOOP
}
ELSE
FOR i IN [0..len) DO str ¬ Rope.Concat["0", str]; ENDLOOP;
FOR i IN [0..str.length) DO str[i] ← '0; ENDLOOP;
WriteSortString[str, nulToo, sortSH]};
WriteNumeric: PROCEDURE [val: Rope.ROPE, nulToo: BOOLEAN, sortSH: IO.STREAM] = {
cloned from WriteARId above.
all numeric strings in the sortKey file are 10 chars long.
enough for string rep of largest LONG CARDINAL (2^32)
maxCharsPerLongCardinal: CARDINAL = 10;
str: Rope.ROPE ¬ NIL; -- = [maxCharsPerLongCardinal];
i: CARDINAL;
str.length ← maxCharsPerLongCardinal;
IF val.Length <= maxCharsPerLongCardinal THEN {
pad: CARDINAL ¬ maxCharsPerLongCardinal - val.Length;
str ¬ val;
FOR i IN [0..pad) DO
str ¬ Rope.Concat["0", str];
ENDLOOP;
str[i] ← '0; ENDLOOP;
FOR i IN [pad..maxCharsPerLongCardinal) DO
str[i] ← val[i - pad]; ENDLOOP
}
ELSE -- safety valve. should never happen.
FOR i IN [0..str.Length) DO
str ¬ Rope.Concat["0", str];
ENDLOOP;
WriteSortString[str, nulToo, sortSH]};
WriteSortNumber: PROCEDURE [num: UNSPECIFIED, len: CARDINAL, nulToo: BOOLEAN,
sortSH: IO.STREAM] = { -- Pack num into string of length len and write.
If len is zero then don't pad
i: CARDINAL;
str: Rope.ROPE ¬ NIL; -- = [10];
str.length ← 0;
str ¬ Convert.RopeFromCard[num, 10, FALSE];
String.AppendNumber[str, num, 10];
IF len > 0 AND str.Length < INT[len] THEN {
oldLen: CARDINAL ¬ str.Length;
FOR i IN [oldLen..len) DO
str ¬ Rope.Concat["0", str];
ENDLOOP;
};
str.length ← len;
FOR i IN [0..oldLen) DO
str[len - i - 1] ← str[oldLen - i - 1]; ENDLOOP;
FOR i IN [0..len - oldLen) DO str[i] ← '0; ENDLOOP;
END;
WriteSortString[str, nulToo, sortSH];
RETURN;
};
WriteSortString: PROCEDURE [s: Rope.ROPE, nulToo: BOOLEAN, sortSH: IO.STREAM] = {
i: CARDINAL;
IF s # NIL THEN
FOR i IN [0..s.Length) DO
ARSortTool can't handle CRs as data in sortkeys file.
IO.PutChar[sortSH, IF s.Fetch[i] = Ascii.CR THEN Ascii.SP ELSE s.Fetch[i]];
ENDLOOP;
IF nulToo THEN IO.PutChar[sortSH, Ascii.NUL];
RETURN;
};
WriteSortEnd: PROCEDURE [sortSH: IO.STREAM] = {
IO.PutChar[sortSH, Ascii.CR]};
SetFormSWFieldInvisible: PROCEDURE [data: AdobeCommon.Handle,-- wH: Window.Handle,-- invisible: BOOLEAN, index: CARDINAL ← 0, all: BOOLEANFALSE] = {
inst: AdobeCommonInternal.InstanceDataHandle ← NARROW[data.instanceData];
formItem: FormSW.ItemHandle;
IF all THEN {
FOR i: CARDINAL IN
[0..data.context.arSH.formSWOrderArray[data.tool].length) DO
formItem ← FormSW.FindItem[inst.formSW, i];
formItem.flags.invisible ← invisible;
ENDLOOP}
ELSE {
formItem ← FormSW.FindItem[inst.formSW, index];
formItem.flags.invisible ← invisible};
};
END.
RLC   28-Jul-86 9:23:15 Recompile to make df Consistent. Add {} pair to pass compilation
RLC   15-Sep-86 15:47:41 Repair damage from coulmn wrapping fix which broke sorting.
RLC    8-Oct-87 10:52:12 Add WriteNumeric, a clone of WriteARId using a max string size of 10 instead of 5. (AR12070)