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/SVAERecording.c
/* |
File: SVAERecording.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 "SVAERecording.h" |
#include "SVEditAEUtils.h" |
#include "SVEditUtils.h" |
#include "SVAEWindowUtils.h" |
#include "SVAETextUtils.h" |
#include "SVAppleEvents.h" |
#include <AEPackObject.h> |
#include <TextUtils.h> |
static short gBigBrother; |
static char *gTypingBuffer; |
static short gCharsInBuffer; |
static AEDesc gTypingTargetObject; |
OSErr InstallRecordingHandlers(void) |
{ |
OSErr err; |
gBigBrother = 0; |
gCharsInBuffer = 0; |
gTypingBuffer = (char *)NewPtr(32000); |
gTypingTargetObject.dataHandle = 0; |
err = AEInstallEventHandler( kCoreEventClass, kAENotifyStartRecording, NewAEEventHandlerProc(HandleStartRecording), noRefCon, false); |
err = AEInstallEventHandler( kCoreEventClass, kAENotifyStopRecording, NewAEEventHandlerProc(HandleStopRecording), noRefCon, false); |
return(err); |
} |
pascal OSErr HandleStartRecording(const AppleEvent *theAppleEvent, |
AppleEvent *reply, |
long handlerRefCon) |
{ |
#pragma unused (reply,handlerRefCon) |
OSErr myErr; |
gBigBrother++; |
myErr = GotRequiredParams(theAppleEvent); |
return(myErr); |
} // HandleStartRecording |
pascal OSErr HandleStopRecording(const AppleEvent *theAppleEvent, |
AppleEvent *reply, |
long handlerRefCon) |
{ |
#pragma unused (theAppleEvent,reply,handlerRefCon) |
gBigBrother--; |
return(noErr); |
} // HandleStopRecording |
// Make an object specifier for a window given the WindowPtr |
OSErr MakeWindowObj(WindowPtr theWindow, AEDesc *result) |
{ |
AEDesc nullDesc = {typeNull, NULL}, |
absoluteDesc = {typeNull, NULL}; |
long windowIndex; |
OSErr err; |
windowIndex = GetNthWindowOfWindowPtr(theWindow); |
if (! windowIndex) |
return(errAENoSuchObject); |
err = AECreateDesc(typeInteger,(Ptr)&windowIndex, sizeof(windowIndex), &absoluteDesc); |
if (noErr != err) goto done; |
err = CreateObjSpecifier(cWindow, &nullDesc, formAbsolutePosition, |
&absoluteDesc, false, result); |
done: |
if (absoluteDesc.dataHandle) |
AEDisposeDesc(&absoluteDesc); |
return(err); |
} // MakeWindowObj |
// Make an object specifier for a document given the WindowPtr |
OSErr MakeDocumentObj(WindowPtr theWindow, AEDesc *result) |
{ |
AEDesc nullDesc = {typeNull, NULL}, |
absoluteDesc = {typeNull, NULL}; |
long windowIndex; |
OSErr err; |
windowIndex = GetNthWindowOfWindowPtr(theWindow); |
if (! windowIndex) |
return(errAENoSuchObject); |
err = AECreateDesc(typeInteger,(Ptr)&windowIndex, sizeof(windowIndex), &absoluteDesc); |
if (noErr != err) goto done; |
err = CreateObjSpecifier(cDocument, &nullDesc, formAbsolutePosition, |
&absoluteDesc, false, result); |
done: |
if (absoluteDesc.dataHandle) |
AEDisposeDesc(&absoluteDesc); |
return(err); |
} // MakeDocumentObj |
OSErr MakeTextObjFromToken(TextToken* theToken, AEDesc* result) |
{ |
OSErr err; |
err = GetTextTokenObjectSpecifier(theToken, result); |
return(err); |
} |
OSErr MakeSelectedTextObj(WindowPtr theWindow, TEHandle theTextEditHandle, AEDesc* result) |
{ |
return( MakeTextObj(theWindow, (**theTextEditHandle).selStart, |
(**theTextEditHandle).selEnd, result)); |
} // MakeSelectedTextObj |
OSErr MakeTextObj(WindowPtr theWindow, short selStart, short selEnd, AEDesc* result) |
{ |
TextToken aToken; |
OSErr err; |
aToken.tokenWindow = theWindow; |
aToken.tokenOffset = selStart + 1; |
aToken.tokenLength = selEnd - selStart; |
err = MakeTextObjFromToken(&aToken, result); |
return(err); |
} |
OSErr SendSelectionEvent(DPtr docPtr) |
{ |
AEAddressDesc ourAddress = {typeNull, NULL}; |
AppleEvent selectEvent = {typeNull, NULL}, |
ignoreReply = {typeNull, NULL}; |
AEDesc textObj = {typeNull, NULL}; |
OSErr err; |
err = MakeSelfAddress(&ourAddress); |
if (noErr != err) goto done; |
// Build an object to represent the current document's selection |
// MakeSelectedTextObj |
err = MakeSelectedTextObj(docPtr->theWindow, docPtr->theText, &textObj); |
if (noErr != err) goto done; |
err = AECreateAppleEvent(kAEMiscStandards, kAESelect, &ourAddress, 0, 0, &selectEvent); |
if (noErr != err) goto done; |
// add parameter |
err = AEPutParamDesc(&selectEvent, keyDirectObject, &textObj); |
if (noErr != err) goto done; |
// and now send the message |
err = AESend(&selectEvent, &ignoreReply, kAENoReply, kAEHighPriority, kAEDefaultTimeout, NULL, NULL); |
if (noErr != err) goto done; |
done: |
if (ourAddress.dataHandle) |
AEDisposeDesc(&ourAddress); |
if (selectEvent.dataHandle) |
AEDisposeDesc(&selectEvent); |
if (ignoreReply.dataHandle) |
AEDisposeDesc(&ignoreReply); |
if (textObj.dataHandle) |
AEDisposeDesc(&textObj); |
return(err); |
} |
void DoEditCommand(DPtr theDocument, editCommandType whatCommand) |
{ |
AEAddressDesc ourAddress = {typeNull, NULL}; |
AppleEvent editCommandEvent = {typeNull, NULL}, |
ignoreReply = {typeNull, NULL}; |
AEEventID theEventID; |
AEEventClass theEventClass; |
OSErr err; |
err = SendSelectionEvent(theDocument); |
if (noErr != err) goto done; |
// Now create and send the appropriate cut, copy, paste or clear AppleEvent |
switch (whatCommand) |
{ |
case editCutCommand: |
theEventID = kAECut; |
theEventClass = kAEMiscStandards; |
break; |
case editCopyCommand: |
theEventID = kAECopy; |
theEventClass = kAEMiscStandards; |
break; |
case editPasteCommand: |
theEventID = kAEPaste; |
theEventClass = kAEMiscStandards; |
break; |
case editClearCommand: |
theEventID = kAEDelete; |
theEventClass = kAECoreSuite; |
break; |
} |
err = MakeSelfAddress(&ourAddress); |
if (noErr != err) goto done; |
err = AECreateAppleEvent(theEventClass, theEventID, &ourAddress, 0, 0, &editCommandEvent); |
if (noErr != err) goto done; |
// and now Send the message |
err = AESend(&editCommandEvent, &ignoreReply, kAENoReply, kAEHighPriority, kAEDefaultTimeout, NULL, NULL); |
done: |
if (ourAddress.dataHandle) |
AEDisposeDesc(&ourAddress); |
if (editCommandEvent.dataHandle) |
AEDisposeDesc(&editCommandEvent); |
if (ignoreReply.dataHandle) |
AEDisposeDesc(&ignoreReply); |
} // DoEditCommand |
void IssueCutCommand(DPtr theDocument) |
{ |
DoEditCommand(theDocument, editCutCommand); |
} |
void IssueCopyCommand(DPtr theDocument) |
{ |
DoEditCommand(theDocument, editCopyCommand); |
} |
void IssuePasteCommand(DPtr theDocument) |
{ |
DoEditCommand(theDocument, editPasteCommand); |
} |
void IssueClearCommand(DPtr theDocument) |
{ |
DoEditCommand(theDocument, editClearCommand); |
} |
// --------------------------------------------------------------------- |
// Name : SendAESetObjProp |
// Function : Creates a property object from an object, |
// a property type and its data and sends it to |
// the requested address, and cleans up zapping params too |
// --------------------------------------------------------------------- |
OSErr SendAESetObjProp(AEDesc *theObj, DescType theProp, AEDesc *theData, AEAddressDesc *toWhom) |
{ |
AEDesc propObjSpec; |
AppleEvent myAppleEvent; |
AppleEvent defReply; |
OSErr myErr; |
OSErr ignoreErr; |
AEDesc theProperty; |
// create an object spec that represents the property of the given object |
myErr = AECreateDesc(typeType, (Ptr)&theProp, sizeof(theProp), &theProperty); |
if (myErr==noErr) |
myErr = CreateObjSpecifier(cProperty, theObj, formPropertyID, |
&theProperty, true, &propObjSpec); |
// create event |
if (myErr==noErr) |
myErr = AECreateAppleEvent(kAECoreSuite, kAESetData, toWhom, 0, 0, &myAppleEvent); |
// add prop obj spec to the event |
if (myErr==noErr) |
myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &propObjSpec); |
// add prop data to the event |
if (myErr==noErr) |
myErr = AEPutParamDesc(&myAppleEvent,keyAEData, theData); |
// send event |
if (myErr==noErr) |
myErr = AESend(&myAppleEvent, &defReply, kAENoReply+kAEAlwaysInteract, |
kAENormalPriority, kAEDefaultTimeout, nil, nil); |
if (myAppleEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&myAppleEvent); |
if (&propObjSpec.dataHandle) |
ignoreErr = AEDisposeDesc(&propObjSpec); |
if (theData->dataHandle) |
ignoreErr = AEDisposeDesc(theData); |
if (toWhom->dataHandle) |
ignoreErr = AEDisposeDesc(toWhom); |
return(myErr); |
} // SendAESetObjProp |
void IssueFontCommand(DPtr theDocument, short theItem) |
{ |
Str255 name; |
AEDesc strDesc; |
AEAddressDesc theAddress; |
AEDesc selTextObj; |
OSErr err; |
err = MakeSelfAddress(&theAddress); |
err = MakeSelectedTextObj(theDocument->theWindow, theDocument->theText, &selTextObj); |
GetMenuItemText(myMenus[fontM], theItem, name); |
if (err==noErr) |
err = AECreateDesc(typeChar, (Ptr)&name[1], name[0], &strDesc); |
if (err==noErr) |
err = SendAESetObjProp(&selTextObj, pFont, &strDesc, &theAddress); |
} |
// Window property routines |
void IssueZoomCommand(WindowPtr whichWindow, short whichPart) |
{ |
Boolean zoomBool; |
AEDesc zoomDesc; |
AEAddressDesc selfAddr; |
AEDesc frontWinObj; |
OSErr err; |
err = MakeSelfAddress(&selfAddr); |
err = MakeWindowObj(whichWindow, &frontWinObj); |
zoomBool = (whichPart==inZoomOut); |
err = AECreateDesc(typeBoolean, (Ptr)&zoomBool, sizeof(zoomBool), &zoomDesc); |
err = SendAESetObjProp(&frontWinObj, pIsZoomed, &zoomDesc, &selfAddr); |
} // IssueZoomCommand |
void IssueCloseCommand(WindowPtr whichWindow) |
{ |
AEAddressDesc selfAddr; |
AEDesc frontWinObj; |
OSErr err; |
OSErr ignoreErr; |
AppleEvent closeCommandEvent; |
AppleEvent ignoreReply; |
frontWinObj.dataHandle = nil; |
err = MakeSelfAddress(&selfAddr); |
err = MakeWindowObj(whichWindow, &frontWinObj); |
err = AECreateAppleEvent( kAECoreSuite, kAEClose, &selfAddr, 0, 0, &closeCommandEvent) ; |
// add parameter - the window to close |
if (err==noErr) |
err = AEPutParamDesc(&closeCommandEvent, keyDirectObject, &frontWinObj); |
if (err==noErr) |
err = AESend(&closeCommandEvent,&ignoreReply,kAENoReply+kAEAlwaysInteract,kAEHighPriority,10000,nil, nil); |
if (closeCommandEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&closeCommandEvent); |
if (selfAddr.dataHandle) |
ignoreErr = AEDisposeDesc(&selfAddr); |
if (frontWinObj.dataHandle) |
ignoreErr = AEDisposeDesc(&frontWinObj); |
} // IssueCloseCommand |
void IssueSizeWindow(WindowPtr whichWindow, short newHSize, short newVSize) |
{ |
Rect sizeRect; |
Rect contentRect; |
short edgeSize; |
AEDesc sizeDesc; |
AEAddressDesc selfAddr; |
AEDesc frontWinObj; |
OSErr err; |
sizeRect = (**(((WindowPeek)whichWindow)->strucRgn)).rgnBBox; |
contentRect = (**(((WindowPeek)whichWindow)->contRgn)).rgnBBox; |
edgeSize = sizeRect.right-sizeRect.left-(contentRect.right-contentRect.left); |
sizeRect.right = sizeRect.left+newHSize+edgeSize; |
edgeSize = sizeRect.bottom-sizeRect.top-(contentRect.bottom-contentRect.top); |
sizeRect.bottom = sizeRect.top+newVSize+edgeSize; |
err = MakeSelfAddress(&selfAddr); |
err = MakeWindowObj(whichWindow, &frontWinObj); |
if (err==noErr) |
err = AECreateDesc(typeQDRectangle, (Ptr)&sizeRect, sizeof(sizeRect), &sizeDesc); |
if (err==noErr) |
err = SendAESetObjProp(&frontWinObj, pBounds, &sizeDesc, &selfAddr); |
} // IssueSizeWindow |
void IssueMoveWindow(WindowPtr whichWindow, Rect sizeRect) |
{ |
AEDesc sizeDesc; |
AEAddressDesc selfAddr; |
AEDesc frontWinObj; |
OSErr err; |
err = MakeSelfAddress(&selfAddr); |
err = MakeWindowObj(whichWindow, &frontWinObj); |
if (err==noErr) |
err = AECreateDesc(typeQDRectangle, (Ptr)&sizeRect, sizeof(sizeRect), &sizeDesc); |
if (err==noErr) |
err = SendAESetObjProp(&frontWinObj, pBounds, &sizeDesc, &selfAddr); |
} // IssueMoveWindow |
void IssuePageSetupWindow(WindowPtr whichWindow, TPrint thePageSetup) |
{ |
AEDesc sizeDesc; |
AEAddressDesc selfAddr; |
AEDesc frontWinObj; |
OSErr err; |
err = MakeSelfAddress(&selfAddr); |
err = MakeWindowObj(whichWindow, &frontWinObj); |
if (err==noErr) |
err = AECreateDesc(typeTPrint, (Ptr)&thePageSetup, sizeof(thePageSetup), &sizeDesc); |
if (err==noErr) |
err = SendAESetObjProp(&frontWinObj, pPageSetup, &sizeDesc, &selfAddr); |
} //IssuePageSetupWindow |
void IssuePrintWindow(WindowPtr whichWindow, Boolean useDialog) |
{ |
AEAddressDesc selfAddr; |
AEDesc frontWinObj; |
OSErr err; |
OSErr ignoreErr; |
AppleEvent printCommandEvent; |
AppleEvent ignoreReply; |
AESendMode sendModeFlags; |
err = MakeSelfAddress(&selfAddr); |
err = MakeWindowObj(whichWindow, &frontWinObj); |
err = AECreateAppleEvent(kCoreEventClass, kAEPrintDocuments, &selfAddr, 0, 0, &printCommandEvent) ; |
// add parameter - the window to print |
if (err==noErr) |
err = AEPutParamDesc(&printCommandEvent, keyDirectObject, &frontWinObj); |
if (err==noErr) |
{ |
sendModeFlags = kAENoReply; |
if (useDialog) |
sendModeFlags = sendModeFlags + kAEAlwaysInteract; |
else |
sendModeFlags = sendModeFlags + kAENeverInteract; |
err = AESend(&printCommandEvent,&ignoreReply,sendModeFlags,kAEHighPriority,10000,nil, nil); |
} |
if (printCommandEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&printCommandEvent); |
if (frontWinObj.dataHandle) |
err = AEDisposeDesc(&frontWinObj); |
if (selfAddr.dataHandle) |
err = AEDisposeDesc(&selfAddr); |
} // IssuePrintWindow |
OSErr IssueAEOpenDoc(FSSpec myFSSpec) |
// send OpenDocs AppleEvent to myself, with a one-element list |
// containing the given file spec |
// |
// NOTES : the core AEOpenDocs event is defined as taking a list of |
// aliases (not file specs) as its direct parameter. However, |
// we can send the file spec instead and depend on AppleEvents' |
// automatic coercion. In fact, we don't really even have to put |
// in a list; AppleEvents will coerce a descriptor into a 1-element |
// list if called for. In this routine, though, we'll make the |
// list for demonstration purposes. |
{ |
AppleEvent myAppleEvent; |
AppleEvent defReply; |
AEDescList docList; |
AEAddressDesc selfAddr; |
OSErr myErr; |
OSErr ignoreErr; |
myAppleEvent.dataHandle = nil; |
docList.dataHandle = nil; |
selfAddr.dataHandle = nil; |
defReply.dataHandle = nil; |
// Create empty list and add one file spec |
myErr = AECreateList(nil,0,false, &docList); |
if (myErr==noErr) |
myErr = AEPutPtr(&docList,1,typeFSS,(Ptr)&myFSSpec,sizeof(myFSSpec)); |
// Create a self address to send it to |
if (myErr==noErr) |
myErr = MakeSelfAddress(&selfAddr); |
if (myErr==noErr) |
myErr = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &selfAddr, |
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent); |
// Put Params into our event and send it |
if (myErr == noErr) |
myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &docList); |
myErr = AESend(&myAppleEvent, &defReply, kAENoReply+kAEAlwaysInteract, kAENormalPriority, |
kAEDefaultTimeout, nil, nil); |
if (selfAddr.dataHandle) |
ignoreErr = AEDisposeDesc(&selfAddr); |
if (myAppleEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&myAppleEvent); |
if (docList.dataHandle) |
ignoreErr = AEDisposeDesc(&docList); |
return(myErr); |
} // IssueAEOpenDoc |
void IssueAENewWindow(void) |
// send the New Element event to myself with a null container |
{ |
AppleEvent myAppleEvent; |
AppleEvent defReply; |
AEAddressDesc selfAddr; |
OSErr myErr; |
OSErr ignoreErr; |
DescType elemClass; |
myAppleEvent.dataHandle = nil; |
// Create the address of us |
myErr = MakeSelfAddress(&selfAddr); |
// create event |
myErr = AECreateAppleEvent(kAECoreSuite, kAECreateElement, &selfAddr, |
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent); |
// attach desired class of new element |
elemClass = cWindow; |
if (myErr == noErr) |
myErr = AEPutParamPtr(&myAppleEvent, keyAEObjectClass, typeType, |
(Ptr)&elemClass, sizeof(elemClass)); |
// send the event |
if (myErr == noErr) |
myErr = AESend(&myAppleEvent, &defReply, kAENoReply+kAENeverInteract, |
kAENormalPriority, kAEDefaultTimeout, nil, nil); |
// Clean up - reply never created so don't throw away |
if (selfAddr.dataHandle) |
ignoreErr = AEDisposeDesc(&selfAddr); |
if (myAppleEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&myAppleEvent); |
} // IssueAENewWindow |
OSErr IssueSaveCommand(WindowPtr theWindow, FSSpecPtr where) |
// send an AppleEvent Save Event to myself |
{ |
AEDesc windowObj; |
AppleEvent myAppleEvent; |
AppleEvent defReply; |
OSErr myErr; |
OSErr ignoreErr; |
AEAddressDesc selfAddr; |
windowObj.dataHandle = nil; |
myAppleEvent.dataHandle = nil; |
myErr = MakeWindowObj(theWindow, &windowObj); |
if (myErr==noErr) |
myErr = MakeSelfAddress(&selfAddr); |
// Build event |
if (myErr == noErr) |
myErr = AECreateAppleEvent(kAECoreSuite, kAESave, &selfAddr, |
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent); |
// say which window |
if (myErr==noErr) |
myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObj); |
// add optional file param if we need to |
if (where) |
if (myErr==noErr) |
myErr = AEPutParamPtr(&myAppleEvent, keyAEDestination, typeFSS, |
(Ptr)where, sizeof(FSSpec)); |
// send the event |
if (myErr==noErr) |
myErr = AESend(&myAppleEvent, &defReply, kAENoReply+kAENeverInteract, |
kAENormalPriority, kAEDefaultTimeout, nil, nil); |
if (selfAddr.dataHandle) |
ignoreErr = AEDisposeDesc(&selfAddr); |
if (windowObj.dataHandle) |
ignoreErr = AEDisposeDesc(&windowObj); |
if (myAppleEvent.dataHandle) |
myErr = AEDisposeDesc(&myAppleEvent); |
return(myErr); |
} // IssueSaveCommand |
OSErr IssueRevertCommand(WindowPtr theWindow) |
// send an AppleEvent Revert Event to myself |
{ |
AEDesc windowObj; |
AppleEvent myAppleEvent; |
AppleEvent defReply; |
OSErr myErr; |
OSErr ignoreErr; |
AEAddressDesc selfAddr; |
windowObj.dataHandle = nil; |
myAppleEvent.dataHandle = nil; |
myErr = MakeWindowObj(theWindow, &windowObj); |
if (myErr==noErr) |
myErr = MakeSelfAddress(&selfAddr); |
// Build event |
if (myErr == noErr) |
myErr = AECreateAppleEvent(kAEMiscStandards, kAERevert, &selfAddr, |
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent); |
// say which window |
if (myErr == noErr) |
myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObj); |
// send the event |
if (myErr==noErr) |
myErr = AESend(&myAppleEvent, &defReply, kAENoReply+kAENeverInteract, |
kAENormalPriority, kAEDefaultTimeout, nil, nil); |
if (windowObj.dataHandle) |
ignoreErr = AEDisposeDesc(&windowObj); |
if (myAppleEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&myAppleEvent); |
if (selfAddr.dataHandle) |
ignoreErr = AEDisposeDesc(&selfAddr); |
return(myErr); |
} // IssueRevertCommand |
// ---------------------------------------------------- |
// Name : IssueQuitCommand |
// Purpose : Sends self a Quit AppleEvent |
// ---------------------------------------------------- |
OSErr IssueQuitCommand(void) |
{ |
AppleEvent myAppleEvent; |
AppleEvent defReply; |
OSErr myErr; |
OSErr ignoreErr; |
AEAddressDesc selfAddr; |
DescType mySaveOpt; |
myAppleEvent.dataHandle = nil; |
selfAddr.dataHandle = nil; |
myErr = MakeSelfAddress(&selfAddr); |
// Build event |
if (myErr == noErr) |
myErr = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &selfAddr, |
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent); |
// say which save option |
mySaveOpt = kAEAsk; |
if (myErr == noErr) |
myErr = AEPutParamPtr(&myAppleEvent, keyAESaveOptions, typeEnumerated, |
(Ptr)&mySaveOpt, sizeof(mySaveOpt)); |
// send the event |
if (myErr==noErr) |
myErr = AESend(&myAppleEvent, &defReply, kAENoReply+kAEAlwaysInteract, |
kAENormalPriority, kAEDefaultTimeout, nil, nil); |
if (myAppleEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&myAppleEvent); |
if (selfAddr.dataHandle) |
ignoreErr = AEDisposeDesc(&selfAddr); |
return(myErr); |
} // IssueQuitCommand |
#define kOK 1 |
#define kCancel 2 |
#define kOtherSize 4 |
#define kOutlineItem 5 |
Boolean PoseSizeDialog(long *whatSize) |
{ |
GrafPtr savedPort; |
DialogPtr aDialog; |
Str255 aString; |
short itemHit; |
GetPort(&savedPort); |
aDialog = GetNewDialog(1004, nil, (WindowPtr)-1); |
ShowWindow(aDialog); |
SetPort(aDialog); |
AdornDefaultButton(aDialog, kOutlineItem); |
//set the edittext button to contain the right size |
NumToString(*whatSize, aString); |
SetText(aDialog, kOtherSize, aString); |
do |
{ |
ModalDialog(nil, &itemHit); |
} while ((itemHit!=kOK) && (itemHit!=kCancel)); |
if (itemHit == kOK) |
RetrieveText(aDialog, kOtherSize, aString); |
DisposeDialog(aDialog); |
SetPort(savedPort); |
if (itemHit == kOK) |
{ |
// set the new size of the text |
StringToNum(aString, whatSize); |
if ((*whatSize<1) || (*whatSize>2000)) |
*whatSize = 12; |
} |
return(itemHit == kOK); |
} |
void IssueSizeCommand(DPtr theDocument,short theItem) |
{ |
Str255 name; |
AEDesc sizeDesc; |
AEAddressDesc theAddress; |
OSErr err; |
AEDesc selTextObj; |
// Vars to do with menu processing |
short lastSize; |
short upItem; |
short downItem; |
short otherItem; |
long theSize; |
TextStyle theStyle; |
short lineHeight; |
short fontAscent; |
err = MakeSelfAddress(&theAddress); |
err = MakeSelectedTextObj(theDocument->theWindow, theDocument->theText, &selTextObj); |
// check if the item is on the Size menu |
// remembering that we can add and delete items from it |
lastSize = CountMItems(myMenus[sizeM]) - 5; |
upItem = lastSize + 2; |
downItem = upItem + 1; |
otherItem = downItem + 2; |
TEGetStyle((**(theDocument->theText)).selStart, &theStyle, &lineHeight, |
&fontAscent, theDocument->theText); |
GetMenuItemText(myMenus[sizeM], theItem, name); |
if (theItem <= lastSize) |
{ |
GetMenuItemText(myMenus[sizeM], theItem, name); |
StringToNum(name, &theSize); |
} |
else if (theItem == upItem) |
theSize = theStyle.tsSize + 1; |
else if (theItem == downItem) |
theSize = theStyle.tsSize - 1; |
else if (theItem == otherItem) |
{ |
theSize = theStyle.tsSize; |
if (!PoseSizeDialog(&theSize)) |
return; |
} |
if (err==noErr) |
err = CreateOffsetDescriptor(theSize, &sizeDesc); |
if (err==noErr) |
err = SendAESetObjProp(&selTextObj, pPointSize, &sizeDesc, &theAddress); |
} // IssueSizeCommand |
void IssueStyleCommand(DPtr theDocument, short theItem) |
{ |
Style theFace; |
OSErr err; |
AEDesc result; |
AEAddressDesc selfAddr; |
AEDesc selTextObj; |
TextStyle theStyle; |
short lineHeight; |
short fontAscent; |
TEGetStyle((**(theDocument->theText)).selStart, &theStyle, |
&lineHeight, &fontAscent, theDocument->theText); |
theFace = 0; |
switch (theItem) |
{ |
case cPlain: |
theFace = 0; |
break; |
case cBold: |
theFace = bold; |
break; |
case cItalic: |
theFace = italic; |
break; |
case cUnderline: |
theFace = underline; |
break; |
case cOutline: |
theFace = outline; |
break; |
case cShadow: |
theFace = shadow; |
break; |
case cCondense: |
theFace = condense; |
break; |
case cExtend: |
theFace = extend; |
break; |
} // of switch |
if (theFace==0) |
err = BuildTypeTextStylesDesc(0, bold+italic+underline+outline+shadow+condense+extend, &result); |
else if (theFace & theStyle.tsFace) |
err = BuildTypeTextStylesDesc(0, theFace, &result); |
else |
err = BuildTypeTextStylesDesc(theFace, 0, &result); |
err = MakeSelfAddress(&selfAddr); |
if (err==noErr) |
err = MakeSelectedTextObj(theDocument->theWindow, theDocument->theText, &selTextObj); |
if (err==noErr) |
err = SendAESetObjProp(&selTextObj, pTextStyles, &result, &selfAddr); |
} // IssueStyleCommand |
OSErr IssueSetDataObjToBufferContents(const AEDesc* theObj) |
{ |
OSErr myErr; |
OSErr ignoreErr; |
AEAddressDesc theAddress; |
AppleEvent myAppleEvent; |
AppleEvent defReply; |
myErr = MakeSelfAddress(&theAddress); |
// create event |
if (myErr==noErr) |
myErr = AECreateAppleEvent(kAECoreSuite, kAESetData, &theAddress, |
0, 0, &myAppleEvent); |
// add prop obj spec to the event |
if (myErr==noErr) |
myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, theObj); |
// add prop data to the event |
if (myErr==noErr) |
myErr = AEPutParamPtr(&myAppleEvent, keyAEData, typeChar, |
(Ptr)gTypingBuffer, gCharsInBuffer); |
// send event |
if (myErr==noErr) |
if (gRecordingImplemented) |
myErr = AESend(&myAppleEvent, &defReply, kAENoReply+kAEDontExecute, |
kAENormalPriority, kAEDefaultTimeout, nil, nil); |
if (theAddress.dataHandle) |
ignoreErr = AEDisposeDesc(&theAddress); |
if (myAppleEvent.dataHandle) |
ignoreErr = AEDisposeDesc(&myAppleEvent); |
return(myErr); |
} |
void AddKeyToTypingBuffer(DPtr theDocument, char theKey) |
{ |
OSErr myErr; |
OSErr ignoreErr; |
if (theKey==BS || theKey==FS || theKey==GS || theKey==RS || theKey==US) |
{ |
FlushAndRecordTypingBuffer(); |
if (theKey==BS) |
{ |
if ((**theDocument->theText).selStart!=(**theDocument->theText).selEnd) |
{ |
myErr = MakeTextObj(theDocument->theWindow, |
(**theDocument->theText).selStart, |
(**theDocument->theText).selEnd, |
&gTypingTargetObject); |
} |
else |
{ |
myErr = MakeTextObj(theDocument->theWindow, |
(**theDocument->theText).selStart-1, |
(**theDocument->theText).selStart, |
&gTypingTargetObject); |
} |
myErr = IssueSetDataObjToBufferContents(&gTypingTargetObject); |
ignoreErr = AEDisposeDesc(&gTypingTargetObject); |
gTypingTargetObject.dataHandle = nil; |
} |
} |
else |
{ |
if (gCharsInBuffer==0) |
myErr = MakeSelectedTextObj(theDocument->theWindow, theDocument->theText, |
&gTypingTargetObject); |
gTypingBuffer[gCharsInBuffer++] = theKey; |
} |
} |
void FlushAndRecordTypingBuffer(void) |
{ |
OSErr myErr; |
OSErr ignoreErr; |
if (gCharsInBuffer != 0) |
{ |
myErr = IssueSetDataObjToBufferContents(&gTypingTargetObject); |
if (gTypingTargetObject.dataHandle) |
ignoreErr = AEDisposeDesc(&gTypingTargetObject); |
} |
gCharsInBuffer = 0; |
gTypingTargetObject.dataHandle = 0; |
} |
void StyleTokConst(short theStyleItem, DescType *thekConst) |
{ |
switch (theStyleItem) |
{ |
case bold: |
*thekConst = kAEBold; |
break; |
case italic: |
*thekConst = kAEItalic; |
break; |
case underline: |
*thekConst = kAEUnderline; |
break; |
case outline: |
*thekConst = kAEOutline; |
break; |
case shadow: |
*thekConst = kAEShadow; |
break; |
case condense: |
*thekConst = kAECondensed; |
break; |
case extend: |
*thekConst = kAEExpanded; |
break; |
} |
} // StyleTokConst |
OSErr BuildTypeTextStylesDesc(Style onStyles, Style offStyles, AEDesc *resultDesc) |
{ |
OSErr myErr; |
OSErr ignoreErr; |
short myStyleItem; |
DescType styleConst; |
AEDesc onStylesDesc; |
AEDesc offStylesDesc; |
AEDesc dataDesc; |
onStylesDesc.dataHandle = nil; |
offStylesDesc.dataHandle = nil; |
dataDesc.dataHandle = nil; |
myErr = AECreateList(nil, 0, true, &dataDesc); |
myErr = AECreateList(nil, 0, false, &onStylesDesc); |
myErr = AECreateList(nil, 0, false, &offStylesDesc); |
for (myStyleItem = bold; myStyleItem<=extend; myStyleItem = myStyleItem <<1) |
if (myErr==noErr) |
{ |
StyleTokConst(myStyleItem, &styleConst); |
if (myStyleItem & onStyles) |
myErr = AEPutPtr(&onStylesDesc, |
0, // add to end of list |
typeEnumerated, // text for style name |
(Ptr)&styleConst, |
sizeof(styleConst)); |
if (myStyleItem & offStyles) |
myErr = AEPutPtr(&offStylesDesc, |
0, // add to end of list |
typeEnumerated, // text for style name |
(Ptr)&styleConst, |
sizeof(styleConst)); |
} |
if (myErr==noErr) |
myErr = AEPutKeyDesc(&dataDesc, keyAEOnStyles, &onStylesDesc); |
if (myErr==noErr) |
myErr = AEPutKeyDesc(&dataDesc, keyAEOffStyles, &offStylesDesc); |
if (myErr==noErr) |
myErr = AECoerceDesc(&dataDesc, typeTextStyles, resultDesc); |
if (onStylesDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&onStylesDesc); |
if (offStylesDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&offStylesDesc); |
if (dataDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&dataDesc); |
return(myErr); |
} |
OSErr BuildTextStylesDesc(Style theStyle, AEDesc *resultDesc) |
{ |
short myStyleItem; |
Style onStyles; |
Style offStyles; |
onStyles = 0; |
offStyles = 0; |
for (myStyleItem = bold; myStyleItem<=extend; myStyleItem = myStyleItem <<1) |
{ |
if (myStyleItem & theStyle) |
onStyles = onStyles + myStyleItem; |
else |
offStyles = offStyles + myStyleItem; |
} |
return(BuildTypeTextStylesDesc(onStyles, offStyles, resultDesc)); |
} // BuildTextStylesDesc |
OSErr BuildStyledTextDesc(TEHandle theHTE, short start, short howLong, AEDesc *resultDesc) |
{ |
AEDesc listDesc; |
short oldSelStart; |
short oldSelEnd; |
StScrpHandle myStScrpHandle; |
OSErr myErr; |
OSErr ignoreErr; |
listDesc.dataHandle = nil; |
oldSelStart = (**theHTE).selStart; |
oldSelEnd = (**theHTE).selEnd; |
TESetSelect(start-1, start+howLong-2, theHTE); |
myErr = AECreateList(nil, 0, true, &listDesc); |
HLock((Handle)(**theHTE).hText); |
if (myErr == noErr) |
myErr = AEPutKeyPtr(&listDesc, keyAEText, typeChar, |
(Ptr)&(*(**theHTE).hText)[start-1], howLong); |
HUnlock((Handle)(**theHTE).hText); |
myStScrpHandle = TEGetStyleScrapHandle(theHTE); |
if (myStScrpHandle) |
{ |
HLock((Handle)myStScrpHandle); |
if (myErr==noErr) |
myErr = AEPutKeyPtr(&listDesc, keyAEStyles, typeScrapStyles, |
(Ptr)*myStScrpHandle, GetHandleSize((Handle)myStScrpHandle)); |
HUnlock((Handle)myStScrpHandle); |
} |
else |
myErr = AEPutKeyPtr(&listDesc, keyAEStyles, typeScrapStyles, (Ptr)nil, 0); |
if (myErr==noErr) |
myErr = AECoerceDesc(&listDesc, typeStyledText, resultDesc); // should be typeIntlText |
if (listDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&listDesc); |
TESetSelect(oldSelStart, oldSelEnd, theHTE); |
return(myErr); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22