home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-02-04 | 14.6 KB | 709 lines | [TEXT/MPS ] |
- /*
- File: ScriptableObjects.cp
-
- Contains: Script handling & OSA interface
-
- Developed by:
-
- Paul G Smith (commstalk hq & Full Moon Software, Inc)
-
- you can leave messages at (UK): 0727 844232; (US): 408 253 7199
- BUT I prefer to be contacted by e-mail
- AppleLink: SMITH.PG
- Internet: SMITH.PG@applelink.apple.com
-
- "SimpliFace" Sample code to accompany develop article
- on techniques for embedding scripts in applications.
-
- */
-
-
- #include "ScriptableObjects.h"
- #include "SimpliFaceCommon.h"
-
- #ifndef __STDIO__
- #include <StdIO.h>
- #endif
-
- #ifndef __LIMITS__
- #include <Limits.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __PLSTRINGFUNCS__
- #include <PLStringFuncs.h>
- #endif
-
- #ifndef __WINDOWS__
- #include <Windows.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __PROCESSES__
- #include <Processes.h>
- #endif
-
- #ifndef __PLSTRINGFUNCS__
- #include <PLStringFuncs.h>
- #endif
-
- #ifndef __AEOBJECTS__
- #include <AEObjects.h>
- #endif
-
- #ifndef __ASDEBUGGING__
- #include <ASDebugging.h>
- #endif
-
- #ifndef __ASREGISTRY__
- #include <ASRegistry.h>
- #endif
-
- #ifndef __SCRIPTUTILS__
- #include "ScriptUtils.h"
- #endif
-
- #ifndef __SIMPLIFACE__
- #include "SimpliFace.h"
- #endif
-
- #ifndef __AEOMTOKENS__
- #include "ObjModelTokens.h"
- #endif
-
- #ifndef __AEOMEVENTS__
- #include "ObjModelEvents.h"
- #endif
-
-
- #include "DebugTrace.h"
-
- #pragma trace off
-
- // globals
-
-
- TScriptAdministrator* gScriptAdministrator = NULL;
- ComponentInstance gScriptingComponent = NULL;
- AEAddressDesc gSelfAddress;
- ProcessSerialNumber gSelfPSN;
-
-
- #ifndef kComponentNotFound
- #define kComponentNotFound -1
- #endif
-
-
-
-
- OSAError GetOSAerrorInfo(ComponentInstance scriptingSystem,
- OSAError *errNum, char *errStr)
- {
- OSAError err = 0;
- AEDesc infoDesc;
-
- *errNum = 0;
-
- err = OSAScriptError(scriptingSystem, kOSAErrorMessage,
- typeChar, &infoDesc);
- if (!err)
- GetPStringFromDescriptor(&infoDesc, errStr);
-
- err = OSAScriptError(scriptingSystem, kOSAErrorNumber,
- typeShortInteger, &infoDesc);
- if (!err)
- GetLongIntFromDescriptor(&infoDesc, errNum);
-
- return err;
- }
-
-
-
- void DumpOSAerrorInfo(ComponentInstance scriptingSystem, OSAError err)
- {
- char message[256];
- OSAError newerr = 0, errNum;
-
- if (err == errOSAScriptError)
- {
- memset(message, 0, 256);
-
- newerr = GetOSAerrorInfo(scriptingSystem, &errNum, message);
-
- if (!newerr /*&& errNum*/ )
- {
- printf("DumpOSAerrorInfo: errNum = %ld\n", errNum);
- printf("%s\n", &message[1]);
- }
- else
- printf("DumpOSAerrorInfo failed: err = %ld\n", err);
- }
- }
-
-
-
-
-
-
- pascal OSErr StdActiveProc(long refCon)
- {
- if (gSimpliFace && gScriptAdministrator)
- {
- if (!gScriptAdministrator->StartupScriptIsRunning())
- gSimpliFace->InEventLoop();
- }
- return 0;
- }
-
-
- /*
- Name: InitOSAScripting
- Purpose:Connects to the AppleScript component.
- */
- OSAError InitOSAScripting(void)
- {
- OSAError err = 0;
- ComponentDescription descr;
- Component aComponent;
- ProcessSerialNumber aSelfPSN;
- ComponentInstance aScriptingComponent;
- AEAddressDesc aSelfAddress; // A self-addressed address descriptor record
-
- aSelfPSN.highLongOfPSN = 0;
- aSelfPSN.lowLongOfPSN = kCurrentProcess; //* Use this instead of GetCurrentProcess *//
- AECreateDesc(typeProcessSerialNumber, (Ptr)&aSelfPSN,
- sizeof(ProcessSerialNumber), &aSelfAddress);
-
- descr.componentType = kOSAComponentType;
- descr.componentSubType = (OSType) 0;
- descr.componentManufacturer = (OSType) 0;
- descr.componentFlags = kOSASupportsCompiling +
- kOSASupportsGetSource +
- kOSASupportsConvenience +
- kOSASupportsEventHandling;
- descr.componentFlagsMask = descr.componentFlags;
-
- aComponent = FindNextComponent(nil, &descr);
-
- if (!aComponent)
- return(kComponentNotFound);
- else
- {
- aScriptingComponent = OpenComponent(aComponent);
-
- if (!aScriptingComponent)
- return(kComponentNotFound);
-
- if (aScriptingComponent)
- err = OSASetActiveProc(aScriptingComponent,
- (OSAActiveProcPtr)&StdActiveProc, 0);
- }
-
- gScriptingComponent = aScriptingComponent;
- gSelfAddress = aSelfAddress;
- gSelfPSN = aSelfPSN;
-
- return err;
- }
-
-
- /*
- Name : CloseOSAScripting
- Purpose : Shutdown of OSA scripting capabilities
- */
- OSAError CloseOSAScripting(void)
- {
- OSAError err = noErr;
-
- if (gScriptingComponent)
- {
- err = CloseComponent(gScriptingComponent);
- gScriptingComponent = NULL;
- }
-
- return err;
- }
-
-
-
- OSAError StartScriptAdministrator(void)
- {
- OSAError err = InstallEventHandlers();
-
- if (!err)
- err = SFinitAEobjects();
- if (!err)
- err = InitOSAScripting();
-
- if (!err)
- gScriptAdministrator = new TScriptAdministrator;
-
- return err;
- }
-
- OSAError StopScriptAdministrator(void)
- {
- OSAError err = noErr;
-
- if (gScriptAdministrator)
- {
- delete gScriptAdministrator;
- gScriptAdministrator = NULL;
- }
-
- err = SFendAEobjects();
- err = DeInstallEventHandlers();
- err = CloseOSAScripting();
-
- return err;
- }
-
-
-
- /*******************************************************************************
- ** PUBLIC Constructor/Destructor
- ********************************************************************************/
-
- TScriptAdministrator::TScriptAdministrator()
- {
- fStartupScriptRunning = false;
- }
-
-
- TScriptAdministrator::~TScriptAdministrator(void)
- {
- }
-
-
-
- void TScriptAdministrator::RunStartupScript(void)
- {
- if (fStartupScriptRunning)
- printf("•TScriptAdministrator::RunStartupScript(): attempt to run script recursively\n");
- else
- {
- Str255 fileName;
- short appVRefNum;
- long appDirID;
- OSAError err = GetCurrentAppFileSpec(&appVRefNum, &appDirID,
- (StringPtr)&fileName);
-
- printf("TScriptAdministrator::RunStartupScript()\n");
-
- fStartupScriptRunning = true;
-
- if (!err)
- {
- FSSpec theFileSpec;
- OSAID startupScript = kOSANullScript;
-
- GetIndString(fileName, kSimpliFaceBuzzwords, kStartupScriptFileName);
-
- theFileSpec.vRefNum = appVRefNum;
- theFileSpec.parID = appDirID;
- PLstrcpy((StringPtr)&(theFileSpec.name), (ConstStr255Param)fileName);
-
- err = LoadScriptFromFile(&theFileSpec, &startupScript);
-
- if (!err && startupScript != kOSANullScript)
- {
- OSAID resultID = kOSANullScript;
-
- err = OSAExecute(gScriptingComponent, startupScript,
- kOSANullScript, kOSAModeNull, &resultID);
- if (err)
- DumpOSAerrorInfo(gScriptingComponent, err);
- else
- {
- AEDesc displayData;
-
- printf("TScriptAdministrator::RunStartupScript() succeeded, ");
-
- if (resultID != kOSANullScript)
- {
- printf("with result: ");
- err = OSADisplay(gScriptingComponent, resultID,
- typeChar, kOSAModeNull, &displayData);
- if (!err && displayData.dataHandle)
- {
- short zero = 0;
- Handle h = displayData.dataHandle;
-
- PtrAndHand(&zero, h, 1); // shove a zero on the end for stdio
- HLock(h);
- printf((char*)*h);
- HUnlock(h);
- AEDisposeDesc(&displayData);
- }
- }
- else
- printf("no result was returned");
- printf("\n");
- }
-
- OSADispose(gScriptingComponent, startupScript);
- OSADispose(gScriptingComponent, resultID);
- }
- else
- printf("Failed to load startup script from file, err = %d\n", err);
- }
- else
- printf("Failed to establish current directory, err = %d\n", err);
-
- fStartupScriptRunning = false;
- }
- }
-
-
- OSAError TScriptAdministrator::DoScript(AEDesc *scriptDesc, AEDesc *resultDesc)
- {
- OSAError err = errAEEventNotHandled;
-
- if (scriptDesc && (scriptDesc->descriptorType == typeChar
- || scriptDesc->descriptorType == typeIntlText))
- {
- OSAID resultID = kOSANullScript;
-
- err = OSACompileExecute(gScriptingComponent, scriptDesc,
- kOSANullScript, kOSAModeAlwaysInteract,
- &resultID);
- if (err)
- DumpOSAerrorInfo(gScriptingComponent, err);
- else if (resultID != kOSANullScript)
- err = OSACoerceToDesc(gScriptingComponent, resultID, typeWildCard,
- kOSAModeNull, resultDesc);
-
- OSADispose(gScriptingComponent, resultID);
- }
-
- return err;
- }
-
-
- OSAID TScriptAdministrator::GetAttachedScript(TScriptableObject* theObj)
- {
- if (theObj)
- return theObj->GetObjScript();
- else
- return kOSANullScript;
- }
-
-
- OSAError TScriptAdministrator::ReleaseAttachedScript(TScriptableObject* theObj)
- {
- return noErr;
- }
-
-
- OSAError TScriptAdministrator::LoadScriptFromFile(FSSpec *fileSpec, OSAID *theScriptID)
- {
- short fileRef = FSpOpenResFile(fileSpec, fsRdPerm);
- OSAError err = ResError();
-
- if (!err)
- {
- Handle h = Get1Resource(kOSAScriptResourceType, 128);
-
- if (h)
- {
- AEDesc scriptData;
-
- scriptData.descriptorType = typeOSAGenericStorage;
- scriptData.dataHandle = h;
-
- err = OSALoad(gScriptingComponent, &scriptData, kOSAModeNull,
- theScriptID);
-
- ReleaseResource(scriptData.dataHandle);
- }
- CloseResFile(fileRef);
- }
-
- return err;
- }
-
-
- OSAError TScriptAdministrator::SaveScriptToFile(FSSpec *fileSpec, OSAID theScriptID)
- {
- FSpCreateResFile(fileSpec, 'ToyS', 'osas', smRoman);
- // ignore errors - let's see if we can open the file, now
-
- short fileRef = FSpOpenResFile(fileSpec, fsRdPerm);
- OSAError err = ResError();
-
- if (!err)
- {
- AEDesc scriptData;
-
- InitAEDescs(&scriptData, kEndOfList);
-
- err = OSAStore(gScriptingComponent, theScriptID, typeOSAGenericStorage,
- kOSAModeDontStoreParent, &scriptData);
-
- if (!err && scriptData.dataHandle)
- {
- FInfo fndrInfo;
- Handle h = Get1Resource(kOSAScriptResourceType, 128);
-
- if (h)
- { // delete old script resource
- RmveResource(h);
- h = NULL;
- }
-
- AddResource(scriptData.dataHandle, kOSAScriptResourceType, 128,
- (ConstStr255Param)"");
-
- err = FSpGetFInfo(fileSpec, &fndrInfo);
- if (!err)
- {
- fndrInfo.fdType = 'osas';
- fndrInfo.fdCreator = 'ToyS';
- err = FSpSetFInfo(fileSpec, &fndrInfo);
- }
- }
- else if (!err)
- err = -194; // addResFailed
-
- CloseResFile(fileRef);
- }
-
- return err;
- }
-
-
-
- /*******************************************************************************
- ** PUBLIC Constructor/Destructor
- ********************************************************************************/
-
- TScriptableObject::TScriptableObject()
- {
- fAttachedScript = kOSANullScript;
- }
-
- TScriptableObject::~TScriptableObject(void)
- {
- if (fAttachedScript != kOSANullScript && gScriptingComponent)
- {
- OSADispose(gScriptingComponent, fAttachedScript);
- }
- }
-
-
- OSErr TScriptableObject::CountElements(DescType desiredClass, long *result)
- {
- OSErr err = errAEEventNotHandled;
-
- return err;
- }
-
-
- OSErr TScriptableObject::CompareWith (DescType comparisonOperator,
- const TScriptableObject *objToCompare,
- Boolean *result)
- {
- return errAEEventNotHandled;
- }
-
-
-
- OSErr TScriptableObject::ResolveContainer(TScriptableObject **theContainerObj)
- {
- OSErr err = errAEEventNotHandled;
-
- return err;
- }
-
-
- OSErr TScriptableObject::ResolveElementByName(DescType desiredClass,
- CStr255& nameStr,
- TScriptableObject **theResultObj)
- {
- OSErr err = errAEEventNotHandled;
-
- return err;
- }
-
-
- OSErr TScriptableObject::ResolveElementByIndex(DescType desiredClass,
- short theIndex,
- TScriptableObject **theResultObj)
- {
- OSErr err = errAEEventNotHandled;
-
- return err;
- }
-
-
- // data handling
-
- OSErr TScriptableObject::OpenObject(void)
- {
- OSErr err = errAEEventNotHandled;
-
- printf("TScriptableObject::OpenObject(): err = %d\n", err);
- return err;
- }
-
- OSErr TScriptableObject::CloseObject(void)
- {
- OSErr err = errAEEventNotHandled;
-
- return err;
- }
-
- OSErr TScriptableObject::GetData (AEDesc *result)
- {
- // OSErr err = AECreateList(NULL, 0, true, result);
- OSErr err = errAEEventNotHandled;
-
- return err;
- }
-
- OSErr TScriptableObject::SetData (const AEDesc *theData)
- {
- // data is AERecord; for each field of record:
- // save it as property of object with keyword = propertyID
- OSAError err = noErr;
- long numItems = 0;
-
- err = AECountItems(theData, &numItems);
-
- while (!err && numItems > 0)
- {
- AEKeyword theKeyword;
- AEDesc theProperty;
-
- InitAEDescs(&theProperty, kEndOfList);
- err = AEGetNthDesc(theData, numItems, typeWildCard,
- &theKeyword, &theProperty);
- if (!err && theKeyword != typeNull)
- SetProperty(theKeyword, &theProperty);
- DisposeAEDescs(&theProperty, kEndOfList);
- numItems--;
- }
-
- return err;
- }
-
- OSErr TScriptableObject::GetProperty (DescType propertyID, DescType wantType, AEDesc *result)
- {
- OSErr err = errAEEventNotHandled;
-
- switch (propertyID)
- {
- case pScript:
- if (fAttachedScript != kOSANullScript)
- {
- printf("TScriptableObject::GetProperty(): get script as type '%.4s'\n",
- (char*)&wantType);
- if (wantType == typeChar || wantType == typeIntlText)
- { // if caller wants text, we need to de-compile the script
- err = (OSErr)OSAGetSource(gScriptingComponent, fAttachedScript,
- wantType, result);
- }
- else
- {
- if (wantType == typeWildCard)
- wantType = typeOSAGenericStorage;
-
- err = (OSErr)OSAStore(gScriptingComponent, fAttachedScript,
- wantType, kOSAModeDontStoreParent, result);
- }
- }
- break;
- }
-
- return err;
- }
-
- OSErr TScriptableObject::SetProperty (DescType propertyID, const AEDesc *theData)
- {
- OSAError err = errAEEventNotHandled;
-
- if (theData && theData->dataHandle)
- printf("TScriptableObject::SetProperty: dataType=%.4s, size=%ld\n",
- &(theData->descriptorType), GetHandleSize(theData->dataHandle));
-
- switch (propertyID)
- {
- case pScript:
- OSAID theValueID = kOSANullScript;
-
- if (theData->descriptorType == typeChar
- || theData->descriptorType == typeIntlText)
- err = OSACompile(gScriptingComponent, theData,
- kOSAModeCompileIntoContext, &theValueID);
- else // it it's not text, we assume the script is already compiled
- err = OSALoad(gScriptingComponent, theData,
- kOSAModeNull, &theValueID);
- if (!err)
- {
- if (fAttachedScript != kOSANullScript)
- OSADispose(gScriptingComponent, fAttachedScript);
- fAttachedScript = theValueID;
- }
- break;
- }
-
- return (OSErr)err;
- }
-
-
- OSErr TScriptableObject::CreateNewElement (DescType desiredClass,
- DescType position,
- AEDesc *theData,
- AERecord *theProperties,
- TScriptableObject *theContainerObj,
- TScriptableObject **theNewObj)
- {
- OSErr err = errAEEventNotHandled;
-
- return err;
- }
-
-
- OSErr TScriptableObject::DeleteObject (void)
- {
- return errAEEventNotHandled;
- }
-
-
- OSErr TScriptableObject::GetObjectSpecifier (AEDesc *result)
- {
- return errAEEventNotHandled;
- }
-
-
- OSErr TScriptableObject::GetTargetObjectSpecifier (EventRecord& theEvent, AEDesc *result)
- {
- return errAEEventNotHandled;
- }
-
-
-
- // to be added: virtual handlers for
- // does element exist
- // clone object
-
-
-