home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-30 | 32.6 KB | 1,098 lines | [TEXT/MPS ] |
- ///////////////////////////////////////////////////////////
- //
- // ScriptOSAX.c written by Donald Olson
- // Copyright ®1992-3 Apple Computer Inc.
- // All rights reserved.
- //
- // The ScriptEditor OSAX. This is just a little sample
- // that demonstrates how to read and write script files.
- // It also executes scripts from inside the editor dialog
- // or it can execute scripts with out displaying the dialog.
- //
- // As always, bugs and comments to me at D.OLSON on Apple
- // Link.
- //
- // To execute from Toy Surprise:
- // ScriptIt [filepath] [execute only true | false]
- //
- // WARNINGS!!!
- // This is untested code. I mean, I know it works
- // but it's ugly! Scripts and comments are limited to 255
- // characters. I didn't feel like adding TEdit to this thing.
- //
- // Thanks to Theresa, Matt, and Jessica. My wife and kids.
- // Living with a programmer can be a chore sometimes!
- //
- // History:
- // 12/27/92 First pass
- // 12/30/92 Fixed a few bugs
- // 1/8/93 Commented a bit more
- // 1/30/93 Kick it out into the cruel world.
- //
- // To Build:
- // C -b "ScriptOSAX.c" -d SystemSevenOrLater
- // Rez -a -o "ScriptIt OSAX" -t osax -c ascr 'ScriptOSAX.r'
- // Link -p -w -t osax -c ascr -rt osax=4000 -m SCRIPTITENTRY -sg "AEVTaevtscpt" -ra "AEVTaevtscpt"=resSysHeap,resLocked ∂
- // "ScriptOSAX.c.o" ∂
- // "{CLibraries}"StdCLib.o ∂
- // "{Libraries}"Runtime.o ∂
- // "{Libraries}"Interface.o ∂
- // -o "ScriptIt OSAX"
- //
- ///////////////////////////////////////////////////////////
-
- #include <Errors.h>
- #include <Dialogs.h>
- #include <Memory.h>
- #include <Fonts.h>
- #include <OSEvents.h>
- #include <Menus.h>
- #include <Processes.h>
- #include <String.h>
- #include <Resources.h>
- #include <Packages.h>
- #include <Quickdraw.h>
- #ifdef THINK_C
- #include <pascal.h>
- #endif
- #include <AppleEvents.h>
- #include <StandardFile.h>
- #include <Aliases.h>
- #include <Finder.h>
- #include <Files.h>
- #include <QDOffscreen.h>
- #include <ToolUtils.h>
- #include "OSA.h"
-
-
- #define kMYEDITDIALOG 1112 // Dialog id
- #define kSenceOfDecorum 15 // Just above center please
- #define kMySPutRsrc 1111 // Custom put dialog
-
- #define keyJustExecute 'doit' // execute only parameter
- #define kCommentResType 'TEXT'
- #define kStyleResType 'styl' // We don't use this since
- // we don't do styled text
-
- #define kToySurprise 'ToyS' // Script file creator
- #define kCompiledScript 'osas' // Script file type for
- // compiled scripts
- #define kTextScript 'TEXT' // Script file type for
- // text scripts
-
- #define kOk 1 // Our dialog items
- #define kCancel 2
- #define kExecute 3
- #define kSaveAs 4
- #define kCommentField 6
- #define kScriptField 5
- #define kResultField 7
- #define kCycleAgain 10
-
- #define kSaveCompiled 15 // Items for our custom sfput
- #define kSaveText 14
-
- #define kScriptRezID 128 // script rez id's
- #define kCommentRezID 1128
- #define kStyleID 1128
-
-
-
- ///////////////////////////////////////////////////////////
- //
- // ScriptItEntry()
- // This is the main entry point for the ScriptIt OSAX.
- //
- ///////////////////////////////////////////////////////////
-
- pascal OSErr ScriptItEntry(AppleEvent *theEvent, AppleEvent *theReply, long *theRefCon)
- {
- #pragma unused (theRefCon)
-
- /* Our function prototypes */
- pascal Boolean MyDlgFilter(DialogPtr theDlg, EventRecord *theEventRec, short *itemHit);
- Rect ReturnScreenRect(void);
- void CenterWindow(DialogPtr theDialog);
- OSErr EditScript( FSSpec theFileToEdit, Boolean directObjectFound);
- OSErr ExecuteScript( FSSpec theFileToExecute, AEDesc *result);
- OSErr AddFileToDesc(FSSpec theFSSpec, AEDesc *theDesc);
- pascal short mySFPHook(short item, DialogPtr theDialog, void *myData);
- Boolean DoSave(Boolean *SaveAsCompiled, Str255 scriptName, FSSpec *theFileToEdit);
- OSErr AddDescToFile(FSSpec theFSSpec, AEDesc theDesc);
- OSErr DisplayScriptFromFile( FSSpec theFileToEdit, DialogPtr theDialog,
- ComponentInstance gASComponent,Boolean *SaveAsCompiled);
- OSAError CompileScript(DialogPtr theDialog, ComponentInstance gASComponent, AEDesc source, OSAID *resultingID);
-
- /* variables */
- OSErr theErr = noErr;
- Handle tempRezHdl = nil;
- FSSpec theFileToEdit;
- DescType typeCode;
- Size actualSize;
- Boolean directObjectFound = true,
- justExecute = false;
- AEDesc result;
-
- // Init dataHandle for dispose test later
- result.dataHandle = nil;
-
- // Get the file spec of the file to edit or execute
-
- theErr = AEGetParamPtr( theEvent,
- keyDirectObject,
- typeFSS,
- &typeCode,
- (Ptr)&theFileToEdit,
- sizeof(theFileToEdit),
- &actualSize);
-
- if((theErr == errAEDescNotFound) || (theErr != noErr)) {
- directObjectFound = false; // If true, we're editing a script so
- // display it
- }
-
- // Get the optional execute only flag
-
- theErr = AEGetParamPtr( theEvent,
- keyJustExecute,
- typeBoolean,
- &typeCode,
- (Ptr)&justExecute,
- sizeof(justExecute),
- &actualSize);
-
- if(theErr != noErr) justExecute = false;
-
- if(justExecute && (directObjectFound == true))
- theErr = ExecuteScript(theFileToEdit, &result); // just execute
- else {
- /* Set up our dialog */
- /* Check for availability if our resource */
-
- tempRezHdl = Get1Resource('DLOG', kMYEDITDIALOG);
- if(tempRezHdl == nil)
- return resNotFound;
-
- /* Do that interact with user thang */
-
- theErr = AEInteractWithUser(kAEDefaultTimeout, nil, nil);
- if(theErr != noErr)
- {
- if(tempRezHdl != nil)
- ReleaseResource(tempRezHdl); // Set me free
- return theErr;
- }
-
- // Now edit or create a script
- theErr = EditScript(theFileToEdit, directObjectFound);
-
- if(tempRezHdl != nil)
- ReleaseResource(tempRezHdl);
- }
- if(result.dataHandle != nil) // Clean up
- AEPutParamDesc(theReply, keyDirectObject, &result);
- return theErr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // AddFileToDesc
- // Takes the descriptor passed in and adds the data found in the FSSpec to it.
- // This is for text scripts.
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- OSErr AddFileToDesc(FSSpec theFSSpec, AEDesc *theDesc)
- {
- CInfoPBPtr pb = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- HFileInfo *fpb = (HFileInfo*)pb;
- long fileSize = 0;
- Handle tempBuffer;
- short fRefNum = 0;
- OSErr theErr = noErr;
- /*
- Need to know the size of the file so we can create a buffer large enough to contain the
- file.
- */
-
- /* Set up pblock */
- (*pb).hFileInfo.ioNamePtr = (StringPtr)&(theFSSpec.name);
- (*pb).hFileInfo.ioDirID = theFSSpec.parID;
- (*pb).hFileInfo.ioVRefNum = theFSSpec.vRefNum;
- theErr = PBGetCatInfo(pb, false);
-
- if(theErr == noErr) {
- // Make sure we really got a file
- if(fpb->ioFlAttrib & 16) {
- theErr = 3030;
- goto DISPOSELABEL;
- }
- }
- else
- goto DISPOSELABEL;
- fileSize = fpb->ioFlLgLen;
- tempBuffer = NewHandleClear(fileSize);
- if(tempBuffer == nil) {
- theErr = memFullErr;
- goto DISPOSELABEL;
- }
-
- theErr = FSpOpenDF(&theFSSpec, 0, &fRefNum); // Open data fork
- if(theErr != noErr) goto DISPOSELABEL;
-
- HLock(tempBuffer);
- theErr = FSRead(fRefNum, &fileSize, *tempBuffer); // Read in data to buffer
- if(theErr != noErr) goto DISPOSELABEL;
-
- theErr = FSClose(fRefNum); // Close data fork
- if(theErr != noErr) goto DISPOSELABEL;
-
- // Add the data to our descriptor
- theErr = AECreateDesc(typeChar, (Ptr) *tempBuffer, fileSize, theDesc);
-
- DISPOSELABEL:;
- HUnlock(tempBuffer);
- DisposHandle(tempBuffer);
- DisposPtr((Ptr)pb);
-
- return theErr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // AddDescToFile
- // This writes the text in an AEDesc to a data file found at the FSSpec.
- // Used to write text scripts to disk
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- OSErr AddDescToFile(FSSpec theFSSpec, AEDesc theDesc)
- {
- long fileSize = 0;
- short fRefNum = 0;
- OSErr theErr = noErr;
- /*
- Need to know the size of the descriptor
- file.
- */
-
- fileSize = GetHandleSize(theDesc.dataHandle);
-
- theErr = FSpOpenDF(&theFSSpec, 0, &fRefNum);
- if(theErr != noErr) goto DISPOSELABEL;
-
- HLock(theDesc.dataHandle);
-
- theErr = FSWrite(fRefNum, &fileSize, *(theDesc.dataHandle));
- if(theErr != noErr) goto DISPOSELABEL;
-
- theErr = FSClose(fRefNum);
- if(theErr != noErr) goto DISPOSELABEL;
-
- DISPOSELABEL:;
- HUnlock(theDesc.dataHandle);
- return theErr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // ExecuteScript
- // Execute only, no dialog here!
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- OSErr ExecuteScript(FSSpec theFileToExecute, AEDesc *result)
- {
- OSAError theOSAErr = noErr;
- OSErr theErr = noErr;
- OSAID resultingID = 0;
- long modeFlags = 0;
- Handle tempHandle = nil;
- AEDesc source;
- short ourFileRef, curResFile;
- ComponentInstance gASComponent = 0;
-
- // open generic component
-
- gASComponent = OpenDefaultComponent(kOSAComponentType, kOSAGenericScriptingComponentSubtype);
-
- // Check errors here!!
- if((gASComponent == badComponentInstance) || (gASComponent == badComponentSelector))
- return invalidComponentID; // Is this the right error??
-
- curResFile = CurResFile(); // Save current res chain
-
- // Open our resource file for reading
- ourFileRef = FSpOpenResFile(&theFileToExecute, fsRdWrPerm);
- if(ResError())
- return ResError();
-
- UseResFile(ourFileRef);
-
- // Get our resource handle
- tempHandle = Get1Resource(kOSAScriptResourceType, kScriptRezID);
- if(tempHandle == nil)
- {
- theErr = AddFileToDesc(theFileToExecute, &source);
- if(theErr == noErr) {
- theOSAErr = OSACompileExecute( gASComponent,
- &source,
- kOSANullScript,
- modeFlags,
- &resultingID);
-
- if(theOSAErr == noErr){
- /*
- Must use OSACoerceToDesc instead of OSADisplay
- here since we want to preserve the data type
- returned from the execution.
- */
- theOSAErr = OSACoerceToDesc( gASComponent,
- resultingID,
- typeWildCard,
- modeFlags,
- result);
- }
-
- theErr = theOSAErr;
- }
- }
- else {
- DetachResource(tempHandle);
-
- // Put our text into an AEDesc
- theErr = AECreateDesc( kOSAScriptResourceType, (Ptr)*tempHandle,
- (Size)(GetHandleSize(tempHandle)), &source);
- if(theErr != noErr) {
- theErr = theOSAErr;
- goto BAILLABEL;
- }
-
- theOSAErr = OSALoadExecute(gASComponent,
- &source,
- kOSANullScript,
- modeFlags,
- &resultingID);
- if(theOSAErr != noErr){
- theErr = theOSAErr;
- goto BAILLABEL;
- }
- else {
- theOSAErr = OSACoerceToDesc( gASComponent,
- resultingID,
- typeWildCard,
- modeFlags,
- result);
- }
-
- theErr = theOSAErr;
- }
- BAILLABEL:;
- // Clean up time
- if(resultingID != 0) OSADispose( gASComponent, resultingID);
- if(tempHandle != nil) DisposHandle(tempHandle);
- if(source.dataHandle != nil) AEDisposeDesc(&source);
- if(gASComponent != 0) CloseComponent(gASComponent);
-
- // Restore res file and close our script file
- UseResFile(curResFile);
- CloseResFile(ourFileRef);
- return theErr;
- }
-
- OSErr DisplayScriptFromFile (FSSpec theFileToEdit, DialogPtr theDialog,
- ComponentInstance gASComponent,
- Boolean *SaveAsCompiled)
- {
- OSAID resultingID = 0;
- long modeFlags = 0;
- Str255 tempString;
- short iType;
- Handle iHandle;
- Rect iRect;
- short ourFileRef = -1;
- Handle tempHandle = nil;
- OSErr theErr = noErr;
- OSAError theOSAErr = noErr;
- AEDesc source, resultingSourceData;
-
- ourFileRef = FSpOpenResFile(&theFileToEdit, fsRdWrPerm);
- if(ResError()) {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pCouldn't open file to edit!!");
- }
- else {
- UseResFile(ourFileRef);
-
- tempHandle = Get1Resource(kOSAScriptResourceType, kScriptRezID);
- if(tempHandle == nil)
- {
- *SaveAsCompiled = false; // Text script??
- theErr = AddFileToDesc(theFileToEdit, &source);
- if(theErr == noErr) {
- GetIText((Handle)source.dataHandle, tempString);
- GetDItem(theDialog, kScriptField, &iType, &iHandle, &iRect);
- SetIText(iHandle, tempString);
- }
- else {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pError reading script text in!");
- }
-
- if(tempHandle != nil) DisposHandle(tempHandle);
-
- // Now get the comment, if any
- tempHandle = Get1Resource(kCommentResType, kCommentRezID);
- if(tempHandle != nil)
- {
- DetachResource(tempHandle);
- GetIText(tempHandle, tempString);
- GetDItem(theDialog, kCommentField, &iType, &iHandle, &iRect);
- SetIText(iHandle, tempString);
- }
-
- theErr = theOSAErr;
- }
- else
- {
- *SaveAsCompiled = true; // Script is stored as compiled
- DetachResource(tempHandle); // Make it a handle
-
- theErr = AECreateDesc( kOSAScriptResourceType, (Ptr)*tempHandle,
- (Size)(GetHandleSize(tempHandle)), &source);
-
- if(theErr != noErr) {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pFailed creating script descriptor!");
- }
- else {
- // Load script in resource into scriptID
- theOSAErr = OSALoad( gASComponent,
- &source,
- modeFlags,
- &resultingID);
-
-
- if( theOSAErr != noErr) {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to load script!");
- }
- else {
- theOSAErr = OSAGetSource(gASComponent,
- resultingID,
- typeChar,
- &resultingSourceData);
- if( theOSAErr != noErr){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable get script source!");
- }
- else {
- // Now add it to the edit item
- GetIText((Handle)resultingSourceData.dataHandle, tempString);
- GetDItem(theDialog, kScriptField, &iType, &iHandle, &iRect);
- SetIText(iHandle, tempString);
- }
- if(tempHandle != nil) DisposHandle(tempHandle);
-
- // Now get the comment, if any
- tempHandle = Get1Resource(kCommentResType, kCommentRezID);
- if(tempHandle != nil)
- {
- DetachResource(tempHandle);
- GetIText(tempHandle, tempString);
- GetDItem(theDialog, kCommentField, &iType, &iHandle, &iRect);
- SetIText(iHandle, tempString);
- }
-
- if(source.dataHandle != nil) {
- AEDisposeDesc(&source);
- source.dataHandle = nil;
- }
- if(resultingSourceData.dataHandle != nil) {
- AEDisposeDesc(&resultingSourceData);
- resultingSourceData.dataHandle = nil;
- }
- if(tempHandle != nil) {
- DisposHandle(tempHandle);
- tempHandle = nil;
- }
- }
- }
- }
- }
- return theErr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // EditScript
- // This is where we handle our modal edit script dialog
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- OSErr EditScript( FSSpec theFileToEdit, Boolean directObjectFound)
- {
- DialogPtr theDialog;
- GrafPtr savedPort;
- short itemHit = 0;
- Handle tempHandle = nil;
- AEDesc source, resultingSourceData;
- OSErr theErr = noErr;
- OSAError theOSAErr = noErr;
- OSAID resultingID = 0, resultingScriptValueID = 0;
- long modeFlags = 0;
- Str255 tempString;
- short iType;
- Handle iHandle;
- Rect iRect;
- short ourFileRef = -1, curResFile;
- AEDesc result;
- ComponentInstance gASComponent = 0;
- Boolean dirtyField = false, SFOk = false;
- Boolean SaveAsCompiled = true;
-
- // open generic component
- gASComponent = OpenDefaultComponent(kOSAComponentType, kOSAGenericScriptingComponentSubtype);
-
- // Check errors here!!
- if((gASComponent == badComponentInstance) || (gASComponent == badComponentSelector))
- return invalidComponentID; // Is this the right error??
-
- // Nil out dataHandles
- result.dataHandle = nil;
- source.dataHandle = nil;
- resultingSourceData.dataHandle = nil;
-
- curResFile = CurResFile();
-
- GetPort(&savedPort);
-
- theDialog = GetNewDialog(kMYEDITDIALOG, nil, (WindowPtr)-1);
-
- if(theDialog == nil)
- return resNotFound;
-
- SetPort(theDialog);
-
- CenterWindow(theDialog);
-
- InitCursor(); // Should do cursor tracking over edit text fields
-
- // Display script (if any) for file selected
- if(directObjectFound) {
- DisplayScriptFromFile(theFileToEdit, theDialog, gASComponent, &SaveAsCompiled);
- }
-
- ShowWindow(theDialog);
-
- do{
- ModalDialog(MyDlgFilter, &itemHit);
-
- switch(itemHit)
- {
- case kOk:
- // Clear Result Field
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\p");
-
- /*
- Compile and store script. We really should ask the user if
- they really want to save changes but hey, they *DID* say OK!
- */
- if(dirtyField) {
-
- if(!directObjectFound){
- // Make a file to write to, call SFPut here
- UseResFile(curResFile); // So we get our SFP dialogs
- SFOk = DoSave(&SaveAsCompiled, "\pUntitled Script", &theFileToEdit); // Invoke standard put file
- if(ourFileRef != -1) // Have we opened the file before??
- UseResFile(ourFileRef); // Now use other file if opened before
- if(SFOk != true)
- goto BAILLABEL; // We're done
- directObjectFound = true; // Now we have an FSSpec to use
- }
-
- GetDItem(theDialog, kScriptField, &iType, &iHandle, &iRect);
- GetIText(iHandle, tempString);
- theErr = AECreateDesc( typeChar, (Ptr)&tempString[1],
- *tempString, &source);
- if(SaveAsCompiled) {
- theOSAErr = CompileScript(theDialog, gASComponent, source, &resultingID);
- ourFileRef = FSpOpenResFile(&theFileToEdit, fsRdWrPerm);
- if(ResError()) {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to save script!");
- }
-
- UseResFile(ourFileRef);
-
- theOSAErr = OSAStore( gASComponent,
- resultingID,
- kOSAScriptResourceType,
- modeFlags,
- &resultingSourceData);
- if( theOSAErr != noErr){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to store script!");
- }
-
- HLock((Handle)resultingSourceData.dataHandle);
-
- // Remove old script resource if any
- tempHandle = Get1Resource(kOSAScriptResourceType, kScriptRezID);
- if(tempHandle != nil)
- {
- RmveResource(tempHandle);
- UpdateResFile(ourFileRef);
- }
-
- AddResource((Handle)resultingSourceData.dataHandle,
- kOSAScriptResourceType, kScriptRezID, "\p");
- if(ResError()){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to add script resource!");
- }
- WriteResource((Handle)resultingSourceData.dataHandle);
- UpdateResFile(ourFileRef);
-
- AEDisposeDesc(&source);
- DetachResource((Handle)resultingSourceData.dataHandle);
- AEDisposeDesc(&resultingSourceData);
- }
- else { // Save as text
- // Finish up
-
- ourFileRef = FSpOpenResFile(&theFileToEdit, fsRdWrPerm);
- if(ResError()) {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to save script!");
- }
- directObjectFound = true; // Now we have an FSSpec to use
- UseResFile(ourFileRef);
-
- theErr = AddDescToFile(theFileToEdit, source);
- AEDisposeDesc(&source);
- }
- // Remove old comment resource if any
- tempHandle = Get1Resource(kCommentResType, kCommentRezID);
- if(tempHandle != nil)
- {
- RmveResource(tempHandle);
- UpdateResFile(ourFileRef);
- }
-
- // Now add the comment
-
- GetDItem(theDialog, kCommentField, &iType, &iHandle, &iRect);
- GetIText(iHandle, tempString);
- theErr = AECreateDesc( typeChar, (Ptr)&tempString[1],
- *tempString, &source);
-
- if(theErr != noErr){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pAECreateDesc Failed for comment rez!");
- }
- HLock((Handle)source.dataHandle);
- tempHandle = (Handle)source.dataHandle;
- HandToHand(&tempHandle);
- AddResource(tempHandle, kCommentResType, kCommentRezID, "\p");
-
- if(ResError()){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to add comment resource!");
- }
- WriteResource(tempHandle);
- UpdateResFile(ourFileRef);
- if(tempHandle != nil) ReleaseResource(tempHandle);
- }
- break;
- case kCancel:
- /*
- Cancel so bail. If the script was dirty we really should ask the user if
- they really want to save changes but hey, YOU can do it if you want!
- */
- break;
- case kExecute:
- // Clear Result Field
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\p");
-
- // Compile and select errors if any
- GetDItem(theDialog, kScriptField, &iType, &iHandle, &iRect);
- GetIText(iHandle, tempString);
- theErr = AECreateDesc( typeChar, (Ptr)&tempString[1],
- *tempString, &source);
-
- theOSAErr = OSACompileExecute( gASComponent,
- &source,
- kOSANullScript,
- modeFlags,
- &resultingScriptValueID);
- if(theOSAErr != noErr) {
- if(theOSAErr == errOSAScriptError) {
- theOSAErr = OSAScriptError(gASComponent, kOSAErrorMessage,
- typeChar, &resultingSourceData);
- if( theOSAErr != noErr) {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to get error from scripting System");
- }
- else {
- GetIText((Handle)resultingSourceData.dataHandle, tempString);
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, tempString);
- }
- }
- else {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pWasn't errOSAScriptError!");
- }
- itemHit = kCycleAgain;
- }
- else {
- theOSAErr = OSADisplay( gASComponent,
- resultingScriptValueID,
- typeChar,
- modeFlags,
- &result);
-
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- GetIText((Handle)result.dataHandle, tempString);
- SetIText(iHandle, tempString);
- theErr = theOSAErr;
- }
- break;
-
- case kSaveAs:
- // Clear Result Field
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\p");
-
- // Save file
- UseResFile(curResFile);
- if(directObjectFound)
- SFOk = DoSave(&SaveAsCompiled, (Str255)theFileToEdit.name, &theFileToEdit); // Invoke standard put file
- else
- SFOk = DoSave(&SaveAsCompiled, "\pUntitled Script", &theFileToEdit);
- if(SFOk != true)
- break;
- else
- directObjectFound = true; // Now we have an FSSpec to use
- if(ourFileRef != -1)
- UseResFile(ourFileRef);
-
- // Put source text into descriptor
- GetDItem(theDialog, kScriptField, &iType, &iHandle, &iRect);
- GetIText(iHandle, tempString);
- theErr = AECreateDesc( typeChar, (Ptr)&tempString[1],
- *tempString, &source);
-
- if(SaveAsCompiled) {
- theOSAErr = CompileScript(theDialog, gASComponent, source, &resultingID);
-
- ourFileRef = FSpOpenResFile(&theFileToEdit, fsRdWrPerm);
- if(ResError()){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to open script file!");
- }
-
- UseResFile(ourFileRef);
-
- theOSAErr = OSAStore( gASComponent,
- resultingID,
- kOSAScriptResourceType,
- modeFlags,
- &resultingSourceData);
- if( theOSAErr != noErr){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to store script!");
- }
-
- HLock((Handle)resultingSourceData.dataHandle);
-
- tempHandle = Get1Resource(kOSAScriptResourceType, kScriptRezID);
- if(tempHandle != nil) {
- RmveResource(tempHandle);
- UpdateResFile(ourFileRef);
- }
-
- AddResource((Handle)resultingSourceData.dataHandle,
- kOSAScriptResourceType, kScriptRezID, "\p");
- if(ResError()){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to add script resource!");
- }
- WriteResource((Handle)resultingSourceData.dataHandle);
- UpdateResFile(ourFileRef);
- DetachResource((Handle)resultingSourceData.dataHandle);
- AEDisposeDesc(&source);
- AEDisposeDesc(&resultingSourceData);
- }
- else {
-
- // We need to do this so we can add the comment resource later
- ourFileRef = FSpOpenResFile(&theFileToEdit, fsRdWrPerm);
- if(ResError()){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to open script file!");
- }
- UseResFile(ourFileRef);
-
- theErr = AddDescToFile(theFileToEdit, source);
- AEDisposeDesc(&source);
- }
- // Remove old comment resource if any
- tempHandle = Get1Resource(kCommentResType, kCommentRezID);
- if(tempHandle != nil)
- {
- RmveResource(tempHandle);
- UpdateResFile(ourFileRef);
- }
-
- // Now add the comment
- GetDItem(theDialog, kCommentField, &iType, &iHandle, &iRect);
- GetIText(iHandle, tempString);
- theErr = AECreateDesc( typeChar, (Ptr)&tempString[1],
- *tempString, &source);
- if(theErr != noErr){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pAECreateDesc Failed for comment rez!");
- }
- HLock((Handle)source.dataHandle);
- tempHandle = (Handle)source.dataHandle;
- HandToHand(&tempHandle);
- AddResource(tempHandle, kCommentResType, kCommentRezID, "\p");
-
- if(ResError()){
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to add comment resource!");
- }
- WriteResource((Handle)tempHandle);
- UpdateResFile(ourFileRef);
- dirtyField = false;
- if(tempHandle != nil) ReleaseResource(tempHandle);
- UseResFile(curResFile);
- CloseResFile(ourFileRef);
- break;
-
- case kResultField:; // We use hits in the dialog items to
- case kScriptField:; // indicate a dirty script that needs to
- case kCommentField: // be saved to disk.
- dirtyField = true;
- break;
-
- default:
- break;
- }
- }while ((itemHit != ok) && (itemHit != cancel));
-
- BAILLABEL:;
- DisposDialog(theDialog);
-
- UseResFile(curResFile);
- CloseResFile(ourFileRef);
-
- SetPort(savedPort);
-
- if(resultingScriptValueID != 0) OSADispose( gASComponent, resultingScriptValueID);
- if(resultingID != 0) OSADispose( gASComponent, resultingID);
- if(gASComponent != 0) CloseComponent(gASComponent);
- if(tempHandle != nil) ReleaseResource(tempHandle);
- if(source.dataHandle != nil) AEDisposeDesc(&source);
- if(result.dataHandle != nil) AEDisposeDesc(&result);
- if(resultingSourceData.dataHandle != nil) AEDisposeDesc(&resultingSourceData);
-
- return theErr;
- }
-
- OSAError CompileScript(DialogPtr theDialog, ComponentInstance gASComponent, AEDesc source, OSAID *resultingID)
- {
- OSAError theOSAErr, theCompileErr;
- AEDesc resultingSourceData;
- short iType;
- Handle iHandle = nil;
- Rect iRect;
- Str255 tempString;
-
- resultingSourceData.dataHandle = nil;
- theCompileErr = OSACompile( gASComponent,
- &source,
- kOSAModeCompileIntoContext,
- resultingID);
- if( theCompileErr != noErr) {
- if(theCompileErr == errOSAScriptError) {
- // Display error in result field
- theOSAErr = OSAScriptError(gASComponent, kOSAErrorMessage, typeChar, &resultingSourceData);
- if( theOSAErr != noErr) {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pUnable to get error from scripting System");
- }
- else {
- GetIText((Handle)resultingSourceData.dataHandle, tempString);
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, tempString);
- }
- }
- else {
- GetDItem(theDialog, kResultField, &iType, &iHandle, &iRect);
- SetIText(iHandle, "\pWasn't errOSAScriptError!");
- }
- }
- if(resultingSourceData.dataHandle != nil) AEDisposeDesc(&resultingSourceData);
- return theCompileErr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // mySFPHook
- // This is the sfp hook where we set up and take care of our custom dialog
- // items. MyData is a Boolean which if true, indicates to dave as compiled
- // script.
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- pascal short mySFPHook(short item, DialogPtr theDialog, void *myData)
- {
- short iType;
- Handle iHandle = nil;
- Rect iRect;
-
- switch(item) {
- case sfHookFirstCall:
- GetDItem(theDialog, kSaveCompiled, &iType, &iHandle, &iRect);
- if(iHandle != nil) {
- if(*(Boolean*)myData) {
- GetDItem(theDialog, kSaveCompiled, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 1);
- GetDItem(theDialog, kSaveText, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 0);
- *(Boolean*)myData = true;
- }
- else {
- GetDItem(theDialog, kSaveCompiled, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 0);
- GetDItem(theDialog, kSaveText, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 1);
- *(Boolean*)myData = false;
- }
- }
- break;
- case kSaveCompiled :
- GetDItem(theDialog, kSaveCompiled, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 1);
- GetDItem(theDialog, kSaveText, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 0);
- *(Boolean*)myData = true;
- break;
- case kSaveText:
- GetDItem(theDialog, kSaveCompiled, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 0);
- GetDItem(theDialog, kSaveText, &iType, &iHandle, &iRect);
- SetCtlValue((ControlHandle)iHandle, 1);
- *(Boolean*)myData = false;
- break;
-
- default:
- break;
- }
- return item;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // DoSave
- // Wrapper for CustomPutFile
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- Boolean DoSave(Boolean *SaveAsCompiled, Str255 scriptName, FSSpec *theFileToEdit)
- {
- OSErr theErr = noErr;
- Point where;
- StandardFileReply theSFR;
- SetPt(&where, -1, -1);
-
- CustomPutFile( "\pSave Script As:", scriptName, &theSFR, kMySPutRsrc,
- where, mySFPHook, nil, nil, nil, SaveAsCompiled);
- if(theSFR.sfGood != true)
- return false;
- if(theSFR.sfReplacing) {
- theErr = FSpDelete(&theSFR.sfFile);
- if(theErr == noErr)
- FSpCreateResFile(&theSFR.sfFile, kToySurprise, *SaveAsCompiled ? kCompiledScript : kTextScript, theSFR.sfScript);
- }
- else
- FSpCreateResFile(&theSFR.sfFile, kToySurprise, *SaveAsCompiled ? kCompiledScript : kTextScript, theSFR.sfScript);
- *theFileToEdit = theSFR.sfFile;
- return true;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CenterWindow
- // Could use the System 7 autocentering code, but old habits die hard.
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- void CenterWindow(DialogPtr theDialog)
- {
- Rect screenRect,
- dialogRect;
- short vPt = 0, hPt = 0;
-
- dialogRect = theDialog->portRect;
-
- screenRect = ReturnScreenRect();
-
- vPt = ((screenRect.bottom - screenRect.top) - (dialogRect.bottom - dialogRect.top))/3; // Move to top 1/3
- hPt = ((screenRect.right - screenRect.left) - (dialogRect.right - dialogRect.left))/2;
- MoveWindow(theDialog, hPt, vPt - kSenceOfDecorum, false);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // ReturnScreenRect
- // Guess what this does??
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- Rect ReturnScreenRect()
- {
- GrafPtr myPort;
-
- GetWMgrPort(&myPort);
- return (myPort->portRect);//(*MainDevice)->gdRect;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // MyDlgFilter
- // Dialog filter for our edit dialog.
- // Here's where we handle the command period and escape key stuff. We really
- // don't need to do this since in System 7 there are new dailog manager routines
- // that do this for us. Shucks!
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- pascal Boolean MyDlgFilter(DialogPtr theDlg, EventRecord *theEventRec, short *itemHit)
- {
- #pragma unused (theDlg)
- pascal Boolean IsCmdChar(const EventRecord *, short test)
- = {0x2F3C,0x8206,0xFFD0,0xA8B5};
-
- if( theEventRec->what==keyDown || theEventRec->what==autoKey )
- {
- char c = theEventRec->message&0xFF;
- if( IsCmdChar(theEventRec,'.') )
- {
- *itemHit = cancel; // Cmd-Period hit!
- return (true);
- }
- else
- if( c==0x1B && (theEventRec->message&0xFF00)==0x3500 )
- {
- *itemHit = cancel; // Esc key hit!
- return (true);
- }
- }
- return (false);
- }