nstreecontroller rearrangeobjects bug?

Discussion in 'Mac Programming' started by MrFusion, Jun 30, 2009.

  1. macrumors 6502a

    Joined:
    Jun 8, 2005
    Messages:
    583
    Location:
    West-Europe
    #1
    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
     
  2. macrumors 6502a

    Joined:
    Jun 8, 2005
    Messages:
    583
    Location:
    West-Europe
    #2
    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];
    }
    
     

Share This Page