Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSPredicateEditor & NSExpression - Can the display be different than the value for the predicate?

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: Predicate Editor

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?

like image 341
Kyle Avatar asked Dec 06 '12 18:12

Kyle


2 Answers

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.

  1. With a .strings file
  2. With an 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.

like image 112
Dave DeLong Avatar answered Nov 03 '22 15:11

Dave DeLong


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.

like image 31
regulus6633 Avatar answered Nov 03 '22 16:11

regulus6633