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/SVAESelect.c
/* |
File: SVAESelect.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 "SVAESelect.h" |
#include <Windows.h> |
#include "SVEditAEUtils.h" |
#include "SVEditWindow.h" // for DPtrFromWindowPtr() |
#include "SVAETextUtils.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) |
{ |
#pragma unused (refcon) |
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: |
if (directObj.dataHandle) |
AEDisposeDesc(&directObj); |
if (result.dataHandle) |
AEDisposeDesc(&result); |
return(err); |
} // DoSelect |
OSErr SelectWindowToken(WindowToken* theToken) |
{ |
OSErr err = noErr; |
if (! theToken->tokenWindow) |
return(errAENoSuchObject); |
BringToFront(theToken->tokenWindow); |
return(err); |
} |
OSErr SelectWindowDesc(AEDesc* windowDesc) |
{ |
WindowToken aWindowToken; |
Size actualSize; |
OSErr err; |
if (typeMyWndw != windowDesc->descriptorType) |
return(errAETypeError); |
GetRawDataFromDescriptor(windowDesc, (Ptr)&aWindowToken, sizeof(aWindowToken), &actualSize); |
err = SelectWindowToken(&aWindowToken); |
return(err); |
} |
OSErr SelectTextToken(TextToken* theToken) |
{ |
DPtr docPtr; |
OSErr err = noErr; |
docPtr = DPtrFromWindowPtr(theToken->tokenWindow); |
if (! theToken->tokenWindow || ! docPtr) |
return(errAENoSuchObject); |
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 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 |
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: |
err = SelectWindowDesc(&selectDesc); |
break; |
default: |
err = AECoerceDesc(&selectDesc, typeMyText, &textDesc); |
if (noErr != err) goto done; |
err = SelectTextDesc(&textDesc); |
} |
done: |
if (selectDesc.dataHandle) |
AEDisposeDesc(&selectDesc); |
if (textDesc.dataHandle) |
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-07-22