diff --git a/Quicksilver/Code-App/QSController.m b/Quicksilver/Code-App/QSController.m index 6dbc507b0..34fbad132 100644 --- a/Quicksilver/Code-App/QSController.m +++ b/Quicksilver/Code-App/QSController.m @@ -500,6 +500,7 @@ - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard { } - (void)receiveObject:(QSObject *)object { + [[self interfaceController] clearObjectView:[[self interfaceController] dSelector]]; [[self interfaceController] selectObject:object]; [[self interfaceController] actionActivate:nil]; } diff --git a/Quicksilver/Code-QuickStepCore/QSCommand.m b/Quicksilver/Code-QuickStepCore/QSCommand.m index 7d1f9c2d5..1280559ed 100644 --- a/Quicksilver/Code-QuickStepCore/QSCommand.m +++ b/Quicksilver/Code-QuickStepCore/QSCommand.m @@ -102,7 +102,9 @@ - (QSObject *)saveCommand:(QSObject *)dObject toPath:(QSObject *)iObject { id commandObject = [(QSCommand*)dObject dObject]; BOOL asDroplet = [[commandObject identifier] isEqualToString:@"QSDropletItemProxy"]; +#ifdef DEBUG NSLog(@"droplet %d", asDroplet); +#endif NSString *destination = [[[[iObject singleFilePath] stringByAppendingPathComponent:[dObject name]] stringByAppendingPathExtension:asDroplet?@"app":@"qscommand"] firstUnusedFilePath]; if (asDroplet) { [[NSFileManager defaultManager] copyItemAtPath:[[NSBundle mainBundle] pathForResource:@"QSDroplet" ofType:@"app"] toPath:destination error:nil]; @@ -398,34 +400,58 @@ - (QSObject *)execute { #ifdef DEBUG if (VERBOSE) NSLog(@"Execute Command: %@", self); #endif + QSInterfaceController *controller = [(QSController *)[NSApp delegate] interfaceController]; int argumentCount = [(QSAction *)actionObject argumentCount]; - if (argumentCount<2) { - return [actionObject performOnDirectObject:directObject indirectObject:indirectObject]; - } else if (argumentCount == 2) { - if ([indirectObject objectForType:QSTextProxyType]) { - [[(QSController *)[NSApp delegate] interfaceController] executePartialCommand:[NSArray arrayWithObjects:directObject, actionObject, indirectObject, nil]]; - } else if (indirectObject) { - return [aObject performOnDirectObject:directObject indirectObject:indirectObject]; - } else { - if (!indirectObject) { - NSString *selectClass = [[NSUserDefaults standardUserDefaults] stringForKey:@"QSUnidentifiedObjectSelector"]; - id handler = [QSReg getClassInstance:selectClass]; - NSLog(@"handler %@ %@", selectClass, handler); - if (handler && [handler respondsToSelector:@selector(completeAndExecuteCommand:)]) { - [handler completeAndExecuteCommand:self]; - return nil; + if (argumentCount == 2 && (!indirectObject || [[indirectObject primaryType] isEqualToString:QSTextProxyType])) { + // indirect object required, but is either missing or asking for text input + if (!indirectObject) { + // attempt to use the Missing Object Selector + NSString *selectClass = [[NSUserDefaults standardUserDefaults] stringForKey:@"QSUnidentifiedObjectSelector"]; + id handler = [QSReg getClassInstance:selectClass]; +#ifdef DEBUG + NSLog(@"handler %@ %@", selectClass, handler); +#endif + if (handler && [handler respondsToSelector:@selector(completeAndExecuteCommand:)]) { + [handler completeAndExecuteCommand:self]; + return nil; + } + } + // use Quicksilver's interface to get the missing object + [controller executePartialCommand:[NSArray arrayWithObjects:directObject, actionObject, indirectObject, nil]]; + } else { + // indirect object is either present, or unnecessary - run the action + QSObject *returnValue = [actionObject performOnDirectObject:directObject indirectObject:indirectObject]; + if (returnValue) { + // if the action returns something, wipe out the first pane + /* (The main object would get replaced anyway. This is only done to + remove objects selected by the comma trick before the action was run.) */ + [controller clearObjectView:[controller dSelector]]; + // put the result in the first pane and in the results list + [[controller dSelector] performSelectorOnMainThread:@selector(setObjectValue:) withObject:returnValue waitUntilDone:YES]; + if (actionObject) { + if ([actionObject isKindOfClass:[QSRankedObject class]] && [(QSRankedObject *)actionObject object]) { + QSAction* rankedAction = [(QSRankedObject *)actionObject object]; + if (rankedAction != actionObject) { + [rankedAction retain]; + [actionObject release]; + actionObject = rankedAction; + } + } + // bring the interface back to show the result + if ([actionObject displaysResult]) { + // send focus to the second pane if the user has set the preference + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"QSJumpToActionOnResult"]) { + [controller actionActivate:nil]; + } + [controller showMainWindow:controller]; } } - [[(QSController *)[NSApp delegate] interfaceController] executePartialCommand:[NSArray arrayWithObjects:directObject, actionObject, indirectObject, nil]]; + return returnValue; } - return nil; } return nil; -// NS_DURING -// NS_HANDLER -// ; -// NS_ENDHANDLER } + - (void)executeFromMenu:(id)sender { //NSLog(@"sender %@", NSStringFromClass([sender class]) ); QSObject *object = [self execute]; diff --git a/Quicksilver/Code-QuickStepInterface/QSInterfaceController.h b/Quicksilver/Code-QuickStepInterface/QSInterfaceController.h index af49bb851..624f20ce3 100644 --- a/Quicksilver/Code-QuickStepInterface/QSInterfaceController.h +++ b/Quicksilver/Code-QuickStepInterface/QSInterfaceController.h @@ -96,4 +96,5 @@ - (BOOL)preview; - (void)setPreview:(BOOL)flag; +- (void)clearObjectView:(QSSearchObjectView *)view; @end diff --git a/Quicksilver/Code-QuickStepInterface/QSInterfaceController.m b/Quicksilver/Code-QuickStepInterface/QSInterfaceController.m index 8911ddcb9..15072762e 100644 --- a/Quicksilver/Code-QuickStepInterface/QSInterfaceController.m +++ b/Quicksilver/Code-QuickStepInterface/QSInterfaceController.m @@ -519,29 +519,8 @@ - (void)executeCommandThreaded { dObject = [(QSRankedObject*)dObject object]; if( [iObject isKindOfClass:[QSRankedObject class]] ) iObject = [(QSRankedObject*)iObject object]; - QSObject *returnValue = [action performOnDirectObject:dObject indirectObject:iObject]; - if (returnValue) { - // if the action returns something, wipe out the first pane - /* (The main object would get replaced anyway. This is only done to - remove objects selected by the comma trick before the action was run.) */ - [self clearObjectView:dSelector]; - // put the result in the first pane and in the results list - [dSelector performSelectorOnMainThread:@selector(setObjectValue:) withObject:returnValue waitUntilDone:YES]; - if (action) { - if ([action isKindOfClass:[QSRankedObject class]] && [(QSRankedObject *)action object]) { - QSAction* rankedAction = [(QSRankedObject *)action object]; - if (rankedAction != action) { - [rankedAction retain]; - [action release]; - action = rankedAction; - } - } - // bring the interface back to show the result - if ([action displaysResult]) { - [self actionActivate:nil]; - } - } - } + QSCommand *command = [QSCommand commandWithDirectObject:dObject actionObject:action indirectObject:iObject]; + [command execute]; #ifdef DEBUG if (VERBOSE) NSLog(@"Command executed (%dms) ", (int)(-[startDate timeIntervalSinceNow] *1000)); #endif @@ -550,6 +529,8 @@ - (void)executeCommandThreaded { } - (void)executePartialCommand:(NSArray *)array { + // remove objects previously selected by the comma trick + [self clearObjectView:dSelector]; [dSelector setObjectValue:[array objectAtIndex:0]]; if ([array count] == 1) { [self updateActionsNow];