<<>> <> <> <> <> <> DIRECTORY AccessCH USING [NSNameFromRope], AdobeCommon USING [AdobeViewerDataRec, ButtonSeqObject, CatchErrors, DependentsSequenceRec, EnumeratedTypes, EnumeratedTypesRec, GetNextAR, Handle, InitialSetStatus, PostMessage, PostNumber, SelectionsSequence, SetStatus, StringArray, validRelations], AdobeCommonInternal USING [InstanceData, InstanceDataHandle], AdobeOps USING [ARSystemHandle, ARNumber, FieldItemObject, FieldItemObjectRec, FieldType, nilARNumber, nilEnum, QLHandle, QLObject, QueryList, QueryListBody, SetOfARs, SetOfARsObject, ToolType, ArFIO, DateFIO, NumFIO, FixFIO, EnumFIO, StrFIO], AdobeServer USING [FieldItemValueRec, FieldItemQueryValue], AdobeP75V2, AdobeTool, AdobeUI, Ascii USING [CR, NUL, SP, TAB], BasicTime USING [GMT], Convert USING [Error, CardFromRope, RopeFromChar, TimeFromRope], Rope USING [Concat, Equal, Fetch, IsEmpty, Length, ROPE], XNSAdobeClientOps USING [LookupARs, ReadLastARNumber]; AdobeToolImplB: CEDAR MONITOR IMPORTS AccessCH, AdobeCommon, AdobeP75V2, AdobeTool, Convert, Rope, XNSAdobeClientOps EXPORTS AdobeCommon, --AdobeCommonInternal, --AdobeTool = { EnumeratedFIH: TYPE = REF enumerated AdobeOps.FieldItemObjectRec; backStr: Rope.ROPE ¬ NIL; --for NilFormProc <> queryPos: CARDINAL = 0; clearFormPos: CARDINAL = 1; showElemPos: CARDINAL = 2; resetQLPos: CARDINAL = 3; qyBkgdPos: CARDINAL = 4; qlNamePos: CARDINAL = 5; nQueryParams: CARDINAL = 6; <> UnterminatedQuote: PUBLIC SIGNAL = CODE; nonQuote: CHARACTER = Ascii.NUL; SkipMode: TYPE = {none, whiteSpace, nonToken}; GetCharProcType: TYPE = PROCEDURE [h: LSHandle, e: REF BoolRec ¬ NIL] RETURNS [c: CHARACTER]; QuoteProcType: TYPE = PROCEDURE [c: CHARACTER] RETURNS [closing: CHARACTER]; FilterProcType: TYPE = PROCEDURE [c: CHARACTER, data: FilterState, extra: CHAR ¬ ' ] RETURNS [inClass: BOOLEAN]; FilterState: TYPE = REF StandardFilterState; StandardFilterState: TYPE = ARRAY [0..2) OF UNSPECIFIED; Handle: TYPE = REF Object; Object: TYPE = RECORD [ getChar: GetCharProcType, break: CHAR ¬ NULL]; StringToHandle: PROCEDURE [s: Rope.ROPE, offset: CARDINAL ¬ 0] RETURNS [h: LSHandle] ~ { h ¬ NEW[LSObject ¬ [[getChar: StringGetChar, break: NULL], s, offset]] }; StringGetChar: GetCharProcType ~ { IF h.i < Rope.Length[h.s] THEN { c ¬ Rope.Fetch[h.s, h.i]; h.i ¬ h.i + 1} ELSE c ¬ Ascii.NUL; }; WhiteSpaceInline: PROCEDURE [c: CHARACTER] RETURNS [BOOLEAN] = INLINE { RETURN[SELECT c FROM Ascii.SP, Ascii.TAB, Ascii.CR => TRUE, ENDCASE => FALSE]; }; QuoteFilter: FilterProcType = { IF c = Ascii.NUL THEN {SIGNAL UnterminatedQuote; RETURN [FALSE]} ELSE RETURN[c # extra]}; MaybeQuoted: PROCEDURE [h: LSHandle, data: FilterState, filter: FilterProcType, isQuote: QuoteProcType, skip: SkipMode ¬ whiteSpace, temporary: BOOLEAN ¬ TRUE] RETURNS [value: Rope.ROPE] = { closeQuote: CHARACTER; ApplyFilter: FilterProcType ¬ filter; IF data # NIL THEN data ¬ NIL; value ¬ NIL; <> DO IF (h.object.break ¬ h.object.getChar[h]) = Ascii.NUL THEN RETURN; IF skip = whiteSpace AND WhiteSpaceInline[h.object.break] THEN LOOP; IF (closeQuote ¬ isQuote[h.object.break]) # nonQuote THEN IF (h.object.break ¬ h.object.getChar[h]) = closeQuote THEN { h.object.break ¬ h.object.getChar[h]; IF h.object.break = closeQuote THEN EXIT; -- doubling close quote is literal quote character RETURN} ELSE { IF h.object.break = Ascii.NUL THEN {SIGNAL UnterminatedQuote; RETURN}; ApplyFilter ¬ QuoteFilter; EXIT}; IF filter[h.object.break, data] THEN EXIT; IF skip = none OR skip = whiteSpace THEN RETURN; ENDLOOP; <> <> { ENABLE UNWIND => NULL; WHILE h.object.break # Ascii.NUL DO value ¬ value.Concat[Convert.RopeFromChar[h.object.break, FALSE]]; <> IF ~ApplyFilter[h.object.break ¬ h.object.getChar[h], data, closeQuote] THEN { IF ApplyFilter = QuoteFilter THEN { h.object.break ¬ h.object.getChar[h]; -- get next character IF h.object.break = closeQuote THEN LOOP}; -- of closeQuote, include character in token EXIT; }; ENDLOOP; <> <> <> <> }; }; <> ParseError: SIGNAL [errType: ParseErrorType] = CODE; --make more specific later ParseErrorType: TYPE = { badNumber, badDate, notValidEnumerated, strayQuote, badQuerySyntax}; LSHandle: TYPE = REF LSObject; LSObject: TYPE = RECORD [ object: Object, s: Rope.ROPE, i: INT]; TokenType: TYPE = {op, string, andor}; QueryItemHandle: TYPE = REF QueryItemSeq ¬ NIL; QueryItemSeq: TYPE = RECORD [ fLIndex: CARDINAL, seq: SEQUENCE len: CARDINAL OF REF ANY]; DistilledToken: TYPE = RECORD [ SELECT type: TokenType FROM op => [op: AdobeP75V2.Relation], string => [s: Rope.ROPE], andor => [andOr: {and, or}] ENDCASE]; OpDT: TYPE ~ REF op DistilledToken; StringDT: TYPE ~ REF string DistilledToken; AndOrDT: TYPE ~ REF andor DistilledToken; ParseStateType: TYPE = {start, op, andor, string, end}; ProcessedQueryHandle: TYPE = REF ProcessedQuery; ProcessedQuery: TYPE = RECORD [ seq: SEQUENCE len: CARDINAL OF QueryItemHandle]; FieldItemHandle: TYPE = REF FieldItemSeq; FieldItemSeq: TYPE = RECORD [ seq: SEQUENCE len: CARDINAL OF AdobeServer.FieldItemQueryValue]; GetValidRelations: PUBLIC PROCEDURE [ type: AdobeOps.FieldType] RETURNS [relStrings: REF AdobeCommon.StringArray] = { numValid, index: CARDINAL ¬ 0; op: AdobeP75V2.Relation; FOR op IN AdobeP75V2.Relation DO IF AdobeCommon.validRelations[type][op] THEN numValid ¬ numValid + 1; ENDLOOP; IF type = enumerated THEN numValid ¬ numValid + 2 --OR, AND # ELSE numValid ¬ numValid + 3; --OR, AND, NIL relStrings ¬ NEW[AdobeCommon.StringArray[numValid]]; FOR op IN AdobeP75V2.Relation DO IF AdobeCommon.validRelations[type][op] THEN { relStrings[index] ¬ SELECT op FROM equal => " = ", notEqual => " # ", lessThan => " < ", lessThanOrEqual => " <= ", greaterThan => " > ", greaterThanOrEqual => " >= ", in => " HAS ", notIn => " ~HAS ", ENDCASE => ""; index ¬ index + 1}; ENDLOOP; relStrings[index] ¬ " OR "; IF type = enumerated THEN relStrings[index ¬ index + 1] ¬ " AND # " ELSE { relStrings[index ¬ index + 1] ¬ " AND "; relStrings[index ¬ index + 1] ¬ " NIL "}; }; GetPossibilities: PUBLIC PROCEDURE [bh: AdobeCommon.EnumeratedTypes] RETURNS [possibilities: LIST OF Rope.ROPE] = { IF bh.currentMenu >= bh.allSelections.length THEN RETURN [LIST["Nil"]]; RETURN[bh.allSelections[bh.currentMenu].ropes]; }; CountARs: PUBLIC PROCEDURE [set: AdobeOps.SetOfARs] RETURNS [n: LONG CARDINAL] = { n ¬ 0; FOR i: CARDINAL IN [0..set.len) DO n ¬ n + set[i].runLength; ENDLOOP; }; <> SetUpQueryTool: PUBLIC PROC [handle: AdobeCommon.Handle] = { thisViewer: REF ANY ¬ handle.fieldViewer.outer; thisSH: AdobeOps.ARSystemHandle ¬ handle.systemHandle; thisField: AdobeCommon.EnumeratedTypes ¬ NIL; x,y,w,h: CARD; lineIndex: INTEGER ¬ 0; fieldIndex: CARD ¬ 0; fieldHeight: CARDINAL ¬ 14; numFields: CARD ¬ thisSH.fieldList.length; instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[handle.instanceData]; stringCount: CARD _ 0; IF handle.fieldViewer.buttons # NIL THEN AdobeTool.EmptyFieldViewer[handle]; <> FOR field: CARDINAL IN [0..thisSH.fieldList.length) DO WITH thisSH.fieldList[field] SELECT FROM it: AdobeOps.StrFIO => numFields ¬ numFields - 1; ENDCASE; ENDLOOP; handle.fieldViewer.buttons ¬ NEW[AdobeCommon.ButtonSeqObject[numFields]]; WITH instanceData SELECT FROM it: REF AdobeCommonInternal.InstanceData.query => it.queryStrings ¬ NEW[AdobeCommon.StringArray[numFields]]; ENDCASE; FOR field: CARDINAL IN [0..thisSH.fieldList.length) DO WITH thisSH.fieldList[field] SELECT FROM it: AdobeOps.StrFIO => { stringCount _ stringCount + 1; }; ENDCASE => { handle.fieldViewer.buttons[fieldIndex] ¬ NEW[AdobeCommon.EnumeratedTypesRec]; handle.fieldViewer.buttons[fieldIndex].mainViewer ¬ handle; }; IF fieldIndex < handle.fieldViewer.buttons.length THEN thisField ¬ handle.fieldViewer.buttons[fieldIndex]; WITH thisSH.fieldList[field] SELECT FROM it: AdobeOps.EnumFIO => { numSubMenus, saveKey, currentEnum: CARD ¬ 0; thisField.type ¬ enumerated; thisField.dependentsSequence ¬ NEW[AdobeCommon.DependentsSequenceRec[5]]; IF it.field # LAST[CARD16] THEN { currentSubMenu: CARD ¬ 0; thisField.dependentOn ¬ handle.fieldViewer.buttons[it.field - stringCount]; numSubMenus ¬ AdobeTool.CountRopes[thisField.dependentOn.allSelections[0].ropes]; AdobeTool.BumpNumOfDeps[handle.fieldViewer.buttons[fieldIndex], handle.fieldViewer.buttons[it.field - stringCount]]; thisField.currentMenu ¬ numSubMenus - 1; thisField.allSelections ¬ NEW[AdobeCommon.SelectionsSequence[numSubMenus]]; WITH thisSH.fieldList[it.field] SELECT FROM dep: AdobeOps.EnumFIO => { did: BOOL ¬ FALSE; FOR index: CARD IN [0..dep.possibilities[0].enumRecs.length) DO did ¬ FALSE; FOR itIndex: CARD IN [0..it.possibilities.length) DO IF it.possibilities[itIndex].keyedDependency = dep.possibilities[0].enumRecs[index].item THEN { thisField.allSelections[currentSubMenu].num ¬ index; FOR i: CARD IN [0..it.possibilities[itIndex].enumRecs.length) DO thisField.allSelections[currentSubMenu].ropes ¬ CONS[it.possibilities[itIndex].enumRecs[it.possibilities[itIndex].enumRecs.length - i - 1].tag, thisField.allSelections[currentSubMenu].ropes]; ENDLOOP; currentSubMenu ¬ currentSubMenu + 1; did ¬ TRUE; EXIT; }; ENDLOOP; IF ~ did THEN { thisField.allSelections[currentSubMenu] ¬ [index, LIST["Nil"]]; currentSubMenu ¬ currentSubMenu + 1; }; ENDLOOP; }; ENDCASE => ERROR; } ELSE { thisField.dependentOn ¬ NIL; thisField.currentMenu ¬ 0; thisField.allSelections ¬ NEW[AdobeCommon.SelectionsSequence[1]]; thisField.allSelections[0].num ¬ it.possibilities[0].enumRecs[0].item; FOR index: CARD IN [0..it.possibilities[0].enumRecs.length) DO thisField.allSelections[0].ropes ¬ CONS[ it.possibilities[0].enumRecs[it.possibilities[0].enumRecs.length - index - 1].tag, thisField.allSelections[0].ropes]; ENDLOOP; thisField.currentSelection ¬ it.possibilities[0].enumRecs.length - 1; }; thisField.button ¬ handle.makeButton[ parent: thisViewer, x: 0, y: lineIndex * fieldHeight, name: Rope.Concat[it.name, ": "], <> data: handle.fieldViewer.buttons[fieldIndex], scrollable: TRUE, proc: $HintMenuProc, cData: handle.fieldViewer.buttons[fieldIndex] ]; [x, y, w, h] ¬ handle.getBoxGeometry[thisField.button]; thisField.controllerOf ¬ handle.newFieldBox[ parent: thisViewer, x: w+5, y: lineIndex * fieldHeight, w: 400, h: h, border: FALSE, scrollable: FALSE ]; fieldIndex ¬ fieldIndex + 1; }; it: AdobeOps.ArFIO => { handle.fieldViewer.buttons[fieldIndex].type ¬ arId; handle.fieldViewer.buttons[fieldIndex].button ¬ handle.makeButton[ parent: thisViewer, x: 0, y: lineIndex * fieldHeight, name: Rope.Concat[it.name, ": "], <> data: handle.fieldViewer.buttons[fieldIndex], scrollable: TRUE, proc: $HintMenuProc, cData: handle.fieldViewer.buttons[fieldIndex] ]; [x, y, w, h] ¬ handle.getBoxGeometry[handle.fieldViewer.buttons[fieldIndex].button]; handle.fieldViewer.buttons[fieldIndex].controllerOf ¬ handle.newFieldBox[ parent: thisViewer, x: w+5, y: lineIndex * fieldHeight, w: 400, h: h, border: FALSE, scrollable: FALSE ]; handle.setContents[handle.fieldViewer.buttons[fieldIndex].controllerOf, "> 0"]; fieldIndex ¬ fieldIndex + 1; }; it: AdobeOps.DateFIO => { handle.fieldViewer.buttons[fieldIndex].type ¬ dateTime; handle.fieldViewer.buttons[fieldIndex].button ¬ handle.makeButton[ parent: thisViewer, x: 0, y: lineIndex * fieldHeight, name: Rope.Concat[it.name, ": "], <> data: handle.fieldViewer.buttons[fieldIndex], proc: $HintMenuProc, cData: handle.fieldViewer.buttons[fieldIndex] ]; [x, y, w, h] ¬ handle.getBoxGeometry[handle.fieldViewer.buttons[fieldIndex].button]; handle.fieldViewer.buttons[fieldIndex].controllerOf ¬ handle.newFieldBox[ parent: thisViewer, x: w+5, y: lineIndex * fieldHeight, w: 400, h: h, border: FALSE, scrollable: FALSE ]; fieldIndex ¬ fieldIndex + 1; }; it: AdobeOps.NumFIO => { handle.fieldViewer.buttons[fieldIndex].type ¬ numeric; handle.fieldViewer.buttons[fieldIndex].button ¬ handle.makeButton[ parent: thisViewer, x: 0, y: lineIndex * fieldHeight, name: Rope.Concat[it.name, ": "], <> data: handle.fieldViewer.buttons[fieldIndex], proc: $HintMenuProc, cData: handle.fieldViewer.buttons[fieldIndex] ]; [x, y, w, h] ¬ handle.getBoxGeometry[handle.fieldViewer.buttons[fieldIndex].button]; handle.fieldViewer.buttons[fieldIndex].controllerOf ¬ handle.newFieldBox[ parent: thisViewer, x: w+5, y: lineIndex * fieldHeight, w: 400, h: h, border: FALSE, scrollable: FALSE ]; fieldIndex ¬ fieldIndex + 1; }; it: AdobeOps.FixFIO => { handle.fieldViewer.buttons[fieldIndex].type ¬ fixedLengthString; handle.fieldViewer.buttons[fieldIndex].button ¬ handle.makeButton[ parent: thisViewer, x: 0, y: lineIndex * fieldHeight, name: Rope.Concat[it.name, ": "], <> data: handle.fieldViewer.buttons[fieldIndex], scrollable: FALSE, proc: $HintMenuProc, cData: handle.fieldViewer.buttons[fieldIndex] ]; [x, y, w, h] ¬ handle.getBoxGeometry[handle.fieldViewer.buttons[fieldIndex].button]; handle.fieldViewer.buttons[fieldIndex].controllerOf ¬ handle.newFieldBox[ parent: thisViewer, x: w+5, y: lineIndex * fieldHeight, w: 20*it.maxLength, h: h, border: FALSE, scrollable: FALSE ]; fieldIndex ¬ fieldIndex + 1; }; it: AdobeOps.StrFIO => lineIndex ¬ lineIndex - 1; ENDCASE; lineIndex ¬ lineIndex + 1; ENDLOOP; handle.paintBox[thisViewer, $all]; }; QueryCommandProc: PUBLIC PROCEDURE [h: AdobeCommon.Handle] = { <> <> <> windowData: AdobeCommon.Handle ¬ h; <> IF windowData.system = LAST[CARD] --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; <> <> <> <> <> <> AdobeCommon.CatchErrors[ windowData, --item, index, windowData, --ChooseQueryCmd]}--}; }; ChooseQueryCmd: PROC[windowData: AdobeCommon.Handle] = { <> { ENABLE UNWIND => windowData.isBusy ¬ FALSE; <