Revision: 22629
          http://sourceforge.net/p/bibdesk/svn/22629
Author:   hofman
Date:     2018-09-18 12:29:37 +0000 (Tue, 18 Sep 2018)
Log Message:
-----------
Use "any" type for add and remove script commands, evaluate the app event 
descriptors ourselves

Modified Paths:
--------------
    trunk/bibdesk/BDSKAddCommand.m
    trunk/bibdesk/BDSKAppController.m
    trunk/bibdesk/BDSKRemoveCommand.m
    trunk/bibdesk/Scripting/BibDesk.sdef

Modified: trunk/bibdesk/BDSKAddCommand.m
===================================================================
--- trunk/bibdesk/BDSKAddCommand.m      2018-09-18 06:30:38 UTC (rev 22628)
+++ trunk/bibdesk/BDSKAddCommand.m      2018-09-18 12:29:37 UTC (rev 22629)
@@ -49,112 +49,94 @@
 - (id)performDefaultImplementation {
     // get the actual objects to insert
     id directParameter = [self directParameter];
-    id receiver = [self evaluatedReceivers];
-    NSArray *insertionObjects = nil;
-    NSMutableArray *returnValue = nil;
-    BOOL isArray;
+    // for "any" type, directParameter is an NSAppleEventDescriptor and 
evaulatedReceiver is nil
+    NSArray *insertionObjects = [directParameter objCObjectValue];
     
-    if ([directParameter isKindOfClass:[NSAppleEventDescriptor class]] && 
[directParameter descriptorType] == typeAEList) {
-        NSMutableArray *array = [NSMutableArray array];
-        NSUInteger i, iMax = [directParameter numberOfItems];
-        for (i = 1; i <= iMax; i++)
-            [array addObject:[directParameter descriptorAtIndex:i]];
-        directParameter = array;
+    // evaluate object specifiers
+    if ([insertionObjects 
respondsToSelector:@selector(objectsByEvaluatingSpecifier)] ||
+        ([insertionObjects isKindOfClass:[NSArray class]] &&
+         NSNotFound == [insertionObjects indexOfObjectPassingTest:^BOOL(id 
obj, NSUInteger idx, BOOL *stop){ return NO == [obj 
respondsToSelector:@selector(objectsByEvaluatingSpecifier)]; }])) {
+        insertionObjects = [insertionObjects 
valueForKey:@"objectsByEvaluatingSpecifier"];
     }
     
-    isArray = [directParameter isKindOfClass:[NSArray class]] || [receiver 
isKindOfClass:[NSArray class]];
-    
-    if (directParameter && [directParameter isKindOfClass:[NSArray class]] == 
NO)
-        directParameter = [NSArray arrayWithObjects:directParameter, nil];
-    
-    if (NSNotFound == [directParameter indexOfObjectPassingTest:^BOOL(id obj, 
NSUInteger idx, BOOL *stop){ return NO == [obj 
respondsToSelector:@selector(keyClassDescription)]; }]) {
-        insertionObjects = [receiver isKindOfClass:[NSArray class]] ? receiver 
: [NSArray arrayWithObjects:receiver, nil];
-    } else if (NSNotFound == [directParameter 
indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ return NO 
== [obj isKindOfClass:[NSAppleEventDescriptor class]]; }]) {
-        insertionObjects = [directParameter valueForKey:@"objCObjectValue"];
-    }
-    
     if (insertionObjects == nil) {
         [self setScriptErrorNumber:NSArgumentsWrongScriptError];
         [self setScriptErrorString:NSLocalizedString(@"Invalid or missing 
objects to add", @"Error description")];
     } else {
         
-        // get the location to insert
-        id locationSpecifier = [[self arguments] objectForKey:@"ToLocation"];
-        id insertionContainer = nil;
-        NSString *insertionKey = nil;
-        NSInteger insertionIndex = -1;
-        NSScriptClassDescription *containerClassDescription = nil;
-        NSArray *classDescriptions = [insertionObjects 
valueForKey:@"scriptClassDescription"];
-        NSScriptClassDescription *insertionClassDescription = 
[classDescriptions containsObject:[NSNull null]] ? nil : 
[NSScriptClassDescription commonAncestorForClassDescriptions:classDescriptions];
+        // make sure we have an (unnested) array
+        if ([insertionObjects isKindOfClass:[NSArray class]] == NO)
+            insertionObjects = [NSArray arrayWithObjects:insertionObjects, 
nil];
+        else if (NSNotFound == [insertionObjects 
indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ return NO 
== [obj isKindOfClass:[NSArray class]]; }])
+            insertionObjects = [insertionObjects 
valueForKeyPath:@"@unionOfArrays.self"];
         
-        if ([locationSpecifier isKindOfClass:[NSPositionalSpecifier class]]) {
-            [locationSpecifier 
setInsertionClassDescription:insertionClassDescription];
-            insertionContainer = [locationSpecifier insertionContainer];
-            insertionKey = [locationSpecifier insertionKey];
-            insertionIndex = [locationSpecifier insertionIndex];
-        } else if ([locationSpecifier isKindOfClass:[NSPropertySpecifier 
class]]) {
-            insertionContainer = [[locationSpecifier containerSpecifier] 
objectsByEvaluatingSpecifier];
-            insertionKey = [locationSpecifier key];
-        } else if (locationSpecifier) {
-            insertionContainer = [locationSpecifier 
objectsByEvaluatingSpecifier];
-            // make sure this is a valid object, so not something like a range 
specifier
-            if ([insertionContainer 
respondsToSelector:@selector(objectSpecifier)] == NO)
-                insertionContainer = nil;
-            containerClassDescription = [insertionContainer 
scriptClassDescription];
-            if ([classDescriptions containsObject:[NSNull null]] == NO) {
-                for (NSString *key in [containerClassDescription 
toManyRelationshipKeys]) {
-                    NSScriptClassDescription *keyClassDescription = 
[containerClassDescription classDescriptionForKey:key];
-                    if ([insertionClassDescription 
isKindOfClassDescription:keyClassDescription] &&
-                        [containerClassDescription 
isLocationRequiredToCreateForKey:key] == NO) {
-                        insertionKey = key;
-                        break;
+        if ([insertionObjects count]) {
+            
+            // get the location to insert
+            id locationSpecifier = [[self arguments] 
objectForKey:@"ToLocation"];
+            id insertionContainer = nil;
+            NSString *insertionKey = nil;
+            NSInteger insertionIndex = -1;
+            NSScriptClassDescription *containerClassDescription = nil;
+            NSArray *classDescriptions = [insertionObjects 
valueForKey:@"scriptClassDescription"];
+            NSScriptClassDescription *insertionClassDescription = 
[classDescriptions containsObject:[NSNull null]] ? nil : 
[NSScriptClassDescription commonAncestorForClassDescriptions:classDescriptions];
+            
+            if ([locationSpecifier isKindOfClass:[NSPositionalSpecifier 
class]]) {
+                [locationSpecifier 
setInsertionClassDescription:insertionClassDescription];
+                insertionContainer = [locationSpecifier insertionContainer];
+                insertionKey = [locationSpecifier insertionKey];
+                insertionIndex = [locationSpecifier insertionIndex];
+            } else if ([locationSpecifier isKindOfClass:[NSPropertySpecifier 
class]]) {
+                insertionContainer = [[locationSpecifier containerSpecifier] 
objectsByEvaluatingSpecifier];
+                insertionKey = [locationSpecifier key];
+            } else if (locationSpecifier) {
+                insertionContainer = [locationSpecifier 
objectsByEvaluatingSpecifier];
+                // make sure this is a valid object, so not something like a 
range specifier
+                if ([insertionContainer 
respondsToSelector:@selector(objectSpecifier)] == NO)
+                    insertionContainer = nil;
+                containerClassDescription = [insertionContainer 
scriptClassDescription];
+                if ([classDescriptions containsObject:[NSNull null]] == NO) {
+                    for (NSString *key in [containerClassDescription 
toManyRelationshipKeys]) {
+                        NSScriptClassDescription *keyClassDescription = 
[containerClassDescription classDescriptionForKey:key];
+                        if ([insertionClassDescription 
isKindOfClassDescription:keyClassDescription] &&
+                            [containerClassDescription 
isLocationRequiredToCreateForKey:key] == NO) {
+                            insertionKey = key;
+                            break;
+                        }
                     }
                 }
             }
-        }
-        
-        // check if the insertion location is valid
-        if (containerClassDescription == nil && insertionContainer)
-            containerClassDescription = [insertionContainer 
scriptClassDescription];
-        if (insertionContainer == nil || insertionKey == nil || 
-            [[containerClassDescription toManyRelationshipKeys] 
containsObject:insertionKey] == NO) {
-            [self setScriptErrorNumber:NSArgumentsWrongScriptError];
-                       [self setScriptErrorString:NSLocalizedString(@"Could 
not find container to add to", @"Error description")];
-            insertionObjects = nil;
-        } else {
-            // check if the inserted objects are valid for the insertion 
container key
-            NSScriptClassDescription *requiredClassDescription = 
[containerClassDescription classDescriptionForKey:insertionKey];
             
-            if ([insertionClassDescription 
isKindOfClassDescription:requiredClassDescription] == NO || 
-                (insertionIndex == -1 && [containerClassDescription 
isLocationRequiredToCreateForKey:insertionKey])) {
+            // check if the insertion location is valid
+            if (containerClassDescription == nil && insertionContainer)
+                containerClassDescription = [insertionContainer 
scriptClassDescription];
+            if (insertionContainer == nil || insertionKey == nil ||
+                [[containerClassDescription toManyRelationshipKeys] 
containsObject:insertionKey] == NO) {
                 [self setScriptErrorNumber:NSArgumentsWrongScriptError];
-                [self setScriptErrorString:NSLocalizedString(@"Invalid 
container to add to", @"Error description")];
+                [self setScriptErrorString:NSLocalizedString(@"Could not find 
container to add to", @"Error description")];
+                insertionObjects = nil;
             } else {
-                // insert using scripting KVC
-                if (insertionIndex >= 0) {
-                    for (id obj in insertionObjects)
-                        [insertionContainer insertValue:obj 
atIndex:insertionIndex++ inPropertyWithKey:insertionKey];
+                // check if the inserted objects are valid for the insertion 
container key
+                NSScriptClassDescription *requiredClassDescription = 
[containerClassDescription classDescriptionForKey:insertionKey];
+                
+                if ([insertionClassDescription 
isKindOfClassDescription:requiredClassDescription] == NO ||
+                    (insertionIndex == -1 && [containerClassDescription 
isLocationRequiredToCreateForKey:insertionKey])) {
+                    [self setScriptErrorNumber:NSArgumentsWrongScriptError];
+                    [self setScriptErrorString:NSLocalizedString(@"Invalid 
container to add to", @"Error description")];
                 } else {
-                    for (id obj in insertionObjects)
-                        [insertionContainer insertValue:obj 
inPropertyWithKey:insertionKey];
+                    // insert using scripting KVC
+                    if (insertionIndex >= 0) {
+                        for (id obj in insertionObjects)
+                            [insertionContainer insertValue:obj 
atIndex:insertionIndex++ inPropertyWithKey:insertionKey];
+                    } else {
+                        for (id obj in insertionObjects)
+                            [insertionContainer insertValue:obj 
inPropertyWithKey:insertionKey];
+                    }
                 }
-                
-                // get the return value, either by getting the objectSpecifier 
or the AppleEventDescriptor
-                returnValue = [NSMutableArray array];
-                for (id obj in insertionObjects) {
-                    id returnObj = nil;
-                    if ([obj respondsToSelector:@selector(objectSpecifier)])
-                        returnObj = [obj objectSpecifier];
-                    if (returnObj == nil)
-                        returnObj = [obj aeDescriptorValue];
-                    if (returnObj)
-                        [returnValue addObject:returnObj];
-                }
-                
             }
         }
     }
-    return isArray ? returnValue : [returnValue firstObject];
+    return nil;
 }
 
 @end

Modified: trunk/bibdesk/BDSKAppController.m
===================================================================
--- trunk/bibdesk/BDSKAppController.m   2018-09-18 06:30:38 UTC (rev 22628)
+++ trunk/bibdesk/BDSKAppController.m   2018-09-18 12:29:37 UTC (rev 22629)
@@ -329,6 +329,11 @@
                                              
selector:@selector(fileURLWithAEDesc:)
                                    forDescriptorTypes:typeFileURL, typeAlias, 
typeFSRef, 'fss ', 'bmrk', nil];
     
+    // register NSScriptObjectSpecifier as conversion handler for specifier 
type
+    [NSAppleEventDescriptor registerConversionHandler:[NSScriptObjectSpecifier 
class]
+                                             
selector:@selector(objectSpecifierWithDescriptor:)
+                                   forDescriptorTypes:typeObjectSpecifier, 
nil];
+    
     // register URL handler
     [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self 
andSelector:@selector(handleGetURLEvent:withReplyEvent:) 
forEventClass:kInternetEventClass andEventID:kAEGetURL];
 }

Modified: trunk/bibdesk/BDSKRemoveCommand.m
===================================================================
--- trunk/bibdesk/BDSKRemoveCommand.m   2018-09-18 06:30:38 UTC (rev 22628)
+++ trunk/bibdesk/BDSKRemoveCommand.m   2018-09-18 12:29:37 UTC (rev 22629)
@@ -39,6 +39,7 @@
 #import "BDSKRemoveCommand.h"
 #import "NSAppleEventDescriptor_BDSKExtensions.h"
 #import "NSScriptClassDescription_BDSKExtensions.h"
+#import "KFASHandlerAdditions-TypeTranslation.h"
 #import "NSObject_BDSKExtensions.h"
 
 
@@ -47,81 +48,80 @@
 - (id)performDefaultImplementation {
     // get the actual objects to remove
     id directParameter = [self directParameter];
-    id receiver = [self evaluatedReceivers];
-    NSArray *removeObjects = nil;
+    // for "any" type, directParameter is an NSAppleEventDescriptor and 
evaulatedReceiver is nil
+    NSArray *removeObjects = [directParameter objCObjectValue];
     
-    if ([directParameter isKindOfClass:[NSAppleEventDescriptor class]] && 
[directParameter descriptorType] == typeAEList) {
-        NSMutableArray *array = [NSMutableArray array];
-        NSUInteger i, iMax = [directParameter numberOfItems];
-        for (i = 1; i <= iMax; i++)
-         [array addObject:[directParameter descriptorAtIndex:i]];
-        directParameter = array;
+    // evaluate object specifiers
+    if ([removeObjects 
respondsToSelector:@selector(objectsByEvaluatingSpecifier)] ||
+        ([removeObjects isKindOfClass:[NSArray class]] &&
+         NSNotFound == [removeObjects indexOfObjectPassingTest:^BOOL(id obj, 
NSUInteger idx, BOOL *stop){ return NO == [obj 
respondsToSelector:@selector(objectsByEvaluatingSpecifier)]; }])) {
+            removeObjects = [removeObjects 
valueForKey:@"objectsByEvaluatingSpecifier"];
     }
     
-    if (directParameter && [directParameter isKindOfClass:[NSArray class]] == 
NO)
-        directParameter = [NSArray arrayWithObjects:directParameter, nil];
-    
-    if (NSNotFound == [directParameter indexOfObjectPassingTest:^BOOL(id obj, 
NSUInteger idx, BOOL *stop){ return NO == [obj 
respondsToSelector:@selector(keyClassDescription)]; }]) {
-        removeObjects = [receiver isKindOfClass:[NSArray class]] ? receiver : 
[NSArray arrayWithObjects:receiver, nil];
-    } else if (NSNotFound == [directParameter 
indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ return NO 
== [obj isKindOfClass:[NSAppleEventDescriptor class]]; }]) {
-        removeObjects = [directParameter valueForKey:@"objCObjectValue"];
-    }
-    
     if (removeObjects == nil) {
         [self setScriptErrorNumber:NSArgumentsWrongScriptError];
         [self setScriptErrorString:NSLocalizedString(@"Invalid or missing 
objects to remove", @"Error description")];
     } else {
         
-        // get the container to remove from
-        id containerSpecifier = [[self arguments] 
objectForKey:@"FromContainer"];
-        id removeContainer = nil;
-        NSString *removeKey = nil;
-        NSScriptClassDescription *containerClassDescription = nil;
-        NSArray *classDescriptions = [removeObjects 
valueForKey:@"scriptClassDescription"];
-        NSScriptClassDescription *removeClassDescription = [classDescriptions 
containsObject:[NSNull null]] ? nil : [NSScriptClassDescription 
commonAncestorForClassDescriptions:classDescriptions];
+        // make sure we have an (unnested) array
+        if ([removeObjects isKindOfClass:[NSArray class]] == NO)
+            removeObjects = [NSArray arrayWithObjects:removeObjects, nil];
+        else if (NSNotFound == [removeObjects 
indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ return NO 
== [obj isKindOfClass:[NSArray class]]; }])
+            removeObjects = [removeObjects 
valueForKeyPath:@"@unionOfArrays.self"];
         
-        if (containerSpecifier == nil) {
-            id obj = directParameter;
-            if ([obj isKindOfClass:[NSArray class]])
-                obj = [obj firstObject];
-            if ([obj respondsToSelector:@selector(containerSpecifier)])
-                containerSpecifier = [obj containerSpecifier];
-        }
-        
-        if ([containerSpecifier isKindOfClass:[NSPropertySpecifier class]]) {
-            removeContainer = [[containerSpecifier containerSpecifier] 
objectsByEvaluatingSpecifier];
-            removeKey = [containerSpecifier key];
-        } else if (containerSpecifier) {
-            removeContainer = [containerSpecifier 
objectsByEvaluatingSpecifier];
-            // make sure this is a valid object, so not something like a range 
specifier
-            if ([removeContainer 
respondsToSelector:@selector(objectSpecifier)] == NO)
-                removeContainer = nil;
-            containerClassDescription = [removeContainer 
scriptClassDescription];
-            for (NSString *key in [containerClassDescription 
toManyRelationshipKeys]) {
-                NSScriptClassDescription *keyClassDescription = 
[containerClassDescription classDescriptionForKey:key];
-                if ([removeClassDescription 
isKindOfClassDescription:keyClassDescription]) {
-                    removeKey = key;
-                    break;
+        if ([removeObjects count]) {
+            
+            // get the container to remove from
+            id containerSpecifier = [[self arguments] 
objectForKey:@"FromContainer"];
+            id removeContainer = nil;
+            NSString *removeKey = nil;
+            NSScriptClassDescription *containerClassDescription = nil;
+            NSArray *classDescriptions = [removeObjects 
valueForKey:@"scriptClassDescription"];
+            NSScriptClassDescription *removeClassDescription = 
[classDescriptions containsObject:[NSNull null]] ? nil : 
[NSScriptClassDescription commonAncestorForClassDescriptions:classDescriptions];
+            
+            if (containerSpecifier == nil) {
+                id obj = directParameter;
+                if ([obj isKindOfClass:[NSArray class]])
+                    obj = [obj firstObject];
+                if ([obj respondsToSelector:@selector(containerSpecifier)])
+                    containerSpecifier = [obj containerSpecifier];
+            }
+            
+            if ([containerSpecifier isKindOfClass:[NSPropertySpecifier 
class]]) {
+                removeContainer = [[containerSpecifier containerSpecifier] 
objectsByEvaluatingSpecifier];
+                removeKey = [containerSpecifier key];
+            } else if (containerSpecifier) {
+                removeContainer = [containerSpecifier 
objectsByEvaluatingSpecifier];
+                // make sure this is a valid object, so not something like a 
range specifier
+                if ([removeContainer 
respondsToSelector:@selector(objectSpecifier)] == NO)
+                    removeContainer = nil;
+                containerClassDescription = [removeContainer 
scriptClassDescription];
+                for (NSString *key in [containerClassDescription 
toManyRelationshipKeys]) {
+                    NSScriptClassDescription *keyClassDescription = 
[containerClassDescription classDescriptionForKey:key];
+                    if ([removeClassDescription 
isKindOfClassDescription:keyClassDescription]) {
+                        removeKey = key;
+                        break;
+                    }
                 }
             }
-        }
-        
-        // check if the remove location is valid
-        if (containerClassDescription == nil && removeContainer)
-            containerClassDescription = [removeContainer 
scriptClassDescription];
-        if (removeContainer == nil || removeKey == nil || 
-            [[containerClassDescription toManyRelationshipKeys] 
containsObject:removeKey] == NO) {
-            [self setScriptErrorNumber:NSArgumentsWrongScriptError];
-                       [self setScriptErrorString:NSLocalizedString(@"Could 
not find container to remove from", @"Error description")];
-        } else {
-            NSScriptClassDescription *requiredClassDescription = 
[containerClassDescription classDescriptionForKey:removeKey];
             
-            if ([removeClassDescription 
isKindOfClassDescription:requiredClassDescription] == NO) {
+            // check if the remove location is valid
+            if (containerClassDescription == nil && removeContainer)
+                containerClassDescription = [removeContainer 
scriptClassDescription];
+            if (removeContainer == nil || removeKey == nil ||
+                [[containerClassDescription toManyRelationshipKeys] 
containsObject:removeKey] == NO) {
                 [self setScriptErrorNumber:NSArgumentsWrongScriptError];
-                [self setScriptErrorString:NSLocalizedString(@"Invalid 
container to remove from", @"Error description")];
+                [self setScriptErrorString:NSLocalizedString(@"Could not find 
container to remove from", @"Error description")];
             } else {
-                // remove using KVC, I don't know how to use scripting KVC as 
I don't know how to get the indexes in general
-                [[removeContainer mutableArrayValueForKey:removeKey] 
removeObjectsInArray:removeObjects];
+                NSScriptClassDescription *requiredClassDescription = 
[containerClassDescription classDescriptionForKey:removeKey];
+                
+                if ([removeClassDescription 
isKindOfClassDescription:requiredClassDescription] == NO) {
+                    [self setScriptErrorNumber:NSArgumentsWrongScriptError];
+                    [self setScriptErrorString:NSLocalizedString(@"Invalid 
container to remove from", @"Error description")];
+                } else {
+                    // remove using KVC, I don't know how to use scripting KVC 
as I don't know how to get the indexes in general
+                    [[removeContainer mutableArrayValueForKey:removeKey] 
removeObjectsInArray:removeObjects];
+                }
             }
         }
     }

Modified: trunk/bibdesk/Scripting/BibDesk.sdef
===================================================================
--- trunk/bibdesk/Scripting/BibDesk.sdef        2018-09-18 06:30:38 UTC (rev 
22628)
+++ trunk/bibdesk/Scripting/BibDesk.sdef        2018-09-18 12:29:37 UTC (rev 
22629)
@@ -443,13 +443,7 @@
         <command name="add" code="BDSKAdd "
                        description="Add items to a collection.">
             <cocoa class="BDSKAddCommand"/>
-            <direct-parameter
-                               description="the object(s) to add.">
-                <type type="specifier"/>
-                <type type="specifier" list="yes"/>
-                <type type="any"/>
-                <type type="any" list="yes"/>
-            </direct-parameter>
+            <direct-parameter type="any" description="the object(s) to add.">
             <parameter name="to" code="insh"
                 description="The container or location to add the item to.">
                 <cocoa key="ToLocation"/>
@@ -456,24 +450,12 @@
                 <type type="specifier"/>
                 <type type="location specifier"/>
             </parameter>
-            <result description="the added item">
-                <type type="specifier"/>
-                <type type="specifier" list="yes"/>
-                <type type="any"/>
-                <type type="any" list="yes"/>
-            </result>
         </command>
         
         <command name="remove" code="BDSKRemv"
                        description="Remove items from a collection.">
             <cocoa class="BDSKRemoveCommand"/>
-            <direct-parameter
-                               description="the object(s) to remove.">
-                <type type="specifier"/>
-                <type type="specifier" list="yes"/>
-                <type type="any"/>
-                <type type="any" list="yes"/>
-            </direct-parameter>
+            <direct-parameter type="any" description="the object(s) to 
remove.">
             <parameter name="from" code="from" optional="yes"
                 description="The container to remove the object(s) from.">
                 <cocoa key="FromContainer"/>

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to