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/MSAESetData.c
// MSAESetData.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. |
/* |
Changes for 4.0 |
29-Feb-96 : GS : Added abiltiy to set properties from menus and menu items. |
29-Feb-96 : GS : Added script properties to application and document objects. |
*/ |
#include "MSAESetData.h" |
#include "MSWindow.h" |
#include "MSGlobals.h" |
#include "MSAEUtils.h" |
#include "MSAETextUtils.h" |
#include "MSAEWindowUtils.h" |
#include "MSAEMenuUtils.h" |
#include "MSAppleEvents.h" |
#include "MSAESelect.h" |
#include "MSScript.h" |
#include "MSAECreate.h" |
#ifdef THINK_C |
#include "PLStrs.h" |
#else |
#include <PLStringFuncs.h> |
#endif |
#include <string.h> |
// Prototypes |
void SendwCalcRgnsToWind( WindowPtr wP ); |
// -------------------------------------------------------------------------- |
// Name: DoSetData |
// Purpose: Handles the SetData Apple Event, extracting the direct |
// object (which says what to set) and the data (what to set |
// it to). |
// -------------------------------------------------------------------------- |
pascal OSErr DoSetData(const AppleEvent *theAppleEvent, |
AppleEvent *reply, |
long handlerRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (reply, handlerRefCon) |
#endif |
AEDesc directObj = {typeNull, NULL}, |
dataDesc = {typeNull, NULL}; |
OSErr err; |
// pick up the direct object, which is the object whose data is to be set |
err = AEGetParamDesc(theAppleEvent, keyDirectObject, |
typeWildCard, &directObj); |
if (noErr != err) goto done; |
// now the data to set it to - typeWildCard means get as is |
// e.g. this is the name of the font for text |
err = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &dataDesc); |
if (noErr != err) goto done; |
// missing any parameters? |
err = GotRequiredParams(theAppleEvent); |
if (noErr != err) goto done; |
// set the data |
err = HandleSetData(&directObj, &dataDesc); |
done: |
(void)AEDisposeDesc(&directObj); |
(void)AEDisposeDesc(&dataDesc); |
return(err); |
} // DoSetData |
// --------------------------------------------------------------------------- |
// Name: HandleSetData |
// Purpose: Resolves the object into a token (could be one of |
// many) andthe sets the data of that object to dataDesc. |
// --------------------------------------------------------------------------- |
OSErr HandleSetData(const AEDesc *theObj, AEDesc *dataDesc) |
{ |
TextToken theTextToken; |
Size tokenSize; |
AEDesc objTokenDesc = {typeNull, NULL}, |
itemDesc = {typeNull, NULL}, |
ignoreResult = {typeNull, NULL}; |
long index; |
DescType returnedType; |
OSErr err; |
// Coerce theObj into a token which we can use - |
// set the property or data for that token |
if ( typeObjectSpecifier == theObj->descriptorType ) |
err = AEResolve( theObj, kAEIDoMinimum, &objTokenDesc ); |
else if ( typeNull != theObj->descriptorType ) // Otherwise, just copy it |
err = AEDuplicateDesc( theObj, &objTokenDesc ); |
if (noErr != err) goto done; |
switch (objTokenDesc.descriptorType) |
{ |
case typeMyApplProp: |
err = SetApplicationProperty( &objTokenDesc, dataDesc ); |
break; |
case typeMyWindowProp: |
err = SetWindowProperty(&objTokenDesc, dataDesc); |
break; |
case typeMyDocumentProp: |
err = SetDocumentProperty(&objTokenDesc, dataDesc); |
break; |
case typeMyMenuProp: |
err = SetMenuProperty( &objTokenDesc, dataDesc ); |
break; |
case typeMyMenuItemProp: |
err = SetMenuItemProperty( &objTokenDesc, dataDesc ); |
break; |
case typeMyTextProp: |
err = SetTextProperty(&objTokenDesc, dataDesc); |
break; |
case typeMyText: |
GetRawDataFromDescriptor(&objTokenDesc, (Ptr)&theTextToken, |
sizeof(theTextToken), &tokenSize); |
// itemDesc is a null descriptor here |
err = CreateAtTextToken(cText, dataDesc, &theTextToken, |
&itemDesc, &ignoreResult); |
break; |
case typeAEList: // If it's a list then do each item |
err = AECountItems(&objTokenDesc, &index); |
if (noErr != err) goto done; |
for (; index > 0; index--) |
{ |
err = AEGetNthDesc(&objTokenDesc, index, typeWildCard, &returnedType, &itemDesc); |
if (noErr == err) // Get property by calling this function again |
err = HandleSetData(&itemDesc, dataDesc); |
if (itemDesc.dataHandle) |
AEDisposeDesc(&itemDesc); |
} |
break; |
default: |
err = errAEWrongDataType; |
} |
done: |
(void)AEDisposeDesc( &objTokenDesc ); |
(void)AEDisposeDesc( &itemDesc ); |
(void)AEDisposeDesc( &ignoreResult ); |
return err; |
} // HandleSetData |
OSErr SetApplicationProperty( const AEDesc *theTokenDesc, const AEDesc *dataDesc ) |
{ |
AppPropToken aToken; |
AEDesc aDesc = {typeNull, NULL}; |
Size tokenSize; |
OSErr err; |
err = AECoerceDesc( theTokenDesc, typeMyApplProp, &aDesc ); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor( &aDesc, (Ptr)&aToken, |
sizeof( aToken ), &tokenSize ); |
SetApplicationTokenProperty( &aToken, dataDesc ); |
done: |
(void)AEDisposeDesc(&aDesc); |
return(err); |
} // SetApplicationProperty |
OSErr SetApplicationTokenProperty( AppPropToken* theToken, const AEDesc *dataDesc ) |
{ |
OSErr err; |
switch ( theToken->tokenProperty ) |
{ |
case pScript: |
err = SetScriptDesc( dataDesc, &gAppRec.theScriptID ); |
break; |
default: |
err = errAEEventNotHandled; |
} |
return err; |
} |
OSErr SetWindowSelectionProperty(WindowPtr theWindow, const AEDesc *dataDesc) |
{ |
AEDesc textDesc = {typeNull, NULL}, |
ignoreResult = {typeNull, NULL}; |
TextToken aTextToken; |
Size actualSize; |
short ignore; |
OSErr err; |
// first check to see if we are dealing with a TEXT descriptor or |
// an object specifier. Since AECoerceDesc will end up calling |
// AEResolve, we don't want to call this if the user entered something |
// like 'Set selection of window 1 to "some text" |
switch (dataDesc->descriptorType) |
{ |
case typeChar: |
case typeIntlText: |
case typeStyledText: |
err = GetWindowSelection(theWindow, &aTextToken, &ignore); |
if (noErr != err) goto done; |
// textDesc is a null descriptor here |
err = CreateAtTextToken(cText, dataDesc, &aTextToken, |
&textDesc, &ignoreResult); |
break; |
default: // we are dealing with an object specifier |
err = AECoerceDesc(dataDesc, typeMyText, &textDesc); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&textDesc, (Ptr)&aTextToken, sizeof(aTextToken), |
&actualSize); |
SelectTextToken(&aTextToken); |
} |
done: |
(void)AEDisposeDesc(&textDesc); |
return(err); |
} |
void SendwCalcRgnsToWind( WindowPtr wP ) |
{ |
// This forces a wCalcRgns message to be sent to the windows proc!! Ughhhhhhh..... |
Handle h; |
long param = 0; |
SInt8 hState; |
h = (*(WindowPeek)wP).windowDefProc; |
hState = HGetState(h); |
HLock(h); // paranoia? |
CallWindowDefProc((WindowDefProcPtr)*h, documentProc, wP, wCalcRgns, param); |
HSetState(h, hState); |
} |
OSErr SetWindowProperty( const AEDesc *theTokenDesc, const AEDesc *dataDesc ) |
{ |
WindowPropToken theWindowPropToken; |
AEDesc aDesc = {typeNull, NULL}; |
Size tokenSize; |
OSErr err; |
err = AECoerceDesc( theTokenDesc, typeMyWindowProp, &aDesc ); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor( &aDesc, (Ptr)&theWindowPropToken, |
sizeof(theWindowPropToken), &tokenSize ); |
err = SetWindowTokenProperty( &theWindowPropToken, dataDesc ); |
done: |
(void)AEDisposeDesc( &aDesc ); |
return err; |
} |
// ------------------------------------------------------------------------ |
// Name: SetWindowTokenProperty |
// Purpose: Sets the window property specified in theToken to |
// be that supplied in dataDesc. |
// ------------------------------------------------------------------------ |
OSErr SetWindowTokenProperty( WindowPropToken* theToken, const AEDesc* theData ) |
{ |
Rect aRect, |
strucRect, |
contRect; |
Boolean aBoolean; |
Str255 aString; |
long aLong; |
GrafPtr aPort; |
WindowPeek aWindowPeek; |
OSErr err = noErr; |
switch (theToken->tokenProperty) |
{ |
case pBounds: |
err = GetRectFromDescriptor( theData, &aRect ); |
if ( noErr != err ) goto done; |
err = GetWindowBounds( theToken->tokenWindowToken.tokenWindow, &strucRect ); |
// Don't set bounds if they're the same as before |
if ( noErr != err || EqualRect( &aRect, &strucRect ) ) goto done; |
aWindowPeek = (WindowPeek)theToken->tokenWindowToken.tokenWindow; |
aBoolean = IsVisible( theToken->tokenWindowToken.tokenWindow ); |
if ( ! aBoolean ) |
SendwCalcRgnsToWind( theToken->tokenWindowToken.tokenWindow ); |
strucRect = (*aWindowPeek->strucRgn)->rgnBBox; |
contRect = (*aWindowPeek->contRgn)->rgnBBox; |
// the rectangle is for the structure region, and is in global coordinates |
// MoveWindow and SizeWindow apply to the content region, so we have to massage a little |
aRect.top += contRect.top - strucRect.top; |
aRect.left += contRect.left - strucRect.left; |
aRect.bottom -= strucRect.bottom - contRect.bottom; |
aRect.right -= strucRect.right - contRect.right; |
if ( EmptyRect( &aRect ) ) |
err = errAECorruptData; |
else |
{ |
if ( aBoolean ) // IsVisible |
{ |
MoveWindow( theToken->tokenWindowToken.tokenWindow, |
aRect.left, |
aRect.top, |
false ); |
SizeWindow( theToken->tokenWindowToken.tokenWindow, |
aRect.right - aRect.left, |
aRect.bottom - aRect.top, |
true ); |
} |
else |
{ // Move offscreen first |
MoveWindow( theToken->tokenWindowToken.tokenWindow, |
10000, |
10000, |
false ); |
// Encapsulate the resizing in Show then Hide |
ShowWindow( theToken->tokenWindowToken.tokenWindow ); |
SizeWindow( theToken->tokenWindowToken.tokenWindow, |
aRect.right - aRect.left, |
aRect.bottom - aRect.top, |
true ); |
HideWindow( theToken->tokenWindowToken.tokenWindow ); |
// Move it to the proper place |
MoveWindow( theToken->tokenWindowToken.tokenWindow, |
aRect.left, |
aRect.top, |
false ); |
} |
GetPort( &aPort ); |
SetPort( theToken->tokenWindowToken.tokenWindow ); |
ResizeWindow( DPtrFromWindowPtr( theToken->tokenWindowToken.tokenWindow ) ); |
SetPort( aPort ); |
} |
break; |
case pVisible: |
err = GetBooleanFromDescriptor(theData, &aBoolean); |
if (noErr != err) goto done; |
if (aBoolean) |
ShowMSWindow(theToken->tokenWindowToken.tokenWindow); |
else |
HideMSWindow(theToken->tokenWindowToken.tokenWindow); |
break; |
case pIsZoomed: |
GetPort( &aPort ); |
SetPort( theToken->tokenWindowToken.tokenWindow ); |
err = GetBooleanFromDescriptor( theData, &aBoolean ); |
if ( aBoolean ) |
ZoomWindow( qd.thePort, inZoomOut, false ); |
else |
ZoomWindow( qd.thePort, inZoomIn, false ); |
ResizeWindow( DPtrFromWindowPtr( theToken->tokenWindowToken.tokenWindow ) ); |
SetPort( aPort ); |
break; |
case pName: |
err = GetPStringFromDescriptor(theData, aString); |
if (noErr != err) goto done; |
SetWTitle(theToken->tokenWindowToken.tokenWindow, aString); |
break; |
case pIndex: |
err = GetLongIntFromDescriptor(theData, &aLong); |
if (noErr != err) goto done; |
SetWindowIndex( theToken->tokenWindowToken.tokenWindow, aLong ); |
break; |
case pBestType: |
case pClass: |
case pDefaultType: |
case pHasCloseBox: |
case pIsZoomable: |
err = errAEEventNotHandled; |
break; |
default: |
err = errAEEventNotHandled; |
} |
done: |
return(err); |
} |
OSErr SetDocumentProperty( const AEDesc *theTokenDesc, const AEDesc *dataDesc ) |
{ |
WindowPropToken theWindowPropToken; |
AEDesc aDesc = {typeNull, NULL}; |
Size tokenSize; |
OSErr err; |
err = AECoerceDesc( theTokenDesc, typeMyDocumentProp, &aDesc ); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor( &aDesc, (Ptr)&theWindowPropToken, |
sizeof(theWindowPropToken), &tokenSize ); |
SetDocumentTokenProperty( &theWindowPropToken, dataDesc ); |
done: |
(void)AEDisposeDesc(&aDesc); |
return(err); |
} // SetDocumentProperty |
OSErr SetDocumentTokenProperty( WindowPropToken* theToken, const AEDesc *dataDesc ) |
{ |
Str255 aPStr; |
DPtr theDocument; |
THPrint theTHPrint; |
TextToken aTextToken; |
Boolean aBoolean; |
AEDesc nullDesc = {typeNull, NULL}, |
aDesc = {typeNull, NULL}; |
Handle hGXJobData; |
OSErr err = noErr; |
theDocument = DPtrFromWindowPtr( theToken->tokenWindowToken.tokenWindow ); |
switch ( theToken->tokenProperty ) |
{ |
case pName: |
err = GetPStringFromDescriptor( dataDesc, aPStr ); |
if (noErr != err) goto done; |
if ( aPStr[0] == 0) |
err = errAEWrongDataType; |
else |
{ |
SetWTitle( theToken->tokenWindowToken.tokenWindow, aPStr ); |
PLstrcpy( theDocument->theFileName, aPStr ); // Should we do this??? |
} |
break; |
case pText: |
case pContents: |
// Get whole window as place to insert data |
err = TextTokenFromDocumentToken(&(theToken->tokenWindowToken), &aTextToken); |
if (noErr != err) goto done; |
err = CreateAtTextToken( cText, dataDesc, &aTextToken, |
&nullDesc, &aDesc ); |
break; |
case pIsModified: |
err = GetBooleanFromDescriptor( dataDesc, &aBoolean ); |
if (noErr != err) goto done; |
theDocument->dirty = aBoolean; |
goto done; // Don't set dirty flag again |
case pPageSetup: |
if ( ! gGXIsPresent ) |
{ |
err = GetTHPrintFromDescriptor(dataDesc, &theTHPrint); |
if (theTHPrint) |
{ |
if (theDocument->thePrintSetup) |
DisposHandle((Handle)theDocument->thePrintSetup); |
theDocument->thePrintSetup = theTHPrint; |
ResizePageSetupForDocument(theDocument); |
} |
} |
else |
err = errAEEventNotHandled; |
break; |
case pGXPageSetup: |
if ( gGXIsPresent ) |
{ |
err = AECoerceDesc(dataDesc,typeTGXPrint,&aDesc); |
hGXJobData = nil; |
if (err==noErr) |
{ |
hGXJobData = NewHandle(GetHandleSize(aDesc.dataHandle)); |
BlockMove(*(aDesc.dataHandle), |
*hGXJobData, |
GetHandleSize(aDesc.dataHandle)); |
} |
if (hGXJobData) |
{ |
GXUnflattenJobFromHdl(theDocument->documentJob, hGXJobData); |
err = GXGetJobError(theDocument->documentJob); |
ResizePageSetupForDocument(theDocument); |
} |
} |
else |
err = errAEEventNotHandled; |
break; |
case pSelection: |
err = SetWindowSelectionProperty(theToken->tokenWindowToken.tokenWindow, dataDesc); |
break; |
case pScript: |
err = SetScriptDesc( dataDesc, &theDocument->theScriptID ); |
break; |
default: |
err = SetWindowTokenProperty( theToken, dataDesc ); |
} |
if ( noErr == err && pIsModified != theToken->tokenProperty) |
theDocument->dirty = true; |
done: |
(void)AEDisposeDesc( &nullDesc ); |
(void)AEDisposeDesc( &aDesc ); |
return(err); |
} |
OSErr GetTHPrintFromDescriptor(const AEDesc *sourceDesc, THPrint *result) |
{ |
Size ptSize; |
AEDesc resultDesc; |
OSErr err; |
*result = NULL; |
err = AECoerceDesc(sourceDesc, typeTPrint, &resultDesc); |
if (noErr != err) goto done; |
*result = (THPrint)NewHandle(sizeof(TPrint)); |
PrOpen(); |
PrintDefault(*result); |
HLock((Handle)*result); |
GetRawDataFromDescriptor(&resultDesc, (Ptr)**result, sizeof(TPrint), &ptSize); |
HUnlock((Handle)*result); |
if ((ptSize<sizeof(TPrint)) || (PrValidate(*result))) |
{ |
err = errAECoercionFail; |
DisposHandle((Handle)*result); |
*result = NULL; |
} |
PrClose(); |
done: |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
return(err); |
} // GetTHPrintFromDescriptor |
OSErr SetMenuProperty( const AEDesc *theTokenDesc, const AEDesc *dataDesc ) |
{ |
MenuPropToken aToken; |
Size tokenSize; |
OSErr err; |
if ( typeMyMenuProp != theTokenDesc->descriptorType ) |
return errAEWrongDataType; |
GetRawDataFromDescriptor( theTokenDesc, (Ptr)&aToken, |
sizeof( aToken ), &tokenSize ); |
err = SetMenuTokenProperty( &aToken, dataDesc ); |
return err; |
} |
OSErr SetMenuTokenProperty( MenuPropToken* theToken, const AEDesc* theData ) |
{ |
MenuScriptRecPtr aMenuRecPtr; |
OSErr err; |
switch ( theToken->tokenProperty ) |
{ |
case pScript: |
aMenuRecPtr = GetMenuScriptRecPtr( theToken->token.tokenID * 32 ); |
if ( ! aMenuRecPtr || kOSANullScript == aMenuRecPtr->theScriptID ) |
{ |
err = errAENoSuchObject; |
goto done; |
} |
err = SetScriptDesc( theData, &aMenuRecPtr->theScriptID ); |
if ( noErr == err ) |
aMenuRecPtr->fChanged = true; |
break; |
default: |
err = errAEEventNotHandled; |
} |
done: |
return(err); |
} |
OSErr SetMenuItemProperty( const AEDesc *theTokenDesc, const AEDesc *dataDesc ) |
{ |
MenuItemPropToken aToken; |
Size tokenSize; |
OSErr err; |
if ( typeMyMenuItemProp != theTokenDesc->descriptorType ) |
return errAEWrongDataType; |
GetRawDataFromDescriptor( theTokenDesc, (Ptr)&aToken, |
sizeof( aToken ), &tokenSize ); |
err = SetMenuItemTokenProperty( &aToken, dataDesc ); |
return err; |
} |
OSErr SetMenuItemTokenProperty( MenuItemPropToken* theToken, const AEDesc* theData ) |
{ |
AEDesc aDesc = { typeNull, NULL }; |
MenuScriptRecPtr aMenuRecPtr; |
Str255 aPStr; |
short aResID; |
OSErr err; |
aResID = theToken->token.tokenMenuToken.tokenID * 32 + theToken->token.tokenItem; |
aMenuRecPtr = GetMenuScriptRecPtr( aResID ); |
switch ( theToken->tokenProperty ) |
{ |
case pName: |
err = GetPStringFromDescriptor( theData, aPStr ); |
if ( noErr != err ) goto done; |
SetMenuItemName( &theToken->token, aPStr ); |
// If there is a script associated then try setting the |
// itemName property. |
if ( aMenuRecPtr && kOSANullScript != aMenuRecPtr->theScriptID ) |
{ |
err = PutPStringToDescriptor( &aDesc, "\pitemname" ); |
if ( noErr != err ) goto done; |
// Ignore the error because it may not have the property |
(void)SetScriptProperty( aMenuRecPtr->theScriptID, &aDesc, theData ); |
} |
break; |
case pScript: |
if ( ! aMenuRecPtr || kOSANullScript == aMenuRecPtr->theScriptID ) |
{ |
err = errAENoSuchObject; |
goto done; |
} |
err = SetScriptDesc( theData, &aMenuRecPtr->theScriptID ); |
if ( noErr == err ) |
{ |
aMenuRecPtr->fChanged = true; |
err = CheckForMenuItemName( aResID, aMenuRecPtr->theScriptID ); |
} |
break; |
default: |
err = errAEEventNotHandled; |
} |
done: |
(void)AEDisposeDesc( &aDesc ); |
return(err); |
} |
OSErr CheckForMenuItemName( short theResID, OSAID theOSAID ) |
{ |
AEDesc aDesc = { typeNull, NULL }, |
aNameDesc = { typeNull, NULL }; |
Str255 aPStr; |
OSErr anErr; |
anErr = PutPStringToDescriptor( &aDesc, "\pitemname" ); |
if ( noErr != anErr ) goto done; |
anErr = GetScriptProperty( theOSAID, &aDesc, &aNameDesc ); |
if ( noErr == anErr ) |
{ |
anErr = GetPStringFromDescriptor( &aNameDesc, aPStr ); |
if ( noErr != anErr ) goto done; |
SetMenuItemText( MenuHandleFromMenuID( theResID / 32 ), theResID % 32, aPStr ); |
} |
else |
anErr = noErr; // Just doesn't have the property so no error |
done: |
return anErr; |
} |
// ---------------------------------------------------------------------- |
// Name: SetTextProperty |
// Purpose: Sets the text property specfied by theTextPropToken to |
// that in dataDesc. |
// ---------------------------------------------------------------------- |
OSErr SetTextProperty(const AEDesc *tokenDesc, const AEDesc *dataDesc) |
{ |
DPtr theDoc; |
Str255 name; |
short theSize; |
Style onStyle; |
Style offStyle; |
TextPropToken theTextPropToken; |
AEDesc newDesc = {typeNull, NULL}, |
nullDesc = {typeNull, NULL}, |
ignoreResult = {typeNull, NULL}; |
Size tokenSize; |
OSErr err; |
err = AECoerceDesc(tokenDesc, typeMyTextProp, &newDesc); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextPropToken, |
sizeof(theTextPropToken), &tokenSize); |
theDoc = DPtrFromWindowPtr(theTextPropToken.tokenTextToken.tokenWindow); |
theDoc->dirty = true; |
switch (theTextPropToken.tokenProperty) |
{ |
case pText: |
case pContents: |
err = CreateAtTextToken(cText, dataDesc, &(theTextPropToken.tokenTextToken), |
&nullDesc, &ignoreResult); |
break; |
case pFont: |
err = GetPStringFromDescriptor(dataDesc, name); |
if (noErr != err) goto done; |
err = SetFontOfTextToken(&theTextPropToken.tokenTextToken, name); |
break; |
case pPointSize: |
err = GetIntegerFromDescriptor(dataDesc, &theSize); |
if (noErr != err) goto done; |
err = SetSizeOfTextToken(&theTextPropToken.tokenTextToken, theSize); |
break; |
case pTextStyles: |
onStyle = 0; |
offStyle = 0; |
err = GetTextStyles(dataDesc, &onStyle, &offStyle); |
if (noErr != err) goto done; |
if (onStyle & offStyle != 0) |
err = errAEEventFailed; |
else |
err = SetStyleOfTextToken(&theTextPropToken.tokenTextToken, onStyle, offStyle); |
break; |
default: |
err = errAEWrongDataType; |
} |
done: |
(void)AEDisposeDesc(&newDesc); |
return(err); |
} // SetTextProperty |
short ItemForNamedFont(Str255 theName) |
{ |
Str255 itemName; |
short limit; |
limit = CountMItems(myMenus[fontM]); |
while (limit>0) |
{ |
GetItem(myMenus[fontM],limit, itemName); |
if (IUEqualString(theName, itemName)==0) |
return(limit); |
else |
limit--; |
} |
return(0); |
} // ItemForNamedFont |
// ----------------------------------------------------------------------- |
// Name: SetFontOfTextToken |
// Purpose: Sets the font of the text specified by theToken to |
// the font in name. |
// ----------------------------------------------------------------------- |
OSErr SetFontOfTextToken(TextToken* theToken, Str255 name) |
{ |
DPtr docPtr; |
TextToken oldSelection; |
short theNumber, |
theItem; |
TextStyle newStyle; |
Boolean fCurrentSelection; |
OSErr err; |
docPtr = DPtrFromWindowPtr(theToken->tokenWindow); |
if (!docPtr) return(errAENoSuchObject); |
// ignore theNumber result |
err = GetWindowSelection(theToken->tokenWindow, &oldSelection, &theNumber); |
if (noErr != err) goto done; |
if (memcmp(theToken, &oldSelection, sizeof(TextToken))) |
{ |
fCurrentSelection = false; |
err = SelectTextToken(theToken); // Only set the selection if it's different |
if (noErr != err) goto done; |
} |
else |
fCurrentSelection = true; |
GetFNum(name, &theNumber); |
theItem = ItemForNamedFont(name); // returns 0 if failed - i.e. SystemFont |
if (gFontMItem) |
CheckItem(myMenus[fontM], gFontMItem, false); |
gFontMItem = theItem; |
CheckItem(myMenus[fontM], gFontMItem, true); |
docPtr->theFont = theNumber; |
newStyle.tsFont = theNumber; |
TESetStyle(doFont, &newStyle, true, docPtr->theText); |
AdjustScrollbars(docPtr, false); |
DrawPageExtras(docPtr); |
docPtr->dirty = true; |
if (! fCurrentSelection) |
err = SelectTextToken(&oldSelection); |
done: |
return(err); |
} // SetFontOfTextToken |
// ----------------------------------------------------------------------- |
// Name: SetSizeOfTextToken |
// Purpose: Sets the size of the text specified by theToken to |
// the size in theSize. |
// ----------------------------------------------------------------------- |
OSErr SetSizeOfTextToken(TextToken* theToken, short theSize) |
{ |
DPtr docPtr; |
TextToken oldSelection; |
TextStyle newStyle; |
short ignore; |
Boolean fCurrentSelection; |
OSErr err; |
docPtr = DPtrFromWindowPtr(theToken->tokenWindow); |
if (!docPtr) return(errAENoSuchObject); |
// Save the old selection |
err = GetWindowSelection(theToken->tokenWindow, &oldSelection, &ignore); |
if (noErr != err) goto done; |
if (memcmp(theToken, &oldSelection, sizeof(TextToken))) |
{ |
fCurrentSelection = false; |
err = SelectTextToken(theToken); |
if (noErr != err) goto done; |
} |
else |
fCurrentSelection = true; |
docPtr->theSize = theSize; |
newStyle.tsSize = theSize; |
TESetStyle(doSize, &newStyle, true, docPtr->theText); |
AdjustScrollbars(docPtr, false); |
DrawPageExtras(docPtr); |
docPtr->dirty = true; |
if (! fCurrentSelection) // If we reset the selection we may loose the |
err = SelectTextToken(&oldSelection); // Size or style just set |
done: |
return(err); |
} // SetSizeOfTextToken |
// ------------------------------------------------------------------------ |
// Name: SetStyleOfTextToken |
// Purpose: Sets the style of the text specified by theToken to |
// the style in theStyle. |
// ------------------------------------------------------------------------ |
OSErr SetStyleOfTextToken(TextToken* theToken, Style onStyle, Style offStyle) |
{ |
DPtr docPtr; |
TextToken oldSelection; |
TextStyle newStyle; |
short mode; |
Boolean wasContinuous; |
short ignore; |
Boolean fCurrentSelection; |
OSErr err; |
docPtr = DPtrFromWindowPtr(theToken->tokenWindow); |
if (!docPtr) return(errAENoSuchObject); |
// Save the old selection |
err = GetWindowSelection(theToken->tokenWindow, &oldSelection, &ignore); |
if (noErr != err) goto done; |
if (memcmp(theToken, &oldSelection, sizeof(TextToken))) |
{ |
fCurrentSelection = false; |
err = SelectTextToken(theToken); |
if (noErr != err) goto done; |
} |
else |
fCurrentSelection = true; |
docPtr->theStyle = onStyle; |
// Check to see if off styles are on for whole selection |
mode = doFace; |
wasContinuous = TEContinuousStyle(&mode, &newStyle, docPtr->theText); |
if ((newStyle.tsFace & offStyle) != offStyle) // not off styles are on for all |
{ |
// switch on across board so that toggle off will clear all |
newStyle.tsFace = offStyle - (newStyle.tsFace & offStyle); |
TESetStyle(doFace+doToggle, &newStyle, false, docPtr->theText); |
} |
newStyle.tsFace = offStyle; |
TESetStyle(doFace+doToggle, &newStyle,(onStyle==0), docPtr->theText); // toggle all to off |
mode = doFace; |
if (onStyle) |
{ |
wasContinuous = TEContinuousStyle(&mode, &newStyle, docPtr->theText); |
if ((newStyle.tsFace & onStyle) != onStyle) // are they on for only a few chars |
{ |
// Need to make all chars have these characteristics |
newStyle.tsFace = onStyle - (newStyle.tsFace & onStyle); // take out those continuous |
TESetStyle(doFace+doToggle, &newStyle, true, docPtr->theText); |
} |
else |
TESetStyle(0, &newStyle, true, docPtr->theText); // Just Draw it, no changes |
} |
AdjustScrollbars(docPtr, false); |
DrawPageExtras(docPtr); |
docPtr->dirty = true; |
if (! fCurrentSelection) |
err = SelectTextToken(&oldSelection); |
done: |
return(err); |
} // SetStyleOfTextToken |
OSErr GetTextStyles(const AEDesc *dataDesc, Style *onStyles, Style *offStyles) |
{ |
OSErr myErr; |
AEDescList textSDesc = { typeNull, NULL }; |
AEDescList onDesc = { typeNull, NULL }; |
AEDescList offDesc = { typeNull, NULL }; |
Boolean hadPlain; |
*onStyles = 0; |
*offStyles = 0; |
myErr = AECoerceDesc(dataDesc, typeAERecord, &textSDesc); |
if (myErr==noErr) |
myErr = AEGetKeyDesc(&textSDesc, keyAEOnStyles, typeAEList, &onDesc); |
if (myErr==noErr) |
myErr = AEGetKeyDesc(&textSDesc, keyAEOffStyles, typeAEList, &offDesc); |
if (myErr==noErr) |
myErr = MakeStyleFromAEList(&onDesc, onStyles, &hadPlain); |
if (hadPlain) |
*offStyles = bold+italic+underline+outline+shadow+condense+extend; |
else |
{ |
if (myErr==noErr) |
myErr = MakeStyleFromAEList(&offDesc, offStyles, &hadPlain); |
if (hadPlain) |
myErr = errAEEventFailed; |
} |
(void)AEDisposeDesc(&textSDesc); |
(void)AEDisposeDesc(&onDesc); |
(void)AEDisposeDesc(&offDesc); |
return(myErr); |
} // GetTextStyles |
// ----------------------------------------------------------------------- |
// Name: AddDescStyleItem |
// Purpose: Adds the kAEXXXX style to theStyle. |
// ----------------------------------------------------------------------- |
void AddDescStyleItem(DescType theDesc, Style *theStyle) |
{ |
if (theDesc == kAEBold) |
*theStyle = *theStyle+bold; |
else |
if (theDesc == kAEItalic) |
*theStyle = *theStyle+italic; |
else |
if (theDesc == kAEUnderline) |
*theStyle = *theStyle+underline; |
else |
if (theDesc == kAEOutline) |
*theStyle = *theStyle+outline; |
else |
if (theDesc == kAEShadow) |
*theStyle = *theStyle+shadow; |
else |
if (theDesc == kAECondensed) |
*theStyle = *theStyle+condense; |
else |
if (theDesc == kAEExpanded) |
*theStyle = *theStyle+extend; |
else |
if (theDesc == kAEPlain) |
*theStyle = 0; |
} // AddDescStyleItem |
OSErr MakeStyleFromAEList(const AEDescList *styleList, Style *theStyle, Boolean *hadPlain) |
{ |
OSErr myErr; |
DescType styleDesc; |
long itemsInList; |
long actSize; |
AEKeyword keywd; |
DescType typeCode; |
*hadPlain = false; |
*theStyle = 0; |
myErr = AECountItems(styleList, &itemsInList); |
while (itemsInList>0) |
if (myErr==noErr) |
{ |
myErr = AEGetNthPtr(styleList, itemsInList, typeEnumerated, &keywd, |
&typeCode, (Ptr)&styleDesc, sizeof(styleDesc), &actSize); |
AddDescStyleItem(styleDesc, theStyle); |
if (styleDesc == kAEPlain) |
{ |
itemsInList = 0; |
*hadPlain = true; |
} |
else |
itemsInList--; |
} |
return(myErr); |
} // MakeStyleFromAEList |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14