NSTreeController Grouping Nodes - Grouping At All
NSTreeController Grouping Nodes - Grouping At All
- Subject: NSTreeController Grouping Nodes - Grouping At All
- From: Arved von Brasch <email@hidden>
- Date: Mon, 29 May 2006 23:10:22 +1000
Hi all,
With a few helpful tips, I've been able to work through almost all of
my NSTreeController problems. Indeed I almost feel that I have
mastered NSTreeController's issues with CoreData.
From before, here is my situation:
I have two CoreData entities as the base of my NSOutlineView:
AritcleGroup and Article. ArticleGroup has attributes title,
author and rating, which are the three OutlineView column
headings. It also has an attribute leaf, and relationships parent
and children. Parent is to-one, and children is to-many, both are
optional. Article inherits from ArticleGroup and adds the
attribute filename which is a path to a the actual PDF or HTML
article, not stored in the CoreData persistent store.
I only want 2 levels in my OutlineView. Articles should be able to
appear at the top level or as one of the children of an
ArticleGroup. ArticleGroups should only be able to appear at the
top level. This is why Articles inherit from ArticleGroup, so they
can just as happily be at the top level.
The behaviour I want is for the user to be able to select several
top level articles and then click a group button. This should
result in an ArticleGroup being created with its children being the
previously selected Articles.
I have managed to make an NSTreeController subclass support this
behaviour with one behavioural anomaly that I am at a loss to explain.
Here is my grouping code:
- (IBAction)group: (id)sender {
NSArray *selectedArticles = [[self selectedObjects]
filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"leaf
== 1"]];
NSArray *selectedGroups = [[self selectedObjects]
filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"leaf
== 0"]];
NSMutableSet *oldGroups = [NSMutableSet setWithArray:
[selectedArticles valueForKey: @"parent"]];
[oldGroups addObjectsFromArray: selectedGroups];
[oldGroups removeObject: [NSNull null]];
NSManagedObject *group;
if ([selectedGroups count] == 0)
group = [NSEntityDescription insertNewObjectForEntityForName: [self
entityName] inManagedObjectContext: [self managedObjectContext]];
else
group = [selectedGroups objectAtIndex: 0];
[[selectedGroups valueForKey: @"children"] setValue: group forKey:
@"parent"];
[selectedArticles setValue: group forKey: @"parent"];
// Clean up: remove groups with no children
id current;
NSEnumerator *enumerator = [oldGroups objectEnumerator];
while (current = [enumerator nextObject])
if ([[current valueForKey: @"children"] count] == 0)
[[self managedObjectContext] deleteObject: current];
[[self managedObjectContext] processPendingChanges];
[articleTable expandItem: [self outlineItemForObject: group]];
[articleTable selectRowIndexes: [NSIndexSet indexSetWithIndex:
[articleTable rowForItem: [self outlineItemForObject: group]]]
byExtendingSelection: NO];
}
The group button is only available if the selection has at least 2
items in it. This works wonderfully with all possible selection
possibilities in my NSOutlineView (that I've tested) except one: The
case when there are no ArticleGroups at all and the selection is
every Article available will cause a run time error at the
processPendingChanges stage:
Exception raised during posting of notification. Ignored.
exception: *** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1)
-[NSKeyValueObservance indexPath]: selector not recognized [self =
0x168a3a0]
-[NSKeyValueObservance indexPath]: selector not recognized [self =
0x168a3a0]
I do have custom code for both ArticleGroup and Article, but both
rely on the default implementation for keys 'parent' and 'children'.
As 'leaf' is a transient, I have ArticleGroups always return NO and
Articles always return YES. Otherwise, the only custom code is to
return special values for 'rating' and 'author' in groupings.
Any ideas on why this particular case fails? It is easy enough to
disallow grouping in this case, but that seems like such a hack when
everything else is so elegant.
Cheers and thanks in advance,
Arved von Brasch
_______________________________________________
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