File: SVFilesImpl.mesa
Last edited by: Eric Bier on July 22, 1987 4:17:14 pm PDT
Copyright © 1984 by Xerox Corporation. All rights reserved.
Contents: Interfaces which make creating scenes look like opening files.
DIRECTORY
AtomButtonsTypes, Feedback, FileNames, FS, IO, MessageWindow, Rope, SVArtwork, SVFileIn, SVFileOut, SVFiles, SVScene, SVSceneTypes, SVTransforms, SVParseIn, ViewerClasses;
SVFilesImpl: CEDAR PROGRAM
IMPORTS SVScene, SVFileIn, SVFileOut, FileNames, FS, IO, MessageWindow, Rope, SVArtwork, Feedback, SVTransforms, SVParseIn
EXPORTS SVFiles =
BEGIN
FeedbackData: TYPE = AtomButtonsTypes.FeedbackData;
Scene: TYPE = SVSceneTypes.Scene;
SceneTable: TYPE = LIST OF Scene;
Viewer: TYPE = ViewerClasses.Viewer;
FindScene: PRIVATE PROC [name: Rope.ROPE, table: SceneTable] RETURNS [scene: Scene, success: BOOL] = {
success ← FALSE;
FOR list: SceneTable ← table, list.rest UNTIL list = NIL OR success DO
IF Rope.Equal[s1: name, s2: list.first.name, case: TRUE] THEN {
success ← TRUE;
scene ← list.first;
};
ENDLOOP;
};
AddSceneToTable: PRIVATE PROC [scene: Scene, table: SceneTable] RETURNS [newtable: SceneTable] = {
newtable ← CONS[scene, table];
};
OpenScene: PUBLIC PROC [picName: Rope.ROPE, wdirForAIS: Rope.ROPE, feedback: FeedbackData] RETURNS [scene: Scene, success: BOOL] = {
Look for the pic file on the local disk. If there, read in the scene. If not, Tell the user "file not found" and return success = false.
f: IO.STREAM;
[f, success] ← OpenFile[picName, feedback];
IF NOT success THEN RETURN; -- OpenFile prints any error messages.
Now we must turn the text file into a scene.
[scene, success] ← MakeScene[f, picName, wdirForAIS, feedback]; -- MakeScene will print any error messages
};
OpenFile: PUBLIC PROC [picName: Rope.ROPE, feedback: FeedbackData] RETURNS [f: IO.STREAM, success: BOOL] = {
success ← TRUE;
Two possiblilities
1) File doesn't exist. Print error message.
2) File does exist. File it in. Succeed.
f ← FS.StreamOpen[picName
! FS.Error => {
IF error.group = user THEN {
success ← FALSE;
Feedback.PutF[feedback, oneLiner, "Picture file problem: %g", [rope[error.explanation]]];
}
ELSE ERROR;
CONTINUE}];
}; -- end of OpenFile
MakeScene: PRIVATE PROC [f: IO.STREAM, picName: Rope.ROPE, wdirForAIS: Rope.ROPE, feedback: FeedbackData] RETURNS [scene: Scene, success: BOOL] = {
errorPos: NAT;
errorRope, expected, actual: Rope.ROPE;
fileNotFound: BOOLFALSE;
allMapsFound: BOOLTRUE;
success ← TRUE;
scene ← SVScene.CreateEmptyScene[picName];
Feedback.PutF[feedback, begin, "Reading file: %g...", [rope[picName]]];
SVFileIn.FileinScene [scene, f, wdirForAIS, feedback
!SVParseIn.RopeNotOnTop => {
success ← FALSE; errorPos ← position; expected ← notThere;
actual ← wasThere; CONTINUE};
SVArtwork.FileNotFound => {allMapsFound ← FALSE; CONTINUE}
];
IF NOT allMapsFound THEN {
errorRope ← IO.PutFR["Some AIS mapping file not found"];
Feedback.Append[feedback, errorRope, oneLiner];
success ← FALSE;
RETURN
};
IF NOT success THEN {
errorRope ← IO.PutFR["At %g in %g expected '%g' not '%g'", [integer[errorPos]], [rope[picName]], [rope[expected]], [rope[actual]]];
Feedback.Append[feedback, errorRope, oneLiner];
RETURN
}
ELSE Feedback.Append[feedback, "Done", end];
}; -- end of MakeScene
SaveScene: PUBLIC PROC [updatedScene: Scene, picName: Rope.ROPE, feedback: FeedbackData] RETURNS [success: BOOL] = {
Check local disk to see that we have a scene with this name. If so, save it as a file on the local disk after confirmation. scene.dirty ← FALSE.
If not, Feedback "File not found. Use Store." and return success = FALSE.
f: IO.STREAM;
success ← TRUE;
IF FileExists[picName] THEN {
f ← FS.StreamOpen[picName, $create
! FS.Error => {
IF error.group = user THEN {
success ← FALSE;
Feedback.PutF[feedback, oneLiner, "Pic file problem: %g", [rope[error.explanation]]];
Feedback.Blink[feedback];
CONTINUE}
ELSE ERROR}];
IF success THEN {
SVTransforms.TidyUpCoordSysTree[updatedScene.coordSysRoot];
SaveFile[updatedScene, f, picName, feedback];
};
}
ELSE {
Feedback.Append[feedback, "File not found. Use Store.", oneLiner];
Feedback.Blink[feedback];
};
};
SaveFile: PROC [scene: Scene, f: IO.STREAM, picName: Rope.ROPE, feedback: FeedbackData] = {
Feedback.PutF[feedback, begin, "Writing file: %g...", [rope[picName]]];
SVFileOut.FileoutScene [scene, f, picName];
scene.dirty ← FALSE;
Feedback.Append[feedback, "Done", end];
}; -- end of SaveFile
StoreScene: PUBLIC PROC [unNamedScene: Scene, newPicName: Rope.ROPE, feedback: FeedbackData] RETURNS [success: BOOL] = {
Check the local disk for this name. Ask for confirmation to store to new (or old) file. Store if confirmed.
f: IO.STREAM;
fileAlreadyExists: BOOLFALSE;
confirmation: BOOLFALSE;
success ← FALSE;
IF FileExists[newPicName] THEN {
confirmation ← MessageWindow.Confirm["Confirm overwrite of existing pic file"];
IF confirmation THEN
f ← FS.StreamOpen[newPicName, $create]
ELSE RETURN;
}
ELSE f ← FS.StreamOpen[newPicName, $create];
Feedback.PutF[feedback, begin, "Writing file: %g...", [rope[newPicName]]];
SVTransforms.TidyUpCoordSysTree[unNamedScene.coordSysRoot];
SVFileOut.FileoutScene [unNamedScene, f, newPicName];
Feedback.Append[feedback, "Done", end];
success ← TRUE;
unNamedScene.dirty ← FALSE;
unNamedScene.name ← newPicName;
}; -- end of StoreScene
FileExists: PUBLIC PROC [fileName: Rope.ROPE] RETURNS [answer: BOOL] = {
answer ← TRUE;
[----, ----, ----, ----] ← FS.FileInfo[fileName
! FS.Error => {IF error.code = $unknownFile THEN {answer ← FALSE; CONTINUE}
ELSE ERROR}];
};
FilenameMinusExtension: PUBLIC PROC [wholeName: Rope.ROPE] RETURNS [firstPart: Rope.ROPE] = {
directory, shortName, shortNameMinusExtension: Rope.ROPE;
shortNameStream: IO.STREAM;
directory ← FileNames.Directory[wholeName];
shortName ← FileNames.GetShortName[wholeName, TRUE];
shortNameStream ← IO.RIS[shortName];
[shortNameMinusExtension, ----] ← IO.GetTokenRope[shortNameStream, PeriodBreakProc];
firstPart ← Rope.Concat[directory, shortNameMinusExtension];
};
PeriodBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = {
SELECT char FROM
'.=> RETURN[sepr];
ENDCASE => RETURN[other];
};
END.