New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Action config #2423
Action config #2423
Changes from 2 commits
d170d62
0c5cacf
6153603
320ee7b
e4eadbe
f4a64ed
68853ea
30d7dfd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
#import "QSResourceManager.h" | ||
#import "NSBundle_BLTRExtensions.h" | ||
#import "QSExecutor.h" | ||
#import <objc/objc-runtime.h> | ||
|
||
//static NSDictionary *actionPrecedence; | ||
|
||
|
@@ -119,6 +120,12 @@ - (CGFloat)precedence { | |
return num ? [num doubleValue] : 0.0; | ||
} | ||
|
||
- (void)setPrecedence:(CGFloat)precedence | ||
{ | ||
NSNumber *num = [NSNumber numberWithFloat:precedence]; | ||
[[self actionDict] setObject:num forKey:kActionPrecedence]; | ||
} | ||
|
||
- (NSInteger)rank { return rank; } | ||
- (void)_setRank:(NSInteger)newRank { | ||
[self willChangeValueForKey:@"rank"]; | ||
|
@@ -192,6 +199,32 @@ - (void)setAction:(SEL)newAction { | |
[[self actionDict] removeObjectForKey:kActionSelector]; | ||
} | ||
|
||
- (BOOL)setActionUisngBlock:(QSObject *(^)(id, QSObject *))actionBlock selectorName:(NSString *)selName | ||
{ | ||
if (![self provider]) { | ||
NSLog(@"define provider before setting a block as the action"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd be tempted to NSAssert that, but maybe I'm being too paranoid… There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It’s mostly there so a developer will catch it during the plug-in’s creation. Wouldn’t an assert crash QS if the mythical developer doesn’t fix things, potentially punishing end users? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, if the mythical lets a crashing assert come up in the wild, isn't the mythical to blame for its sloppiness 😉 ? NSLogs can and will be ignored by the developer, and by the user. Exceptions will not. I'd say document that "It is a programming error to use this method if the action doesn't have a provider". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Of course, but it’s the user that’ll feel the pain. Not the developer. The creators of all these plug-ins aren’t exactly jumping on issues they day they get reported. Or even the year they get reported.
I don’t expect the log message to be what gets their attention. But when they realize their new action doesn’t exist, the message will explain why. If we’re assuming they’re going to fix the issue during development one way or another, I suppose an exception gets the job done. I’ll change it. |
||
return NO; | ||
} | ||
IMP actionFunction = imp_implementationWithBlock(actionBlock); | ||
SEL actionSelector = NSSelectorFromString(selName); | ||
BOOL actionDefined = class_addMethod([[self provider] class], actionSelector, actionFunction, "@@:@"); | ||
[self setAction:actionSelector]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe logging the failure and returning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve made this a little better. |
||
return actionDefined; | ||
} | ||
|
||
- (BOOL)setActionWithIndirectUisngBlock:(QSObject *(^)(id, QSObject *, QSObject *))actionBlock selectorName:(NSString *)selName | ||
{ | ||
if (![self provider]) { | ||
NSLog(@"define provider before setting a block as the action"); | ||
return NO; | ||
} | ||
IMP actionFunction = imp_implementationWithBlock(actionBlock); | ||
SEL actionSelector = NSSelectorFromString(selName); | ||
BOOL actionDefined = class_addMethod([[self provider] class], actionSelector, actionFunction, "@@:@@"); | ||
[self setAction:actionSelector]; | ||
return actionDefined; | ||
} | ||
|
||
- (NSInteger)argumentCount { | ||
id obj = [[self actionDict] objectForKey:kActionArgumentCount]; | ||
if (obj) | ||
|
@@ -222,6 +255,15 @@ - (void)setIndirectOptional:(BOOL)flag { | |
[[self actionDict] setObject:[NSNumber numberWithInteger:flag] forKey:kActionIndirectOptional]; | ||
} | ||
|
||
- (BOOL)validatesObjects | ||
{ | ||
return [[[self actionDict] objectForKey:kActionValidatesObjects] boolValue]; | ||
} | ||
- (void)setValidatesObjects:(BOOL)flag | ||
{ | ||
[[self actionDict] setObject:[NSNumber numberWithInteger:flag] forKey:kActionValidatesObjects]; | ||
} | ||
|
||
- (BOOL)resolvesProxy { | ||
if ([[self actionDict] objectForKey:kActionResolvesProxy] == nil) { | ||
return YES; | ||
|
@@ -364,7 +406,7 @@ - (NSString *)commandFormat { | |
|
||
//Check the action dictionary | ||
if (!format) | ||
format = [[self actionDict] objectForKey:@"commandFormat"]; | ||
format = [[self actionDict] objectForKey:kActionCommandFormat]; | ||
|
||
// Check the main bundle | ||
if (!format) | ||
|
@@ -377,6 +419,11 @@ - (NSString *)commandFormat { | |
return format; | ||
} | ||
|
||
- (void)setCommandFormat:(NSString *)commandFormat | ||
{ | ||
[[self actionDict] setObject:commandFormat forKey:kActionCommandFormat]; | ||
} | ||
|
||
- (CGFloat)score { | ||
return 0.0; | ||
} | ||
|
@@ -426,4 +473,4 @@ - (BOOL)loadIconForObject:(QSObject *)object { | |
return NO; | ||
} | ||
|
||
@end | ||
@end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uisng
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific reason you're using
NSString *
instead ofSEL
? I'd prefer the latter (as well as aselector:
parameter).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Because strings are “normal” and easy to create, while selectors are “weird” and difficult to create. “Difficult” meaning I had to look it up. I didn’t say it was a good reason. 😄 I was just trying to make it as simple as possible on the calling end.
Are you saying it should keep the string but also require you to create and pass in a
SEL
? Or drop the string?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use
-setActionUsingBlock:(…)block selector:(SEL)aSelector
.Take for example
-mySelector:
. If you mistype"mySelectr:"
you will get a "missing method" at runtime. If you use@selector(mySelectr:)
, you willl/should get a compiler warning that it doesn't know about that particular selector.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but the only time you ever type the name is during creation. It can be misspelled and still work. Also, I don’t think the compiler is aware of these methods even if you spell them correctly, so you’ll always get a warning. (I haven’t tested that today, but I think I was seeing such warnings during early attempts.)