Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MrFusion

macrumors 6502a
Original poster
Jun 8, 2005
613
0
West-Europe
Hi folks

I have my own NSTreeController and NSOutlineView subclass, with a coredata backend. I can drag and drop objects around and each object knows it position.

When I change something (add/remove/drag&drop) the position is correctly updated, but the view is not. [myTreeController rearrangeobjects] is called, but only the top group (with parent == nil) is automatically rearranged. All the subgroups are not.

My question is this. Did I overlook something, or is this a bug with NSTreeController? Does this problem sound familiar to you? NSTreeController has had a lot of bugs in the past, from what I can tell. Running 10.5.7 on intel.


thanks for reading
 
I am trying to fix this bug once more, but with no luck so far. Maybe one of you sees the problem?

The bug is this. Adding a new node to a folder, when one of the nodes of that folder is selected, will add a new node to the tree with the correct value for the position. However, in the NSOutlineView the node is not correctly positioned in the tree.

Code:
-(id) addManagedObject:(NSString *) entityName {
	// First get selected object, then add new object. this returns the correct user selection!
	id parent = ([[self selectedObjects] count] > 0) ? [[self selectedObjects] objectAtIndex:0] : nil;
	
	int position = def_newNodePosition;
	if (parent && ![parent isFolder]) { //parent is a node itself, use its parent instead. rootnode = nil and a folder <if (![parent isFolder])> is true for rootnode
		position = [[parent valueForKey:@"position"] intValue] + def_incrementNodePosition;
		parent = [parent parent];
	}
	return [self addManagedObject:entityName toParent:parent atPosition:position];
}

-(id) addManagedObject:(NSString *) entityName toParent:(id) parent atPosition:(int) position {
	id newNode = [NSEntityDescription insertNewObjectForEntityForName:entityName
 											   inManagedObjectContext:[self managedObjectContext]];  //Add a new node into the tree.
	[newNode setParent:parent];
	[newNode setValue:[NSNumber numberWithInt:position]
			   forKey:@"position"];
	[self resetPositionsFor:parent];
	[[self managedObjectContext] processPendingChanges]; //to speed up display of new node
	return newNode;
}

#pragma mark (re)order data
-(void) resetPositionsFor:(id)node {
	if (node) {
		[node resetPositions];
	} else {
		NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Group" 
															 inManagedObjectContext:[self managedObjectContext]];
		NSFetchRequest *request = [[NSFetchRequest alloc] init];
		[request setEntity:entityDescription];
		[request setIncludesSubentities:YES];
		NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"parent == nil"]];
		[request setPredicate:pred];
		NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"position"
															 ascending:YES];
		[request setSortDescriptors:[NSArray arrayWithObject:sort]];
		NSError *error = nil;
		NSArray *ordered = [[self managedObjectContext] executeFetchRequest:request
																	  error:&error];
		[request release];
		//reset position of children
		for (int i = 0; i < [ordered count]; i++) {
			id item = [ordered objectAtIndex:i];
			[item setValue:[NSNumber numberWithInt:i*def_positioninterval]
					forKey:@"position"];
			[item resetPositions]; //reset positions of childrenchildren of this child
		}
		//cleanup 
		[sort release];
	}

	//re-order and reload
	[self rearrangeObjects];
	[myOutlineView reloadData];
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.