NSTreeController Grouping Nodes
NSTreeController Grouping Nodes
- Subject: NSTreeController Grouping Nodes
- From: Arved von Brasch <email@hidden>
- Date: Tue, 9 May 2006 23:43:31 +1000
Hello Cocoa Dev List,
I have, probably to know one's great surprise, run into problems with
NSTreeController. I have search extensively on this issue, but no
one seems to be using NSTreeController in this manner, and hence I
haven't been able to find a solution.
I want to represent collections of articles using CoreData. My data
model is made up of 2 entities. An ArticleGroup is the parent Entity
of Articles. ArticleGroups currently have the following attributes:
title, author and leaf. Leaf for ArticleGroups always returns NO.
ArticleGroups would thus have disclosure triangles in my
NSOutlineView. ArticleGroups have a 1-to-many relationship to
themselves named parent and children. Articles inherit from
ArticleGroup, but leaf always returns YES.
I have an NSTreeController bound to these entities, with the children
key path being children and the leaf key path being leaf. I have an
NSOutlineView with title and author columns, each bound to the
respective attributes from the data model.
The idea is that as your reading various articles, you can add them
to the program, hence Articles can appear at the top level. As you
add more, you can group articles together based on subject or
whatever. Hence, an ArticleGroup can contain many Articles but isn't
an article itself. An ArticleGroup should not be able to exist if it
contains no Articles.
I can happily add articles to the top level using the add: method on
the NSTreeController. The trouble comes when I try to implement
grouping. I have quite complex logic for working out when grouping
or ungrouping should be allowed, and what happens if two groups are
grouped together, etc, but that's getting ahead of myself. I'm
having problems with getting the NSTreeController to group two
previously existing items. As the Articles could be anywhere in the
selection, I don't feel I can use the add: or insert: methods that
NSTreeController provides.
For the simple case of a selection that includes only top level
articles I do this:
// IBOutlet NSTreeController articles;
- (IBAction)group: (id)sender {
NSArray *allGroups = [[articles selectedObjects]
filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"leaf
== 0"]];
NSArray * articlesNotInGroups = [[articles selectedObjects]
filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"leaf
== 1 AND parent == nil"]];
if ([allGroups count] == 0 && [articlesNotInGroups count] ==
[[articles selectedObjects] count]) {
// Group creation
NSManagedObject *group = [NSEntityDescription
insertNewObjectForEntityForName: @"ArticleGroup"
inManagedObjectContext: [articles managedObjectContext]];
[[articles selectedObjects] setValue: group forKey: @"parent"];
[articles addObject: group];
}
}
I will eventually add to this method to include logic for what should
happen if an ArticleGroup is included in the selection, but this
simple case is causing me trouble for now.
Testing indicates that this method finishes before problems start.
The first is that the new group does not appear in the NSOutlineView,
and the selected Articles remain at the top level. I also get weird
console messages about Article not responding to isEqualToString or
Compare.
I've tried calling rearrangeObjects on my NSTreeController and
various other tricks, but nothing seems to work. The new group does
appear if one of the column headers is clicked, but the errors
prevent further testing on its usefulness.
I suspect I'm not notifying the NSTreeController of the changes
properly, but I can't see any methods to do this. Some of the
NSTreeController documentation states that modifying the data
directly is slower, but it does not explicitly forbid it.
Is there a way to do this? I'm already going to have to subclass
NSTreeController to filter the values, but I don't want to have to
write more code than I have to.
Cheers for any help / comments provided,
Arved
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden