home *** CD-ROM | disk | FTP | other *** search
- /*
- MSFile.c
-
- Version 1.0d4
-
- Copyright © Apple Computer UK Ltd. 1992
-
- All rights reserved.
-
- Produced by : UK Developer Technical Support
- AppleLink : UK.DTS
- */
- /*
- Changes for 1.0d3:
-
- 27-Aug-92 : NH : Fix length of 'STR ' #-16396
- */
-
- #include <Errors.h>
- #include <Resources.h>
- #include <Desk.h>
- #include <PLStringFuncs.h>
- #include <AppleEvents.h>
- #include <AERegistry.h>
- #include "MSFile.h"
-
- /**-----------------------------------------------------------------------
- Name: FileError
- Purpose: Puts up an error alert.
- -----------------------------------------------------------------------**/
-
-
- #pragma segment File
-
- pascal void FileError(Str255 s, Str255 f)
- {
- short alertResult;
-
- SetCursor(&qd.arrow);
- ParamText(s, f, "", "");
- alertResult = Alert(ErrorAlert, nil);
- }
-
- /**-----------------------------------------------------------------------
- Name: DoClose
- Purpose: Closes a window.
- -----------------------------------------------------------------------**/
-
- #pragma segment File
-
- pascal OSErr DoClose(WindowPtr aWindow,Boolean canInteract,DescType dialogAnswer)
- {
- DPtr aDocument;
- short alertResult;
- Str255 theName;
- OSErr myErr;
-
- myErr = noErr;
-
- if (gWCount>0)
- {
- aDocument = DPtrFromWindowPtr(aWindow);
-
- if (aDocument->dirty)
- if (canInteract && (dialogAnswer==kAEAsk))
- {
- if (aDocument->everSaved == false)
- GetWTitle(aWindow, theName); /* Pick it up as a script may have changed it */
- else
- PLstrcpy(theName, aDocument->theFileName);
-
- ParamText("\pSave Changes for ", theName, "", "");
- SetCursor(&qd.arrow);
- alertResult = Alert(AdviseAlert, nil);
- switch (alertResult) {
- case aaSave :if (aDocument->everSaved == false)
- {
- myErr = GetFileNameToSaveAs(aDocument);
- if (myErr == noErr)
- myErr = DoSave(aDocument, aDocument->theFSSpec);
-
- if (myErr==noErr)
- AssocAllSections(aDocument);
- }
- else
- myErr = SaveUsingTemp(aDocument);
- break;
-
- case aaCancel : return(userCanceledErr);
- break;
-
- case aaDiscard: aDocument->dirty = false;
- }
- }
- else
- {
- if (dialogAnswer==kAEYes)
- if (aDocument->everSaved == false)
- {
- if (canInteract)
- {
- myErr = GetFileNameToSaveAs(aDocument);
- if (myErr==noErr)
- myErr = DoSave(aDocument, aDocument->theFSSpec);
- if (myErr==noErr)
- AssocAllSections(aDocument);
- }
- else
- return(errAENoUserInteraction);
- }
- else
- myErr = SaveUsingTemp(aDocument);
- else
- myErr = noErr; /* Don't save */
- }
-
- if (myErr==noErr)
- {
- if (aDocument->numSections)
- DeRegisterAllSections(aDocument);
- CloseMyWindow(aWindow);
- }
- }
- else
- myErr = errAEIllegalIndex;
-
- return(myErr);
- }
-
- #pragma segment File
-
- // DoQuit
- // saveOpt - one of kAEAsk,kAEYes,kAENo
- // if kAEYes or kAEAsk then AEInteactWithUser should have been called
- // before DoQuit. Assumes that it can interact if it needs to.
-
- pascal void DoQuit(DescType saveOpt)
- {
- WindowPtr aWindow;
- WindowPtr nextWindow;
- WindowPeek nextWPeek;
- short theKind;
- OSErr check;
-
- aWindow = FrontWindow();
-
- while (aWindow)
- {
- nextWPeek = ((WindowPeek)aWindow)->nextWindow;
- nextWindow = &nextWPeek->port;
- if (Ours(aWindow))
- {
- check = DoClose(aWindow, true, saveOpt);
- if (check!=noErr)
- return;
- }
- else
- {
- theKind = ((WindowPeek)aWindow)->windowKind;
- if (theKind < 0)
- CloseDeskAcc(theKind);
- }
- aWindow = nextWindow;
- } /*WHILE loop*/
- gQuitting = true;
- }
-
- pascal OSErr GetFile(FSSpec *theFSSpec)
- {
- SFTypeList myTypes;
- StandardFileReply reply;
-
- myTypes[0] = 'TEXT';
-
- StandardGetFile(nil, 1, myTypes, &reply);
-
- if (reply.sfGood)
- {
- *theFSSpec = reply.sfFile;
- return(noErr);
- }
- else
- return(userCanceledErr);
- }
-
- #pragma segment File
-
-
- pascal OSErr DoCreate(FSSpec theSpec)
- {
- OSErr err;
-
- err = FSpCreate(&theSpec, MenuScripterAppSig, 'TEXT', smSystemScript);
-
- if (err != noErr)
- ShowError("\pDoCreate", err);
-
- return(err);
- }
-
- #pragma segment File
-
-
- pascal OSErr WriteFile(DPtr theDocument,
- short refNum,
- FSSpec theFSSpec)
- {
- short resFile;
- long length;
- HHandle theHHandle;
- StScrpHandle theSHandle;
- OSErr err;
- StringHandle theAppName;
- short oldSelStart;
- short oldSelEnd;
- Handle thePHandle;
- Handle myText;
-
- /* WriteFile := 1; */
-
- /*first write out the text to the data fork*/
-
- length = (*(theDocument->theText))->teLength;
-
- myText = (*(theDocument->theText))->hText;
-
- HLock(myText);
-
- err = FSWrite(refNum, &length, *myText);
- if (err)
- return(err);
-
- HUnlock(myText);
-
- /*we are writing to a temporary file, so we need to create the resource file*/
- /*before writing out the resources*/
- /*now open the resource file*/
-
- HCreateResFile(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name);
- err = ResError();
- if (err)
- {
- ShowError("\pHCreateResFile", err);
- return(err);
- }
-
- resFile = HOpenResFile(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name, fsWrPerm);
- err = ResError();
-
- if (err)
- {
- ShowError("\pHOpenResFile", err);
- return(err);
- }
-
- /*write out our 'TFSF' resource to file*/
-
- oldSelStart = (*(theDocument->theText))->selStart;
- oldSelEnd = (*(theDocument->theText))->selEnd;
- TESetSelect(0,32000, theDocument->theText);
-
- theSHandle = GetStylScrap(theDocument->theText);
-
- TESetSelect(oldSelStart,oldSelEnd, theDocument->theText);
-
- AddResource((Handle)theSHandle, 'TFSF', 255, "\pStyle Info");
- err = ResError();
- if (err)
- {
- ShowError("\pAddResource- TFSF", err);
- return(err);
- }
-
- /* write out the printer info */
-
- if (theDocument->thePrintSetup)
- {
- thePHandle = (Handle)theDocument->thePrintSetup;
- err = HandToHand(&thePHandle);
-
- AddResource(thePHandle, 'TFSP', 255, "\pPrinter Info");
- err = ResError();
- if (err)
- {
- ShowError("\pAddResource- TFSP", err);
- return(err);
- }
- }
-
-
- theHHandle = (HHandle)NewHandle(sizeof(HeaderRec));
- HLock((Handle)theHHandle);
-
- GetFontName(theDocument->theFont, &(*theHHandle)->theFont);
- (*theHHandle)->theSize = theDocument->theSize;
- (*theHHandle)->theStyle = theDocument->theStyle;
- (*theHHandle)->lastID = theDocument->lastID;
- (*theHHandle)->numSections = theDocument->numSections;
-
- HUnlock((Handle)theHHandle);
-
- AddResource((Handle)theHHandle, 'TFSS', 255, "\pHeader Info");
-
- err = ResError();
- if (err)
- {
- ShowError("\pAddResource- TFSS", err);
- return(err);
- }
-
- /*if we have any sections, write out the records and resources*/
-
- if (theDocument->numSections)
- {
- /*now write out the section records*/
- SaveSections(theDocument);
-
- /*write the latest versions of all editions to their containers*/
-
- WriteAllEditions(theDocument);
- /*now close the resource file*/
- err = ResError();
- if (err)
- {
- ShowError("\pCloseResFile", err);
- return(err);
- }
- }
-
- /*Now put an AppName in for Finder in 7.0*/
-
- theAppName = (StringHandle)NewHandle(20); // at least as long as "\pMenuScripter"
- PLstrcpy(*theAppName,"\pMenuScripter");
-
- AddResource((Handle)theAppName, 'STR ', -16396, "\pFinder App Info");
-
- err = ResError();
-
- if (err)
- {
- ShowError("\pAppName", err);
- return(err);
- }
-
- CloseResFile(resFile);
-
- return(noErr);
- } /* WriteFile */
-
- #pragma segment File
-
- pascal OSErr ReadFile(DPtr theDocument,
- short refNum,
- Str255 fn)
- {
- long theSize;
- short resFile;
- OSErr err;
- HHandle aHandle;
- Handle gHandle;
-
- err = GetEOF(refNum, &theSize);
- if (err)
- return(err);
-
- /*we're only using TE, so check that there is not more than 32K worth of text*/
-
- if (theSize > 32000)
- return(1);
-
- gHandle = NewHandle(theSize);
- HLock(gHandle);
- err = FSRead(refNum, &theSize, *gHandle);
-
- if (err)
- {
- HUnlock(gHandle);
- return(err);
- }
-
- resFile = HOpenResFile(theDocument->theFSSpec.vRefNum,
- theDocument->theFSSpec.parID,
- fn,
- fsWrPerm);
- if (resFile == -1)
- err = fnfErr;
-
- theDocument->numSections = 0;
-
- if (err==noErr)
- {
- aHandle = nil;
-
- if (Count1Resources('TFSS'))
- aHandle = (HHandle)Get1Resource('TFSS', 255);
-
- if (aHandle)
- theDocument->numSections = (*aHandle)->numSections;
-
- /*
- New Format Info
- */
-
- aHandle = nil;
-
- if (Count1Resources('TFSF'))
- aHandle = (HHandle)Get1Resource('TFSF', 255);
-
- HLock(gHandle);
- TEStylInsert( *gHandle,
- GetHandleSize(gHandle),
- (StScrpHandle)aHandle,
- theDocument->theText);
-
- HUnlock(gHandle);
-
- /*
- If there is a print record saved, ditch the old one
- created by new document and fill this one in
- */
- if (Count1Resources('TFSP'))
- {
- if (theDocument->thePrintSetup)
- DisposHandle((Handle)theDocument->thePrintSetup);
-
- theDocument->thePrintSetup = (THPrint)Get1Resource('TFSP', 255);
- err = HandToHand((Handle *)&theDocument->thePrintSetup);
-
- PrValidate(theDocument->thePrintSetup);
- }
-
- if (theDocument->numSections)
- {
- ReadSectionRecords(theDocument);
- ReadAllSectionResources(theDocument);
- }
-
- CloseResFile(resFile);
-
- err = ResError();
- if (err)
- {
- ShowError("\pread file- CloseResFile", err);
- return(err);
- }
- }
- else
- TESetText(*gHandle,
- GetHandleSize(gHandle),
- theDocument->theText);
-
- if (gHandle)
- DisposHandle(gHandle);
-
- if (err==fnfErr)
- err = noErr;
-
- return(err);
- } /* ReadFile */
-
- /** -----------------------------------------------------------------------
- Name: GetFileContents
- Purpose: Opens the document specified by theFSSpec and puts
- the contents into theDocument.
- -----------------------------------------------------------------------**/
-
-
- #pragma segment File
-
- pascal OSErr GetFileContents(FSSpec theFSSpec, DPtr theDocument)
- {
- OSErr err;
- short theRefNum;
-
- /*this can be called from two places- on an OpenDoc AppleEvent*/
- /*and by the user just selecting Open from the File Menu*/
- /*assume that the CFS is correct when the routine is called*/
-
- err = FSpOpenDF(&theFSSpec,
- fsRdWrPerm,
- &theRefNum);
- if (err)
- {
- ShowError("\pFSpOpenDF", err);
- return(err);
- }
- else
- {
- err = ReadFile(theDocument, theRefNum, theFSSpec.name);
- if (err)
- {
- ShowError("\pReadFile", err);
- return(err);
- }
- err=FSClose(theRefNum);
- if (err)
- {
- ShowError("\pFSClose", err);
- return(err);
- }
- return(noErr);
- }
- }
-
-
- #pragma segment File
-
- pascal OSErr SaveUsingTemp(DPtr theDocument)
- {
- Str255 tempName;
- OSErr err;
- FSSpec tempFSSpec;
-
- /*save the file to disk using a temporary file*/
- /*this is the recommended way of doing things*/
- /*first write out the file to disk using a temporary filename*/
- /*if it is sucessfully written, exchange the temporary file with the last one saved*/
- /*then delete the temporary file- so if anything goes wrong, the original version is still there*/
- /*first generate the temporary filename*/
-
- GetTempFileName(theDocument, &tempName);
- /*create this file on disk*/
-
- tempFSSpec = theDocument->theFSSpec;
- PLstrcpy(tempFSSpec.name,tempName);
-
- err = DoCreate(tempFSSpec);
-
- /*now save the file as normal*/
-
- if (err==noErr)
- err = DoSave(theDocument, tempFSSpec);
-
- if (err == noErr)
- err = FSpExchangeFiles(&tempFSSpec, &theDocument->theFSSpec);
-
- /*we've exchanged the files, now delete the temporary one*/
-
- if (err==noErr)
- err = FSpDelete(&tempFSSpec);
-
- return(err);
- }
-
-
- #pragma segment File
-
- /*
- Fills in the document record with the user chosen destination
- */
-
- pascal OSErr GetFileNameToSaveAs(DPtr theDocument)
- {
- StandardFileReply reply;
- OSErr err;
- Str255 suggestName;
-
- GetWTitle(theDocument->theWindow, suggestName);
-
- StandardPutFile("\pSave Document As:", suggestName, &reply);
-
- if (reply.sfGood)
- {
- err = FSpDelete(&reply.sfFile);
-
- if (!((err==noErr) || (err==fnfErr)))
- return(err);
- else
- err = noErr;
-
- theDocument->theFSSpec = reply.sfFile;
- PLstrcpy(theDocument->theFileName, reply.sfFile.name);
- }
- else
- err = userCanceledErr;
-
- return(err);
- } /* GetFileNameToSaveAs */
-
-
- #pragma segment File
-
- pascal OSErr DoSave(DPtr theDocument, FSSpec theFSSpec)
- {
- short refNum;
- OSErr fileErr;
-
- fileErr = FSpOpenDF(&theFSSpec, fsRdWrPerm, &refNum);
-
- if (fileErr == fnfErr)
- {
- fileErr = DoCreate(theFSSpec);
-
- if (fileErr)
- return(fileErr);
-
- fileErr = FSpOpenDF(&theFSSpec, fsRdWrPerm, &refNum);
- }
-
- if (fileErr == noErr)
- {
- fileErr = WriteFile(theDocument, refNum, theFSSpec);
-
- if (fileErr==noErr)
- theDocument->dirty = false;
-
- fileErr = FSClose(refNum);
- }
- else
- FileError("\perror opening file ", theFSSpec.name);
-
- return(fileErr);
- }
-
-
- #pragma segment File
-
- pascal OSErr OpenOld(FSSpec aFSSpec)
- {
- DPtr theDocument;
- OSErr fileErr;
-
- theDocument = NewDocument(true);
-
- SetWTitle(theDocument->theWindow, aFSSpec.name);
-
- SetPort(theDocument->theWindow);
-
- theDocument->theFSSpec = aFSSpec;
-
- PLstrcpy(theDocument->theFileName,aFSSpec.name);
-
- theDocument->dirty = false;
- theDocument->everSaved = true;
-
- fileErr = GetFileContents(aFSSpec, theDocument);
-
- if (fileErr == noErr)
- {
- ResizeWindow(theDocument);
- ShowWindow(theDocument->theWindow);
- }
- else
- FileError("\pError Opening ", aFSSpec.name);
-
- return(fileErr);
- } /* OpenOld */
-
-
- #pragma segment File
-
- pascal OSErr OpenUsingAlias(AliasHandle theAliasH)
- {
- OSErr err;
- FSSpec aFSSpec;
- Boolean dummy;
-
- err = ResolveAlias(nil, theAliasH, &aFSSpec, &dummy);
-
- if (err == noErr)
- err = OpenOld(aFSSpec);
-
- return(err);
- }
-
-