home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacFormat 1994 November
/
macformat-018.iso
/
Utility Spectacular
/
Developer
/
OSAX Samples
/
ScriptIt OSAX
/
ScriptOSAX.c
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
UTF-8
Wrap
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);
}