Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Source/SVAEGetData.c
/* |
File: SVAEGetData.c |
Contains: |
Written by: Original version by Jon Lansdell and Nigel Humphreys. |
3.1 updates by Greg Sutton. |
Copyright: Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/20/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include "SVAEGetData.h" |
#include "SVEditWindow.h" |
#include "SVEditGlobals.h" |
#include "SVEditAEUtils.h" |
#include "SVAppleEvents.h" |
#include "SVAETextUtils.h" |
#include "SVAEWindowUtils.h" |
#include "SVAEAccessors.h" |
#include "SVAERecording.h" |
#include "SVToken.h" |
#include <AEPackObject.h> |
#include <Resources.h> |
#include <Script.h> |
extern short gRefNum; |
// ----------------------------------------------------------------------- |
// Name: DoGetData |
// Purpose: Handles the GetData AppleEvent. |
// ----------------------------------------------------------------------- |
pascal OSErr DoGetData(const AppleEvent *theAppleEvent, |
AppleEvent *reply, |
long handlerRefCon) |
{ |
#pragma unused (handlerRefCon) |
AEDesc directObj = {typeNull, NULL}, |
result = {typeNull, NULL}; |
Size actualSize; |
DescType returnedType; |
DescType reqType; |
OSErr reqTypeErr, |
err; |
// extract the direct object, which is the object |
// whose data is to be returned |
err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &directObj); |
if (noErr != err) goto done; |
// now the get the type of data wanted - optional |
reqTypeErr = AEGetParamPtr(theAppleEvent, keyAERequestedType, typeType, |
&returnedType, (Ptr)&reqType, sizeof(reqType), &actualSize); |
err = GotRequiredParams(theAppleEvent); |
if (noErr != err) goto done; |
// get the data |
err = HandleGetData(&directObj, &result); |
err = AddResultToReply(&result, reply, err); |
done: |
if (directObj.dataHandle) |
AEDisposeDesc(&directObj); |
if (result.dataHandle) |
AEDisposeDesc(&result); |
return(err); |
} // DoGetData |
// ----------------------------------------------------------------------- |
// Name: HandleGetData |
// Purpose: Coerces theObj into a token which we understand and |
// extracts the data requested in the token and puts it |
// into dataDesc. |
// ----------------------------------------------------------------------- |
OSErr HandleGetData(AEDesc *theObj, AEDesc *dataDesc) |
{ |
TextToken theTextToken; |
Size tokenSize; |
AEDesc objTokenDesc = {typeNull, NULL}, |
itemDesc = {typeNull, NULL}, |
resultDesc = {typeNull, NULL}; |
long index; |
DescType returnedType; |
OSErr err; |
// Coerce theObj into a token which we can use - |
// this may involve converting a list of tokens to a list of property tokens |
if (typeObjectSpecifier == theObj->descriptorType) |
err = AEResolve(theObj, kAEIDoMinimum, &objTokenDesc); |
else // Otherwise, just copy it |
err = AEDuplicateDesc(theObj, &objTokenDesc); |
if (noErr != err) goto done; |
switch (objTokenDesc.descriptorType) |
{ |
case typeMyApplProp: |
err = GetApplicationProperty(&objTokenDesc, dataDesc); |
break; |
case typeMyTextProp: |
err = GetTextProperty(&objTokenDesc, dataDesc); |
break; |
case typeMyWindowProp: |
err = DoGetWindowProperty(&objTokenDesc, dataDesc); |
break; |
case typeMyText: |
GetRawDataFromDescriptor(&objTokenDesc, (Ptr)&theTextToken, |
sizeof(theTextToken), &tokenSize); |
err = GetTextTextProperty(&theTextToken, dataDesc); |
break; |
case typeAEList: |
err = AECountItems(&objTokenDesc, &index); |
if (noErr != err) goto done; |
for (; index > 0; index--) |
{ |
err = AEGetNthDesc(&objTokenDesc, index, typeWildCard, &returnedType, &itemDesc); |
if (noErr == err) // Call this function recursively if necessary |
err = HandleGetData(&itemDesc, &resultDesc); |
if (noErr == err) // Overwrite item in list with descriptor item |
err = AEPutDesc(&objTokenDesc, index, &resultDesc); |
// objTokenDesc is just a copy anyway. |
if (itemDesc.dataHandle) |
AEDisposeDesc(&itemDesc); |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
} |
err = AEDuplicateDesc(&objTokenDesc, dataDesc); // Copy list into result |
break; |
default: |
err = errAEWrongDataType; |
} |
done: |
if (objTokenDesc.dataHandle) |
AEDisposeDesc(&objTokenDesc); |
return(err); |
} // HandleGetData |
// Get the actual data for a text token - rather than just offset and length |
// used internally. |
OSErr GetTextTextProperty(TextToken* theToken, AEDesc *dataDesc) |
{ |
TEHandle aTEH; |
short anOffset, |
aLength; |
OSErr err; |
aTEH = TEHandleFromTextToken(theToken); |
anOffset = theToken->tokenOffset; |
aLength = theToken->tokenLength; |
err = BuildStyledTextDesc(aTEH, anOffset, aLength, dataDesc); |
return(err); |
} |
// ----------------------------------------------------------------------- |
// Name: GetTextProperty |
// Purpose: Fills dataDesc with the requested text property. |
// ----------------------------------------------------------------------- |
OSErr GetTextProperty(const AEDesc *theTokenDesc, AEDesc *dataDesc) |
{ |
DPtr theDocument; |
TEHandle theHTE; |
Str255 fontName; |
TextStyle theTextStyle; |
short lineHeight; |
short fontAscent; |
TextPropToken theTextPropToken; |
Size tokenSize; |
AEDesc tempDesc; |
OSErr err; |
err = AECoerceDesc(theTokenDesc, typeMyTextProp, &tempDesc); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&tempDesc, (Ptr)&theTextPropToken, |
sizeof(theTextPropToken), &tokenSize); |
// For each property we build a descriptor to be returned as the reply. |
theDocument = DPtrFromWindowPtr(theTextPropToken.tokenTextToken.tokenWindow); |
theHTE = theDocument->theText; |
TEGetStyle(theTextPropToken.tokenTextToken.tokenOffset - 1, &theTextStyle, |
&lineHeight, &fontAscent, theHTE); |
switch (theTextPropToken.tokenProperty) |
{ |
case pText: |
case pContents: |
err = GetTextTextProperty(&(theTextPropToken.tokenTextToken), dataDesc); |
break; |
case pFont: |
GetFontName(theTextStyle.tsFont, fontName); |
err = AECreateDesc(typeChar, (Ptr)&fontName[1], fontName[0], dataDesc); |
break; |
case pTextStyles: |
err = BuildTextStylesDesc(theTextStyle.tsFace, dataDesc); |
break; |
case pPointSize: |
err = CreateOffsetDescriptor(theTextStyle.tsSize, dataDesc); |
break; |
case pScriptTag: |
err = CreateOffsetDescriptor(smSystemScript, dataDesc); |
break; |
case pColor: |
err = AECreateDesc(typeRGBColor, (Ptr)&theTextStyle.tsColor, |
sizeof(theTextStyle.tsColor), dataDesc); |
break; |
case pLength: |
tokenSize = theTextPropToken.tokenTextToken.tokenLength; |
err = AECreateDesc(typeInteger, (Ptr)&tokenSize, |
sizeof(tokenSize), dataDesc); |
break; |
case pOffset: |
tokenSize = theTextPropToken.tokenTextToken.tokenOffset; |
err = AECreateDesc(typeInteger, (Ptr)&tokenSize, |
sizeof(tokenSize), dataDesc); |
break; |
default: |
err = errAEEventNotHandled; |
} |
done: |
if (tempDesc.dataHandle) |
AEDisposeDesc(&tempDesc); |
return(err); |
} // GetTextProperty |
// ----------------------------------------------------------------------- |
// Name: GetWindowProperty |
// Purpose: Fills dataDesc with the requested window property. |
// ----------------------------------------------------------------------- |
typedef Rect **RectHandle; |
OSErr DoGetWindowProperty(const AEDesc *theWPTokenObj, AEDesc *dataDesc) |
{ |
Str255 theName; |
Boolean theBoolean; |
Rect theRect; |
Point thePoint; |
Rect winRect; |
Rect userRect; |
short theIndex; |
DPtr docPtr; |
TEHandle theHTE; |
GrafPtr savePort; |
WindowPropToken theWindowPropToken; |
AEDesc tempDesc = {typeNull, NULL}; |
Size tokenSize; |
OSErr err; |
err = AECoerceDesc(theWPTokenObj,typeMyWindowProp, &tempDesc); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&tempDesc, (Ptr)&theWindowPropToken, |
sizeof(theWindowPropToken), &tokenSize); |
switch (theWindowPropToken.tokenProperty) |
{ |
case pName: |
GetWTitle(theWindowPropToken.tokenWindowToken.tokenWindow, theName); |
err = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc); |
break; |
case pText: |
case pContents: |
docPtr = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken.tokenWindow); |
theHTE = docPtr->theText; |
err = BuildStyledTextDesc(theHTE, 1, (**theHTE).teLength, dataDesc); |
break; |
case pBounds: |
GetPort(&savePort); |
SetPort(theWindowPropToken.tokenWindowToken.tokenWindow); |
theRect = (*((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn)->rgnBBox; |
err = AECreateDesc(typeQDRectangle, (Ptr)&theRect, sizeof(theRect), dataDesc); |
SetPort(savePort); |
break; |
case pPosition: |
thePoint.v = (*((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn)->rgnBBox.top; |
thePoint.h = (*((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->strucRgn)->rgnBBox.left; |
err= AECreateDesc(typeQDPoint, (Ptr)&thePoint, sizeof(thePoint), dataDesc); |
break; |
case pVisible: |
theBoolean = ((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->visible; |
err = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc); |
break; |
case pIsModal: |
case pIsFloating: |
theBoolean = false; |
err = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc); |
break; |
case pIsZoomed: |
if (((WindowPeek)theWindowPropToken.tokenWindowToken.tokenWindow)->spareFlag) |
{ |
GetPort(&savePort); |
SetPort(theWindowPropToken.tokenWindowToken.tokenWindow); |
userRect = **((RectHandle)((WindowPeek)qd.thePort)->dataHandle); |
winRect = qd.thePort->portRect; |
LocalToGlobal((Point *)&winRect.top); |
LocalToGlobal((Point *)&winRect.bottom); |
theBoolean = ! EqualRect(&userRect, &winRect); |
SetPort(savePort); |
} |
else |
theBoolean = false; |
err = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc); |
break; |
case pIsResizable: |
case pHasTitleBar: |
case pHasCloseBox: |
case pIsZoomable: |
theBoolean = true; |
err = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc); |
break; |
case pIsModified: |
docPtr = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken.tokenWindow); |
theBoolean = docPtr->dirty; |
err = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc); |
break; |
case pIndex: |
theIndex = 0; |
if (theWindowPropToken.tokenWindowToken.tokenWindow) |
do |
theIndex++; |
while (theWindowPropToken.tokenWindowToken.tokenWindow != GetWindowPtrOfNthWindow(theIndex)); |
err = AECreateDesc(typeShortInteger, (Ptr)theIndex, sizeof(theIndex), dataDesc); |
break; |
case pPageSetup: |
docPtr = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken.tokenWindow); |
HLock((Handle)docPtr->thePrintSetup); |
err = AECreateDesc(typeTPrint, (Ptr)*(docPtr->thePrintSetup), |
sizeof(TPrint), dataDesc); |
HUnlock((Handle)docPtr->thePrintSetup); |
case pSelection: |
docPtr = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken.tokenWindow); |
err = MakeSelectedTextObj(theWindowPropToken.tokenWindowToken.tokenWindow, |
docPtr->theText, dataDesc); |
break; |
default: |
err = errAEEventNotHandled; |
} |
done: |
if (tempDesc.dataHandle) |
AEDisposeDesc(&tempDesc); |
return(err); |
} // GetWindowProperty |
// ----------------------------------------------------------------------- |
// Name: GetApplicationProperty |
// Purpose: Fills dataDesc with the requested application property. |
// ----------------------------------------------------------------------- |
OSErr GetApplicationProperty(const AEDesc *theObjToken, AEDesc *result) |
{ |
Str255 name; |
Boolean isFront; |
ApplPropToken theApplPropToken; |
AEDesc aDesc = {typeNull, NULL}, |
nullDesc = {typeNull, NULL}; |
Size tokenSize; |
DescType theType; |
ProcessInfoRec processInfo; |
ProcessSerialNumber currentProcess; |
short refNum; |
Handle aHandle; |
OSErr err; |
err = AECoerceDesc(theObjToken, typeMyApplProp, &aDesc); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&aDesc, (Ptr)&theApplPropToken, |
sizeof(theApplPropToken), &tokenSize); |
switch (theApplPropToken.tokenApplProperty) |
{ |
case pBestType: // Return the null descriptor representing |
case pDefaultType: // the application. |
err = AEDuplicateDesc(&nullDesc, result); |
break; |
case pClass: |
theType = cApplication; |
err = AECreateDesc(typeType, (Ptr)&theType, sizeof(DescType), result); |
break; |
case pName: |
// Clear out the name, and then call the process manager to get |
// the string for the name of our application. |
name[0] = 0; |
processInfo.processInfoLength = sizeof(processInfo); |
processInfo.processName = name; |
processInfo.processAppSpec = NULL; |
GetCurrentProcess(¤tProcess); |
GetProcessInformation(¤tProcess, &processInfo); |
// Create an AEDesc returning the application name string |
// returned by the process manager. |
err = AECreateDesc(typeChar, (Ptr)&name[1], name[0], result); |
break; |
case pIsFrontProcess: |
isFront = ! gInBackground; |
err = AECreateDesc(typeBoolean, (Ptr)&isFront, sizeof(isFront), result); |
break; |
case pVersion: |
refNum = CurResFile(); // save current resource |
UseResFile(gRefNum); // set this resource to be current |
aHandle = (Handle)Get1Resource((ResType)'vers', 1); |
HLock(aHandle); |
err = AECreateDesc(typeVersion, *aHandle, GetHandleSize(aHandle), result); |
HUnlock(aHandle); |
UseResFile(refNum); // reset back to resource previously set |
break; |
default: // We don't handle the requested property. |
err = errAEEventNotHandled; |
} |
done: |
if (aDesc.dataHandle) |
AEDisposeDesc(&aDesc); |
return(err); |
} // GetApplicationProperty |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22