home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************
- * document.c
- *
- * File Management Package
- *
- * Written by Paco Xander Nathan
- * ⌐1990, Motorola Inc. Public domain source code.
- ********************************************************************************/
-
- #include "applic.h"
- #include "window.h"
- #include "dialog.h"
- #include "context.h"
- #include "text.h"
- #include "list.h"
- #include "error.h"
- #include "string.h"
- #include "ascii.h"
- #include "document.h"
- #include "print.h"
- #include "gnosis.h"
-
-
- /* Local Function Prototypes
- */
- #ifdef PROTOTYPES
- void DocReadLine (WORD refNum, LONG count, BYTE *data);
- void DocWriteLine (WORD refNum, LONG count, BYTE *data);
-
- void DocReadNum (WORD refNum, WORD *theNum);
- void DocWriteNum (WORD refNum, WORD theNum);
-
- void DocReadText (WORD refNum, Handle textHdl);
- void DocWriteText (WORD refNum, Handle textHdl);
-
- void DocReadGnos (WORD refNum, GnosPtr gnosPtr);
- void DocWriteGnos (WORD refNum, GnosPtr gnosPtr);
- void DocRecurGnos (WORD refNum, GnosPtr gnosPtr);
- #endif
-
-
- void
- DocReadLine (refNum, count, data)
- register WORD refNum;
- LONG count;
- register BYTE *data;
- {
- LONG bufLen = count + 1;
- BYTE theBuf[100];
-
- FSRead(refNum, &bufLen, theBuf);
- BlockMove(theBuf, data, count);
- }
-
-
- void
- DocWriteLine (refNum, count, data)
- register WORD refNum;
- LONG count;
- register BYTE *data;
- {
- BYTE theEnd = asciiReturn;
-
- FSWrite(refNum, &count, data);
-
- count = 1L;
- FSWrite(refNum, &count, &theEnd);
- }
-
-
- void
- DocReadNum (refNum, theNum)
- register WORD refNum;
- register WORD *theNum;
- {
- BYTE lineBuf[100];
- BYTE *theLine = lineBuf;
- LONG count = 1L;
-
- /* Get the length word
- */
- while ((FSRead(refNum, &count, theLine) == noErr) && (*theLine++ != asciiReturn))
- ;
-
- /* Parse the length word
- */
- *--theLine = '\0';
- sscanf(lineBuf, "%d", theNum);
- }
-
-
- void
- DocWriteNum (refNum, theNum)
- register WORD refNum;
- register WORD theNum;
- {
- BYTE theEnd = asciiReturn;
- BYTE lineBuf[100];
- LONG theLen;
-
- theLen = sprintf(lineBuf, "%d", theNum);
- FSWrite(refNum, &theLen, lineBuf);
-
- /* Write a separator
- */
- theLen = 1L;
- FSWrite(refNum, &theLen, &theEnd);
- }
-
-
- void
- DocReadText (refNum, textHdl)
- register WORD refNum;
- register Handle textHdl;
- {
- WORD textLen;
- LONG count;
- BYTE theEnd;
-
- /* Get the length word, allocate a handle
- */
- DocReadNum(refNum, &textLen);
- count = textLen;
- SetHandleSize(textHdl, count);
-
- /* Read the text
- */
- HLock(textHdl);
- FSRead(refNum, &count, *textHdl);
- HUnlock(textHdl);
-
- /* Read a separator
- */
- count = 1L;
- FSRead(refNum, &count, &theEnd);
- }
-
-
- void
- DocWriteText (refNum, textHdl)
- register WORD refNum;
- register Handle textHdl;
- {
- BYTE theEnd = asciiReturn;
- LONG count;
-
- /* Write the length word
- */
- count = GetHandleSize(textHdl);
- DocWriteNum(refNum, (WORD) count);
-
- /* Write the text
- */
- HLock(textHdl);
- FSWrite(refNum, &count, *textHdl);
- HUnlock(textHdl);
-
- /* Write a separator
- */
- count = 1L;
- FSWrite(refNum, &count, &theEnd);
- }
-
-
- void
- DocReadGnos (refNum, gnosPtr)
- register WORD refNum;
- register GnosPtr gnosPtr;
- {
- WORD titleLen;
-
- DocReadLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->color);
- DocReadLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->pair);
- DocReadLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->mark);
- DocReadLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->anxiety);
- DocReadLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->stress);
-
- DocReadNum(refNum, &(gnosPtr->total[0]));
- DocReadNum(refNum, &(gnosPtr->total[1]));
-
- DocReadNum(refNum, &titleLen);
- DocReadLine(refNum, titleLen, (BYTE *) (gnosPtr->title + 1));
- gnosPtr->title[0] = titleLen;
-
- DocReadText(refNum, gnosPtr->textHdl);
- }
-
-
- void
- DocWriteGnos (refNum, gnosPtr)
- register WORD refNum;
- register GnosPtr gnosPtr;
- {
- WORD titleLen;
-
- DocWriteLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->color);
- DocWriteLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->pair);
- DocWriteLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->mark);
- DocWriteLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->anxiety);
- DocWriteLine(refNum, MAXPAD * 2, (BYTE *) gnosPtr->stress);
-
- DocWriteNum(refNum, gnosPtr->total[0]);
- DocWriteNum(refNum, gnosPtr->total[1]);
-
- titleLen = gnosPtr->title[0];
- DocWriteNum(refNum, titleLen);
- DocWriteLine(refNum, titleLen, (BYTE *) (gnosPtr->title + 1));
-
- DocWriteText(refNum, gnosPtr->textHdl);
- }
-
-
- /* Recursively output the prognosis list in reverse to preserve order
- * next time this document is read
- */
- void
- DocRecurGnos (refNum, gnosPtr)
- register WORD refNum;
- register GnosPtr gnosPtr;
- {
- if (gnosPtr) {
- ApplSpinCurs(FALSE);
- DocRecurGnos(refNum, gnosPtr->next);
- DocWriteGnos(refNum, gnosPtr);
- }
- }
-
-
- /* Read the named file
- */
- Boolean
- DocReadFile (fileName, vRefNum)
- register StringPtr fileName;
- register WORD vRefNum;
- {
- register Boolean result = TRUE;
- register OSErr IOResult;
- WORD gnosCount;
- ioParam pb;
-
- /* Set up the pb. Note that it's set up as read-only
- */
- pb.ioCompletion = NULL;
- pb.ioNamePtr = fileName;
- pb.ioVRefNum = vRefNum;
- pb.ioVersNum = 0;
- pb.ioPermssn = fsRdPerm;
- pb.ioMisc = NULL;
-
- /* If we can't open it for some reason, signal an error and return
- */
- ApplSpinCurs(FALSE);
-
- if (!(result = !PBOpen(&pb, FALSE))) {
- ErrFileMgr(pb.ioResult, fileName);
- return FALSE;
- }
-
- /* Read file into handle and set the new text
- */
- ApplSpinCurs(FALSE);
- DocReadNum(pb.ioRefNum, &gnosCount);
-
- for (; gnosCount--; ) {
- ApplSpinCurs(FALSE);
- DocReadGnos(pb.ioRefNum, GnosNew());
- }
-
- /* Close file before returning
- */
- FSClose(pb.ioRefNum);
- return result;
- }
-
-
- /* Write the named file
- */
- Boolean
- DocWriteFile (fileName, vRefNum)
- register StringPtr fileName;
- register WORD vRefNum;
- {
- register OSErr IOResult = noErr;
- register Boolean result = TRUE;
- WORD refNum;
- LONG logEOF;
- FInfo theFInfo;
-
- /* Try the open the specified file
- */
- if (IOResult = FSOpen(fileName, vRefNum, &refNum)) {
- ErrFileMgr(IOResult, fileName);
- result = FALSE;
- }
-
- /* Try to make the file empty, as a test
- */
- ApplSpinCurs(FALSE);
- logEOF = 0L;
-
- if (result && (IOResult = SetEOF(refNum, logEOF))) {
- /* Don't forget to close it! Otherwise it will remain
- * open until you reboot the machine
- */
- FSClose(refNum);
- ErrFileMgr(IOResult, fileName);
- result = FALSE;
- }
-
- /* Write out the list of data
- */
- ApplSpinCurs(FALSE);
-
- if (result) {
- DocWriteNum(refNum, gnosList.count);
- DocRecurGnos(refNum, gnosList.head);
- }
-
- /* Close the file and flush the volume, to make sure disk is correct
- */
- if (result) {
- FSClose(refNum);
- FlushVol(NULL, vRefNum);
-
- /* Update the creatrix so that the icon will be correct and the file
- * will launch our application
- */
- if (!GetFInfo(fileName, vRefNum, &theFInfo)) {
- theFInfo.fdCreator = LUCH_TAG;
- SetFInfo(fileName, vRefNum, &theFInfo);
- }
- }
-
- ApplSpinCurs(FALSE);
- return result;
- }
-
-
- /* Open the named file into the specified window
- */
- Boolean
- DocOpenFile (theWindow, fileName, vRefNum)
- register WindowPtr theWindow;
- register StringPtr fileName;
- register WORD vRefNum;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register Boolean result;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* Open the file
- */
- ApplSpinCurs(FALSE);
-
- if (result = DocReadFile(fileName, vRefNum)) {
- infoPtr->named = TRUE;
-
- StrPCpy(infoPtr->fileName, fileName);
- SetWTitle(theWindow, fileName);
- infoPtr->vRefNum = vRefNum;
-
- WindSwitch(theWindow, TRUE);
- GnosRefresh();
- GnosLearn();
- }
-
- SetPort(savePort);
- return result;
- }
-
-
- /* Save the contents of the window into the designated file
- */
- Boolean
- DocSaveFile (theWindow, fileName, vRefNum)
- register WindowPtr theWindow;
- register StringPtr fileName;
- register WORD vRefNum;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register Boolean result = TRUE;
- register OSErr IOResult;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* Delete the former contents of the file, without changing
- */
- FSDelete(fileName, vRefNum);
-
- /* Now try to create it again
- */
- if (IOResult = Create(fileName, vRefNum, LUCH_TAG, LUCH_TAG)) {
- ErrFileMgr(IOResult, fileName);
- result = FALSE;
- }
-
- /* Try to write, then update the name and volume ref
- */
- if (result && (result = DocWriteFile(fileName, vRefNum))) {
- StrPCpy(infoPtr->fileName, fileName);
- SetWTitle(theWindow, fileName);
- ApplSpinCurs(FALSE);
-
- infoPtr->vRefNum = vRefNum;
- infoPtr->dirty = FALSE;
- infoPtr->named = TRUE;
- }
-
- SetPort(savePort);
- return result;
- }
-
-
- /* Open a new document
- */
- void
- DocNew (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- GetIndString(infoPtr->fileName, RSRCBASE, strUntitled);
- SetWTitle(theWindow, infoPtr->fileName);
- ApplSpinCurs(FALSE);
-
- infoPtr->dirty = FALSE;
- infoPtr->named = FALSE;
-
- /* Switch to the window and redraw it
- */
- WindSwitch(theWindow, TRUE);
- SetPort(savePort);
- }
-
-
- /* Prompt for an existing document file
- */
- void
- DocOpen (theWindow)
- register WindowPtr theWindow;
- {
- static SFTypeList myTypes = { LUCH_TAG };
- static Point SFGwhere = { 80, 72 };
- SFReply theReply;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* Select on input
- */
- DlogOrigin(getDlgID, &SFGwhere);
- SFPGetFile(SFGwhere, NULL, NULL, 1, myTypes, NULL, &theReply, getDlgID, (Ptr) DlogModalEvent);
- ApplSpinCurs(TRUE);
-
- if (theReply.good)
- DocOpenFile(theWindow, theReply.fName, theReply.vRefNum);
-
- SetPort(savePort);
- }
-
-
- /* Close the document, saving if needed and the user agrees
- */
- Boolean
- DocClose (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register Boolean result = TRUE;
- register WORD prompt;
- Str255 param1, param2;
-
- /* Prompt the user whether or not to save before closing
- */
- if (infoPtr->dirty) {
- GetIndString(param1, RSRCBASE, strDocMod);
- GetIndString(param2, RSRCBASE, strDocSave);
-
- prompt = ErrWarning(warnCancel, FALSE, infoPtr->fileName, param1, param2, NullStr);
-
- if (prompt == warnYes)
- result = DocSave(theWindow);
- else if (prompt == warnCancel)
- result = FALSE;
- }
-
- /* Back to the business of closing shop
- */
- if (result) {
- GnosClose();
-
- infoPtr->dirty = FALSE;
- infoPtr->named = FALSE;
- }
-
- return result;
- }
-
-
- /* Save the document to disk; return FALSE is the user decides to cancel...
- */
- Boolean
- DocSave (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register Boolean result;
-
- /* Give the user a chance to name or cancel an unnamed buffer
- */
- if (!infoPtr->named)
- result = DocSaveAs(theWindow);
- else
- result = DocSaveFile(theWindow, infoPtr->fileName, infoPtr->vRefNum);
-
- return result;
- }
-
-
- /* Save the document into a file; return FALSE if cancelled
- */
- Boolean
- DocSaveAs (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register Boolean result = FALSE;
- static Point SFPwhere = { 80, 72 };
- SFReply theReply;
- Str255 param1;
-
- /* Prompt for the new file name... If cancelled, don't change anything
- */
- DlogOrigin(putDlgID, &SFPwhere);
- GetIndString(param1, RSRCBASE, strSaveAs);
- SFPPutFile(SFPwhere, param1, infoPtr->fileName, NULL, &theReply, putDlgID, (Ptr) DlogModalEvent);
- ApplSpinCurs(TRUE);
-
- if (theReply.good && DocSaveFile(theWindow, theReply.fName, theReply.vRefNum))
- result = TRUE;
-
- return result;
- }
-
-
- /* Reload a previous version of the file
- */
- void
- DocRevert (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register WORD prompt;
- Str255 param1, param2;
-
- /* Prompt for reverting
- */
- GetIndString(param1, RSRCBASE, strRevert);
- GetIndString(param2, RSRCBASE, strQuestion);
- prompt = ErrWarning(warnNo, FALSE, param1, infoPtr->fileName, param2, NullStr);
-
- /* Read in the document again if the user so wishes
- */
- if (prompt == warnYes) {
- ApplSpinCurs(TRUE);
- infoPtr->dirty = FALSE;
-
- if (DocClose(theWindow))
- DocOpenFile(theWindow, infoPtr->fileName, infoPtr->vRefNum);
- else
- infoPtr->dirty = TRUE;
- }
- }
-
-
- /* Execute file menu selection
- */
- void
- DocMenu (theItem)
- register WORD theItem;
- {
- switch (theItem) {
- case fmNew:
- DocNew(wPtrGnos);
- break;
-
- case fmOpen:
- DocOpen(wPtrGnos);
- break;
-
- case fmClose:
- DocClose(wPtrGnos);
- break;
-
- case fmSave:
- DocSave(wPtrGnos);
- break;
-
- case fmSaveAs:
- DocSaveAs(wPtrGnos);
- break;
-
- case fmRevert:
- DocRevert(wPtrGnos);
- break;
-
- case fmSetUp:
- PrintDocument(NULL);
- UnloadSeg((Ptr) PrintDocument);
- break;
-
- case fmPrint:
- PrintDocument(wPtrGnos);
- UnloadSeg((Ptr) PrintDocument);
- break;
-
- case fmQuit:
- ApplQuit();
- break;
-
- default:
- break;
- }
- }
-