home *** CD-ROM | disk | FTP | other *** search
- /*
- WASTE Demo Project:
- Minimal Scripting Support:
- service "get data" and "set data" events
- in which the object descriptor is "contents of selection"
-
- Based on public domain code written by:
- Ed Lai, Apple Computer Inc.
-
- Copyright © 1993-1997 Marco Piovanelli
- All Rights Reserved
-
- */
-
- #ifndef __AEOBJECTS__
- #include <AEObjects.h>
- #endif
-
- #ifndef __AEREGISTRY__
- #include <AERegistry.h>
- #endif
-
- #ifndef __WEDEMOAPP__
- #include "WEDemoIntf.h"
- #endif
-
- enum {
- kMaxPropLevel = 2
- };
-
- typedef DescType PropArray[kMaxPropLevel];
-
- static void InitDesc(AEDesc *desc)
- {
- desc->descriptorType = typeNull;
- desc->dataHandle = nil;
- }
-
- static Boolean PropertyOf(const AERecord *spec, SInt16 *propLevel, PropArray properties)
- {
- AERecord objSpec;
- AEKeyword key;
- DescType theType;
- DescType actualType;
- Size actualSize;
- Boolean retVal = false;
-
- InitDesc(&objSpec);
-
- // if spec is an Apple event (*propLevel = 0), extract its direct parameter
- // otherwise spec is an object specifier record: extract its container param
- key = (*propLevel == 0) ? keyDirectObject : keyAEContainer;
-
- // extract object specifier
- if (AEGetParamDesc(spec, key, typeAERecord, &objSpec) != noErr)
- goto cleanup;
-
- // does this object specifier specify a property?
- if (AEGetParamPtr(&objSpec, keyAEDesiredClass, typeType, &actualType,
- &theType, sizeof(theType), &actualSize) != noErr)
- goto cleanup;
-
- // sanity check: make sure the key form is formPropertyID
- // this is probably redundant, but checking doesn't hurt
- if (AEGetParamPtr(&objSpec, keyAEKeyForm, typeEnumerated, &actualType,
- &theType, sizeof(theType), &actualSize) != noErr)
- goto cleanup;
- if (theType != formPropertyID)
- goto cleanup;
-
- // which property does this object specifier specify?
- if (AEGetParamPtr(&objSpec, keyAEKeyData, typeType, &actualType,
- &theType, sizeof(theType), &actualSize) != noErr)
- goto cleanup;
-
- // bump property level and save property tag into property array
- properties[(*propLevel)++] = theType;
-
- // property of what?
- if (AESizeOfParam(&objSpec, keyAEContainer, &actualType, &actualSize) == noErr)
- if (actualType == typeNull)
- // property of application (i.e., null container): we are done
- retVal = true;
- else if ((actualType == typeObjectSpecifier) && (*propLevel < kMaxPropLevel))
- // property of another object, so do a recursive call
- // unless we have already reached max recursion depth
- retVal = PropertyOf(&objSpec, propLevel, properties);
-
- cleanup:
- AEDisposeDesc(&objSpec);
- return retVal;
- }
-
- OSErr WEGetContentsDesc(SInt32 rangeStart, SInt32 rangeEnd, Boolean wantStyledText,
- AEDesc *desc, WEReference we)
- {
- AEDesc textDesc, stylesDesc, recordDesc;
- OSErr err;
-
- InitDesc(desc);
- InitDesc(&textDesc);
- InitDesc(&stylesDesc);
- InitDesc(&recordDesc);
-
- // allocate a handle to hold the text
- textDesc.dataHandle = NewHandle(0);
- textDesc.descriptorType = typeChar;
- if ((err = MemError()) != noErr)
- goto cleanup;
-
- if (wantStyledText)
- {
- // allocate a handle to hold the styles
- stylesDesc.dataHandle = NewHandle(0);
- stylesDesc.descriptorType = typeScrapStyles;
- if ((err = MemError()) != noErr)
- goto cleanup;
- } // if wantStyledText
-
- // make a copy of the specified text range
- if ((err = WECopyRange(rangeStart, rangeEnd, textDesc.dataHandle,
- (StScrpHandle) stylesDesc.dataHandle, nil, we)) != noErr)
- goto cleanup;
-
- if (wantStyledText)
- {
- // create an Apple event record to hold text + styles
- if ((err = AECreateList(nil, 0, true, &recordDesc)) != noErr)
- goto cleanup;
-
- // add the text descriptor to the record
- if ((err = AEPutParamDesc(&recordDesc, keyAEText, &textDesc)) != noErr)
- goto cleanup;
- AEDisposeDesc(&textDesc);
-
- // add the styles descriptor to the record
- if ((err = AEPutParamDesc(&recordDesc, keyAEStyles, &stylesDesc)) != noErr)
- goto cleanup;
- AEDisposeDesc(&stylesDesc);
-
- // coerce the record into a styled text descriptor
- if ((err = AECoerceDesc(&recordDesc, typeStyledText, desc)) != noErr)
- goto cleanup;
-
- }
- else {
- *desc = textDesc;
- InitDesc(&textDesc);
- }
-
- err = noErr;
-
- cleanup:
- AEDisposeDesc(&textDesc);
- AEDisposeDesc(&stylesDesc);
- AEDisposeDesc(&recordDesc);
-
- return err;
- }
-
- OSErr WESetContentsDesc(SInt32 rangeStart, SInt32 rangeEnd,
- const AEDesc *desc, WEReference we)
- {
- AEDesc textDesc, stylesDesc, recordDesc;
- OSErr err;
-
- InitDesc(&textDesc);
- InitDesc(&stylesDesc);
- InitDesc(&recordDesc);
-
- // we expect desc type to be either TEXT or STXT
- if (desc->descriptorType == typeStyledText)
- {
- // STYLED TEXT
- // coerce the styled text descriptor to an Apple event record
- if ((err = AECoerceDesc(desc, typeAERecord, &recordDesc)) != noErr)
- goto cleanup;
-
- // extract text + styles from the record
- if ((err = AEGetParamDesc(&recordDesc, keyAEText, typeChar, &textDesc)) != noErr)
- goto cleanup;
- if ((err = AEGetParamDesc(&recordDesc, keyAEStyles, typeScrapStyles, &stylesDesc)) != noErr)
- goto cleanup;
- }
- else {
- // UNSTYLED TEXT
- if ((err = AECoerceDesc(desc, typeChar, &textDesc)) != noErr)
- goto cleanup;
- }
-
- // replace the specified range with the given text
- HLock(textDesc.dataHandle);
- WESetSelection(rangeStart, rangeEnd, we);
- err = WEInsert(*textDesc.dataHandle, GetHandleSize(textDesc.dataHandle),
- (StScrpHandle) stylesDesc.dataHandle, nil, we);
- HUnlock(textDesc.dataHandle);
-
- cleanup:
- AEDisposeDesc(&recordDesc);
- AEDisposeDesc(&textDesc);
- AEDisposeDesc(&stylesDesc);
-
- return err;
- }
-
- static pascal OSErr HandleGetData(const AppleEvent *ae, AppleEvent *reply, SInt32 refCon)
- {
- #pragma unused (refCon)
-
- AEDesc textDesc;
- DocumentHandle hDocument;
- SInt16 propLevel = 0;
- PropArray properties;
- FlavorType requestedType;
- Boolean wantStyledText = false;
- DescType actualType;
- Size actualSize;
- SInt32 selStart, selEnd;
- OSErr err;
-
- InitDesc(&textDesc);
-
- // the only Apple event object we recognize is "contents of selection"
- err = errAENoSuchObject;
- if (!PropertyOf(ae, &propLevel, properties) || (propLevel != 2) ||
- (properties[0] != pContents) || (properties[1] != pSelection))
- {
- goto cleanup;
- }
-
- // extract the optional parameter keyAERequestedType, if present
- // The Apple Event Registry says this parameter can be a list
- // of type tags, but in most cases it is just a single tag, as we assume here.
- if (AEGetParamPtr(ae, keyAERequestedType, typeType, &actualType,
- &requestedType, sizeof(requestedType), &actualSize) == noErr)
- {
- wantStyledText = (requestedType == typeStyledText);
- }
-
- // make sure there is a document window in front
- err = errAENoUserSelection;
- if ((hDocument = GetWindowDocument(FrontWindow())) == nil)
- {
- goto cleanup;
- }
-
- // get the selection range
- WEGetSelection(&selStart, &selEnd, (*hDocument)->we);
-
- // create an Apple event descriptor for the selected text
- if ((err = WEGetContentsDesc(selStart, selEnd, wantStyledText,
- &textDesc, (*hDocument)->we)) != noErr)
- {
- goto cleanup;
- }
-
- // put the text descriptor into the reply event
- if ((err = AEPutParamDesc(reply, keyDirectObject, &textDesc)) != noErr)
- {
- goto cleanup;
- }
-
- // clear result code
- err = noErr;
-
- cleanup:
- AEDisposeDesc(&textDesc);
-
- return err;
- }
-
- static pascal OSErr HandleSetData(const AppleEvent *ae, AppleEvent *reply, SInt32 refCon)
- {
- #pragma unused (reply, refCon)
-
- AEDesc textDesc;
- DocumentHandle hDocument;
- SInt16 propLevel = 0;
- PropArray properties;
- SInt32 selStart, selEnd;
- OSErr err;
-
- InitDesc(&textDesc);
-
- // the only Apple event object we recognize is "contents of selection"
- err = errAENoSuchObject;
- if (!PropertyOf(ae, &propLevel, properties) || (propLevel != 2) ||
- (properties[0] != pContents) || (properties[1] != pSelection))
- {
- goto cleanup;
- }
-
- // make sure there is a document window in front
- err = errAENoUserSelection;
- if ((hDocument = GetWindowDocument(FrontWindow())) == nil)
- {
- goto cleanup;
- }
-
- // extract the required keyAEData parameter
- if ((err = AEGetParamDesc(ae, keyAEData, typeWildCard, &textDesc)) != noErr)
- goto cleanup;
-
- // get current selection range
- WEGetSelection(&selStart, &selEnd, (*hDocument)->we);
-
- // set the contents of the selection
- if ((err = WESetContentsDesc(selStart, selEnd, &textDesc, (*hDocument)->we)) != noErr)
- {
- goto cleanup;
- }
-
- // clear result code
- err = noErr;
-
- cleanup:
- AEDisposeDesc(&textDesc);
-
- return err;
- }
-
- OSErr InstallCoreHandlers(void)
- {
- OSErr err;
-
- if ((err = AEInstallEventHandler(kAECoreSuite, kAEGetData,
- NewAEEventHandlerProc(HandleGetData), 0L, false)) != noErr)
- {
- return err;
- }
-
- if ((err = AEInstallEventHandler(kAECoreSuite, kAESetData,
- NewAEEventHandlerProc(HandleSetData), 0L, false)) != noErr)
- {
- return err;
- }
-
- return noErr;
- }