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.ROPENIL;
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;
EXITS
errEx =>
RETURN[TRUE];
};
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];
}.