home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / µSim 1.1 / source / ControlStore.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-25  |  12.6 KB  |  490 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993-1997 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11. #ifndef __MOREFILESEXTRAS__
  12. #include    <MoreFilesExtras.h>
  13. #endif
  14.  
  15. #include    "UtilsSys7.h"
  16. #include    "FabLibResIDs.h"
  17. #include    "SimResIDs.h"
  18.  
  19. #include    "Globals.h"
  20. #include    "Animation.h"
  21. #include    "ControlStore.h"
  22. #include    "DoMenu.h"
  23. #include    "Microprogram_Ed.h"
  24. #include    "SimUtils.h"
  25.  
  26. #if defined(FabSystem7orlater)
  27.  
  28. #pragma segment Rare
  29.  
  30. static const short controlStoreObject[] = {kP_CONTSTORE, 0 };
  31.  
  32. static short    myFileRefN;
  33.  
  34. static Boolean    sDocIsOpen = false;
  35.  
  36. static FSSpec    workingFile;
  37. static ScriptCode    wkFileScript;
  38. static Boolean    dirtyCSFlag = false;
  39.  
  40. /*====== internal routines ======*/
  41. static OSErr gotSave(Handle buf);
  42. static OSErr gotSaveAs(Handle buf, OSType);
  43. static OSErr SafeSave(Handle wrBuf, FSSpec *onWhichFile, ScriptCode);
  44.  
  45.  
  46. /* RevertFile: we revert to the last saved version of the doc */
  47.  
  48. OSErr RevertFile(void)
  49. {
  50. FSSpec    tempNewFile = workingFile;
  51.  
  52. FSClose(myFileRefN);
  53. myFileRefN = 0;
  54. DocumentIsDirty(false);
  55. return myOpenCSFile(&tempNewFile, wkFileScript, false);
  56. }
  57.  
  58. /* myOpenCSFile: we read all that stuff (the microprogram) from the file */
  59.  
  60. OSErr myOpenCSFile(FSSpec *theFile, ScriptCode theScript, Boolean StationeryDoc)
  61. {
  62. Str255    tempS;
  63. ParamBlockRec    myPB;
  64. EventRecord    dummyEv;
  65. Rect    tempRect;
  66. GrafPtr    savePort;
  67. Handle    tempBuffer;
  68. UInt32    fileSize;
  69. short    length;
  70. OSErr    err;
  71. Boolean    isLocked = false;
  72.  
  73. SetCursor(*gWatchHandle);
  74. GetPort(&savePort);
  75. SetPort(gWPtr_Microprogram_Ed);
  76. if ((err = FSpOpenDFCompat(theFile, StationeryDoc ? fsRdPerm : fsRdWrPerm, &myFileRefN)) == permErr) {
  77.     err = FSpOpenDFCompat(theFile, fsRdPerm, &myFileRefN);
  78.     isLocked = true;
  79.     }
  80. if (err == noErr) {
  81.     if ((err = GetEOF(myFileRefN, (long *)&fileSize)) == noErr) {
  82.         if ((tempBuffer = NewHandleGeneral(fileSize)) != 0L) {
  83.             myPB.ioParam.ioCompletion = 0L;
  84.             myPB.ioParam.ioRefNum = myFileRefN;
  85.             HLock(tempBuffer);
  86.             myPB.ioParam.ioBuffer = *tempBuffer;
  87.             myPB.ioParam.ioReqCount = fileSize;
  88.             myPB.ioParam.ioPosMode = fsFromStart;
  89.             myPB.ioParam.ioPosOffset = 0L;
  90.             (void)PBReadAsync(&myPB);
  91.             while (myPB.ioParam.ioResult > 0) {
  92.                 SystemTask();
  93.                 (void)EventAvail(everyEvent, &dummyEv);
  94.                 }
  95.             HUnlock(tempBuffer);
  96.             if ((err = myPB.ioParam.ioResult) == noErr) {
  97.                 Point    tempCell;
  98.                 register unsigned char *spanningPtr;
  99.                 register short    i;
  100.  
  101.                 LSetDrawingMode(false, Lists[kL_COMMENTS]);
  102.                 DoNew();
  103.                 BlockMoveData(*tempBuffer, gCsMemory, kSIZE_CSMEM + kSIZE_ASSMEM);
  104.                 tempCell.h = 0;
  105.                 HLock(tempBuffer);
  106.                 for (spanningPtr = (unsigned char *)*tempBuffer + kSIZE_CSMEM + kSIZE_ASSMEM,
  107.                     i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  108.  
  109.                     tempCell.v = i;
  110.                     LSetCell(spanningPtr + 1, *spanningPtr, tempCell, Lists[kL_COMMENTS]);
  111.                     spanningPtr += *spanningPtr + 1;
  112.                     }
  113.                 HUnlock(tempBuffer);
  114.                 LSetDrawingMode(true, Lists[kL_COMMENTS]);
  115.                 if (StationeryDoc == false) {
  116.                     workingFile = *theFile;
  117.                     wkFileScript = theScript;
  118.                     SetWTitle(gWPtr_Microprogram_Ed, theFile->name);
  119.                     }
  120.                 DocumentIsDirty(false);
  121.             /* get cell contents and put into TextEdit field */
  122.                 length = 255;    /* maximum length of text */
  123.                 tempCell.h = 0;
  124.                 tempCell.v = theSelection[kL_COMMENTS];
  125.                 LGetCell(&tempS, &length, tempCell, Lists[kL_COMMENTS]);
  126.                 SetMicroProgramComment((Ptr)&tempS, length);
  127.                 RefreshTE(kKEY_COMMENT);
  128.         //        UnloadSeg(RefreshTE);
  129.                 SetMir((*(gCsMemory + theSelection[kL_COMMENTS])).cstore);
  130.                 tempRect = *keyrects[kKEY_LIST];
  131.                 tempRect.right -= kScrollbarAdjust;
  132.                 InvalRect(&tempRect);
  133.                 DoMenuWindows(kMItem_Microprogram);
  134.                 }
  135.             DisposeHandle(tempBuffer);
  136.             }
  137.         else err = MemError();
  138.         }
  139.     if (err || StationeryDoc || isLocked)
  140.         (void)FSClose(myFileRefN);
  141.     }
  142. if (err || StationeryDoc || isLocked)
  143.     myFileRefN = 0;
  144. SetPort(savePort);
  145. InitCursor();
  146. return err;
  147. }
  148.  
  149. /* mySaveCSFile: the user has chosen Save or Save As… from the menus */
  150.  
  151. OSErr mySaveCSFile(int selector)
  152. {
  153. Point    tempCell;
  154. Handle    readyBuffer;
  155. OSErr    err;
  156.  
  157. SetCursor(*gWatchHandle);
  158. tempCell.h = 0;
  159. tempCell.v = theSelection[kL_COMMENTS];
  160. ChangedListSelection(tempCell, kL_COMMENTS, false);
  161. if (readyBuffer = PrepareBufferFromList()) {
  162.     switch (selector) {
  163.         case kGOT_SAVE: err = gotSave(readyBuffer);
  164.             break;
  165.         case kGOT_SAVEAS: err = gotSaveAs(readyBuffer, kFTY_CSTORE);
  166.             break;
  167.         case kGOT_SAVESTATIONERY: err = gotSaveAs(readyBuffer, kFTY_CSTOREPAD);
  168.             break;
  169.         }
  170.     DisposeHandle(readyBuffer);
  171.     }
  172. else err = MemError();
  173. InitCursor();
  174. return err;
  175. }
  176.  
  177. /*    gotSave: the user has told us to Save. Is he working at a previously saved
  178.     document or not? */
  179.  
  180. static OSErr gotSave(Handle buf)
  181. {
  182. OSErr    err;
  183.  
  184. if (myFileRefN != 0)
  185.     err = SafeSave(buf, &workingFile, wkFileScript);
  186. else
  187.     err = gotSaveAs(buf, kFTY_CSTORE);
  188. return err;
  189. }
  190.  
  191. /*    gotSaveAs: we must definitely show up the dialog box for "save-a-file"
  192.     and save it if asked for */
  193.  
  194. static OSErr gotSaveAs(Handle buf, OSType theType)
  195. {
  196. StandardFileReply    mySFR;
  197. FInfo    fndrInfo;
  198. Handle    sH1;
  199. Handle    sH2;
  200. short    tmpFRefN;
  201. SignedByte    state1, state2;
  202. OSErr    err;
  203.  
  204. state1 = WantThisHandleSafe(sH1 = (Handle)GetString(kSTR_CSPROMPT));
  205. state2 = WantThisHandleSafe(sH2 = (Handle)GetString(kSTR_CSDEFNAME));
  206. InitCursor();
  207. StandardPutFile((ConstStr255Param)*sH1, (ConstStr255Param)*sH2, &mySFR);
  208. SetCursor(*gWatchHandle);
  209. if (mySFR.sfGood) {
  210.     if (mySFR.sfReplacing) {
  211.         if (noErr == (err = FSpGetFInfoCompat(&mySFR.sfFile, &fndrInfo))) {
  212.             if (fndrInfo.fdType == theType)
  213.                 err = SafeSave(buf, &mySFR.sfFile, mySFR.sfScript);
  214.             else
  215.                 (void)StopAlert_UPP(kALRT_WRONGEXISTINGDOC, myStdFilterProcNoCancel);
  216.             }
  217.         }
  218. /* not replacing an existing file */
  219.     else if ((err = FSpCreateCompat(&mySFR.sfFile, kFCR_MINE, theType, mySFR.sfScript)) == noErr)
  220.         if ((err = FSpOpenDFCompat(&mySFR.sfFile, fsRdWrPerm, &tmpFRefN)) == noErr)
  221.             if ((err = WriteMicroprogramData(buf, &mySFR.sfFile, theType, tmpFRefN, mySFR.sfScript)) == noErr) {
  222.                 if (theType == kFTY_CSTORE) {
  223.                     if (myFileRefN)    /* close old working file if any */
  224.                         (void)FSClose(myFileRefN);
  225.                     myFileRefN = tmpFRefN;    /* this is the new work file */
  226.                     workingFile = mySFR.sfFile;
  227.                     wkFileScript = mySFR.sfScript;
  228.                     SetWTitle(gWPtr_Microprogram_Ed, mySFR.sfFile.name);
  229.                     DocumentIsDirty(false);
  230.                     }
  231.                 else if (theType == kFTY_CSTOREPAD) {
  232.                     (void) FSpSetIsStationery(&mySFR.sfFile);
  233.                     (void)FSClose(tmpFRefN);
  234.                     }
  235.                 }
  236.             else {    /* error writing data */
  237.                 (void)FSClose(tmpFRefN);
  238.                 (void)FSpDeleteCompat(&mySFR.sfFile);
  239.                 }
  240.     }
  241. else err = 1;
  242. HSetState(sH1, state1);
  243. HSetState(sH2, state2);
  244. return(err);
  245. }
  246.  
  247. /*    SafeSave: we should do a safe save of the document
  248.     (a previously saved version already exists) */
  249.  
  250. OSErr SafeSave(Handle buf, FSSpec *onWhichFile, ScriptCode myFScript)
  251. {
  252. Str255    tempFName;
  253. FSSpec    thisFSSpec;
  254. long    thisDirID;
  255. short    thisVRefNum, newFileRefn;
  256. register OSErr    err;
  257.  
  258. if (0)    /* test if file locked (FSpExchange does not, it's a bug) */
  259.     err = fLckdErr;
  260. else {
  261.     MyNumToString(TickCount(), tempFName);
  262.     if ((err = FindFolder(onWhichFile->vRefNum, kTemporaryFolderType, kCreateFolder,
  263.                     &thisVRefNum, &thisDirID)) == noErr) {
  264.         (void)FSMakeFSSpecCompat(thisVRefNum, thisDirID, (ConstStr255Param)&tempFName, &thisFSSpec);
  265.         if ((err = FSpCreateCompat(&thisFSSpec, kFCR_MINE, kFTY_CSTORE,
  266.                             myFScript)) == noErr)
  267.             if ((err = FSpOpenDFCompat(&thisFSSpec, fsRdWrPerm, &newFileRefn)) == noErr)
  268.                 if ((err = WriteMicroprogramData(buf, &thisFSSpec, kFTY_CSTORE, newFileRefn, myFScript)) == noErr) {
  269.                     if ((err = FSpExchangeFilesCompat(&thisFSSpec, onWhichFile)) == noErr) {
  270.                         if (myFileRefN)
  271.                             (void)FSClose(myFileRefN);
  272.                         myFileRefN = newFileRefn;
  273.                         workingFile = *onWhichFile;
  274.                         wkFileScript = myFScript;
  275.                         SetWTitle(gWPtr_Microprogram_Ed, onWhichFile->name);
  276.                         DocumentIsDirty(false);
  277.                         err = FSpDeleteCompat(&thisFSSpec);
  278.                         }
  279.                     }
  280.                 else {
  281.                     (void)FSClose(newFileRefn);
  282.                     (void)FSpDeleteCompat(&thisFSSpec);    // the temporary one
  283.                     if (err == dskFulErr) {
  284.                         (void)StopAlert_UPP(kALRT_NOSAVE, myStdFilterProcNoCancel);
  285.                         err = 1;
  286.                         }
  287.                     }
  288.         }
  289.     }
  290. return(err);
  291. }
  292.  
  293. /* WriteMicroprogramData: writes physically the data into the file */
  294.  
  295. OSErr WriteMicroprogramData(Handle prepBuffer, FSSpec *theFSpec, OSType theType, short theOpenedFile,
  296.                         ScriptCode theFileSc)
  297. {
  298. ParamBlockRec    myPB;
  299. EventRecord    dummyEv;
  300. register OSErr    err;
  301.  
  302. myPB.ioParam.ioCompletion = 0L;
  303. myPB.ioParam.ioBuffer = (Ptr)gCsMemory;
  304. myPB.ioParam.ioReqCount = kSIZE_CSMEM + kSIZE_ASSMEM;
  305. myPB.ioParam.ioPosMode = fsFromStart;
  306. myPB.ioParam.ioRefNum = theOpenedFile;
  307. myPB.ioParam.ioPosOffset = 0L;
  308. (void)PBWriteAsync(&myPB);
  309. while (myPB.ioParam.ioResult > 0) {
  310.     SystemTask();
  311.     (void)EventAvail(everyEvent, &dummyEv);
  312.     }
  313. if ((err = myPB.ioParam.ioResult) == noErr) {
  314.     myPB.ioParam.ioBuffer = *prepBuffer;
  315.     myPB.ioParam.ioReqCount = InlineGetHandleSize(prepBuffer);
  316.     myPB.ioParam.ioPosMode = fsAtMark;
  317.     myPB.ioParam.ioRefNum = theOpenedFile;
  318.     myPB.ioParam.ioPosOffset = 0L;
  319.     HLock(prepBuffer);
  320.     (void)PBWriteAsync(&myPB);
  321.     while (myPB.ioParam.ioResult > 0) {
  322.         SystemTask();
  323.         (void)EventAvail(everyEvent, &dummyEv);
  324.         }
  325.     HUnlock(prepBuffer);
  326.     if ((err = myPB.ioParam.ioResult) == noErr)
  327.         err = AddSTRRes2Doc(theFSpec, kFCR_MINE, theType, kSTR_ApplicationName, theFileSc);
  328.     }
  329. return err;
  330. }
  331.  
  332. /* DoNew: starts afresh with a new microprogram */
  333.  
  334. void DoNew(void)
  335. {
  336. StringHandle    UntitledStr;
  337. SignedByte    oldstate;
  338.  
  339. ResetMicroprogramWindow();
  340. sDocIsOpen = true;
  341. ActivateObjs(controlStoreObject);
  342. if (UntitledStr = GetString(kSTR_UNTITLED)) {
  343.     oldstate = WantThisHandleSafe((Handle)UntitledStr);
  344.     SetWTitle(gWPtr_Microprogram_Ed, *UntitledStr);
  345.     (void) PLstrcpy(workingFile.name, *UntitledStr);
  346.     HSetState((Handle)UntitledStr, oldstate);
  347.     }
  348. }
  349.  
  350. /* ResetMicroprogramWindow: wipes out the window to an empty one */
  351.  
  352. void ResetMicroprogramWindow(void)
  353. {
  354. Str255    tempS;
  355. register Point tempCell = { 0, 0};
  356. short    leng;
  357. register short    i;
  358.  
  359. for ( i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  360.     tempCell.v = i;
  361.     LClrCell(tempCell, Lists[kL_COMMENTS]);
  362.     }
  363. tempCell.v = 0;
  364. leng = 255;
  365. LGetCell(&tempS, &leng, tempCell, Lists[kL_COMMENTS]);
  366. SetMicroProgramComment((Ptr)&tempS, leng);
  367. keyDownDest = kKEY_BRTO;
  368.  
  369.     {
  370.     register union u_mir tempmir;
  371.  
  372.     tempmir.cstore = 0L;
  373.     tempmir.bits.c = 15;
  374.     tempmir.bits.dsc = 1;
  375.     SetControlsFromMir(tempmir);
  376.     }
  377. }
  378.  
  379. /*    PrepareBufferFromList: sets up a buffer containing all the info
  380.     about the microprogram, so that it is ready to be saved into a file. */
  381.  
  382. Handle PrepareBufferFromList(void)
  383. {
  384. Str255    tempS;
  385. Point    tempCell;
  386. register Handle    myH = nil;
  387. short    len;
  388. register OSErr    err;
  389. register short i;
  390.  
  391. if (Lists[kL_COMMENTS] && gCsMemory)
  392.     if (myH = NewHandleGeneral(0L)) {
  393.         tempCell.h = 0;
  394.         for (i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  395.             tempCell.v = i;
  396.             len = 255;
  397.             LGetCell(&tempS[1], &len, tempCell, Lists[kL_COMMENTS]);
  398.             tempS[0] = len;
  399.             if (err = PtrAndHand(&tempS, myH, len + 1))
  400.                 break;
  401.             }
  402.         if (err) {
  403.             DisposeHandle(myH);
  404.             myH = nil;
  405.             }
  406.         }
  407. return myH;
  408. }
  409.  
  410. #pragma segment Main
  411.  
  412. /*
  413. DocIsOpen: accessor */
  414.  
  415. Boolean DocIsOpen(void)
  416. {
  417. return sDocIsOpen;
  418. }
  419.  
  420. /*    ReadyToTerminate: we decide if we are ready to quit gracefully;
  421.     shall we save an unsaved document? Let the user choose… */
  422.  
  423. Boolean ReadyToTerminate(void)
  424. {
  425. enum {
  426. kPUSH_SAVE = 1,
  427. kPUSH_CANCEL,
  428. kPUSH_DONTSAVE
  429. };
  430.  
  431. OSErr    err;
  432.  
  433. if (gRstatus) {
  434.     if (CautionAlert_UPP(kALRT_CPURUNNING, myStdFilterProc) == cancel)
  435.         return false;
  436.     }
  437. if (dirtyCSFlag) {
  438.     ParamText(workingFile.name, nil, nil, nil);
  439.     switch (CautionAlert_UPP(kALRT_SAVE, myStdFilterProc)) {
  440.         case kPUSH_SAVE:
  441.             err = mySaveCSFile(kGOT_SAVE);
  442.             UnloadSeg(mySaveCSFile);
  443.             if (err) {
  444.                 if (err != 1)
  445.                     ErrorAlert(err);
  446.                 return false;
  447.                 }
  448.             break;
  449.         case kPUSH_CANCEL:
  450.             return false;
  451.             break;
  452.         case kPUSH_DONTSAVE:
  453.             break;
  454.         }
  455.     }
  456. if (myFileRefN) {
  457.     FSClose(myFileRefN);
  458.     myFileRefN = 0;
  459.     }
  460. DocumentIsDirty(false);
  461. sDocIsOpen = false;
  462. DeactivateObjs(controlStoreObject);
  463. MyZeroBuffer((long *)gCsMemory, numOfLongs(kSIZE_ASSMEM + kSIZE_CSMEM));
  464. CloseMicroProg(gWPtr_Microprogram_Ed);
  465. SetMir(0L);
  466. return true;
  467. }
  468.  
  469. /*    DocumentIsDirty: has the document been modified since last save?
  470.     Update the menus accordingly. */
  471.  
  472. void DocumentIsDirty(Boolean dirtiness)
  473. {
  474. if (dirtyCSFlag != dirtiness) {
  475.     if (dirtyCSFlag = dirtiness) {
  476.         EnableItem(gMenu_File, kMItem_Save_Control_St);
  477.         }
  478.     else {
  479.         DisableItem(gMenu_File, kMItem_Save_Control_St);
  480.         }
  481.     if (myFileRefN && dirtyCSFlag)
  482.         EnableItem(gMenu_File, kMItem_Revert_to_Saved);
  483.     else
  484.         DisableItem(gMenu_File, kMItem_Revert_to_Saved);
  485.     }
  486. }
  487.  
  488. #endif
  489.  
  490.