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
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];
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;
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};
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};
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]
};
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]
};
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]};