Пример #1
0
AECoreClass::AECoreClass(Boolean suspendEvents)
:	mSuspendEventHandlerUPP(nil)
,	mStandardSuiteHandlerUPP(nil)
,	mRequiredSuiteHandlerUPP(nil)
,	mCreateElementHandlerUPP(nil)
,	mMozillaSuiteHandlerUPP(nil)
,	mGetURLSuiteHandlerUPP(nil)
,	mSpyGlassSuiteHandlerUPP(nil)
,	mPropertyFromListAccessor(nil)
,	mAnythingFromAppAccessor(nil)
,	mCountItemsCallback(nil)
,	mCompareItemsCallback(nil)
{
	mSuspendedEvent.descriptorType = typeNull;
	mSuspendedEvent.dataHandle = nil;

	mReplyToSuspendedEvent.descriptorType = typeNull;
	mReplyToSuspendedEvent.dataHandle = nil;
	
	OSErr	err = ::AEObjectInit();
	ThrowIfOSErr(err);
	
	mSuspendEventHandlerUPP = NewAEEventHandlerUPP(AECoreClass::SuspendEventHandler);
	ThrowIfNil(mSuspendEventHandlerUPP);

	mRequiredSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::RequiredSuiteHandler);
	ThrowIfNil(mRequiredSuiteHandlerUPP);

	mStandardSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::CoreSuiteHandler);
	ThrowIfNil(mStandardSuiteHandlerUPP);

	mMozillaSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::MozillaSuiteHandler);
	ThrowIfNil(mMozillaSuiteHandlerUPP);

	mGetURLSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::GetURLSuiteHandler);
	ThrowIfNil(mGetURLSuiteHandlerUPP);

	mSpyGlassSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::SpyglassSuiteHandler);
	ThrowIfNil(mSpyGlassSuiteHandlerUPP);

	InstallSuiteHandlers(suspendEvents);

	mCreateElementHandlerUPP = NewAEEventHandlerUPP(AECoreClass::CreateElementHandler);
	ThrowIfNil(mCreateElementHandlerUPP);
	
	// Special handler for StandardSuite Make (CreateElement) event
	// Make (CreateElement) is different than the other events processed above
	// because it passes its ospec in the insertionLoc parameter instead of
	// in the direct object parameter.

	err = ::AEInstallEventHandler(kAECoreSuite, 	kAECreateElement, 
										mCreateElementHandlerUPP, 
										(long)this, 
										false);
	ThrowIfOSErr(err);

	/*	We'd like to be able to install a generic handler that is used to get anything from null.
		Unfortunately, some formRelative requests require a handler for getting an item from
		another of the same type (e.g. "get the window after window 'foo'" requires a cWindow
		from cWindow handler).
	*/
	// Install a generic handler to get an item from the app
	mAnythingFromAppAccessor = NewOSLAccessorUPP(AECoreClass::AnythingFromAppAccessor);
	ThrowIfNil(mAnythingFromAppAccessor);
	
	// Install a handler to get properties from anything.
	err = ::AEInstallObjectAccessor(typeWildCard, typeWildCard, mAnythingFromAppAccessor, (long)this, false);
	ThrowIfOSErr(err);
	
	// Install a generic handler to get a property from a typeAEList of tokens
	mPropertyFromListAccessor = NewOSLAccessorUPP(AECoreClass::PropertyTokenFromAnything);
	ThrowIfNil(mPropertyFromListAccessor);
	
	// Install a handler to get properties from anything.
	err = ::AEInstallObjectAccessor(cProperty, typeWildCard, mPropertyFromListAccessor, (long)this, false);
	ThrowIfOSErr(err);

	// Install the OSL object callbacks, use for compare and count
	mCountItemsCallback = NewOSLCountUPP(AECoreClass::CountObjectsCallback);
	ThrowIfNil(mCountItemsCallback);

	mCompareItemsCallback = NewOSLCompareUPP(AECoreClass::CompareObjectsCallback);
	ThrowIfNil(mCompareItemsCallback);
	
	err = ::AESetObjectCallbacks(
						mCompareItemsCallback,
						mCountItemsCallback,
						(OSLDisposeTokenUPP)	nil, 
						(OSLGetMarkTokenUPP)	nil, 
						(OSLMarkUPP)			nil, 
						(OSLAdjustMarksUPP)	nil, 
						(OSLGetErrDescUPP)  	nil);
	ThrowIfOSErr(err);

	// create the dispatchers for various object types. This should be the only place
	// that new classes have to be added
	AEApplicationClass*		appDispatcher = new AEApplicationClass;
	RegisterClassHandler(cApplication, appDispatcher);
	RegisterClassHandler(typeNull, appDispatcher, true);

	AEDocumentClass*		docDispatcher = new AEDocumentClass;
	RegisterClassHandler(cDocument, docDispatcher);

	AEWindowClass*		windowDispatcher = new AEWindowClass(cWindow, kAnyWindowKind);
	RegisterClassHandler(cWindow, windowDispatcher);

/*	
	AETextClass*		textDispatcher = new AETextClass;
	RegisterClassHandler(AETextClass::cTEText, textDispatcher);
	
	AEWordClass*		wordDispatcher = new AEWordClass;
	RegisterClassHandler(cWord, wordDispatcher);
	
	AECharacterClass*	charDispatcher = new AECharacterClass;
	RegisterClassHandler(cChar, charDispatcher);
*/
}
Пример #2
0
/*----------------------------------------------------------------------------
	HandleClose 
	
----------------------------------------------------------------------------*/
void AEGenericClass::HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
	ThrowIfOSErr(errAEEventNotHandled);
}
Пример #3
0
/*----------------------------------------------------------------------------
	HandleCoreSuiteEvent 
	
----------------------------------------------------------------------------*/
void AECoreClass::HandleCoreSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply)
{
	StAEDesc		directParameter;
	StAEDesc		token;
	OSErr		err = noErr;
	
	// extract the direct parameter (an object specifier)
	err = ::AEGetKeyDesc(appleEvent, keyDirectObject, typeWildCard, &directParameter);
	ThrowIfOSErr(err);

	DescType	tokenType		= typeNull;
	DescType	dispatchClass  	= typeNull;
	
	// check for null descriptor, which AEResolve doesn't handle well
	// If it's not null, then AEResolve will return an application-defined token
	if (directParameter.descriptorType == typeNull) 
	{
		token = directParameter;			// can throw
	}
	else
	{
		// The direct parameter contains an object specifier, or an "reference" in
		// AppleScript terminology, such as "rectangle 1 of document 1". 
		// AEResolve() will recursively call our installed object accessors
		// until it returns a token with data referencing the requested object.
		 
		err = ::AEResolve(&directParameter, kAEIDoMinimum, &token);
	}

	if (err == errAENoSuchObject || err == errAEIllegalIndex)
	{
		// If we were executing an "Exists..." AppleEvent, we can reply it here
		// because we have already determined that it DOES NOT exist.
		// First, we get the event ID. We use "eventError" instead of "err"
		// so that the result of AEGetAttributePtr() does not disturb the
		// errAENoSuchObject result previously returned.
		
		AEEventID		eventID;
		OSType		typeCode;
		Size			actualSize = 0;		
		OSErr		eventError = ::AEGetAttributePtr(appleEvent, 
										  		 keyEventIDAttr, 
										  		 typeType, 
										  		 &typeCode, 
										  		 (Ptr)&eventID, 	// Get the eventID from the AppleEvent
										  		 sizeof(eventID), 
										  		 &actualSize);
										  
		// If event was an "Exists..." message, store the result (false) in the reply
		// because AEResolve() returned errAENoSuchObject.
		
		if (eventError == noErr && eventID == kAEDoObjectsExist)
		{
			Boolean	foundIt = false;
			(void)AEPutParamPtr(reply, keyAEResult, typeBoolean, (Ptr)&foundIt, sizeof(Boolean));
			
			// Now, we set the err to noErr so that the scripting component doesn't complain
			// that the object does not exist. We only do this if we were executing an "Exists..."
			// event. Otherwise, the errAENoSuchObject will be returned.
			ThrowNoErr();
		}
		
		ThrowIfOSErr(err);
		return;
	}

	ThrowIfOSErr(err);
	
	// Pass the token returned by AEResolve(), and the original AppleEvent event and reply,
	// on to the appropriate object dispatcher

	// The token type is, by convention, the same as class ID that handles this event.
	// However, for property tokens, tokenType is cProperty for all objects, so
	// we look inside the token at its dispatchClass to find out which class of object
	// should really handle this AppleEvent.
	
	// Also, if the resolver returned a list of objects in the token, 
	// the type will be typeAEList or one of our special list types, so
	// we set the dispatch class based on the list type
	// instead of on the type of the token itself
	
	if (AEListUtils::TokenContainsTokenList(&token))
	{
		SInt32	numItems;
		
		err = AECountItems(&token, &numItems);
		
		if (numItems == 0)	// could be an empty list
		{
			dispatchClass = typeNull;
		}
		else
		{
			StAEDesc	tempToken;
			err = AEListUtils::GetFirstNonListToken((AEDesc *)&token, &tempToken);
			if (err == noErr && tempToken.descriptorType != typeNull)
			{
				ConstAETokenDesc	tokenDesc(&tempToken);
				dispatchClass = tokenDesc.GetDispatchClass();
			}
			else
			{
				dispatchClass = typeNull;
				err = noErr;
			}
		}
	}
	else if (token.descriptorType == typeNull)	           // make sure we correctly handle things for cApplication that don't have a direct parameter
	{
		dispatchClass = typeNull;
	}
	else
	{
		ConstAETokenDesc	tokenDesc(&token);
		dispatchClass = tokenDesc.GetDispatchClass();
	}
	
	// why is this special-cased?
	if (dispatchClass == cFile)
	{
		AEEventID		eventID	= 0;
		OSType		typeCode 	= 0;
		Size			actualSize	= 0;
		
		OSErr		eventError = AEGetAttributePtr(appleEvent, 	keyEventIDAttr, 
														typeType, 
														&typeCode, 
														(Ptr)&eventID, 	// Get the eventID from the AppleEvent
														sizeof(eventID), 
														&actualSize);										  
	}


	AEDispatchHandler*	handler = GetDispatchHandler(dispatchClass);
	if (!handler)
		ThrowIfOSErr(errAEEventNotHandled);
		
	handler->DispatchEvent(&token, appleEvent, reply);
}