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.
Sources/MSAESelect.c
// MSAESelect.c |
// |
// Original version by Jon Lansdell and Nigel Humphreys. |
// 4.0 and 3.1 updates by Greg Sutton. |
// ©Apple Computer Inc 1996, all rights reserved. |
#include "MSAESelect.h" |
#include <Windows.h> |
#include "MSAEUtils.h" |
#include "MSWindow.h" // for DPtrFromWindowPtr() |
#include "MSAETextUtils.h" |
#include "MSAEWindowUtils.h" |
#include "MSMain.h" |
// ----------------------------------------------------------------------- |
// Name: DoSelect |
// Purpose: Handles the 'Select' Apple Event, extracting the direct |
// object (which is the text range to set the selection to) |
// 'Select' is equivalent to 'set the selection to...' |
// ----------------------------------------------------------------------- |
pascal OSErr DoSelect(const AppleEvent *theAppleEvent, AppleEvent *reply, long refcon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (refcon) |
#endif |
AEDesc directObj = {typeNull, NULL}, |
result = {typeNull, NULL}; |
OSErr err; |
err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &directObj); |
// There was a direct parameter |
if (directObj.descriptorType != typeNull) |
err = SelectDesc(&directObj, &result); |
else // There was no direct parameter |
{ |
err = PutPStringToDescriptor(&result, "\pYou have not specified an object to select"); |
if (noErr != err) goto done; |
err = errAENoSuchObject; |
} |
err = AddResultToReply(&result, reply, err); |
done: |
(void)AEDisposeDesc(&directObj); |
(void)AEDisposeDesc(&result); |
return(err); |
} // DoSelect |
OSErr SelectWindowToken(WindowToken* theToken) |
{ |
OSErr err = noErr; |
if (! theToken->tokenWindow) |
return errAENoSuchObject; |
SelectWindow( theToken->tokenWindow ); |
if ( IsVisible( theToken->tokenWindow ) ) |
{ |
DoActivate( GetNthWindow( 2 ), false ); |
DoActivate( theToken->tokenWindow, true ); |
} |
return(err); |
} |
OSErr SelectWindowDesc(AEDesc* windowDesc) |
{ |
AEDesc aDesc = { typeNull, NULL }; |
WindowToken aToken; |
Size actualSize; |
OSErr err; |
err = AECoerceDesc( windowDesc, typeMyWndw, &aDesc ); |
if ( noErr != err ) goto done; |
GetRawDataFromDescriptor( &aDesc, (Ptr)&aToken, sizeof( aToken ), &actualSize ); |
err = SelectWindowToken( &aToken ); |
done: |
(void)AEDisposeDesc( &aDesc ); |
return(err); |
} |
OSErr SelectTextToken(TextToken* theToken) |
{ |
DPtr docPtr; |
OSErr err = noErr; |
docPtr = DPtrFromWindowPtr(theToken->tokenWindow); |
if (! theToken->tokenWindow || ! docPtr) |
return errAEWrongDataType; |
TESetSelect(theToken->tokenOffset - 1, |
theToken->tokenOffset + theToken->tokenLength - 1, |
docPtr->theText); |
return(err); |
} |
OSErr SelectTextDesc(AEDesc* textDesc) |
{ |
TextToken aTextToken; |
Size actualSize; |
OSErr err; |
if (typeMyText != textDesc->descriptorType) |
return(errAETypeError); |
GetRawDataFromDescriptor(textDesc, (Ptr)&aTextToken, sizeof(aTextToken), &actualSize); |
err = SelectTextToken(&aTextToken); |
return(err); |
} |
OSErr SelectMenuItemToken( MenuItemToken* theToken ) |
{ |
OSErr err = noErr; |
DoMenuItem( theToken->tokenMenuToken.tokenID, theToken->tokenItem ); |
return err; |
} |
OSErr SelectMenuItemDesc( AEDesc* theDesc ) |
{ |
MenuItemToken aToken; |
Size actualSize; |
OSErr err; |
if ( typeMyMenuItem != theDesc->descriptorType ) |
return errAETypeError; |
GetRawDataFromDescriptor( theDesc, (Ptr)&aToken, sizeof( aToken ), &actualSize ); |
err = SelectMenuItemToken( &aToken ); |
return err; |
} |
OSErr SelectDesc( const AEDesc* aDesc, AEDesc* result ) |
{ |
AEDesc selectDesc = {typeNull, NULL}, |
textDesc = {typeNull, NULL}; |
OSErr err; |
if ( typeObjectSpecifier == aDesc->descriptorType ) |
err = AEResolve( aDesc, kAEIDoMinimum, &selectDesc ); |
else if ( typeNull != aDesc->descriptorType ) |
err = AEDuplicateDesc( aDesc, &selectDesc ); |
if (noErr != err) goto done; |
switch (selectDesc.descriptorType) |
{ |
case typeAEList: |
err = PutPStringToDescriptor(result, "\pThis application cannot select a list of objects"); |
if (noErr != err) goto done; |
err = errAETypeError; |
break; |
case typeMyWndw: |
case typeMyDocument: |
err = SelectWindowDesc(&selectDesc); |
break; |
case typeMyMenuItem: |
err = SelectMenuItemDesc(&selectDesc); |
break; |
default: |
err = AECoerceDesc(&selectDesc, typeMyText, &textDesc); |
if (noErr != err) goto done; |
err = SelectTextDesc(&textDesc); |
} |
done: |
(void)AEDisposeDesc( &selectDesc ); |
(void)AEDisposeDesc( &textDesc ); |
return(err); |
} |
// Given a window, this routine will fill out a TextToken with details |
// of the window's current selection. The total text length can also be retrieved |
// so that the selection can be updated depending on changes. |
OSErr GetWindowSelection(WindowPtr aWindow, TextToken* resultToken, short* resultLength) |
{ |
AEDesc propertyDesc = {typeNull, NULL}, |
dataDesc = {typeNull, NULL}, |
textDesc = {typeNull, NULL}; |
TEHandle aTextEditHandle; |
OSErr err = noErr; |
if (! aWindow) |
return(errAENoSuchObject); |
aTextEditHandle = TEHandleFromWindow(aWindow); |
resultToken->tokenWindow = aWindow; |
// TEHandle starts counting characters from 1, not 0 |
resultToken->tokenOffset = (*aTextEditHandle)->selStart + 1; |
resultToken->tokenLength = (*aTextEditHandle)->selEnd - (*aTextEditHandle)->selStart; |
if (resultLength) |
*resultLength = (*aTextEditHandle)->teLength; |
return(err); |
} |
// Given the selection that was deleted/changed/?moved? and the original |
// selection before the operation. Also the old length of text in the |
// TextEdit. This routine sorts out the selection that may change |
// due to position of delete/change/?move?. It returns in insertLength |
// the length of the inserted data (not just the difference). |
OSErr UpdateSelectionToken(TextToken* anInsertToken, TextToken* aSelectionToken, |
short oldLength, short* insertLength) |
{ |
TextToken updatedToken; |
short newLength, // Lots of local variables to make |
deleteLength, // things clearer. |
insertOffset, |
selectOffset, |
selectLength, |
numPartial; |
OSErr err; |
if (! anInsertToken->tokenWindow || ! aSelectionToken->tokenWindow) |
return(errAENoSuchObject); |
updatedToken.tokenWindow = aSelectionToken->tokenWindow; |
newLength = (*TEHandleFromWindow(anInsertToken->tokenWindow))->teLength; |
deleteLength = anInsertToken->tokenLength; // Characters deleted |
insertOffset = anInsertToken->tokenOffset; |
selectOffset = aSelectionToken->tokenOffset; |
selectLength = aSelectionToken->tokenLength; |
*insertLength = newLength - oldLength + deleteLength; // Characters inserted |
switch (TokenWithinToken(aSelectionToken, anInsertToken, &numPartial)) |
{ |
case kTokenBefore: |
updatedToken.tokenOffset = selectOffset + *insertLength - deleteLength; |
updatedToken.tokenLength = selectLength; |
break; |
case kTokenAfter: |
case kTokenPartialBefore: |
case kTokenPartialAfter: |
updatedToken.tokenOffset = selectOffset; |
updatedToken.tokenLength = selectLength; |
break; |
case kTokenWithin: |
updatedToken.tokenOffset = selectOffset; |
updatedToken.tokenLength = selectLength + *insertLength - deleteLength; |
break; |
} |
err = SelectTextToken(&updatedToken); |
return(err); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14