diff options
Diffstat (limited to 'Foundation/GTMNSAppleScript+Handler.m')
-rw-r--r-- | Foundation/GTMNSAppleScript+Handler.m | 251 |
1 files changed, 125 insertions, 126 deletions
diff --git a/Foundation/GTMNSAppleScript+Handler.m b/Foundation/GTMNSAppleScript+Handler.m index 01e15e1..e4ace96 100644 --- a/Foundation/GTMNSAppleScript+Handler.m +++ b/Foundation/GTMNSAppleScript+Handler.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -32,9 +32,9 @@ static NSString *const GTMNSAppleScriptErrorKey = @"GTMNSAppleScriptError"; // Error keys that we may return in the error dictionary on top of the standard // NSAppleScriptError* keys. -NSString const* GTMNSAppleScriptErrorPartialResult +NSString const* GTMNSAppleScriptErrorPartialResult = @"GTMNSAppleScriptErrorPartialResult"; -NSString const* GTMNSAppleScriptErrorOffendingObject +NSString const* GTMNSAppleScriptErrorOffendingObject = @"GTMNSAppleScriptErrorOffendingObject"; NSString const* GTMNSAppleScriptErrorExpectedType = @"GTMNSAppleScriptErrorExpectedType"; @@ -76,7 +76,7 @@ NSString const* GTMNSAppleScriptErrorExpectedType - (NSSet*)gtm_scriptProperties; // Handles creating an NSAppleEventDescriptor from an OSAID -- (NSAppleEventDescriptor*)descForScriptID:(OSAID)scriptID +- (NSAppleEventDescriptor*)descForScriptID:(OSAID)scriptID component:(ComponentInstance)component; // Utility methods for converting between real and generic OSAIDs. @@ -89,45 +89,63 @@ NSString const* GTMNSAppleScriptErrorExpectedType component:(ComponentInstance)component; @end +// Private methods for dealing with Scripts/Events and NSAppleEventDescriptors +@interface NSAppleEventDescriptor (GTMAppleEventDescriptorScriptAdditions) + +// Return an NSAppleScript for a desc of typeScript. This will create a new +// Applescript that is a copy of the script that you want. +// Returns nil on failure. +- (NSAppleScript*)gtm_scriptValue; + +// Return an NSAppleScript for a desc of typeGTMOSAID. This will not copy the +// script, but will create an NSAppleScript wrapping the script represented +// by the OSAID. +// Returns nil on failure. +- (NSAppleScript*)gtm_osaIDValue; + +// Return a NSString with [eventClass][eventID] for typeEvent 'evnt' +- (NSString*)gtm_eventValue; +@end + @implementation NSAppleScript(GTMAppleScriptHandlerAdditions) GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_descriptorWithPositionalHandler:parametersArray:); GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_descriptorWithLabeledHandler:labels:parameters:count:); GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); + (void)load { - DescType types[] = { + DescType types[] = { typeScript }; - + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_scriptValue) forTypes:types count:sizeof(types)/sizeof(DescType)]; - - DescType types2[] = { + + DescType types2[] = { 'evnt' // No type code for this one }; - + [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_eventValue) forTypes:types2 count:sizeof(types2)/sizeof(DescType)]; - + DescType types3[] = { typeGTMOSAID }; - + [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_osaIDValue) forTypes:types3 count:sizeof(types3)/sizeof(DescType)]; [pool drain]; } -- (NSAppleEventDescriptor *)gtm_executeAppleEvent:(NSAppleEventDescriptor *)event +- (NSAppleEventDescriptor *)gtm_executeAppleEvent:(NSAppleEventDescriptor *)event error:(NSDictionary **)error { NSMutableDictionary *data = [NSMutableDictionary dictionaryWithObjectsAndKeys: event, GTMNSAppleScriptEventKey, nil]; [self performSelectorOnMainThread:@selector(gtm_internalExecuteAppleEvent:) - withObject:data + withObject:data waitUntilDone:YES]; if (error) { *error = [data objectForKey:GTMNSAppleScriptErrorKey]; @@ -135,51 +153,51 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); return [data objectForKey:GTMNSAppleScriptResultKey]; } -- (NSAppleEventDescriptor*)gtm_executePositionalHandler:(NSString*)handler - parameters:(NSArray*)params +- (NSAppleEventDescriptor*)gtm_executePositionalHandler:(NSString*)handler + parameters:(NSArray*)params error:(NSDictionary**)error { - NSAppleEventDescriptor *event - = [NSAppleEventDescriptor gtm_descriptorWithPositionalHandler:handler + NSAppleEventDescriptor *event + = [NSAppleEventDescriptor gtm_descriptorWithPositionalHandler:handler parametersArray:params]; return [self gtm_executeAppleEvent:event error:error]; -} +} - (NSAppleEventDescriptor*)gtm_executeLabeledHandler:(NSString*)handler labels:(AEKeyword*)labels parameters:(id*)params count:(NSUInteger)count error:(NSDictionary **)error { - NSAppleEventDescriptor *event - = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:handler + NSAppleEventDescriptor *event + = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:handler labels:labels parameters:params count:count]; return [self gtm_executeAppleEvent:event error:error]; -} +} - (NSSet*)gtm_handlers { return [self gtm_allValuesUsingSelector:@selector(gtm_scriptHandlers)]; } - + - (NSSet*)gtm_properties { return [self gtm_allValuesUsingSelector:@selector(gtm_scriptProperties)]; } // Set a value for a property by type (eg pASTopLevelScript) -- (BOOL)gtm_setValue:(id)value +- (BOOL)gtm_setValue:(id)value forPropertyEnum:(DescType)property addingDefinition:(BOOL)adding { - GTMFourCharCode *fcc + GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:property]; return [self gtm_setValue:value forProperty:fcc addingDefinition:adding]; } -- (BOOL)gtm_setValue:(id)value - forProperty:(id)property +- (BOOL)gtm_setValue:(id)value + forProperty:(id)property addingDefinition:(BOOL)adding{ OSAError error = paramErr; BOOL wasGood = NO; - NSAppleEventDescriptor *propertyName + NSAppleEventDescriptor *propertyName = [self gtm_descriptorForPropertyValue:property]; NSAppleEventDescriptor *desc = [value gtm_appleEventDescriptor]; if (propertyName && desc) { @@ -188,22 +206,22 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); ComponentInstance component; OSAID scriptID = [script gtm_realIDAndComponent:&component]; error = OSACoerceFromDesc(component, - [desc aeDesc], - kOSAModeNull, + [desc aeDesc], + kOSAModeNull, &valueID); if (error == noErr) { - error = OSASetProperty(component, - adding ? kOSAModeNull : kOSAModeDontDefine, - scriptID, - [propertyName aeDesc], - valueID); + error = OSASetProperty(component, + adding ? kOSAModeNull : kOSAModeDontDefine, + scriptID, + [propertyName aeDesc], + valueID); if (error == noErr) { wasGood = YES; } } } if (!wasGood) { - _GTMDevLog(@"Unable to setValue:%@ forProperty:%@ from %@ (%d)", + _GTMDevLog(@"Unable to setValue:%@ forProperty:%@ from %@ (%d)", value, property, self, error); } return wasGood; @@ -223,13 +241,13 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSAID osaID = [self gtm_realIDAndComponent:&component]; AEDesc result = { typeNull, NULL }; NSAppleEventDescriptor *desc = nil; - OSAError error = OSACoerceToDesc(component, - osaID, + OSAError error = OSACoerceToDesc(component, + osaID, typeScript, kOSAModeNull, &result); if (error == noErr) { - desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&result] + desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&result] autorelease]; } else { _GTMDevLog(@"Unable to coerce script %d", error); @@ -262,17 +280,17 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); for (NSUInteger i = 1; i < count; i++) { [types appendString:@"@"]; } - signature = [NSMethodSignature signatureWithObjCTypes:[types UTF8String]]; + signature = [NSMethodSignature signatureWithObjCTypes:[types UTF8String]]; } return signature; } - (void)forwardInvocation:(NSInvocation *)invocation { SEL sel = [invocation selector]; - NSMutableString *handlerName + NSMutableString *handlerName = [NSMutableString stringWithString:NSStringFromSelector(sel)]; NSUInteger handlerOrigLength = [handlerName length]; - [handlerName replaceOccurrencesOfString:@":" + [handlerName replaceOccurrencesOfString:@":" withString:@"" options:0 range:NSMakeRange(0,handlerOrigLength)]; @@ -285,9 +303,9 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); [args addObject:arg]; } NSDictionary *error = nil; - NSAppleEventDescriptor *desc = [self gtm_executePositionalHandler:handlerName - parameters:args - error:&error]; + NSAppleEventDescriptor *desc = [self gtm_executePositionalHandler:handlerName + parameters:args + error:&error]; if ([[invocation methodSignature] methodReturnLength] > 0) { id returnValue = [desc gtm_objectValue]; [invocation setReturnValue:&returnValue]; @@ -303,7 +321,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); propDesc = [property gtm_appleEventDescriptorOfType:typeProperty]; } else if ([property isKindOfClass:[NSString class]]) { propDesc = [property gtm_appleEventDescriptor]; - } + } return propDesc; } @@ -311,23 +329,23 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); GTMAssertRunningOnMainThread(); OSAError error = paramErr; NSAppleEventDescriptor *desc = nil; - NSAppleEventDescriptor *propertyName + NSAppleEventDescriptor *propertyName = [self gtm_descriptorForPropertyValue:property]; if (propertyName) { ComponentInstance component; OSAID scriptID = [self gtm_realIDAndComponent:&component]; OSAID valueID = kOSANullScript; - error = OSAGetProperty(component, - kOSAModeNull, - scriptID, - [propertyName aeDesc], + error = OSAGetProperty(component, + kOSAModeNull, + scriptID, + [propertyName aeDesc], &valueID); if (error == noErr) { desc = [self descForScriptID:valueID component:component]; } } if (error) { - _GTMDevLog(@"Unable to get valueForProperty:%@ from %@ (%d)", + _GTMDevLog(@"Unable to get valueForProperty:%@ from %@ (%d)", property, self, error); } return desc; @@ -366,8 +384,8 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSAID osaID = [self gtm_realIDAndComponent:&component]; OSAError error = OSAGetHandlerNames(component, kOSAModeNull, osaID, &names); if (error == noErr) { - NSAppleEventDescriptor *desc - = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] + NSAppleEventDescriptor *desc + = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] autorelease]; array = [desc gtm_objectValue]; } @@ -385,8 +403,8 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSAID osaID = [self gtm_realIDAndComponent:&component]; OSAError error = OSAGetPropertyNames(component, kOSAModeNull, osaID, &names); if (error == noErr) { - NSAppleEventDescriptor *desc - = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] + NSAppleEventDescriptor *desc + = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] autorelease]; array = [desc gtm_objectValue]; } @@ -408,7 +426,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); return exactID; } -- (NSAppleEventDescriptor*)descForScriptID:(OSAID)osaID +- (NSAppleEventDescriptor*)descForScriptID:(OSAID)osaID component:(ComponentInstance)component { GTMAssertRunningOnMainThread(); NSAppleEventDescriptor *desc = nil; @@ -427,17 +445,17 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); if (value == typeScript) { osaID = [self gtm_genericID:osaID forComponent:component]; desc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeGTMOSAID - bytes:&osaID + bytes:&osaID length:sizeof(osaID)]; } else { AEDesc aeDesc; - err = OSACoerceToDesc(component, - osaID, - typeWildCard, - kOSAModeNull, + err = OSACoerceToDesc(component, + osaID, + typeWildCard, + kOSAModeNull, &aeDesc); if (err == noErr) { - desc = [[[NSAppleEventDescriptor alloc] + desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&aeDesc] autorelease]; } } @@ -480,12 +498,12 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); ComponentInstance component; OSAID scriptID = [self gtm_realIDAndComponent:&component]; OSAID valueID; - OSAError err = OSAExecuteEvent(component, [event aeDesc], scriptID, + OSAError err = OSAExecuteEvent(component, [event aeDesc], scriptID, kOSAModeNull, &valueID); if (err == noErr) { // descForScriptID:component: is what sets this apart from the // standard executeAppleEvent:error: in that it handles - // taking script results and turning them into AEDescs of typeGTMOSAID + // taking script results and turning them into AEDescs of typeGTMOSAID // instead of typeScript. desc = [self descForScriptID:valueID component:component]; if (desc) { @@ -511,51 +529,51 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); SEL extractor; id key; } errMap[] = { - { - kOSAErrorNumber, - typeSInt16, - @selector(gtm_numberValue), - NSAppleScriptErrorNumber + { + kOSAErrorNumber, + typeSInt16, + @selector(gtm_numberValue), + NSAppleScriptErrorNumber }, { - kOSAErrorMessage, - typeText, - @selector(stringValue), + kOSAErrorMessage, + typeText, + @selector(stringValue), NSAppleScriptErrorMessage }, - { - kOSAErrorBriefMessage, - typeText, - @selector(stringValue), + { + kOSAErrorBriefMessage, + typeText, + @selector(stringValue), NSAppleScriptErrorBriefMessage }, - { kOSAErrorApp, - typeText, - @selector(stringValue), - NSAppleScriptErrorAppName + { kOSAErrorApp, + typeText, + @selector(stringValue), + NSAppleScriptErrorAppName }, - { kOSAErrorRange, - typeOSAErrorRange, - @selector(gtm_OSAErrorRangeValue), + { kOSAErrorRange, + typeOSAErrorRange, + @selector(gtm_OSAErrorRangeValue), NSAppleScriptErrorRange }, - { - kOSAErrorPartialResult, - typeBest, - @selector(gtm_objectValue), - GTMNSAppleScriptErrorPartialResult + { + kOSAErrorPartialResult, + typeBest, + @selector(gtm_objectValue), + GTMNSAppleScriptErrorPartialResult }, - { - kOSAErrorOffendingObject, - typeBest, - @selector(gtm_objectValue), - GTMNSAppleScriptErrorOffendingObject + { + kOSAErrorOffendingObject, + typeBest, + @selector(gtm_objectValue), + GTMNSAppleScriptErrorOffendingObject }, - { - kOSAErrorExpectedType, - typeType, - @selector(gtm_fourCharCodeValue), - GTMNSAppleScriptErrorExpectedType + { + kOSAErrorExpectedType, + typeType, + @selector(gtm_fourCharCodeValue), + GTMNSAppleScriptErrorExpectedType }, }; for (size_t i = 0; i < sizeof(errMap) / sizeof(errMap[0]); ++i) { @@ -563,9 +581,9 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSStatus err = OSAScriptError(component, errMap[i].selector, errMap[i].desiredType, - &errorResult); + &errorResult); if (err == noErr) { - NSAppleEventDescriptor *desc = [[[NSAppleEventDescriptor alloc] + NSAppleEventDescriptor *desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&errorResult] autorelease]; id value = [desc performSelector:errMap[i].extractor]; if (value) { @@ -576,10 +594,10 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); } else if (status != noErr) { // Unknown error. Do our best to give the user something good. NSNumber *errNum = [NSNumber numberWithInt:status]; - error - = [NSMutableDictionary dictionaryWithObject:errNum + error + = [NSMutableDictionary dictionaryWithObject:errNum forKey:NSAppleScriptErrorNumber]; - NSString *briefMessage + NSString *briefMessage = [NSString stringWithUTF8String:GetMacOSStatusErrorString(status)]; if (briefMessage) { [error setValue:briefMessage forKey:NSAppleScriptErrorBriefMessage]; @@ -594,30 +612,11 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); } @end -// Private methods for dealing with Scripts/Events and NSAppleEventDescriptors -@interface NSAppleEventDescriptor (GTMAppleEventDescriptorScriptAdditions) - -// Return an NSAppleScript for a desc of typeScript. This will create a new -// Applescript that is a copy of the script that you want. -// Returns nil on failure. -- (NSAppleScript*)gtm_scriptValue; - -// Return an NSAppleScript for a desc of typeGTMOSAID. This will not copy the -// script, but will create an NSAppleScript wrapping the script represented -// by the OSAID. -// Returns nil on failure. -- (NSAppleScript*)gtm_osaIDValue; - -// Return a NSString with [eventClass][eventID] for typeEvent 'evnt' -- (NSString*)gtm_eventValue; -@end - - @implementation NSAppleEventDescriptor (GMAppleEventDescriptorScriptAdditions) - (NSAppleScript*)gtm_scriptValue { NSDictionary *error; - NSAppleScript *script = [[[NSAppleScript alloc] _initWithData:[self data] + NSAppleScript *script = [[[NSAppleScript alloc] _initWithData:[self data] error:&error] autorelease]; if (!script) { _GTMDevLog(@"Unable to create script: %@", error); // COV_NF_LINE @@ -637,7 +636,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); AEEventID eventID; }; NSData *data = [self data]; - const struct AEEventRecordStruct *record + const struct AEEventRecordStruct *record = (const struct AEEventRecordStruct*)[data bytes]; NSString *eClass = [GTMFourCharCode stringWithFourCharCode:record->eventClass]; NSString *eID = [GTMFourCharCode stringWithFourCharCode:record->eventID]; @@ -661,4 +660,4 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); } @end - + |