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/MSResultWind.c
// MSResultWind.c |
// |
// Written by Don Swatman and Greg Sutton |
// ©Apple Computer Inc 1996, all rights reserved. |
#include "MSResultWind.h" |
#ifdef THINK_C |
#include "PLStrs.h" |
#else |
#include <PLStringFuncs.h> |
#endif |
#include <ASRegistry.h> |
#include "MSWindow.h" |
#include "MSAETextUtils.h" |
#include "MSAEWindowUtils.h" |
#include "MSAEDelete.h" |
#include "MSAESetData.h" |
#include "MSAECreate.h" |
#include "MSAESelect.h" |
#include "MSMain.h" |
// Prototypes |
OSErr AddPStrToResults( StringPtr theStringPtr ); |
OSErr AddDescToResults( AEDesc* theDesc ); |
static OSErr EndOfDocumentTextToken( WindowPtr theWindow, TextToken* theToken ); |
OSAError TextDescUsingOSADisplay( AEDesc* theDesc, AEDesc* theResult ); |
OSErr SelectErrorRange( AEDesc* theRangeDesc, DPtr theDoc ); |
// Globals |
extern ComponentInstance gScriptingComponent; |
WindowPtr gPResultWind = NULL; |
OSErr OpenResultWind( void ) |
{ |
DPtr myDoc; |
if ( ! gPResultWind ) |
{ |
myDoc = NewDocument(false, (WindowPtr)-1L ); |
myDoc->windowType = kResultsWind; |
SetWTitle(myDoc->theWindow, "\presults" ); |
gPResultWind = myDoc->theWindow; |
} |
else |
{ |
ShowMSWindow( gPResultWind ); |
SelectWindow( gPResultWind ); |
} |
return noErr; |
} |
Boolean IsThereAResultWind( void ) |
{ |
WindowPtr aWindow = GetResultsWindPtr( ); |
if ( aWindow && ((WindowPeek)aWindow)->visible ) |
return ( true ); |
else |
return ( false ); |
} |
Boolean IsThisResultWind( WindowPtr theWind ) |
{ |
return ( theWind == GetResultsWindPtr( ) ); |
} |
void CloseResultWind( WindowPtr theWind ) |
{ |
if ( IsThisResultWind( theWind ) ) |
HideMSWindow( theWind ); |
} |
WindowPtr GetResultsWindPtr( void ) |
{ |
if ( ! gPResultWind ) // Just hasn't been accessed yet - usually always around |
{ // just hidden. |
OpenResultWind( ); |
CloseResultWind( gPResultWind ); // Just hides it |
} |
return gPResultWind; |
} |
DPtr GetResultsDoc( void ) |
{ |
return DPtrFromWindowPtr( GetResultsWindPtr( ) ); |
} |
OSErr DisplayDescResult( WindowPtr theWindow, AEDesc* theTextDesc, DPtr theDoc, OSErr theErr ) |
{ |
WindowPropToken aToken; |
OSErr err; |
if ( errOSAScriptError == theErr ) |
return (OSErr)DisplayOSAScriptError( theDoc ); |
if ( ! theWindow ) |
return noErr; |
aToken.tokenWindowToken.tokenWindow = theWindow; |
// If the descriptor is NULL then clear the window |
if ( typeNull == theTextDesc->descriptorType ) |
{ |
err = TextDescFromDocumentToken( &aToken.tokenWindowToken, theTextDesc ); |
if ( noErr == err ) |
err = DeleteDesc( theTextDesc ); |
(void)AEDisposeDesc( theTextDesc ); |
} |
else // Set the text to that provided |
{ |
aToken.tokenProperty = pText; // All of the text in document |
err = SetDocumentTokenProperty( &aToken, theTextDesc ); |
} |
return err; |
} |
OSErr DisplayOSAIDResult( WindowPtr theWindow, OSAID theOSAID, DPtr theDoc, OSErr theErr ) |
{ |
AEDesc textDesc = { typeNull, NULL }; |
OSErr err; |
if ( errOSAScriptError == theErr ) |
return (OSErr)DisplayOSAScriptError( theDoc ); |
err = OSADisplay( gScriptingComponent, theOSAID, typeStyledText, |
kOSAModeNull, &textDesc ); |
if ( noErr != err ) goto done; |
err = DisplayDescResult( theWindow, &textDesc, theDoc, theErr ); |
done: |
(void)AEDisposeDesc( &textDesc ); |
return err; |
} |
OSAError DisplayOSAScriptError( DPtr theDoc ) |
{ |
AEDesc applicationDesc = { typeNull, NULL }, |
messageDesc = { typeNull, NULL }, |
numberDesc = { typeNull, NULL }, |
typeDesc = { typeNull, NULL }, |
objectDesc = { typeNull, NULL }, |
partialDesc = { typeNull, NULL }, |
rangeDesc = { typeNull, NULL }, |
aDesc = { typeNull, NULL }; |
Str255 aPStr; |
OSAError anErr; |
(void)OSAScriptError( gScriptingComponent, kOSAErrorApp, typeChar, &applicationDesc ); |
(void)OSAScriptError( gScriptingComponent, kOSAErrorMessage, typeChar, &messageDesc ); |
(void)OSAScriptError( gScriptingComponent, kOSAErrorNumber, typeShortInteger, &numberDesc ); |
(void)OSAScriptError( gScriptingComponent, kOSAErrorExpectedType, typeWildCard, &typeDesc ); |
(void)OSAScriptError( gScriptingComponent, kOSAErrorOffendingObject, typeWildCard, &objectDesc ); |
(void)OSAScriptError( gScriptingComponent, kOSAErrorPartialResult, typeWildCard, &partialDesc ); |
(void)OSAScriptError( gScriptingComponent, kOSAErrorRange, typeOSAErrorRange, &rangeDesc ); |
// Select the range before bringing results document forward |
anErr = SelectErrorRange( &rangeDesc, theDoc ); |
// This calls a script that is executed through OSA so we need |
// to get all the script errors before calling. |
if ( ! IsVisible( GetResultsWindPtr( ) ) ) |
DoMenuItem( mscriptID, cResultWindow ); // Go through script on menu item |
else |
SelectWindow( GetResultsWindPtr( ) ); |
PLstrcpy( aPStr, "\pError" ); |
anErr = AECreateDesc( typeChar, (Ptr)&aPStr[1], aPStr[0], &aDesc ); |
if ( noErr != anErr ) goto done; |
// Just blat it straight into the results document |
// deleting anything that's there. |
anErr = DisplayDescResult( GetResultsWindPtr( ), &aDesc, NULL, noErr ); |
if ( noErr != anErr ) goto done; |
// Add the application name |
if ( typeNull != applicationDesc.descriptorType ) |
{ |
anErr = AddPStrToResults( "\p in application " ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &applicationDesc ); |
if ( noErr != anErr ) goto done; |
} |
if ( typeNull != messageDesc.descriptorType ) |
{ |
anErr = AddPStrToResults( "\p\r\rMessage : " ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &messageDesc ); |
if ( noErr != anErr ) goto done; |
} |
if ( typeNull != numberDesc.descriptorType ) |
{ |
anErr = AddPStrToResults( "\p\r\rNumber : " ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &numberDesc ); |
if ( noErr != anErr ) goto done; |
} |
if ( typeNull != typeDesc.descriptorType ) |
{ |
anErr = AddPStrToResults( "\p\r\rType : " ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &typeDesc ); // Try and use OSADisplay() to get terminology |
if ( noErr != anErr ) goto done; // for the type. |
} |
if ( typeNull != objectDesc.descriptorType ) |
{ |
anErr = AddPStrToResults( "\p\r\rOffending Object : " ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &objectDesc ); |
if ( noErr != anErr ) goto done; |
} |
if ( typeNull != partialDesc.descriptorType ) |
{ |
anErr = AddPStrToResults( "\p\r\rPartial Result : " ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &partialDesc ); |
if ( noErr != anErr ) goto done; |
} |
done: |
(void)AEDisposeDesc( &applicationDesc ); |
(void)AEDisposeDesc( &messageDesc ); |
(void)AEDisposeDesc( &numberDesc ); |
(void)AEDisposeDesc( &typeDesc ); |
(void)AEDisposeDesc( &objectDesc ); |
(void)AEDisposeDesc( &partialDesc ); |
(void)AEDisposeDesc( &rangeDesc ); |
(void)AEDisposeDesc( &aDesc ); |
return anErr; |
} |
OSErr SelectErrorRange( AEDesc* theRangeDesc, DPtr theDoc ) |
{ |
AEDesc aRecordDesc = { typeNull, NULL }; |
DescType aType; |
short errorStart, |
errorEnd; |
Size actSize; |
TextToken aTextToken; |
OSErr anErr; |
if ( ! theDoc ) |
return noErr; |
anErr = AECoerceDesc( theRangeDesc, typeAERecord, &aRecordDesc ); |
if ( noErr != anErr ) goto done; |
anErr = AEGetKeyPtr( &aRecordDesc, keyOSASourceStart, typeShortInteger, |
&aType, (Ptr)&errorStart, sizeof( errorStart ), &actSize ); |
if ( noErr != anErr ) goto done; |
anErr = AEGetKeyPtr( &aRecordDesc, keyOSASourceEnd, typeShortInteger, |
&aType, (Ptr)&errorEnd, sizeof( errorEnd ), &actSize ); |
if ( noErr != anErr ) goto done; |
aTextToken.tokenWindow = theDoc->theWindow; |
aTextToken.tokenOffset = errorStart + 1; |
aTextToken.tokenLength = errorEnd - errorStart; |
anErr = SelectTextToken( &aTextToken ); |
done: |
(void)AEDisposeDesc( &aRecordDesc ); |
return anErr; |
} |
OSErr AddPStrToResults( StringPtr theStringPtr ) |
{ |
AEDesc aTextDesc = { typeNull, NULL }; |
OSErr anErr; |
anErr = AECreateDesc( typeChar, (Ptr)&theStringPtr[1], theStringPtr[0], &aTextDesc ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &aTextDesc ); |
done: |
(void)AEDisposeDesc( &aTextDesc ); |
return anErr; |
} |
OSErr AddDescToResults( AEDesc* theDesc ) |
{ |
AEDesc aTextDesc = { typeNull, NULL }, |
aNullDesc = {typeNull, NULL}, |
aResultDesc = { typeNull, NULL }; |
TextToken aTextToken; |
long aCount, |
anIndex; |
DescType anAEKeyword; |
OSErr anErr; |
switch ( theDesc->descriptorType ) |
{ |
case typeNull: |
case typeScript: |
return noErr; |
case typeChar: |
case typeStyledText: |
case typeIntlText: |
anErr = AEDuplicateDesc( theDesc, &aTextDesc ); |
break; |
case typeObjectSpecifier: |
case cEventIdentifier: |
anErr = TextDescUsingOSADisplay( theDesc, &aTextDesc ); |
break; |
case typeAEList: |
anErr = AddPStrToResults( "\p{ " ); // Brackets to signify a list |
if ( noErr != anErr ) goto done; |
anErr = AECountItems( theDesc, &aCount ); |
if ( noErr != anErr ) goto done; |
for ( anIndex = 1; anIndex <= aCount; anIndex++ ) |
{ |
anErr = AEGetNthDesc( theDesc, anIndex, typeWildCard, &anAEKeyword, &aTextDesc ); |
if ( noErr != anErr ) goto done; |
// Call recursively - may even be another list |
anErr = AddDescToResults( &aTextDesc ); |
if ( noErr != anErr ) goto done; |
(void)AEDisposeDesc( &aTextDesc ); |
} |
anErr = AddPStrToResults( "\p }" ); |
goto done; // We have been through the list so no further descriptor to add |
case typeType: |
case typeEnumeration: |
anErr = AECoerceDesc( theDesc, typeChar, &aTextDesc ); |
if ( noErr != anErr ) goto done; // Add the OSType first |
anErr = AddPStrToResults( "\p'" ); |
if ( noErr != anErr ) goto done; |
anErr = AddDescToResults( &aTextDesc ); |
if ( noErr != anErr ) goto done; |
anErr = AddPStrToResults( "\p'" ); |
if ( noErr != anErr ) goto done; |
(void)AEDisposeDesc( &aTextDesc ); // We're using it again |
anErr = TextDescUsingOSADisplay( theDesc, &aTextDesc ); |
if ( noErr == anErr ) |
anErr = AddPStrToResults( "\p - " ); // Go on to display the terminology |
else |
{ // Couldn't get terminology |
anErr = noErr; // so make do with OSType. |
goto done; |
} |
break; |
default: // Apple Event Manager can coerce numbers and stuff |
anErr = AECoerceDesc( theDesc, typeChar, &aTextDesc ); |
} |
if ( noErr != anErr ) goto done; |
anErr = EndOfDocumentTextToken( GetResultsWindPtr( ), &aTextToken ); |
if ( noErr != anErr ) goto done; |
// Add text to end of results window |
anErr = CreateAtTextToken( cText, &aTextDesc, &aTextToken, &aNullDesc, &aResultDesc ); |
done: |
(void)AEDisposeDesc( &aTextDesc ); |
(void)AEDisposeDesc( &aResultDesc ); |
return anErr; |
} |
static OSErr EndOfDocumentTextToken( WindowPtr theWindow, TextToken* theToken ) |
{ |
DPtr aDoc = DPtrFromWindowPtr( theWindow ); |
if ( ! aDoc ) |
return errAEWrongDataType; |
theToken->tokenWindow = theWindow; |
theToken->tokenOffset = (**aDoc->theText).teLength + 1; |
theToken->tokenLength = 0; |
return noErr; |
} |
// Routine that takes a type descriptor and returns the text that is |
// used to describe the type in a script. |
// e.g. atypeType descriptor for 'docu' will return a text descriptor containing "document" |
OSAError TextDescUsingOSADisplay( AEDesc* theDesc, AEDesc* theResult ) |
{ |
OSAID aScriptID = kOSANullScript; |
OSAError anErr; |
// Convert from a descriptor to a script ID |
anErr = OSACoerceFromDesc( gScriptingComponent, theDesc, kOSAModeNull, &aScriptID ); |
if (noErr != anErr) goto done; |
// typeStyledText |
anErr = OSADisplay( gScriptingComponent, aScriptID, typeChar, kOSAModeNull, theResult ); |
done: // Clean up memory |
(void)OSADispose( gScriptingComponent, aScriptID ); |
return anErr; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14