I have a predicate editor, which the template was generate via the following:
NSArray * test = [NSArray arrayWithObjects:
[NSExpression expressionForKeyPath: @"Abc"],
[NSExpression expressionForKeyPath: @"Def"],
nil];
NSPredicateEditorRowTemplate * template = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions: test
rightExpressionAttributeType: NSStringAttributeType
modifier: NSDirectPredicateModifier
operators: [NSArray arrayWithObject:
[NSNumber numberWithUnsignedInteger:NSContainsPredicateOperatorType]]
options:(NSCaseInsensitivePredicateOption|NSDiacriticInsensitivePredicateOption)];
So if I fill in a predicate editor like this:
When I log out the generated predicate I get:
Abc CONTAINS[cd] "abc" OR Def CONTAINS[cd] "def"
What I'm wondering is if I can somehow have the predicate editors template display be different than the value that gets set in the generated predicate.
EX: I want the output predicate to have:
Field1 CONTAINS[cd] "abc" OR Field2 CONTAINS[cd] "def"
Even though the editor still displays abc
and def
as the fields. Is this possible?
Yes, you can do this.
You want the array of left expressions to be the actual keyPaths in the final predicate. In your case, "Field1"
and "Field2"
.
As for making a different value appear in the popup, here's where a mind-bending concept comes in:
You're going to localize your predicate editor into English.
There are two ways you could do this.
NSDictionary
With a .strings file
In your source, you would include the following in a comment:
// NSLocalizedStringFromTable(@"%[Field1,Field2]@ %[contains]@ %@", @"PredicateEditor", @"")
When you run genstrings
on your source code, this will generate a PredicateEditor.strings
file with the following entries:
"%[Field1]@ %[contains]@ %@" = "%[Field1]@ %[contains]@ %@";
"%[Field2]@ %[contains]@ %@" = "%[Field2]@ %[contains]@ %@";
You would change the values to be:
"%[Field1]@ %[contains]@ %@" = "%[Abc]@ %[contains]@ %@";
"%[Field2]@ %[contains]@ %@" = "%[Def]@ %[contains]@ %@";
Then, when you create your NSPredicateEditor
, you would set the formattingStringsFileName
property to "PredicateEditor"
, and the editor will take care of the rest.
With an NSDictionary
This would follow the same fundamental concepts as the .strings option, except that you would essentially do:
NSDictionary *formatting = @{
@"%[Field1]@ %[contains]@ %@" : @"%[Abc]@ %[contains]@ %@",
@"%[Field2]@ %[contains]@ %@" : @"%[Def]@ %[contains]@ %@"
}
[myPredicateEditor setFormattingDictionary:formatting];
That's all you have to do.
I blogged about this a long time ago, and that has more information that you might find useful.
Basically you want to modify the title of the menu items in your popup button. That's all you need to do. It shouldn't effect the underlying predicate that you get returned. If you created it in interface builder it's easy to get at the menu items of a template and set their title. But since you did this in code you'll have to fix it in code.
Here's how you might do that. In my row template class I wanted to change the width of my NSTextFields. So in my row template class I look for them and modify them like this...
- (void)awakeFromNib {
NSArray* views = [self templateViews];
for (id view in views) {
if ([[view class] isEqual:[NSTextField class]]) {
NSRect tfFrame = [view frame];
tfFrame.size.width = 600;
[view setFrame:tfFrame];
}
}
}
You can see that I get the templateViews and look for the NSTextFields... and then modify them. You could do something similar looking for NSPopupButtons. Once you found one check their menu item titles and look for the ones titled "abc" and "def" and change their title to "Field1" and "Field2" respectively.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With