Re: Having problems understanding NSPredicateEditor

2009-12-27 Thread Timothy Stafford Larkin
The only way I have done this is to build the thing in IB.

Forget the NSSearchField.

First add a Predicate Editor to a window. This gives you a top-level compound 
predicate (Any of the following are true) and a single predicate template. 
The predicate template has three parts, a left expression, a set of operators, 
and a right expression. Click on the template to show its attributes in the 
Inspector. 

Each template combines a single type of L.E, e.g. Key Paths, and a single type 
of R.E., e.g. Strings, and a set of operators. For instance, all the searchable 
key paths that have string values are included in a single template. You would 
add cardName and any other searchable string variable. In the middle section, 
select the required comparison operators. The R.E. is then set to Strings, and 
since these are provided by the user, you don't list them here. If you had a 
date variable, then you make another template, this time setting the R.E. to 
Date. Obviously there are many combinations possible, since there are 6 
possibilities for L.E. and R.E. You need to work out the characteristics of 
each template appropriately.

You must understand that, although the editor you create in I.B. looks visually 
like the filter predicate the user creates, it really is very different. The 
set of the templates you create in I.B. define the types of comparisons the 
user can make, but doesn't create any instances of them. The user instantiates 
as many of each template as he likes at run time to build the total predicate.

When you enter the list of L.E.s, the left popup in the row template is 
populated with choices that have the same names as appear in the L.E. list. You 
can change the popup item strings by double-clicking the item and changing the 
string, in the usual way.

Once you understand this much, you should understand how many templates you 
need. (This does not mean how many filter comparisons the user can define, 
which are unlimited, but how many types of comparisons your program allows. For 
instance, a comparison of a key path to a string would be one, to a date would 
be another, to a constant a third, and so on.) Call this number N. Now you 
should examine the Editor itself in the Inspector and set the number of 
templates to N. This will produce N templates. You set up each one of them to 
match one of the types of comparison.

The editor also has an attribute to allow all rows to be deleted. If this is 
turned on, then the top row template can be deleted by the user using the minus 
button. If the user does this, then the top level compound row also disappears 
(sometimes), leaving a totally blank view, which makes the editor useless. At 
least this was the case under Leopard. So you pretty much have to turn this 
off. This leaves you with a predicate that must have at least one comparison, 
even if you might like to have a predicate editor without any comparisons, 
which would match everything. I'm suspicious that I don't quite understand 
what's going on here, but I haven't achieved any greater clarity.

Now, when the editor is created out of the nib file, it is created with a 
single empty compound. But since this produces a editor that is totally blank, 
it is useless. So at some early stage, for instance, in awakeFromNib, you have 
to add a row by sending the editor an addRow message. Adding this row actually 
produces two rows, since once a row template is added, the compound row also 
appears, and you're good to go.

I have used the action method of the predicate editor to inform my app delegate 
that the user has changed the predicate, which I then apply to an array 
controller. There are probably other approaches.

I have not created one of these in Snow Leopard, so some of the details may 
have changed.

Tim Larkin
Abstract Tools


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Having problems understanding NSPredicateEditor

2009-12-26 Thread Mike Chambers
I have an application that contains a NSTableView of Card data types.
The NSTableView gets its data from an NSArray of Card instances.

I want to allow the user to be able to filter the view based on the
Card fields. I know I need to use a NSPredicateEditor to present the
UI for the user, and to create the NSPredicate instances. However, I
cannot wrap my head around how this works, and cannot get a simple
example working (with a single rule). I have spent the last two days
reading up on it, and it is just not clicking for me.

So, does anyone have a very simple example of how to use
NSPredicateEditor programmatically?

I want to be able to allow the user to potentially filter on multiple
fields, but would be happy if I can get a single field to work right
now.

Here is the current predicate I am using with a NSSearchField:

NSPredicate *namePredicate = [NSPredicate
predicateWithFormat:@cardName contains[c] %@, searchString];
[filteredCards filterUsingPredicate:namePredicate];

Card has a property (NSString) named cardName.

I have tried to programmatically add a NSPredicateEditorRowTemplate,
but when I do this, nothing shows up in the editor at runtime.

NSPredicateEditorRowTemplate *template = [[NSPredicateEditorRowTemplate alloc]
 initWithLeftExpressions:[NSArray arrayWithObjects:[NSExpression
expressionForKeyPath:@cardName], nil]
rightExpressions:[NSArray arrayWithObjects:[NSExpression
expressionForConstantValue:@Foo], nil]
modifier:NSDirectPredicateModifier

  operators:[NSArray arrayWithObject:[NSNumber
numberWithInt:NSContainsPredicateOperatorType]]
options:NSCaseInsensitivePredicateOption
 ];

predicateEditor.rowTemplates = [NSArray arrayWithObject:template];

I am really stumped on this one, and would appreciate it if someone
could help nudge me in the right direction. Does anyone have a simple
example of how to construct NSPredicateEditorRowTemplate that will
create a filter like so:

cardName contains USER_INPUT

I think if I can get that working, then it will put me over the hump
and I can figure out the rest.

mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com