Revision: 24326
          http://sourceforge.net/p/bibdesk/svn/24326
Author:   hofman
Date:     2019-10-22 14:49:04 +0000 (Tue, 22 Oct 2019)
Log Message:
-----------
Run all script hooks asynchronously. Perform paper filing using a recursive 
block, because the Will Auto File script hook may make it asynchronous.

Modified Paths:
--------------
    trunk/bibdesk/BDSKAppleScript.h
    trunk/bibdesk/BDSKAppleScript.m
    trunk/bibdesk/BDSKFiler.m
    trunk/bibdesk/BDSKScriptHookManager.m

Modified: trunk/bibdesk/BDSKAppleScript.h
===================================================================
--- trunk/bibdesk/BDSKAppleScript.h     2019-10-22 14:45:24 UTC (rev 24325)
+++ trunk/bibdesk/BDSKAppleScript.h     2019-10-22 14:49:04 UTC (rev 24326)
@@ -41,12 +41,10 @@
 
 @interface BDSKAppleScript : NSObject {
     id appleScript;
-    BOOL synchronous;
 }
 
 + (dispatch_queue_t)appleScriptQueue;
 
-- (id)initWithURL:(NSURL *)url synchronous:(BOOL)sync error:(NSError **)error;
 - (id)initWithURL:(NSURL *)url error:(NSError **)error;
 - (id)initWithSource:(NSString *)source;
 

Modified: trunk/bibdesk/BDSKAppleScript.m
===================================================================
--- trunk/bibdesk/BDSKAppleScript.m     2019-10-22 14:45:24 UTC (rev 24325)
+++ trunk/bibdesk/BDSKAppleScript.m     2019-10-22 14:49:04 UTC (rev 24326)
@@ -79,10 +79,10 @@
     return [NSError errorWithDomain:@"NSAppleScriptErrorDomain" code:code 
userInfo:userInfo];
 }
 
-- (id)initWithURL:(NSURL *)url synchronous:(BOOL)sync error:(NSError **)error {
+- (id)initWithURL:(NSURL *)url error:(NSError **)error {
     self = [super init];
     if (self) {
-        if (sync == NO && NSUserAppleScriptTaskClass) {
+        if (NSUserAppleScriptTaskClass) {
             appleScript = [[NSUserAppleScriptTaskClass alloc] initWithURL:url 
error:error];
         } else {
             NSDictionary *errorDict = nil;
@@ -90,7 +90,6 @@
             if (appleScript == nil && error != NULL)
                 *error = errorFromDictionary(errorDict);
         }
-        synchronous = sync;
         if (appleScript == nil) {
             [self release];
             self = nil;
@@ -99,16 +98,10 @@
     return self;
 }
 
-- (id)initWithURL:(NSURL *)url error:(NSError **)error {
-    self = [self initWithURL:url synchronous:NO error:error];
-    return self;
-}
-
 - (id)initWithSource:(NSString *)source {
     self = [super init];
     if (self) {
         appleScript = [[NSAppleScript alloc] initWithSource:source];
-        synchronous = NO;
         if (appleScript == nil) {
             [self release];
             self = nil;
@@ -125,28 +118,6 @@
 - (void)executeWithAppleEvent:(NSAppleEventDescriptor *)event 
completionHandler:(void (^)(NSAppleEventDescriptor *result, NSError 
*error))handler {
     if ([appleScript 
respondsToSelector:@selector(executeWithAppleEvent:completionHandler:)]) {
         [appleScript executeWithAppleEvent:event completionHandler:handler];
-    } else if (synchronous) {
-        if (event && [appleScript 
respondsToSelector:@selector(executeAppleEvent:error:)]) {
-            dispatch_sync([[self class] appleScriptQueue], ^{
-                NSError *error = nil;
-                NSDictionary *errorDict = nil;
-                NSAppleEventDescriptor *result = [appleScript 
executeAppleEvent:event error:&errorDict];
-                if (result == nil)
-                    error = errorFromDictionary(errorDict);
-                if (handler)
-                    handler(result, error);
-            });
-        } else if (event == nil && [appleScript 
respondsToSelector:@selector(executeAndReturnError:)]) {
-            dispatch_sync([[self class] appleScriptQueue], ^{
-                NSError *error = nil;
-                NSDictionary *errorDict = nil;
-                NSAppleEventDescriptor *result = [appleScript 
executeAndReturnError:&errorDict];
-                if (result == nil)
-                    error = errorFromDictionary(errorDict);
-                if (handler)
-                    handler(result, error);
-            });
-        }
     } else if (event && [appleScript 
respondsToSelector:@selector(executeAppleEvent:error:)]) {
         dispatch_async([[self class] appleScriptQueue], ^{
             NSError *error = nil;

Modified: trunk/bibdesk/BDSKFiler.m
===================================================================
--- trunk/bibdesk/BDSKFiler.m   2019-10-22 14:45:24 UTC (rev 24325)
+++ trunk/bibdesk/BDSKFiler.m   2019-10-22 14:49:04 UTC (rev 24326)
@@ -185,125 +185,149 @@
         [[self window] orderFront:nil];
        }
        
-       for (id paperInfo in paperInfos) {
-        BDSKLinkedFile *file = [paperInfo valueForKey:BDSKFilerFileKey];
-        BibItem *pub = [paperInfo valueForKey:BDSKFilerPublicationKey];
-        NSString *oldPath = nil;
-        NSString *newPath = nil;
+    __block void (^filePaperInfo)(NSInteger) = Block_copy(^(NSInteger i){
         
-        if (generate == NO) // new path provided, e.g. undo
-            newPath = [paperInfo valueForKey:BDSKFilerNewPathKey];
-        else if (isLinkedFiles) // initial auto file of file
-            newPath = [[pub suggestedURLForLinkedFile:file] path];
-        else // initial auto file of field
-            newPath = [[pub suggestedURLForField:field] path];
-        if (isLinkedFiles)
-            oldPath = [file path];
-        else if (initial)
-            oldPath = [[pub localFileURLForField:field] path];
-        else
-            oldPath = [paperInfo valueForKey:BDSKFilerOldPathKey];
+        if (i < numberOfPapers) {
+            // file the i'th paper
+            
+            id paperInfo = [paperInfos objectAtIndex:i];
+            BDSKLinkedFile *file = [paperInfo valueForKey:BDSKFilerFileKey];
+            BibItem *pub = [paperInfo valueForKey:BDSKFilerPublicationKey];
+            NSString *oldPath = nil;
+            NSString *newPath = nil;
         
-               if (numberOfPapers > 1) {
-                       [progressIndicator incrementBy:1.0];
-                       [progressIndicator displayIfNeeded];
-               }
-                       
-               if ([NSString isEmptyString:oldPath]) {
+            if (generate == NO) // new path provided, e.g. undo
+                newPath = [paperInfo valueForKey:BDSKFilerNewPathKey];
+            else if (isLinkedFiles) // initial auto file of file
+                newPath = [[pub suggestedURLForLinkedFile:file] path];
+            else // initial auto file of field
+                newPath = [[pub suggestedURLForField:field] path];
             if (isLinkedFiles)
-                [pub removeFileToBeFiled:file];
-                       continue;
-        }
+                oldPath = [file path];
+            else if (initial)
+                oldPath = [[pub localFileURLForField:field] path];
+            else
+                oldPath = [paperInfo valueForKey:BDSKFilerOldPathKey];
         
-        NSMutableDictionary *info = [NSMutableDictionary 
dictionaryWithCapacity:6];
-               [info setValue:file forKey:BDSKFilerFileKey];
-               [info setValue:oldPath forKey:BDSKFilerOldPathKey];
-               [info setValue:pub forKey:BDSKFilerPublicationKey];
+            if (numberOfPapers > 1) {
+                [progressIndicator incrementBy:1.0];
+                [progressIndicator displayIfNeeded];
+            }
         
-        if (check && NO == (isLinkedFiles ? [pub canSetURLForLinkedFile:file] 
: [pub canSetURLForField:field])) {
-            
-            [info setValue:NSLocalizedString(@"Incomplete information to 
generate file name.",@"") forKey:BDSKFilerStatusKey];
-            [info setValue:[NSNumber 
numberWithInteger:BDSKIncompleteFieldsErrorMask] forKey:BDSKFilerFlagKey];
-            [info setValue:NSLocalizedString(@"Move anyway.",@"") 
forKey:BDSKFilerFixKey];
-            [info setValue:newPath forKey:BDSKFilerNewPathKey];
-            [errorInfoDicts addObject:info];
-            
-        } else if ([NSString isEmptyString:newPath] || [oldPath 
isEqualToString:newPath]) {
-            
-            if (isLinkedFiles)
-                [pub removeFileToBeFiled:file];
-            else if ([field isEqualToString:BDSKLocalUrlString])
-                [pub setLocalUrlNeedsToBeFiled:NO];
-            
-        } else {
-            
-            [[BDSKScriptHookManager sharedManager] 
runScriptHookWithName:BDSKWillAutoFileScriptHookName 
-                forPublications:[NSArray arrayWithObject:pub] document:doc 
-                field:field oldValues:[NSArray arrayWithObject:oldPath] 
newValues:[NSArray arrayWithObject:newPath]];
-            
-            NSError *error = nil;
-            
-            if (NO == [[NSFileManager defaultManager] moveItemAtURL:[NSURL 
fileURLWithPath:oldPath isDirectory:NO] toURL:[NSURL fileURLWithPath:newPath 
isDirectory:NO] force:force error:&error]){
+            if ([NSString isEmptyString:oldPath]) {
+                if (isLinkedFiles)
+                    [pub removeFileToBeFiled:file];
                 
-                NSDictionary *errorInfo = [error userInfo];
-                [info setValue:[errorInfo 
objectForKey:NSLocalizedRecoverySuggestionErrorKey] forKey:BDSKFilerFixKey];
-                [info setValue:[errorInfo 
objectForKey:NSLocalizedDescriptionKey] forKey:BDSKFilerStatusKey];
-                [info setValue:[NSNumber numberWithInteger:[error code]] 
forKey:BDSKFilerFlagKey];
+                filePaperInfo(i + 1);
+                return;
+            }
+        
+            NSMutableDictionary *info = [NSMutableDictionary 
dictionaryWithCapacity:6];
+            [info setValue:file forKey:BDSKFilerFileKey];
+            [info setValue:oldPath forKey:BDSKFilerOldPathKey];
+            [info setValue:pub forKey:BDSKFilerPublicationKey];
+        
+            if (check && NO == (isLinkedFiles ? [pub 
canSetURLForLinkedFile:file] : [pub canSetURLForField:field])) {
+                
+                [info setValue:NSLocalizedString(@"Incomplete information to 
generate file name.",@"") forKey:BDSKFilerStatusKey];
+                [info setValue:[NSNumber 
numberWithInteger:BDSKIncompleteFieldsErrorMask] forKey:BDSKFilerFlagKey];
+                [info setValue:NSLocalizedString(@"Move anyway.",@"") 
forKey:BDSKFilerFixKey];
                 [info setValue:newPath forKey:BDSKFilerNewPathKey];
                 [errorInfoDicts addObject:info];
                 
-            } else {
+                filePaperInfo(i + 1);
                 
-                // switch them as this is used in undo
-                [info setValue:oldPath forKey:BDSKFilerNewPathKey];
-                [info setValue:newPath forKey:BDSKFilerOldPathKey];
-                [fileInfoDicts addObject:info];
+            } else if ([NSString isEmptyString:newPath] || [oldPath 
isEqualToString:newPath]) {
                 
-                if (isLinkedFiles) {
-                    [file updateWithPath:newPath];
-                    // make sure the UI is updated
-                    [pub noteFilesChanged:YES];
-                } else if (initial) {
-                    // if this is not an initial move, undo should take care 
of this
-                    NSString *value = [pub fieldValueForFileURL:[NSURL 
fileURLWithPath:newPath isDirectory:NO] withFormat:[[NSUserDefaults 
standardUserDefaults] integerForKey:BDSKLocalFileOptionKey]];
-                    [pub setField:field toValue:value];
-                    // make sure the undo of the move is paired with setting 
the field
-                    // the undo group may be broken up due to the script hooks
-                    [[[doc undoManager] prepareWithInvocationTarget:self] 
movePapers:[NSArray arrayWithObject:info] forField:field fromDocument:doc 
options:0 actionName:nil];
-                    if (actionName)
-                        [[doc undoManager] setActionName:actionName];
-                }
+                if (isLinkedFiles)
+                    [pub removeFileToBeFiled:file];
+                else if ([field isEqualToString:BDSKLocalUrlString])
+                    [pub setLocalUrlNeedsToBeFiled:NO];
                 
-                [[BDSKScriptHookManager sharedManager] 
runScriptHookWithName:BDSKDidAutoFileScriptHookName
-                    forPublications:[NSArray arrayWithObject:pub] document:doc 
-                    field:field oldValues:[NSArray arrayWithObject:oldPath] 
newValues:[NSArray arrayWithObject:newPath]];
+                filePaperInfo(i + 1);
                 
+            } else {
+                
+                [[BDSKScriptHookManager sharedManager] 
runScriptHookWithName:BDSKWillAutoFileScriptHookName
+                    forPublications:[NSArray arrayWithObject:pub] document:doc
+                    field:field oldValues:[NSArray arrayWithObject:oldPath] 
newValues:[NSArray arrayWithObject:newPath]
+                    completionHandler:^{
+                    
+                    NSError *error = nil;
+                    
+                    if (NO == [[NSFileManager defaultManager] 
moveItemAtURL:[NSURL fileURLWithPath:oldPath isDirectory:NO] toURL:[NSURL 
fileURLWithPath:newPath isDirectory:NO] force:force error:&error]){
+                        
+                        NSDictionary *errorInfo = [error userInfo];
+                        [info setValue:[errorInfo 
objectForKey:NSLocalizedRecoverySuggestionErrorKey] forKey:BDSKFilerFixKey];
+                        [info setValue:[errorInfo 
objectForKey:NSLocalizedDescriptionKey] forKey:BDSKFilerStatusKey];
+                        [info setValue:[NSNumber numberWithInteger:[error 
code]] forKey:BDSKFilerFlagKey];
+                        [info setValue:newPath forKey:BDSKFilerNewPathKey];
+                        [errorInfoDicts addObject:info];
+                        
+                    } else {
+                        
+                        // switch them as this is used in undo
+                        [info setValue:oldPath forKey:BDSKFilerNewPathKey];
+                        [info setValue:newPath forKey:BDSKFilerOldPathKey];
+                        [fileInfoDicts addObject:info];
+                        
+                        if (isLinkedFiles) {
+                            [file updateWithPath:newPath];
+                            // make sure the UI is updated
+                            [pub noteFilesChanged:YES];
+                        } else if (initial) {
+                            // if this is not an initial move, undo should 
take care of this
+                            NSString *value = [pub fieldValueForFileURL:[NSURL 
fileURLWithPath:newPath isDirectory:NO] withFormat:[[NSUserDefaults 
standardUserDefaults] integerForKey:BDSKLocalFileOptionKey]];
+                            [pub setField:field toValue:value];
+                            // make sure the undo of the move is paired with 
setting the field
+                            // the undo group may be broken up due to the 
script hooks
+                            [[[doc undoManager] 
prepareWithInvocationTarget:self] movePapers:[NSArray arrayWithObject:info] 
forField:field fromDocument:doc options:0 actionName:nil];
+                            if (actionName)
+                                [[doc undoManager] setActionName:actionName];
+                        }
+                        
+                        [[BDSKScriptHookManager sharedManager] 
runScriptHookWithName:BDSKDidAutoFileScriptHookName
+                            forPublications:[NSArray arrayWithObject:pub] 
document:doc
+                            field:field oldValues:[NSArray 
arrayWithObject:oldPath] newValues:[NSArray arrayWithObject:newPath]];
+                        
+                    }
+                    
+                    // we always do this even when it failed, to avoid 
retrying at every edit
+                    [pub removeFileToBeFiled:file];
+                    
+                    filePaperInfo(i + 1);
+                }];
             }
             
-            // we always do this even when it failed, to avoid retrying at 
every edit
-            [pub removeFileToBeFiled:file];
+        } else {
+            // we've exhauster the paperInfos array, finish up
             
+            if (numberOfPapers > 1)
+                [[self window] orderOut:nil];
+            
+            if ((isLinkedFiles || initial == NO) && [fileInfoDicts count] > 0) 
{
+                [[[doc undoManager] prepareWithInvocationTarget:self] 
movePapers:fileInfoDicts forField:field fromDocument:doc options:0 
actionName:nil];
+                if (actionName)
+                    [[doc undoManager] setActionName:actionName];
+            }
+            
+            if ([errorInfoDicts count] > 0) {
+                BDSKFilerErrorController *errorController = 
[[[BDSKFilerErrorController alloc] initWithErrors:errorInfoDicts forField:field 
options:mask actionName:actionName] autorelease];
+                [doc addWindowController:errorController];
+                [errorController showWindow:nil];
+            }
+            
+            filing = NO;
+            
+            [self runPendingFilingIfNeeded];
+            
+            // this balances the Block_copy, avoids a retain cycle
+            Block_release(filePaperInfo);
         }
-       }
+    });
        
-       if (numberOfPapers > 1)
-               [[self window] orderOut:nil];
-       
-    if ((isLinkedFiles || initial == NO) && [fileInfoDicts count] > 0) {
-        [[[doc undoManager] prepareWithInvocationTarget:self] 
movePapers:fileInfoDicts forField:field fromDocument:doc options:0 
actionName:nil];
-        if (actionName)
-            [[doc undoManager] setActionName:actionName];
-    }
-       
-       if ([errorInfoDicts count] > 0) {
-        BDSKFilerErrorController *errorController = 
[[[BDSKFilerErrorController alloc] initWithErrors:errorInfoDicts forField:field 
options:mask actionName:actionName] autorelease];
-        [doc addWindowController:errorController];
-        [errorController showWindow:nil];
-    }
-    
-    filing = NO;
-    
-    [self runPendingFilingIfNeeded];
+    // file the first paper, this will recursively call the next one
+    filePaperInfo(0);
 }
 
 @end

Modified: trunk/bibdesk/BDSKScriptHookManager.m
===================================================================
--- trunk/bibdesk/BDSKScriptHookManager.m       2019-10-22 14:45:24 UTC (rev 
24325)
+++ trunk/bibdesk/BDSKScriptHookManager.m       2019-10-22 14:49:04 UTC (rev 
24326)
@@ -122,9 +122,8 @@
         NSLog(@"No script file found for script hook %@.", name);
                return nil;
        } else {
-        BOOL sync = [name isEqualToString:BDSKWillAutoFileScriptHookName];
                NSError *error = nil;
-        script = [[BDSKAppleScript alloc] initWithURL:[NSURL 
fileURLWithPath:path isDirectory:NO] synchronous:sync error:&error];
+        script = [[BDSKAppleScript alloc] initWithURL:[NSURL 
fileURLWithPath:path isDirectory:NO] error:&error];
                if (script == nil) {
                        NSLog(@"Error creating AppleScript: %@", error);
                        return nil;

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



_______________________________________________
Bibdesk-commit mailing list
Bibdesk-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to