home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-06-23 | 56.6 KB | 2,138 lines |
- // MSScript.c
- //
- // Original version by Jon Lansdell and Nigel Humphreys.
- // 4.0 and 3.1 updates by Greg Sutton.
- // Human Interface changes and GX Printing by Don Swatman
- // ©Apple Computer Inc 1996, all rights reserved.
-
-
- #include <Memory.h>
- #include <Resources.h>
- #include <TextEdit.h>
- #include <Controls.h>
- #include <Dialogs.h>
- #include <Errors.h>
- #include <Files.h>
- #include <Folders.h>
- #include <Components.h>
- #include <AppleEvents.h>
- #include <AppleScript.h>
- #include <AERegistry.h>
- #include <ASRegistry.h>
- #include <ASDebugging.h>
- #include <Processes.h>
-
- #include "MSScript.h"
-
- #include "MSUtils.h"
- #include "MSAEUtils.h"
- #include "MSAETextUtils.h"
- #include "MSAEMenuUtils.h"
- #include "MSWindow.h"
- #include "MSAESetData.h"
- #include "MSAEGetData.h"
- #include "MSResultWind.h"
- #include "MSAEDelete.h"
- #include "MSASSubroutines.h"
- #include "MSMain.h"
- #include "MSAEWindowUtils.h"
- #include "MSAERecording.h"
-
- /*
- Each menu (or menu item) can have a script associated with it. This
- script has an ID equal to 32 * theMenuID + theItem number. A script
- with an item number of 0 applies to the whole menu unless it is
- overridden by a particular script for an item in the menu.
-
- Scripts are stored in two resource types
- 'scpt' is a compiled script as returned by OSAStore()
- 'SCPT' is a raw text script as defined in the resource file
-
- At open application time scripts are built from the 'SCPT' resources
- if there are not any existing complied scripts of that resource ID.
- These are stored in the preferences file for the application.
-
- One problem with the scripted menu commands is that if the application
- name is changed the target is no longer found. This may be addressed later.
- */
-
-
- // Constants
- #define kMaxScriptsInApp 100
- #define kCompiledScriptType kOSAScriptResourceType
- #define kTextScriptType 'SCPT'
-
- const short kLaunchScriptID = 128;
- const short kApplicationScriptID = 200;
- const short kResultsScriptID = 300;
- const short kPleaseWaitStart = 1006;
- const short kPleaseWaitEnd = 1007;
-
- const short kEscapeKey = 27;
- const short kEndOfTextKey = 3;
-
- const short MenuScriptEditor = 400;
-
- const Str31 kPrefFileName = "\pMenuScripter Prefs";
-
- // Prototypes
- pascal OSErr MySendProc(const AppleEvent* theAppleEvent,
- AppleEvent* reply,
- AESendMode sendMode,
- AESendPriority sendPriority,
- long timeOutInTicks,
- AEIdleUPP idleProc,
- AEFilterUPP filterProc,
- long refCon);
- pascal OSErr StdActiveProc( long refCon );
-
- static OSAID GetScriptIDForResID( short lookForID );
- OSErr OpenPreferencesResourceFile(short *theRefNum);
- OSErr ClosePreferencesResourceFile( short theRefNum );
- void AddMenuScript( short theResID, OSAID theScriptID, Boolean fChanged );
- OSErr LoadApplicationScripts( void );
- OSErr StoreApplicationScripts( void );
- OSErr BuildMenuScripts( void );
- OSErr StoreMenuScripts( void );
- Boolean ScriptHasProperties( OSAID theScriptID );
- static void SetUpUniversalProcedures( void );
- static DialogPtr PoseWaitDialog( short theDialogID );
- void DisplayErrorInScript( TEHandle theHTE );
-
- pascal void DrawGrowBoxItem( DialogPtr theDialog, short theItem );
- pascal void DrawStyledTextEditRec( DialogPtr theDialog, short theItem );
- pascal void DrawScrollBar( DialogPtr theDialog, short theItem );
- pascal void ScrollVActionProc( ControlHandle control, short part );
- pascal Boolean MyFilterProc( DialogPtr theDialog, EventRecord *myEvent, short *itemHit );
-
- void MoveCustTextEditItem( DialogPtr theDialog, short theItem,
- short deltaW, short deltaH );
- void MoveScrollBarItem( DialogPtr theDialog, short theItem,
- short deltaW, short deltaH );
- void MoveOneDialogControlItem( DialogPtr theDialog, short theItem,
- short deltaW, short deltaH );
- void MoveOneDialogItem( DialogPtr theDialog, short theItem,
- short deltaW, short deltaH );
-
-
- void SetDrawProcForUserItem( DialogPtr theDialog,
- short theItem, ControlActionUPP theProc );
- void FlashButton( DialogPtr theDialog, short theItem );
- void TrackTEPosn( ControlHandle theControl, TEHandle theHTE );
- void SetScrollLimit( ControlHandle newScroll, TEHandle theHTE );
- Boolean DoDialogMenu ( long menuResult, TEHandle theTE );
-
- OSErr SetMenuScript( short theResID, OSAID theScriptID );
- void SetMenuForDialog( void );
- void ReSetMenuForDialog( void );
-
- pascal OSErr EventPrehandler( AppleEvent *theEvent, AppleEvent *theReply, long theRefcon );
- Boolean CanScriptEvent( AEEventClass theClass, AEEventID theID, AppleEvent* theEvent );
- void AddMissingParameter( AEKeyword theAEKeyword, DescType theType,
- Ptr theData, Size theDataSize, AppleEvent* theEvent );
- OSErr DoScriptEvent( AppleEvent *theEvent,
- AppleEvent *theReply,
- OSAID theScriptID );
- static OSErr GetTokenDescScript( AEDesc* theTokenDesc, OSAID* theOSAID );
-
- // Globals
- extern short gRefNum;
-
- ComponentInstance gScriptingComponent;
- short gActiveMenuItem;
- OSASendUPP oldSendProc;
- long refCon;
- MenuScriptRecPtr gMenuScripts;
- short gNumScripts;
- short gPrefsRefFile;
- OSAActiveUPP gOSAActiveUPP;
- Boolean gEditingScript; // Is the script editing dialog up?
-
- ControlActionUPP gScrollScriptVActionUPP;
- ControlActionUPP gDrawStyledTextUPP;
- ControlActionUPP gDrawScrollBarUPP;
- ControlActionUPP gDrawGrowBoxUPP;
-
-
- // These are used in documentation but not defined in the interfaces
-
- #ifndef kComponentNotFound
- #define kComponentNotFound -1
- #endif
-
-
- pascal OSErr MySendProc(const AppleEvent* theAppleEvent,
- AppleEvent* reply,
- AESendMode sendMode,
- AESendPriority sendPriority,
- long timeOutInTicks,
- AEIdleUPP idleProc,
- AEFilterUPP filterProc,
- long refCon)
- {
- #ifdef __MWERKS__
- #pragma unused(refCon)
- #endif
-
- DescType typeCode;
- Size descSize;
- OSErr myErr;
- OSErr ignoreErr;
- OSType whatEvent;
- AppleEvent myCopyAEvt;
-
- myErr = AEDuplicateDesc( theAppleEvent, &myCopyAEvt );
-
- myErr = AEGetAttributePtr(&myCopyAEvt, keyEventIDAttr, typeType, &typeCode,
- (Ptr)&whatEvent, sizeof(whatEvent), &descSize );
-
- ignoreErr = AEDisposeDesc( &myCopyAEvt );
-
- if (myErr != noErr) whatEvent = 0x3F3F3F3F;
-
- // Record the final Set Data that occurs due to a script
- // 'gdte' = id sent to get 'aete' resource from app, dealt with
- // by system handler.
-
- if ( ( sendMode & kAEDontRecord ) &&
- ( ( whatEvent != kAEGetData ) && ( whatEvent != kGetAETE ) ) )
- sendMode = sendMode - kAEDontRecord;
-
- /* will be this when a5 bug fixed // =Jon=
- return((*oldSendProc)(theAppleEvent,
- reply,
- sendMode,
- sendPriority,
- timeOutInTicks,
- idleProc,
- filterProc,
- refCon));
- */
-
- return( AESend( theAppleEvent, reply, sendMode, sendPriority,
- timeOutInTicks, idleProc, filterProc ) );
- } // MySendProc
-
-
- // Our activeProc is called at various times during script execution and compilation
- // we use this to detect when the application is being sent to the background. This can happen
- // when a script is targetted to another application, causing this application to be
- // brought to the front. Since HiliteMenu(0) is called when the menu command has completed - and
- // this will be called when the script has completed, we must ensure that the application is
- // in the foreground when HiliteMenu is called. Otherwise the menu bar gets drawn over the frontmost
- // application, which is not what we want.
-
- pascal OSErr StdActiveProc( long refCon )
- {
- #ifdef __MWERKS__
- #pragma unused(refCon)
- #endif
-
- // Call WaitnextEvent() to get suspend event
- EventRecord myEvent;
-
- if ( ! gEditingScript )
- {
- if ( WaitNextEvent( everyEvent, &myEvent, 0, NULL ) )
- {
- switch ( myEvent.what )
- {
- case osEvt:
- HiliteMenu( 0 );// Don't call HiliteMenu in the background
- // so clear it before we switch to the background
-
- if ( ( myEvent.message >> 24 ) & suspendResumeMessage ) // suspend or resume
- {
- gInBackground = ( ( myEvent.message & resumeFlag ) == 0);
- DoActivate( FrontWindow( ), ! gInBackground );
- }
- break;
- }
- }
- }
-
- // Now call the standard ActiveProc
- return ( CallOSAActiveProc( gOSAActiveUPP,0 ) );
- }
-
-
- static OSAID GetScriptIDForResID( short lookForID )
- {
- short index;
-
- for ( index = 0; index < gNumScripts; index++ )
- {
- if ( gMenuScripts[index].theResID == lookForID )
- return gMenuScripts[index].theScriptID;
- }
-
- return kOSANullScript;
- }
-
- MenuScriptRecPtr GetMenuScriptRecPtr( short theResID )
- {
- short index;
-
- for ( index = 0; index < gNumScripts; index++ )
- {
- if ( gMenuScripts[index].theResID == theResID )
- return &gMenuScripts[index];
- }
-
- return NULL;
- }
-
-
- // Name : OpenPreferencesResourceFile
- // Purpose : Opens the prefs file, in the system prefs folder
- // creating it if it is not found. Sets the current
- // resource file to the prefs file so that resources
- // will be read from there in preference to the app
- // if they have been overridden, and new resources
- // will be created in it.
-
- OSErr OpenPreferencesResourceFile(short *theRefNum)
- {
- short foundVRefNum;
- long foundDirID;
- OSErr myErr;
-
- myErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
- &foundVRefNum, &foundDirID);
-
- if (myErr==noErr)
- {
-
- *theRefNum = HOpenResFile(foundVRefNum, foundDirID, kPrefFileName, fsWrPerm);
- myErr = ResError();
-
- if (myErr==fnfErr)
- {
- HCreateResFile(foundVRefNum, foundDirID, kPrefFileName);
- myErr = ResError();
-
- *theRefNum = HOpenResFile(foundVRefNum, foundDirID, kPrefFileName, fsWrPerm);
- myErr = ResError();
- }
- }
-
- return(myErr);
- }
-
- OSErr ClosePreferencesResourceFile( short theRefNum )
- {
- CloseResFile( theRefNum );
- return( ResError( ) );
- }
-
-
- // Name : AddMenuScript
- // Purpose : Adds a compiled script OSAID into the
- // global gMenuScripts array for later access
-
- void AddMenuScript( short theResID, OSAID theScriptID, Boolean fChanged )
- {
- if ( gNumScripts < kMaxScriptsInApp )
- {
- gMenuScripts[gNumScripts].theResID = theResID;
- gMenuScripts[gNumScripts].theScriptID = theScriptID;
- gMenuScripts[gNumScripts].fChanged = fChanged;
- gNumScripts++;
-
- (void)CheckForMenuItemName( theResID, theScriptID );
- }
- }
-
-
- // Name : BuildMenuScripts
- // Purpose : Reads compiled scripts from the prefs file,
- // Any uncompiled scripts ('SCPT' resources with
- // no 'scpt' of same id are compiled. Any which fail
- // to compile are ignored. Changed scripts are stored
- // in the preferences file on quit.
-
- OSErr BuildMenuScripts( void )
- {
- short aScriptCount,
- index,
- anID;
- ResType aResType;
- Str255 aResName;
- Handle aScript;
- AEDesc aScriptDesc = { typeNull, NULL };
- OSAID aScriptID = kOSANullScript;
- OSErr anErr;
-
- gNumScripts = 0;
-
- gMenuScripts = (MenuScriptRecord *)NewPtr( sizeof( MenuScriptRecord ) * kMaxScriptsInApp );
-
- // Firstly load all the 'scpt' scripts stored in the preferences file,
- // these scripts may be customised by the user.
- aScriptCount = Count1Resources( kCompiledScriptType );
- for ( index = 1 ; index <= aScriptCount ; index++ )
- {
- aScript = Get1IndResource( kCompiledScriptType, index );
- GetResInfo( aScript, &anID, &aResType, aResName );
- anErr = ResError( );
- if ( noErr != anErr ) goto done;
-
- HLock( aScript );
- anErr = AECreateDesc( typeOSAGenericStorage, (Ptr)*aScript,
- GetHandleSize( aScript ), &aScriptDesc );
- HUnlock( aScript );
- ReleaseResource( aScript );
- if ( noErr != anErr ) goto done; // This shouldn't happen
-
- aScriptID = kOSANullScript;
- anErr = OSALoad( gScriptingComponent, &aScriptDesc, kOSAModeNull, &aScriptID );
-
- if ( noErr == anErr )
- AddMenuScript( anID, aScriptID, false );
-
- (void)AEDisposeDesc( &aScriptDesc );
- }
-
- // Next load and compile any of the text based scripts, 'SCPT', that
- // have no equivalent 'scpt' in the preferences file.
- aScriptCount = CountResources( kTextScriptType );
- for ( index = 1; index <= aScriptCount; index++ )
- {
- aScript = GetIndResource( kTextScriptType, index );
- GetResInfo( aScript, &anID, &aResType, aResName );
- anErr = ResError( );
- if ( noErr != anErr ) goto done;
-
- if ( GetScriptIDForResID( anID ) == kOSANullScript )
- {
- // Stored as a C string so knock off NULL terninator
- HLock( aScript );
- anErr = AECreateDesc( typeChar, (Ptr)*aScript,
- GetHandleSize( aScript ) - 1, &aScriptDesc );
- HUnlock( aScript );
- ReleaseResource( aScript );
- if ( noErr != anErr ) goto done; // This shouldn't happen
-
- aScriptID = kOSANullScript;
- anErr = OSACompile( gScriptingComponent, &aScriptDesc,
- kOSAModeCompileIntoContext, &aScriptID );
-
- if ( noErr == anErr )
- AddMenuScript( anID, aScriptID, true ); // We need to save this script
- // so set fChanged to true.
- (void)AEDisposeDesc( &aScriptDesc );
- }
- }
-
- done:
- return anErr;
- }
-
- // This checks to see if a script contains
- // properties. These could change in the script and therefore
- // the script needs to be stored for the next
- // time the application is launched.
-
- Boolean ScriptHasProperties( OSAID theScriptID )
- {
- AEDescList resultingPropertyNames = { typeNull, NULL };
- long aCount = 0;
- OSErr anErr;
- Boolean aResult = true;
-
- // OSAGetPropertyNames() returns typeChar descriptors of
- // all the properties in a script.
- anErr = OSAGetPropertyNames( gScriptingComponent, kOSAModeNull,
- theScriptID, &resultingPropertyNames );
-
- if ( noErr != anErr )
- {
- aResult = false;
- goto done;
- }
-
- anErr = AECountItems( &resultingPropertyNames, &aCount );
-
- if ( noErr != anErr || aCount == 0 )
- aResult = false;
-
- done:
- (void)AEDisposeDesc( &resultingPropertyNames );
-
- return aResult;
- }
-
- OSErr StoreMenuScripts( void )
- {
- short index;
- OSErr anErr;
-
- for ( index = 0; index < gNumScripts; index++ )
- {
- // If there are properties or it
- // has changed then store the script
- if ( gMenuScripts[index].fChanged
- || ScriptHasProperties( gMenuScripts[index].theScriptID ) )
- {
- anErr = StoreScriptToResFileRef( gPrefsRefFile, gMenuScripts[index].theResID,
- gMenuScripts[index].theScriptID, "\p" );
- }
- }
-
- return anErr;
- }
-
-
- OSErr LoadApplicationScripts( void )
- {
- OSAID aScriptID = kOSANullScript,
- aResultID = kOSANullScript;
- DPtr aDoc;
- OSErr anErr;
-
- OpenPreferencesResourceFile( &gPrefsRefFile );
-
- gMenuScripts = NULL;
- anErr = BuildMenuScripts( );
- if ( noErr != anErr ) goto done;
-
- // Get the current application scipt from the prefs file.
- // If there isn't one then the launch script can set one.
- anErr = LoadScriptFromResFileRef( gPrefsRefFile,
- kApplicationScriptID, &gAppRec.theScriptID );
-
- // Load the results window script too.
- aDoc = GetResultsDoc( );
- if ( aDoc )
- anErr = LoadScriptFromResFileRef( gPrefsRefFile,
- kResultsScriptID, &aDoc->theScriptID );
-
- // The application script property is set by executing the
- // application script - current script checks to see
- // if there is already a script - from prefs file.
- anErr = LoadScriptFromResFileRef( gRefNum, kLaunchScriptID, &aScriptID );
- if ( noErr != anErr ) goto done;
-
- anErr = OSAExecute( gScriptingComponent, aScriptID, kOSANullScript,
- kOSAModeAlwaysInteract, &aResultID );
-
- done:
- (void)OSADispose( gScriptingComponent, aScriptID );
- (void)OSADispose( gScriptingComponent, aResultID );
-
- return anErr;
- }
-
-
- OSErr StoreApplicationScripts( void )
- {
- DPtr aDoc;
- OSErr anErr;
-
- anErr = StoreMenuScripts( );
- if ( noErr != anErr ) goto done;
-
- // Store any changes to the applications script
- anErr = StoreScriptToResFileRef( gPrefsRefFile, kApplicationScriptID,
- gAppRec.theScriptID, "\pApplicationScript" );
-
- // Store any changes to the results document script
- aDoc = GetResultsDoc( );
- if ( aDoc )
- anErr = StoreScriptToResFileRef( gPrefsRefFile, kResultsScriptID,
- aDoc->theScriptID, "\pResultsScript" );
-
- ClosePreferencesResourceFile( gPrefsRefFile );
-
- done:
- return anErr;
- }
-
-
- static void SetUpUniversalProcedures( void )
- {
- gScrollScriptVActionUPP = NewControlActionProc( ScrollVActionProc );
- gDrawStyledTextUPP = NewControlActionProc( DrawStyledTextEditRec );
- gDrawScrollBarUPP = NewControlActionProc( DrawScrollBar );
- gDrawGrowBoxUPP = NewControlActionProc( DrawGrowBoxItem );
- }
-
-
- static DialogPtr PoseWaitDialog( short theDialogID )
- {
- DialogPtr progressDialog;
-
- // pose a dialog indicating that we are connecting
- // to the AppleScript component.
- progressDialog = GetNewDialog( theDialogID, NULL, (WindowPtr)-1 );
- SetPort( progressDialog );
- DrawDialog( progressDialog );
- return progressDialog;
- }
-
- // Name: InitEditorScripting
- // Purpose:Connects to the AppleScript component.
-
- OSErr InitEditorScripting( void )
- {
- GrafPtr oldPort;
- DialogPtr progressDialog;
- OSAError err = 0;
- ComponentDescription descr;
- Component aComponent;
- ComponentInstance aScriptingComponent;
-
- GetPort( &oldPort );
- progressDialog = PoseWaitDialog( kPleaseWaitStart );
-
- SetUpUniversalProcedures( );
- gEditingScript = false;
-
- descr.componentType = kOSAComponentType;
- descr.componentSubType = (OSType) 0;
- descr.componentManufacturer = (OSType) 0;
- descr.componentFlags = kOSASupportsCompiling +
- kOSASupportsGetSource +
- kOSASupportsAECoercion +
- kOSASupportsAESending +
- kOSASupportsRecording +
- kOSASupportsConvenience +
- kOSASupportsEventHandling;
- descr.componentFlagsMask = descr.componentFlags;
-
- aComponent = FindNextComponent( NULL, &descr );
-
- if ( ! aComponent )
- {
- err = kComponentNotFound;
- goto done;
- }
- else
- {
- aScriptingComponent = OpenComponent( aComponent );
-
- if (! aScriptingComponent)
- {
- err = kComponentNotFound;
- goto done;
- }
- }
-
- gScriptingComponent = aScriptingComponent;
-
-
- err = OSAGetSendProc( gScriptingComponent, &oldSendProc, &refCon );
- if ( noErr != err ) goto done;
-
- err = OSASetSendProc( gScriptingComponent, NewOSASendProc( MySendProc ), 0 );
- if ( noErr != err ) goto done;
-
- err = AEInstallSpecialHandler( keyPreDispatch, (UniversalProcPtr)NewAEEventHandlerProc( EventPrehandler ), false );
- if ( noErr != err ) goto done;
-
- err = LoadApplicationScripts( );
-
- done:
- DisposeDialog( progressDialog );
- SetPort( oldPort );
-
- return err;
- }
-
-
- OSErr SetOSAActiveProcedure(void)
- {
- OSErr err;
- long theRefCon;
-
- // store the old active proc in order to call this from ours
- err = OSAGetActiveProc( gScriptingComponent, &gOSAActiveUPP, &theRefCon );
-
- return( OSASetActiveProc( gScriptingComponent, NewOSAActiveProc( StdActiveProc ), 0 ) );
- }
-
-
- // Name : CloseEditorScripting
- // Purpose : Shutdown of editor scripting capabilities
-
- OSErr CloseEditorScripting( void )
- {
- GrafPtr oldPort;
- DialogPtr progressDialog;
- short index;
- OSErr err;
-
- GetPort( &oldPort );
- progressDialog = PoseWaitDialog( kPleaseWaitEnd );
-
- StoreApplicationScripts( );
-
- for ( index = 0; index < gNumScripts; index++ )
- err = OSADispose( gScriptingComponent, gMenuScripts[index].theScriptID );
-
- err = CloseComponent( gScriptingComponent );
-
- DisposeDialog( progressDialog );
- SetPort( oldPort );
-
- return err;
- }
-
-
-
- // Name: DisplayErrorInScript
- // Purpose: Put up an alert showing the error text for the last error.
- // Also selects the responsible text in theHTE if one is supplied
-
- void DisplayErrorInScript( TEHandle theHTE )
- {
- Str255 errorMessageText;
- AEDesc errRangeDesc;
- AEDesc errRecordDesc;
- AEDesc errTextDesc;
- AEDesc errNumberDesc;
- DescType typeCode;
- Size actSize;
- OSErr myErr;
- OSErr ignoreErr;
- OSErr errorNumber;
- short errorStart;
- short errorEnd;
-
- SetCursor(&qd.arrow);
-
- myErr = OSAScriptError(gScriptingComponent, kOSAErrorNumber,
- typeShortInteger, &errNumberDesc);
-
- myErr = GetIntegerFromDescriptor(&errNumberDesc, &errorNumber);
-
- ignoreErr = AEDisposeDesc(&errNumberDesc);
-
- myErr = OSAScriptError(gScriptingComponent, kOSAErrorMessage,
- typeChar, &errTextDesc);
-
- myErr = GetPStringFromDescriptor( &errTextDesc, errorMessageText );
-
- ignoreErr = AEDisposeDesc(&errTextDesc);
-
- if (theHTE)
- {
- myErr = OSAScriptError(gScriptingComponent, kOSAErrorRange,
- typeOSAErrorRange, &errRangeDesc);
-
- myErr = AECoerceDesc(&errRangeDesc, typeAERecord, &errRecordDesc);
-
- ignoreErr = AEDisposeDesc(&errRangeDesc);
-
- myErr = AEGetKeyPtr(&errRecordDesc, keyOSASourceStart, typeShortInteger,
- &typeCode, (Ptr)&errorStart, sizeof(errorStart), &actSize);
-
- myErr = AEGetKeyPtr(&errRecordDesc, keyOSASourceEnd, typeShortInteger,
- &typeCode, (Ptr)&errorEnd, sizeof(errorEnd), &actSize);
-
- ignoreErr = AEDisposeDesc(&errRecordDesc);
-
- TESetSelect(errorStart, errorEnd, theHTE);
- }
-
- ShowError(errorMessageText, errorNumber);
- }
-
-
- // Name : CompileDocument
- // Purpose : Compiles the text of the supplied document - does NOT keep
- // a compiled version - merely checks that it will compile for now
-
- OSErr CompileDocument( DPtr theDoc )
- {
- WindowPropToken aToken;
- AEDesc aTextDesc = { typeNull, NULL },
- aCompiledDesc = { typeNull, NULL },
- aNullDesc = { typeNull, NULL };
- OSAID aScriptID = kOSANullScript;
- OSErr anErr;
-
- aToken.tokenWindowToken.tokenWindow = theDoc->theWindow;
- aToken.tokenProperty = pText; // All of the text in document
- anErr = GetDocumentTokenProperty( &aToken, typeWildCard, &aTextDesc );
- if ( noErr != anErr ) goto done;
-
- anErr = OSACompile( gScriptingComponent, &aTextDesc,
- kOSAModeCompileIntoContext, &aScriptID );
- if ( noErr != anErr ) goto done;
-
- anErr = OSAGetSource( gScriptingComponent, aScriptID,
- typeStyledText, &aCompiledDesc );
- if ( noErr != anErr ) goto done;
-
- anErr = DisplayDescResult( theDoc->theWindow, &aCompiledDesc, NULL, noErr );
-
- done:
- (void)DisplayDescResult( GetResultsWindPtr( ), &aNullDesc, theDoc, anErr );
-
- (void)OSADispose( gScriptingComponent, aScriptID );
- (void)AEDisposeDesc( &aTextDesc );
- (void)AEDisposeDesc( &aCompiledDesc );
-
- return anErr;
- }
-
-
- // Name : ExecuteDocument
- // Purpose : Compiles the text of the supplied document and then executes it
- // - does NOT keep a compiled version after execution
-
- OSErr ExecuteDocument( DPtr theDoc )
- {
- WindowPropToken aToken;
- AEDesc aTextDesc = { typeNull, NULL },
- aCompiledDesc = { typeNull, NULL };
- OSAID aScriptID = kOSANullScript,
- aResultID = kOSANullScript;
- OSErr anErr;
-
- aToken.tokenWindowToken.tokenWindow = theDoc->theWindow;
- aToken.tokenProperty = pText; // All of the text in document
- anErr = GetDocumentTokenProperty( &aToken, typeWildCard, &aTextDesc );
- if ( noErr != anErr ) goto done;
-
- anErr = OSACompile( gScriptingComponent, &aTextDesc, kOSAModeCompileIntoContext, &aScriptID );
- if ( noErr != anErr ) goto done;
-
- // Set the compiled text first, before executing
- anErr = OSAGetSource( gScriptingComponent, aScriptID,
- typeStyledText, &aCompiledDesc );
- if ( noErr != anErr ) goto done;
-
- anErr = DisplayDescResult( theDoc->theWindow, &aCompiledDesc, NULL, noErr );
- if ( noErr != anErr ) goto done;
-
- anErr = OSAExecute( gScriptingComponent, aScriptID,
- kOSANullScript, kOSAModeNull, &aResultID );
-
- done:
- // If aResultID is kOSANullScript then clear the window
- (void)DisplayOSAIDResult( GetResultsWindPtr( ), aResultID, theDoc, anErr );
-
- (void)OSADispose( gScriptingComponent, aScriptID );
- (void)OSADispose( gScriptingComponent, aResultID );
- (void)AEDisposeDesc( &aTextDesc );
- (void)AEDisposeDesc( &aCompiledDesc );
-
- return anErr;
- }
-
-
- // Name : ScriptForMenuExists
- // Purpose: Tests for the existance of a valid script for a given menu item
-
- OSErr ScriptForMenuExists(short theMenu, short theItem, Boolean *exists)
- {
- short resID;
- OSAID myScriptID;
- OSErr myErr;
-
- myErr = noErr;
-
- resID = (theMenu<<5) + theItem;
-
- myScriptID = GetScriptIDForResID(resID);
-
- if (myScriptID==kOSANullScript)
- {
- if (theItem!=0)
- myErr = ScriptForMenuExists(theMenu, 0, exists);
- else
- *exists = false;
- }
- else
- *exists = true;
-
- return myErr;
- } // ScriptForMenuExists
-
-
- // Name : ExecuteScriptForMenu
- // Purpose: Executes a script associated with the menu item.
- // Should be called only after ScriptForMenuExists
- // returns exists.
-
- OSErr ExecuteScriptForMenu( short theMenu, short theItem )
- {
- short resID;
- OSAID aScriptID,
- aResultID = kOSANullScript;
- OSErr err;
-
- resID = ( theMenu << 5 ) + theItem;
-
- aScriptID = GetScriptIDForResID( resID );
-
- if ( aScriptID == kOSANullScript )
- {
- resID = ( theMenu << 5 ); // look for a script for the whole menu - item 0
- aScriptID = GetScriptIDForResID( resID );
- }
-
- if ( aScriptID != kOSANullScript )
- {
- gActiveMenuItem = theItem;
-
- err = OSAExecute( gScriptingComponent, aScriptID,
- kOSANullScript, 0, &aResultID );
-
- (void)DisplayOSAIDResult( GetResultsWindPtr( ), aResultID, NULL, err );
-
- gActiveMenuItem = 0;
- }
-
- done:
- (void)OSADispose( gScriptingComponent, aResultID );
-
- return err;
- }
-
-
- // Name : GetScriptActiveItem
- // Purpose : Used by SVAppleEvents for the active item property of a menu.
- // Allows a script associated with more than one menu item to
- // find which menu item it was called by.
-
- short GetScriptActiveItem( void )
- {
- return gActiveMenuItem;
- }
-
-
-
- // Routines used in the StyledTextEdit Dialog Item
-
- struct StyleTextInfo
- {
- ControlHandle theScrollBar;
- TEHandle theTEHandle;
- };
- typedef struct StyleTextInfo StyleTextInfo;
- typedef StyleTextInfo *pStyleTextInfo;
-
-
- pascal void DrawGrowBoxItem( DialogPtr theDialog, short theItem )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
- PlotIconID (&itemRect, atBottomRight, ttNone, 400);
- }
-
- pascal void DrawStyledTextEditRec( DialogPtr theDialog, short theItem )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
- FrameRect(&itemRect);
- InsetRect(&itemRect, 5, 5);
-
- TEUpdate(&itemRect, ((pStyleTextInfo) GetWRefCon(theDialog))->theTEHandle);
- }
-
- pascal void DrawScrollBar( DialogPtr theDialog, short theItem )
- {
- #ifdef __MWERKS__
- #pragma unused(theItem)
- #endif
-
- Draw1Control(((pStyleTextInfo) GetWRefCon(theDialog))->theScrollBar);
- }
-
-
- // Name: SetDrawProcForUserItem
- // Purpose: Installs a procedure that will be called when theItem needs
- // to be drawn.
-
- void SetDrawProcForUserItem( DialogPtr theDialog, short theItem, ControlActionUPP theProc )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
- SetDItem(theDialog, theItem, theType, (Handle)theProc, &itemRect);
- }
-
-
- // Name: FlashButton
- // Purpose: Provide visual effect of button having been
- // selected.
-
- void FlashButton( DialogPtr theDialog, short theItem )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
-
- HiliteControl((ControlHandle)theHandle, inButton);
- HiliteControl((ControlHandle)theHandle, 0);
- }
-
-
- // Name: ScrollVActionProc
- // Purpose: Called as scrollbar is tracked in buttons or page up/down.
- // Keeps text in sync with scrollBar
-
- pascal void ScrollVActionProc( ControlHandle control, short part )
- {
- short amount;
- short initialValue;
-
- if ( part )
- {
- switch ( part )
- {
- case inUpButton:
- case inDownButton:
- amount = 24;
- break;
- case inPageUp:
- case inPageDown:
- amount = (**control).contrlRect.bottom - (**control).contrlRect.top;
- break;
- }
-
- if ( part == inUpButton || part == inPageUp )
- amount = -amount; // reverse direction
-
- initialValue = GetCtlValue( control );
-
- SetCtlValue( control, initialValue+amount ); // Pinned within Min/Max automatically
-
- amount = GetCtlValue( control ) - initialValue;
-
- if (amount)
- TEScroll(0, -amount,
- ((pStyleTextInfo)GetWRefCon((**control).contrlOwner))->theTEHandle);
- }
- } // ScrollVActionProc
-
-
- // Name: TrackTEPosn
- // Purpose: Ensures that the scrollbar value matches the position
- // of the text edit record.
-
- void TrackTEPosn( ControlHandle theControl, TEHandle theHTE )
- {
- short shouldBe;
-
- shouldBe = (**theHTE).viewRect.top - (**theHTE).destRect.top;
-
- if ( GetCtlValue( theControl ) != shouldBe )
- SetCtlValue( theControl, shouldBe );
- }
-
-
- // Name: SetScrollLimit
- // Purpose: Ensures that the maximum value of the scrollbar is sufficient
- // to allow showing of all text, and no more.
-
- void SetScrollLimit( ControlHandle newScroll, TEHandle theHTE )
- {
- Point teLimit;
- short currentMax;
- short currentValue;
- TextStyle theStyle;
- short lineHeight;
- short fontAscent;
-
- currentMax = GetCtlMax(newScroll);
-
- // Scroll max should be position of bottom of bottom line when unscrolled
- // This is equal to
- // The position of the bottom line relative to current position +
- // The amount currently scrolled -
- // The height of the visible part
-
- teLimit = TEGetPoint((**theHTE).teLength, theHTE); // Position of bottom relative to current posn
-
- TEGetStyle((**theHTE).teLength, &theStyle, &lineHeight, &fontAscent,theHTE);
- teLimit.v += lineHeight-fontAscent; // Add in for descent - TEGetPoint is posn of baseline not bottom of chars
-
- teLimit.v += ((**theHTE).viewRect.top -(**theHTE).destRect.top); // Amount already scrolled
-
- teLimit.v -= ((**theHTE).viewRect.bottom - (**theHTE).viewRect.top); // Height of page
-
- if (teLimit.v<0) // Cannot be negative
- teLimit.v = 0;
-
- if ( currentMax > teLimit.v )
- {
- currentValue = GetCtlValue( newScroll );
-
- if ( currentValue > teLimit.v )
- {
- TEScroll( 0, currentValue - teLimit.v, theHTE );
- SetCtlValue( newScroll, teLimit.v );
- }
-
- SetCtlMax( newScroll, teLimit.v );
- }
-
- if ( currentMax < teLimit.v )
- SetCtlMax( newScroll, teLimit.v );
- }
-
- #define kCompile 3
- #define kTextItem 4
- #define kScrollBar 5
- #define kGrowBox 6
-
- Boolean DoDialogMenu( long menuResult, TEHandle theTE )
- {
- short theItem;
- short theMenuID;
- Boolean hasHandled = false;
-
- theItem = LoWord( menuResult );
- theMenuID = HiWord( menuResult );
-
- switch ( theMenuID )
- {
- case editID:
- switch (theItem)
- {
- case cutCommand:
- TECut ( theTE );
- hasHandled = true;
- break;
-
- case copyCommand:
- TECopy ( theTE );
- hasHandled = true;
- break;
-
- case pasteCommand:
- {
- TEStylePaste ( theTE );
- hasHandled = true;
- break;
- }
- case clearCommand:
- TEDelete ( theTE );
- hasHandled = true;
- break;
-
- case selectAllCommand:
- TESetSelect(0, kMaxTELength, theTE);
- hasHandled = true;
- break;
- }
-
- break;
- }
- return hasHandled;
- }
-
- void MoveOneDialogItem ( DialogPtr theDialog,
- short theItem,
- short deltaW,
- short deltaH )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
- OffsetRect ( &itemRect, deltaW, deltaH);
- SetDItem(theDialog, theItem, theType, theHandle, &itemRect);
- }
-
- void MoveOneDialogControlItem( DialogPtr theDialog,
- short theItem,
- short deltaW,
- short deltaH )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
- OffsetRect ( &itemRect, deltaW, deltaH);
- SetDItem(theDialog, theItem, theType, theHandle, &itemRect);
-
- MoveControl ( (ControlHandle)theHandle,
- (**(ControlHandle)theHandle).contrlRect.left + deltaW,
- (**(ControlHandle)theHandle).contrlRect.top + deltaH);
- }
-
- void MoveScrollBarItem( DialogPtr theDialog,
- short theItem,
- short deltaW,
- short deltaH )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
- Rect controlRect;
- ControlHandle hTheControl;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
-
- itemRect.left = itemRect.left + deltaW;
- itemRect.right = itemRect.right + deltaW;
- itemRect.bottom = itemRect.bottom + deltaH;
-
- SetDItem(theDialog, theItem, theType, theHandle, &itemRect);
-
- hTheControl = ((pStyleTextInfo) GetWRefCon(theDialog))->theScrollBar;
- controlRect = (**hTheControl).contrlRect;
- HideControl ( hTheControl );
- SizeControl ( hTheControl,
- controlRect.right - controlRect.left,
- deltaH + controlRect.bottom - controlRect.top );
- MoveControl ( hTheControl,
- controlRect.left + deltaW,
- controlRect.top );
- ShowControl ( hTheControl );
- }
-
- void MoveCustTextEditItem( DialogPtr theDialog,
- short theItem,
- short deltaW,
- short deltaH )
- {
- short theType;
- Handle theHandle;
- Rect itemRect;
- TEHandle theTEHandle;
-
- GetDItem(theDialog, theItem, &theType, &theHandle, &itemRect);
-
- itemRect.right = itemRect.right + deltaW;
- itemRect.bottom = itemRect.bottom + deltaH;
- SetDItem(theDialog, theItem, theType, theHandle, &itemRect);
-
- theTEHandle = ((pStyleTextInfo) GetWRefCon(theDialog))->theTEHandle;
- (**theTEHandle).destRect.right = (**theTEHandle).destRect.right + deltaW;
- (**theTEHandle).destRect.bottom = (**theTEHandle).destRect.bottom + deltaH;
- (**theTEHandle).viewRect.right = (**theTEHandle).viewRect.right + deltaW;
- (**theTEHandle).viewRect.bottom = (**theTEHandle).viewRect.bottom + deltaH;
- }
-
-
- pascal Boolean MyFilterProc( DialogPtr theDialog, EventRecord *myEvent, short *itemHit )
- {
- short myPart;
- WindowPtr whichWindow;
- TEHandle newTE;
- Boolean extend;
- GrafPtr oldPort;
- Point mousePt;
- char myKey;
- Boolean returnVal;
- long menuResult;
- Rect teItemRect;
- Rect scrollItemRect;
- Rect growItemRect;
- ControlHandle newScroll;
- ControlHandle theControl;
- short part;
- short value;
- short cntlCode;
- Rect growBounds;
- long newRectSize;
- short deltaW;
- short deltaH;
- SFTypeList myTypes = {'TEXT'};
- #ifdef THINK_C
- ModalFilterUPP standardProc;
- #endif
-
- GetPort(&oldPort);
-
- returnVal = false;
-
- newTE = ((pStyleTextInfo)GetWRefCon(theDialog))->theTEHandle;
- newScroll = ((pStyleTextInfo)GetWRefCon(theDialog))->theScrollBar;
-
- TEIdle(newTE);
-
- // Maintain the cursor
-
- SetPort(theDialog);
- GetMouse(&mousePt);
-
- GetRectOfDialogItem(theDialog, kTextItem, &teItemRect);
- GetRectOfDialogItem(theDialog, kScrollBar, &scrollItemRect);
- GetRectOfDialogItem(theDialog, kGrowBox, &growItemRect);
-
- if (PtInRect(mousePt, &teItemRect))
- SetCursor(&editCursor);
- else
- SetCursor(&qd.arrow);
-
- switch (myEvent->what)
- {
- case mouseDown:
- myPart = FindWindow(myEvent->where, &whichWindow);
-
- if ( ( whichWindow != theDialog ) && ( myPart != inMenuBar ) )
- break;
-
- switch (myPart)
- {
- case inContent:
- case inGrow:
- SetPort(whichWindow);
- mousePt = myEvent->where;
- GlobalToLocal(&mousePt);
-
- extend = ((myEvent->modifiers & shiftKey) != 0);
- if ( PtInRect( mousePt, &(*(newTE))->viewRect ) )
- {
- TEClick(mousePt, extend, newTE);
- TrackTEPosn(newScroll, newTE);
- }
- else
- {
- if (PtInRect(mousePt, &scrollItemRect))
- {
- cntlCode = FindControl(mousePt, theDialog, &theControl);
- if (theControl)
- if (cntlCode == inThumb)
- {
- value = GetCtlValue(theControl);
- part = TrackControl(theControl, mousePt, nil);
- if (part)
- {
- value -= GetCtlValue(theControl);
- if (value)
- TEScroll(0, value, newTE);
- }
- }
- else if ( cntlCode != 0 )
- part = TrackControl(theControl, mousePt, gScrollScriptVActionUPP);
- } // See if click is in grow box
- else if ( PtInRect(mousePt, &growItemRect ))
- {
- // Let the user drag out the new window size
- SetRect(&growBounds, 300, 115,
- qd.screenBits.bounds.right,
- qd.screenBits.bounds.bottom);
- newRectSize = GrowWindow ( whichWindow, myEvent->where,
- &growBounds);
- if (newRectSize)
- {
- // Calculate the change in size of the window
- SetPort(theDialog);
- deltaW = LoWord(newRectSize) + whichWindow->portRect.left
- - whichWindow->portRect.right;
- deltaH = HiWord(newRectSize) + whichWindow->portRect.top
- - whichWindow->portRect.bottom;
-
- // Move all the items arround as appropriate
- MoveOneDialogControlItem( theDialog, ok, deltaW, deltaH );
- MoveOneDialogControlItem( theDialog, cancel, deltaW, deltaH );
- MoveOneDialogControlItem( theDialog, kCompile, deltaW, deltaH );
- MoveOneDialogItem( theDialog, kGrowBox, deltaW, deltaH );
-
- // Move the scroll bar and Text edit around. Change the scroll bar's maximum
- // and current value as necessary
- MoveScrollBarItem( theDialog, kScrollBar, deltaW, deltaH );
- MoveCustTextEditItem( theDialog, kTextItem, deltaW, deltaH );
- SetScrollLimit( newScroll, newTE);
-
- // Resize the window, don't bother about the update because we're going it
- // invalidate it all later
- SizeWindow ( whichWindow,
- LoWord(newRectSize), HiWord(newRectSize),
- false );
-
- // Invalidate the window for update : Note that you have to add an erase rect
- // to make sure that the window is cleared. This seems to be because the
- // Dialog manager doesn't do one.
-
- EraseRect( &whichWindow->portRect );
- InvalRect( &whichWindow->portRect );
- }
- returnVal = true;
- }
- }
- break;
-
- case inDrag:
- DragWindow(whichWindow, myEvent->where, &qd.screenBits.bounds);
- returnVal = true; // Stops modal dialog beeping
- break;
-
- case inMenuBar:
- menuResult = MenuSelect(myEvent->where);
- DoDialogMenu( menuResult, newTE );
- HiliteMenu( 0 );
- returnVal = true; // Always return handled to stop beeping
- break;
- }
- break;
-
- case keyDown:
- case autoKey: // Need hooks here for command keys if menus enabled
- myKey = myEvent->message & charCodeMask;
-
- if ((myEvent->modifiers & cmdKey) == cmdKey)
- {
- menuResult = MenuKey(myKey);
- returnVal = DoDialogMenu( menuResult, newTE );
- HiliteMenu(0);
- }
- else if ( myKey != kEscapeKey ) // Escape Key
- if ( myKey == kEndOfTextKey )
- {
- *itemHit = kCompile;
- FlashButton(theDialog, kCompile);
- returnVal = true;
- }
- else
- {
- TEKey(myKey, newTE);
- SetScrollLimit(newScroll, newTE);
- TrackTEPosn(newScroll, newTE);
- returnVal = true;
- }
- break;
-
- case activateEvt:
- if (((myEvent->modifiers & activeFlag) != 0))
- {
- if ((WindowPtr)myEvent->message == theDialog)
- TEActivate(newTE);
- else
- DoActivate((WindowPtr)myEvent->message, true); // Should not get here!
- }
- else if ((WindowPtr)myEvent->message == theDialog)
- TEDeactivate(newTE);
- else
- DoActivate((WindowPtr)myEvent->message, false);
- break;
-
- case updateEvt:
- if (Ours((WindowPtr)myEvent->message))
- DoUpdate( (WindowPtr)myEvent->message );
- break;
- }
-
- if ( ! returnVal )
- {
- #ifdef THINK_C // Can't use StdFilterProc() get and
- // call the standard filter ourselves
- if ( noErr == GetStdFilterProc( &standardProc ) )
- returnVal= ((ModalFilterUPP)standardProc)( theDialog, myEvent, itemHit );
- #else
- returnVal = StdFilterProc( theDialog, myEvent, itemHit );
- #endif
- }
-
- MaintainEditItems( newTE, 1, myTypes );
- SetPort( oldPort );
-
- return returnVal;
- }
-
-
- // Given a resource ID for a menu, along with a OSAID for a script
- // to be associated with it. This routine sets the menu or menu item
- // script property. This in turn sets that the script has changed
- // so that it will get saved when the application is quit.
-
- OSErr SetMenuScript( short theResID, OSAID theScriptID )
- {
- MenuPropToken aMenuPropToken;
- MenuItemPropToken aMenuItemPropToken;
- AEDesc aDesc = { typeNull, NULL };
- OSErr anErr;
-
- anErr = GetScriptDesc( theScriptID, typeWildCard, &aDesc );
-
- if ( theResID % 32 ) // Then the script is for an item
- {
- MenuItemTokenFromResID( theResID, &aMenuItemPropToken.token );
- aMenuItemPropToken.tokenProperty = pScript;
-
- anErr = SetMenuItemTokenProperty( &aMenuItemPropToken, &aDesc );
- }
- else // The script is for the whole menu
- {
- MenuTokenFromResID( theResID, &aMenuPropToken.token );
- aMenuPropToken.tokenProperty = pScript;
-
- anErr = SetMenuTokenProperty( &aMenuPropToken, &aDesc );
- }
-
- done:
- (void)AEDisposeDesc( &aDesc );
-
- return anErr;
- }
-
- void SetMenuForDialog ( void )
- {
- Boolean redrawMenuBar = false;
-
- // Unhilite the menu bar
- HiliteMenu( 0 );
-
- // Gray out apple menu (This will allow us to get at the edit menu)
- redrawMenuBar |= SetMenuItemState ( false, myMenus[appleM], kMenuTitle);
-
- // Now Gray out everything apart from the edit menu
- redrawMenuBar |= SetMenuItemState ( false, myMenus[fileM], kMenuTitle);
- if ( CountDocuments( ) > 0 )
- {
- redrawMenuBar |= SetMenuItemState ( false, myMenus[fontM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( false, myMenus[sizeM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( false, myMenus[styleM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( false, myMenus[scriptM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( false, myMenus[subroutineM], kMenuTitle);
- }
-
- // Enable the edit menu
- redrawMenuBar |= SetMenuItemState ( true, myMenus[editM], kMenuTitle);
- SetMenuItemState ( true, myMenus[editM], cutCommand);
- SetMenuItemState ( true, myMenus[editM], copyCommand);
- SetMenuItemState ( true, myMenus[editM], pasteCommand);
- SetMenuItemState ( true, myMenus[editM], clearCommand);
- SetMenuItemState ( true, myMenus[editM], selectAllCommand);
-
- if (redrawMenuBar)
- DrawMenuBar();
- }
-
- void ReSetMenuForDialog ( void )
- {
- Boolean redrawMenuBar = false;
-
- // Reset the menus
- redrawMenuBar |= SetMenuItemState ( true, myMenus[appleM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( true, myMenus[fileM], kMenuTitle);
- if ( CountDocuments( ) > 0 )
- {
- redrawMenuBar |= SetMenuItemState ( true, myMenus[fontM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( true, myMenus[sizeM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( true, myMenus[styleM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( true, myMenus[scriptM], kMenuTitle);
- redrawMenuBar |= SetMenuItemState ( true, myMenus[subroutineM], kMenuTitle);
- }
- MaintainMenus( &redrawMenuBar);
- }
-
-
- OSErr EditMenuScript(short theMenu, short theItem)
- {
- short resID;
- OSAID myScriptID;
- OSErr myErr;
- OSErr ignoreErr;
- AEDesc scriptTextDesc;
- DialogPtr scriptEditDlog;
- short itemHit;
- TEHandle newTE;
- GrafPtr oldPort;
- Rect itemRect;
- OSAID myCompiledID;
- Boolean wholeMenu;
- ControlHandle myScrollBar;
- StyleTextInfo theStyleTextInfo;
- ModalFilterUPP modalFilterDescriptor;
-
- SetMenuForDialog( );
-
- gEditingScript = true;
-
- GetPort(&oldPort);
-
- // Look for a script associated with theItem first,
- // and if not found look for one associated with
- // the whole menu
-
- wholeMenu = false;
-
- resID = ( theMenu << 5 ) + theItem;
-
- myScriptID = GetScriptIDForResID( resID );
-
- if ( myScriptID == kOSANullScript )
- {
- resID = (theMenu<<5);
- myScriptID = GetScriptIDForResID(resID);
- wholeMenu = true;
- }
-
- scriptEditDlog = GetNewDialog( MenuScriptEditor, NULL, (WindowPtr)-1 );
- SetPort( scriptEditDlog );
-
- // Create a styled text edit record for the userItem
- // and install it
-
- GetRectOfDialogItem( scriptEditDlog, kTextItem, &itemRect );
-
- InsetRect(&itemRect, 5, 5);
-
- newTE = TEStylNew(&itemRect, &itemRect);
-
- TEAutoView(true, newTE);
-
- SetDrawProcForUserItem(scriptEditDlog, kTextItem, gDrawStyledTextUPP);
-
- // Now create a scrollbar and install it
-
- GetRectOfDialogItem(scriptEditDlog, kScrollBar, &itemRect);
-
- myScrollBar = NewControl(scriptEditDlog, &itemRect, (unsigned char *)"",
- true, 0, 0, kMaxTELength, // Will be fixed up later - by SetScrollLimit()
- scrollBarProc, 0);
-
- SetDrawProcForUserItem(scriptEditDlog, kScrollBar, gDrawScrollBarUPP);
-
- // Now create grow box draw proc
- SetDrawProcForUserItem(scriptEditDlog, kGrowBox, gDrawGrowBoxUPP);
-
- // Use the dialog window refcon to allow access to the
- // TEHandle and scrollHandle avoiding the use
- // of globals
-
- theStyleTextInfo.theTEHandle = newTE;
- theStyleTextInfo.theScrollBar = myScrollBar;
-
- SetWRefCon(scriptEditDlog, (long) &theStyleTextInfo);
-
- // Put the source of the script into the
- // text edit record
-
- myErr = OSAGetSource(gScriptingComponent, myScriptID,
- typeStyledText, &scriptTextDesc);
-
- PutStyledTextFromDescIntoTEHandle(&scriptTextDesc, newTE);
-
- ignoreErr = AEDisposeDesc(&scriptTextDesc);
-
- SetScrollLimit(myScrollBar, newTE);
- TrackTEPosn(myScrollBar, newTE);
-
- // Set item 1 - <OK> to have a default box around it
- SetDialogDefaultItem(scriptEditDlog,ok);
- SetDialogCancelItem(scriptEditDlog,cancel);
-
- // Added during PowerPC port:
-
- modalFilterDescriptor = NewModalFilterProc( MyFilterProc );
-
- do
- {
- ModalDialog(modalFilterDescriptor, &itemHit);
- switch ( itemHit )
- {
- case ok:
- case kCompile:
- SetCursor(&waitCursor);
- HLock((Handle)(**newTE).hText);
- myErr = AECreateDesc(typeChar, (Ptr)*((**newTE).hText),
- (**newTE).teLength, &scriptTextDesc);
- HUnlock((Handle)(**newTE).hText);
-
- myCompiledID = kOSANullScript;
- myErr = OSACompile(gScriptingComponent, &scriptTextDesc,
- kOSAModeCompileIntoContext, &myCompiledID);
-
- ignoreErr = AEDisposeDesc(&scriptTextDesc);
-
- scriptTextDesc.dataHandle = nil;
-
- if (myErr==noErr)
- {
- myErr = OSAGetSource(gScriptingComponent, myCompiledID,
- typeStyledText, &scriptTextDesc);
-
- // Zap current contents and replace with returned source
-
- TESetSelect(0, kMaxTELength, newTE);
- TEDelete(newTE);
-
- // We deleted all the text so it won't be scrolled anymore
- SetCtlValue(myScrollBar, 0);
-
- PutStyledTextFromDescIntoTEHandle(&scriptTextDesc, newTE);
-
- DrawStyledTextEditRec(scriptEditDlog, kTextItem);
-
- ignoreErr = AEDisposeDesc(&scriptTextDesc);
- }
- else if ( errOSAScriptError == myErr )
- {
- DisplayErrorInScript( newTE );
- itemHit = 0; // Stop dialog going away
- }
-
- SetScrollLimit(myScrollBar, newTE);
- TrackTEPosn(myScrollBar, newTE);
-
- SetCursor(&qd.arrow);
-
- if ( ok == itemHit )
- { // Swap this script for the old one even if whole menu
- if ( noErr == myErr )
- SetMenuScript( resID, myCompiledID );
- else
- itemHit = -1;
- }
-
- (void)OSADispose(gScriptingComponent, myCompiledID);
- break;
-
- case cancel:
- case kTextItem:
- case kScrollBar:
- break;
- }
- } while ( itemHit != ok && itemHit != cancel );
-
- DisposeRoutineDescriptor( modalFilterDescriptor );
-
- DisposeDialog( scriptEditDlog );
-
- SetPort(oldPort);
-
- gEditingScript = false;
-
- ReSetMenuForDialog( );
-
- return noErr;
- }
-
-
- OSAError LoadDocumentScript( DPtr theDoc, short theFileRef )
- {
- OSAError err;
-
- theDoc->theScriptID = kOSANullScript;
-
- err = LoadScriptFromResFileRef( theFileRef,
- kDefaultDocumentScript, &theDoc->theScriptID );
-
- return err;
- }
-
-
- OSAError StoreDocumentScript( DPtr theDoc, short theFileRef )
- {
- OSAError err;
-
- if ( kOSANullScript == theDoc->theScriptID )
- return noErr;
-
- err = StoreScriptToResFileRef( theFileRef, kDefaultDocumentScript,
- theDoc->theScriptID, "\pDocument Script" );
-
- return err;
- }
-
-
- OSAError GetScriptProperty( OSAID contextID, const AEDesc* propertyName, AEDesc* result )
- {
- OSAID aScriptValueID = kOSANullScript;
- OSAError err;
-
- if ( kOSANullScript == contextID )
- return errAEEventNotHandled;
-
- // Get the property as a script ID
- err = OSAGetProperty( gScriptingComponent, kOSAModeNull, contextID,
- propertyName, &aScriptValueID );
- if (noErr != err) goto done;
- // Convert the script data located by the script ID to an AEDesc
- err = OSACoerceToDesc( gScriptingComponent, aScriptValueID,
- typeWildCard, kOSAModeNull, result );
-
- done:
- (void)OSADispose( gScriptingComponent, aScriptValueID );
-
- return(err);
- }
-
-
- // Set a script property using a descriptor.
-
- OSAError SetScriptProperty( OSAID contextID, const AEDesc* propertyName, const AEDesc* value )
- {
- OSAID aScriptValueID = kOSANullScript;
- OSAError err;
- // Convert from a descriptor to a script ID
- err = OSACoerceFromDesc( gScriptingComponent, value,
- kOSAModeNull, &aScriptValueID );
- if (noErr != err) goto done;
- // Set the property using the script ID
- err = OSASetProperty( gScriptingComponent, kOSAModeNull,
- contextID, propertyName, aScriptValueID );
-
- done:
- (void)OSADispose( gScriptingComponent, aScriptValueID );
-
- return(err);
- }
-
-
- OSErr GetScriptDesc( OSAID theScriptID, DescType theWantType, AEDesc* theResult )
- {
- OSErr err;
-
- if ( theWantType == typeChar || theWantType == typeIntlText )
- { // If caller wants text, we need to de-compile the script
- err = (OSErr)OSAGetSource( gScriptingComponent, theScriptID,
- theWantType, theResult );
- }
- else
- {
- if ( theWantType == typeWildCard )
- theWantType = typeOSAGenericStorage;
-
- err = (OSErr)OSAStore( gScriptingComponent, theScriptID,
- theWantType, kOSAModeDontStoreParent, theResult );
- }
-
- return err;
- }
-
-
- OSErr SetScriptDesc( const AEDesc* theData, OSAID* theResult )
- {
- OSAID aScriptID = kOSANullScript;
- OSAError err;
-
- switch ( theData->descriptorType )
- {
- case typeChar:
- case typeIntlText:
- err = OSACompile( gScriptingComponent, theData,
- kOSAModeCompileIntoContext, &aScriptID );
- if ( errOSAScriptError == err )
- DisplayOSAScriptError( NULL );
- break;
-
- default:
- err = OSALoad( gScriptingComponent, theData,
- kOSAModeNull, &aScriptID );
- }
-
- if ( noErr == err )
- {
- (void)OSADispose( gScriptingComponent, *theResult );
- *theResult = aScriptID;
- }
-
- return (OSErr)err;
- }
-
- void AddMissingParameter( AEKeyword theAEKeyword, DescType theType,
- Ptr theData, Size theDataSize, AppleEvent* theEvent )
- {
- AEDesc aDesc = { typeNull, NULL };
- OSErr anErr;
-
- // See if the parameter is there first
- anErr = AEGetParamDesc( theEvent, theAEKeyword, typeWildCard, &aDesc );
- if ( noErr == anErr ) goto done;
-
- switch ( theType )
- {
- case typeAEList:
- case typeAERecord:
- anErr = AECreateList( NULL, 0, ( typeAERecord == theType ), &aDesc );
- if ( noErr != anErr ) goto done;
-
- anErr = AEPutParamDesc( theEvent, theAEKeyword, &aDesc );
- break;
-
- default:
- anErr = AECreateDesc( theType, theData, theDataSize, &aDesc );
- if ( noErr != anErr ) goto done;
-
- anErr = AEPutParamDesc( theEvent, theAEKeyword, &aDesc );
- }
-
- done:
- (void)AEDisposeDesc( &aDesc );
- }
-
-
- Boolean CanScriptEvent( AEEventClass theClass, AEEventID theID, AppleEvent* theEvent )
- {
- DescType aType;
- FSSpec aSpec;
- Boolean result;
-
- switch ( theClass )
- {
- case kCoreEventClass:
- switch ( theID )
- {
- case kAEOpenApplication:
- result = false;
- break;
-
- default:
- result = true;
- }
- break;
-
- case kAECoreSuite:
- switch ( theID )
- {
- case kAESetData:
- case kAEGetData:
- case kAEDoObjectsExist:
- result = false;
- break;
-
- case kAECreateElement:
- aType = typeNull; // Null to show nothing
- AddMissingParameter( keyAEInsertHere, typeType,
- (Ptr)&aType, sizeof( aType ), theEvent );
- AddMissingParameter( keyAEData, typeAERecord, NULL, 0, theEvent );
- AddMissingParameter( keyAEPropData, typeAERecord, NULL, 0, theEvent );
- result = true;
- break;
-
- case kAEClose:
- aType = kAEAsk; // Default for no parameter
- AddMissingParameter( keyAESaveOptions, typeEnumeration,
- (Ptr)&aType, sizeof( aType ), theEvent );
- result = true;
- break;
-
- case kAESave:
- aSpec.vRefNum = 0; // Send a blank FSSpec
- aSpec.parID = 0;
- aSpec.name[0] = 0;
- AddMissingParameter( keyAEFile, typeFSS,
- (Ptr)&aSpec, sizeof( aSpec ), theEvent );
- result = true;
- break;
-
- default:
- result = true;
- }
- break;
-
- case kAEMiscStandards: // e.g. kAERevert
- switch ( theID )
- {
- default:
- result = true;
- }
- break;
-
- case kASAppleScriptSuite:
- switch ( theID )
- {
- case kASSubroutineEvent:
- result = true;
- break;
-
- default:
- result = false;
- }
- break;
-
- default:
- result = false;
- }
-
- return result;
- }
-
-
- // Debugging routine
-
- OSAError GetAHandler( AEDesc* theName, OSAID theOSAID );
- OSAError GetAHandler( AEDesc* theName, OSAID theOSAID )
- {
- AEDesc aDesc = { typeNull, NULL };
- OSAID aResultID;
- OSAError anErr;
-
- (void)DisplayDescResult( GetResultsWindPtr( ), theName, NULL, noErr );
-
- anErr = OSAGetHandler( gScriptingComponent, kOSAModeNull, theOSAID, theName, &aResultID );
- if ( noErr != anErr ) goto done;
-
- anErr = OSAGetSource( gScriptingComponent, aResultID, typeStyledText, &aDesc );
- if ( noErr != anErr ) goto done;
-
- done:
- (void)DisplayDescResult( GetResultsWindPtr( ), &aDesc, NULL, anErr );
- (void)AEDisposeDesc( &aDesc );
-
- return anErr;
- }
-
- // Debugging routine
-
- OSErr LookAtHandlers( OSAID theOSAID );
- OSErr LookAtHandlers( OSAID theOSAID )
- {
- AEDesc aList = { typeNull, NULL },
- aDesc = { typeNull, NULL };
- long aCount,
- anIndex;
- AEKeyword anAEKeyword;
- OSAError anErr;
-
- anErr = OSAGetHandlerNames( gScriptingComponent, kOSAModeNull, theOSAID, &aList );
- if ( noErr != anErr ) goto done;
-
- anErr = AECountItems( &aList, &aCount );
- if ( noErr != anErr ) goto done;
-
- for ( anIndex = 1; anIndex <= aCount; anIndex++ )
- {
- anErr = AEGetNthDesc( &aList, anIndex, typeWildCard, &anAEKeyword, &aDesc );
- if ( noErr != anErr ) continue;
-
- anErr = GetAHandler( &aDesc, theOSAID );
- }
-
- done:
- (void)DisplayDescResult( GetResultsWindPtr( ) , &aDesc, NULL, anErr );
- (void)AEDisposeDesc( &aList );
- (void)AEDisposeDesc( &aDesc );
-
- return anErr;
- }
-
-
- static OSErr GetTokenDescScript( AEDesc* theTokenDesc, OSAID* theOSAID )
- {
- WindowToken aWindowToken;
- Size aSize;
- DPtr aDoc;
- OSErr err = noErr;
-
- *theOSAID = kOSANullScript; // Null to begin with
-
- switch ( theTokenDesc->descriptorType )
- {
- case typeMyDocument:
- GetRawDataFromDescriptor( theTokenDesc, (Ptr)&aWindowToken,
- sizeof( aWindowToken ), &aSize );
- aDoc = DPtrFromWindowPtr( aWindowToken.tokenWindow );
- *theOSAID = aDoc->theScriptID;
-
- // LookAtHandlers( *theOSAID );
- break;
-
- case typeMyAppl:
- *theOSAID = gAppRec.theScriptID;
-
- // LookAtHandlers( *theOSAID );
- break;
-
- default:
- err = errAEEventNotHandled;
- }
-
- return err;
- }
-
-
- OSErr DoScriptEvent( AppleEvent *theEvent,
- AppleEvent *theReply,
- OSAID theScriptID )
- {
- OSAError err = errAEEventNotHandled;
- AEEventHandlerUPP oldResumeProc;
- long oldRefcon;
-
- if ( kOSANullScript == theScriptID )
- return err;
-
- OSAGetResumeDispatchProc( gScriptingComponent, &oldResumeProc, &oldRefcon );
-
- err = OSASetResumeDispatchProc( gScriptingComponent,
- (AEEventHandlerUPP)kOSAUseStandardDispatch, kOSADontUsePhac );
- if ( noErr == err )
- {
- err = OSADoEvent( gScriptingComponent, theEvent, theScriptID,
- kOSAModeAlwaysInteract, theReply );
- if ( errOSAScriptError == err )
- (void)DisplayOSAScriptError( NULL );
- }
-
- OSASetResumeDispatchProc( gScriptingComponent, oldResumeProc, oldRefcon ) ;
-
- return (OSErr)err;
- }
-
-
- pascal OSErr EventPrehandler( AppleEvent *theEvent, AppleEvent *theReply, long theRefcon )
- {
- #ifdef __MWERKS__
- #pragma unused( theRefcon )
- #endif
-
- AEEventClass aClass;
- AEEventID anID;
- DescType aType;
- Size aSize;
- AEDesc anObject = { typeNull, NULL },
- aTokenDesc = { typeNull, NULL };
- OSAID aScriptID = kOSANullScript;
- OSAError err;
-
- // Extract the class and ID of the event from the AppleEvent
- err = AEGetAttributePtr( theEvent, keyEventClassAttr, typeType,
- &aType, (Ptr)&aClass, sizeof( aClass ), &aSize );
- if ( noErr != err ) goto done;
-
- err = AEGetAttributePtr( theEvent, keyEventIDAttr, typeType,
- &aType, (Ptr)&anID, sizeof( anID ), &aSize );
- if ( noErr != err ) goto done;
-
- if ( CanScriptEvent( aClass, anID, theEvent ) )
- { // Above test is to make sure we handle all the scriptable events
- // and that we skip the ones we don't want to be scriptable.
- err = AEGetParamDesc( theEvent, keyDirectObject, typeWildCard, &anObject );
-
- // If there is no object specifier for the direct object
- // then well have a go with the application script.
- if ( noErr != err || typeObjectSpecifier != anObject.descriptorType )
- aTokenDesc.descriptorType = typeMyAppl;
- else
- { // Resolve to an internal token
- err = AEResolve( &anObject, kAEIDoMinimum, &aTokenDesc );
- if ( noErr != err ) goto done;
- }
-
- err = GetTokenDescScript( &aTokenDesc, &aScriptID );
- if ( noErr != err ) goto done;
-
- // If there's no script then we want the application
- // to handle it in the normal way.
- if ( kOSANullScript == aScriptID )
- {
- err = errAEEventNotHandled;
- goto done;
- }
-
- err = DoScriptEvent( theEvent, theReply, aScriptID );
- }
- else
- err = errAEEventNotHandled;
-
- done:
- (void)AEDisposeDesc( &anObject );
- (void)AEDisposeDesc( &aTokenDesc );
-
- return (OSErr)err;
- }
-