AdobeIOImpl.mesa
Copyright Ó 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Philip James, March 6, 1992 10:37 am PST
Laurie Horton, January 24, 1991 2:01 pm PST
Christian Jacobi, April 7, 1992 5:51 pm PDT
Foote, June 24, 1992 9:16 am PDT
DIRECTORY
AdobeCommon USING [AdobeTimeRope, EnumeratedTypes, GetFullLoginName, Handle, NoCredentials, PostMessage],
AdobeIO,
AdobeOps USING [ARNumber, WhichToRead],
AdobeTool USING [EmptyContents, SetEnumField],
ARAccess USING [AppendChar],
BasicTime USING [Now],
Convert USING [CardFromRope, Error, RopeFromCard, TimeFromRope],
IO,
PFS USING [Close, Copy, Error, NameConfirmProc, Open, OpenFile, PathFromRope, SetClientProperty, StreamFromOpenFile, StreamOpen],
PFSNames USING [PATH],
Rope,
ViewerTools USING [SelPos, SelPosRec];
AdobeIOImpl:
CEDAR
MONITOR
IMPORTS AdobeCommon, AdobeTool, ARAccess, BasicTime, Convert, IO, PFS, Rope
EXPORTS AdobeIO~ {
PathsLocked: LIST OF Rope.ROPE ¬ NIL;
zeroSelection: ViewerTools.SelPos ¬ NEW[ViewerTools.SelPosRec ¬ [0, 0, FALSE, after]];
MakeARFileName:
PROC [num: AdobeOps.ARNumber]
RETURNS [file: Rope.
ROPE ¬
NIL] = {
power: CARDINAL ¬ 10000;
WHILE (num < power)
DO
file ¬ Rope.Concat[file, "0"];
power ¬ power / 10;
ENDLOOP;
IF num # 0
THEN
file ¬ Rope.Concat[file, Convert.RopeFromCard[num, 10, FALSE]];
file ¬ Rope.Concat[file, ".AR"];
};
LocalAndDomain:
PUBLIC
PROC [location: Rope.
ROPE]
RETURNS [noOrg: Rope.
ROPE ¬
NIL] = {
colonCount: CARD ¬ 0;
index: INT ¬ 0;
IF location = NIL THEN RETURN;
WHILE colonCount < 2
DO
ch: CHAR ~ location.Fetch[index];
index ¬ index + 1;
IF ch = ': THEN colonCount ¬ colonCount + 1;
IF colonCount < 2
THEN
noOrg ¬ noOrg.Concat[Rope.FromChar[ch]];
ENDLOOP;
RETURN[noOrg];
};
AddToLocks:
PROC [r: Rope.
ROPE] ~ {
PathsLocked ¬ CONS[r, PathsLocked];
};
InLocks:
PROC [r: Rope.
ROPE]
RETURNS [in:
BOOL ¬
FALSE] ~ {
FOR p:
LIST
OF Rope.
ROPE ¬ PathsLocked, p.rest
UNTIL p =
NIL
DO
IF Rope.Equal[r, p.first, FALSE] THEN RETURN[TRUE];
ENDLOOP;
};
RemoveFromLocks:
PROC [r: Rope.
ROPE] ~ {
newPaths: LIST OF Rope.ROPE ¬ NIL;
FOR p:
LIST
OF Rope.
ROPE ¬ PathsLocked, p.rest
UNTIL p =
NIL
DO
IF ~Rope.Equal[r, p.first,
FALSE]
THEN
newPaths ¬ CONS[p.first, newPaths];
ENDLOOP;
PathsLocked ¬ newPaths;
};
UnlockProc:
PUBLIC
PROCEDURE[num: AdobeOps.ARNumber, handle: AdobeCommon.Handle] ~ {
ENABLE
PFS.Error => {
AdobeCommon.PostMessage[handle, TRUE, Rope.Concat["PFS.Error: ", error.explanation]];
GOTO cantReachFile;
};
apath: PFSNames.PATH ¬ NIL;
dirRope, short, aRope: Rope.ROPE ¬ NIL;
theFile: PFS.OpenFile ← NIL;
dirRope ¬ LocalAndDomain[handle.systemHandle.host];
dirRope ¬ dirRope.Concat["-XNS:/"];
dirRope ¬ dirRope.Concat[handle.systemHandle.directory];
dirRope ¬ dirRope.Concat["/"];
short ¬ MakeARFileName[num];
aRope ¬ dirRope.Concat[short];
apath ← PFS.PathFromRope[aRope];
theFile ← PFS.Open[apath];
RemoveFromLocks[aRope];
IF handle.ARFile #
NIL
THEN {
PFS.SetClientProperty[handle.ARFile, "ControlType", "lockNone"];
PFS.Close[handle.ARFile];
handle.ARFile ¬ NIL;
};
EXITS
cantReachFile => {};
};
ReadProc:
PUBLIC
PROCEDURE[num: AdobeOps.ARNumber, handle: AdobeCommon.Handle, str:
IO.
STREAM ¬
NIL, lock:
BOOL ¬
FALSE] = {
ENABLE
PFS.Error => {
AdobeCommon.PostMessage[handle, TRUE, Rope.Concat["PFS.Error: ", error.explanation]];
GOTO cantReachFile;
};
apath: PFSNames.PATH ¬ NIL;
dirRope, short, aRope: Rope.ROPE ¬ NIL;
theStream: IO.STREAM ¬ NIL;
numberOfFields: CARDINAL ¬ handle.systemHandle.fieldList.length;
currentFieldIndex: CARDINAL ¬ 0;
currentlyReading: AdobeOps.WhichToRead ¬ fieldname;
dirRope ¬ LocalAndDomain[handle.systemHandle.host];
dirRope ¬ dirRope.Concat["-XNS:/"];
dirRope ¬ dirRope.Concat[handle.systemHandle.directory];
dirRope ¬ dirRope.Concat["/"];
short ¬ MakeARFileName[num];
aRope ¬ dirRope.Concat[short];
apath ¬ PFS.PathFromRope[aRope];
IF str #
NIL
THEN
theStream ¬ str
ELSE {
IF InLocks[aRope] THEN ERROR PFS.Error[[user, $unknownClass, "File is locked."]];
handle.ARFile ¬ PFS.Open[name: apath];
theStream ¬ PFS.StreamFromOpenFile[openFile: handle.ARFile];
IF lock
THEN {
AddToLocks[aRope];
PFS.SetClientProperty[handle.ARFile, "ControlType", "exclusive"];
};
};
AdobeTool.EmptyContents[handle];
{
ENABLE
UNWIND => {}--IO.Close[theStream]--;
currentField, currentValue: Rope.ROPE ¬ NIL;
whereToPut: {nil, stream, viewer} ¬ nil; -- stream no longer used.
enum: AdobeCommon.EnumeratedTypes ¬ NIL;
str: IO.STREAM ¬ NIL;
view: REF ANY ¬ NIL;
index: CARD;
didReturn: BOOL ¬ FALSE;
UNTIL
IO.EndOf[theStream]
DO
c: CHAR ¬ IO.GetChar[theStream];
IF currentlyReading = fieldname
THEN {
SELECT c
FROM
'' => c ¬ IO.GetChar[theStream];
': => {
currentField ¬ ARAccess.AppendChar[currentField, c];
c ¬ IO.GetChar[theStream];
currentlyReading ¬ fieldvalue;
currentValue ¬ NIL;
};
ENDCASE;
currentField ¬ ARAccess.AppendChar[currentField, c];
IF currentlyReading = fieldvalue
THEN {
FOR index ¬ 0, index + 1
UNTIL ((index = handle.fieldViewer.buttons.length)
OR Rope.Equal[handle.getBoxName[handle.fieldViewer.buttons[index].button], currentField,
FALSE])
DO
ENDLOOP;
whereToPut ¬ nil;
IF index # handle.fieldViewer.buttons.length
THEN {
STREAMs no longer used for Database fields
IF handle.fieldViewer.buttons[index].stream # NIL THEN {
whereToPut ← stream;
str ← handle.fieldViewer.buttons[index].stream;
view ← handle.fieldViewer.buttons[index].controllerOf;
}
{
whereToPut ¬ viewer;
view ¬ handle.fieldViewer.buttons[index].controllerOf;
enum ¬ handle.fieldViewer.buttons[index]
};
};
};
}
ELSE
SELECT whereToPut
FROM
stream =>
SELECT c FROM
'' => {
c ← IO.GetChar[theStream];
SELECT c FROM
'J - 75B => IO.PutF[str, "\n"];
ENDCASE => IO.PutF[str, "%g", IO.char[c]];
};
'A + 153B => IO.PutF[str, "←"];
'J - 75B => {
ViewerTools.SetSelection[view, zeroSelection];
c ← IO.GetChar[theStream];
currentlyReading ← fieldname;
currentField ← NIL;
currentFieldIndex ← currentFieldIndex + 1;
};
ENDCASE => IO.PutF[str, "%g", IO.char[c]];
viewer =>
SELECT c
FROM
'' => {
r: Rope.ROPE ← NIL;
c ¬ IO.GetChar[theStream];
IF c = 'J - 75B
THEN
c ¬ 'J - 100B;
IF c = 'J - 100B
THEN
didReturn ¬ TRUE;
SELECT c FROM
'' => r ← "'";
'J - 75B => c ← 'J - 100B;
ENDCASE;
IF r # NIL THEN
currentValue ← currentValue.Concat[r]
ELSE
currentValue ← ARAccess.AppendChar[currentValue, c];
currentValue ¬ ARAccess.AppendChar[currentValue, c];
};
'J - 75B => {
c ¬ IO.GetChar[theStream];
currentlyReading ¬ fieldname;
currentField ¬ NIL;
currentFieldIndex ¬ currentFieldIndex + 1;
IF handle.fieldViewer.buttons[index].type = enumerated
THEN
AdobeTool.SetEnumField[handle, enum, currentValue, TRUE]
ELSE {
IF didReturn
THEN {
handle.setBoxScrollable[view];
handle.setContents[view, currentValue--, FALSE--];
handle.paintBox[view, $client];
}
ELSE
handle.setContents[view, currentValue];
};
didReturn ¬ FALSE;
};
ENDCASE => currentValue ¬ ARAccess.AppendChar[currentValue, c];
ENDCASE => {};
ENDLOOP;
};
EXITS
cantReachFile => {};
};
CheckField:
PROCEDURE [handle: AdobeCommon.Handle, h: AdobeCommon.EnumeratedTypes, f: Rope.
ROPE ¬
NIL]
RETURNS [err:
BOOL ¬
FALSE] ~ {
ENABLE
Convert.Error => {
AdobeCommon.PostMessage[h.mainViewer, TRUE, IO.PutFR["Error in %g field at position %g.", IO.rope[f], IO.card[index]]];
handle.setSelection[h.controllerOf];
GOTO errEx;
};
r: Rope.ROPE ¬ handle.getContents[h.controllerOf];
nameRope: Rope.ROPE ¬ handle.getBoxName[h.button];
f ¬ Rope.Substr[nameRope, 0, nameRope.Length - 2];
IF r = NIL OR r.Length = 0 OR Rope.IsEmpty [r] THEN RETURN [FALSE];
SELECT h.type
FROM
arId => [] ¬ Convert.CardFromRope[r];
dateTime => [] ¬ Convert.TimeFromRope[r];
numeric => [] ¬ Convert.CardFromRope[r];
fixedLengthString =>
IF r.Length >
INT[h.maxLength]
THEN {
AdobeCommon.PostMessage[h.mainViewer, TRUE, IO.PutFR["Error in %g field: %g characters in max %g character field.", IO.rope[f], IO.card[r.Length], IO.card[h.maxLength]]];
handle.setSelection[h.controllerOf];
RETURN[TRUE];
};
enumerated => NULL;
string => NULL;
ENDCASE => ERROR;
};
WriteProc:
PUBLIC
PROCEDURE[handle: AdobeCommon.Handle, str:
IO.
STREAM ¬
NIL, doProc:
PROC[h: AdobeCommon.Handle] ¬
NIL]
RETURNS[success:
BOOL ¬
TRUE] = {
ENABLE
PFS.Error => {
AdobeCommon.PostMessage[handle, TRUE, Rope.Concat["PFS.Error: ", error.explanation]];
handle.currentARState ¬ Normal;
GOTO cantReachFile;
};
create file to put in File Drawer
create accelerator information
logName: Rope.ROPE ¬ NIL;
noGo: BOOL ¬ FALSE;
apath: PFSNames.PATH ¬ NIL;
dirRope, short, aRope: Rope.ROPE ¬ NIL;
theStream: IO.STREAM ¬ NIL;
theFile: PFS.OpenFile ¬ NIL;
fileNameWithQuotes: Rope.ROPE ¬ NIL;
numberOfFields: CARDINAL ¬ handle.systemHandle.fieldList.length;
currentFieldIndex: CARDINAL ¬ 0;
currentlyReading: AdobeOps.WhichToRead ¬ fieldname;
IF str =
NIL
THEN
FOR i:
CARD
IN [0..handle.fieldViewer.buttons.length)
DO
IF handle.fieldViewer.buttons[i].defaults[handle.tool] #
NIL
THEN
SELECT handle.fieldViewer.buttons[i].type
FROM
dateTime =>
IF Rope.Equal[handle.fieldViewer.buttons[i].defaults[handle.tool], "CurrentTOD",
FALSE]
THEN
handle.setContents[handle.fieldViewer.buttons[i].controllerOf, AdobeCommon.AdobeTimeRope[BasicTime.Now[]]];
fixedLengthString =>
IF Rope.Equal[handle.fieldViewer.buttons[i].defaults[handle.tool], "LoginName",
FALSE]
THEN {
ENABLE AdobeCommon.NoCredentials => {
AdobeCommon.PostMessage[handle, TRUE, "You must xnslogin."];
logName ¬ "Login!";
CONTINUE
};
logName ¬ AdobeCommon.GetFullLoginName[];
IF logName.Length >
INT[handle.fieldViewer.buttons[i].maxLength]
THEN
logName ¬ Rope.Substr[logName, 0, handle.fieldViewer.buttons[i].maxLength];
handle.setContents[handle.fieldViewer.buttons[i].controllerOf, logName];
}
ENDCASE => {};
IF CheckField[handle, handle.fieldViewer.buttons[i]] THEN noGo ¬ TRUE;
ENDLOOP;
IF noGo THEN RETURN [FALSE];
IF doProc #
NIL
THEN
doProc[handle];
dirRope ¬ LocalAndDomain[handle.systemHandle.host];
dirRope ¬ dirRope.Concat["-XNS:/"];
dirRope ¬ dirRope.Concat[handle.systemHandle.directory];
dirRope ¬ dirRope.Concat["/"];
short ¬ MakeARFileName[handle.currentAR];
aRope ¬ dirRope.Concat[short];
apath ¬ PFS.PathFromRope[aRope];
fileNameWithQuotes ← ARAccess.AppendChar[fileNameWithQuotes, '"];
fileNameWithQuotes ¬ Rope.Concat[dirRope, short];
fileNameWithQuotes ← ARAccess.AppendChar[fileNameWithQuotes, '"];
IF str #
NIL
THEN
theStream ¬ str
ELSE
IF handle.tool = submit
OR handle.tool = edit
THEN
theStream ¬ PFS.StreamOpen[fileName: PFS.PathFromRope[short], accessOptions: create];
{
ENABLE
UNWIND => IO.Close[theStream];
nameWithColon: Rope.ROPE ¬ NIL;
FOR i:
CARD
IN [0..handle.systemHandle.fieldList.length)
DO
nameWithColon ¬ handle.systemHandle.fieldList[i].name.Concat[": "];
IO.PutRope[theStream, nameWithColon];
FOR j:
CARD
IN [0..handle.fieldViewer.buttons.length)
DO
IF Rope.Equal[handle.getBoxName[handle.fieldViewer.buttons[j].button], nameWithColon]
THEN {
IO.PutRope[theStream, TranslateForXNS[handle.getContents[handle.fieldViewer.buttons[j].controllerOf], IF handle.fieldViewer.buttons[j].type = enumerated THEN TRUE ELSE FALSE]];
IO.PutRope[theStream, xnsPlainRet];
IO.PutRope[theStream, xnsPlainRet];
EXIT;
};
ENDLOOP;
ENDLOOP;
IO.Close[theStream];
IF handle.tool = submit
OR handle.tool = edit
THEN {
IF str =
NIL
THEN
PFS.Copy[to: PFS.PathFromRope[fileNameWithQuotes], from: PFS.PathFromRope[short], confirmProc: ContProc];
};
};
EXITS
cantReachFile => { RETURN [FALSE]};
};
ContProc:
PFS.NameConfirmProc ~ {
RETURN[TRUE];
};
TranslateForXNS:
PROCEDURE [in: Rope.
ROPE, enum:
BOOL ¬
FALSE]
RETURNS[out: Rope.
ROPE ¬
NIL] ~ {
newIn: Rope.ROPE ¬ in;
c: CHAR;
IF enum
THEN
newIn ¬ Rope.Substr[newIn, 1, newIn.Length - 2];
FOR i:
CARD
IN [0..newIn.Length)
DO
SELECT (c ¬ newIn.Fetch[i])
FROM
'% => out ¬ out.Concat["%%"];
': => out ¬ out.Concat["':"];
'' => out ¬ out.Concat["''"];
'J - 100B, 'J - 75B => out ¬ out.Concat[xnsFieldRet];
ENDCASE => out ¬ ARAccess.AppendChar[out, c];
ENDLOOP;
RETURN[out];
};
xnsPlainRet: Rope.ROPE ¬ NIL;
xnsFieldRet: Rope.ROPE ¬ "'";
xnsPlainRet ¬ ARAccess.AppendChar[xnsPlainRet, 'J - 75B];
xnsFieldRet ¬ ARAccess.AppendChar[xnsFieldRet, 'J - 75B];
}.