• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
NSOutlineView Drag And Drop NSTreeController
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NSOutlineView Drag And Drop NSTreeController


  • Subject: NSOutlineView Drag And Drop NSTreeController
  • From: Arved von Brasch <email@hidden>
  • Date: Thu, 25 May 2006 23:17:13 +1000

Hello Cocoa Dev List,

I've worked around many of the NSTreeController problems I'd encountered previously in a different situation. I did this by subclassing NSTreeController and rewriting many of the routines that were causing me grief, as well as making use of the sample code in DragAndDropOutlineEdit. I now have drag and drop working quite well. I have noticed some unusual behaviour that I can't seem to find a way to work around. My NSOutlineView supports drag and drop ordering (similar to http://allusions.sourceforge.net/articles/ treeDragPart2.php) and NSURL drags from other applications. Drag and drop ordering works great (at least I haven't found any bugs). Accepting URL causes strange behaviour:

My NSOutlineView will not update its display every second time a URL is dragged onto the root node (ie, no parent) when the application is in the background. I have tried reloadData and reloadItem. ReloadItem actually causes the drag to be only partially successful, with the following errors:

*** Assertion failure in -[AGURLDragOutlineView reloadItem:reloadChildren:], TableView.subproj/NSOutlineView.m:1058
*** Canceling drag because exception 'NSInternalInconsistencyException' (reason 'Invalid parameter not satisfying: item') was raised during a dragging session


In the situation where the error is thrown, the reload item is nil. The documentation doesn't mention not passing in nil. AGURLDragOutlineView is my NSOutlineView subclass, that redefines dragImageForRowsWithIndexes:tableColumns:event:offset: to have a nice drag image.

I am using a CoreData backing store, but I don't think that's the problem. The part I can't understand is why it only happens every second drag. Here is the relevant code from acceptDrop: in my NSTreeController subclass / OutlineView DataSource. reorderNode: is a routine that normalises the "order" attributes of each child object to be factors of 10. setSelectedObjects is modified from Wil Shipley's NSTreeController's category.

NSManagedObject *draggedDownloadLink // Set in writeItems if this is a local drag

if ([info draggingSource] == nil) {
draggedDownloadLink = [NSEntityDescription insertNewObjectForEntityForName: @"AGDownloadLink" inManagedObjectContext: [self managedObjectContext]];
NSURL *url = [NSURL URLFromPasteboard: [info draggingPasteboard]];
[draggedDownloadLink setValue: [url absoluteString] forKey: @"address"];
if (parentItem == nil) {
if (index == NSOutlineViewDropOnItemIndex) {
// Sort Descriptors are not by order (attach to end of order list)
unsigned int count = [[self arrangedObjects] count];
[draggedDownloadLink setValue: [NSNumber numberWithInt: count * 10] forKey: @"order"];
[self insertObject: draggedDownloadLink atArrangedObjectIndexPath: [NSIndexPath indexPathWithIndex: count]];
}
else {
// Sorting by order
[draggedDownloadLink setValue: [NSNumber numberWithInt: (index * 10) - 5] forKey: @"order"];
[self insertObject: draggedDownloadLink atArrangedObjectIndexPath: [NSIndexPath indexPathWithIndex: index]];
[self reorderNode: nil];
}
}
else {
[draggedDownloadLink setValue: parentItem forKey: @"parent"];
[draggedDownloadLink setValue: [parentItem valueForKey: @"name"] forKey: @"name"];
if (index == NSOutlineViewDropOnItemIndex) {
// Sort Descriptors are not by order (attach to end of order list)
unsigned int count = [[self outlineItemForObject: parentItem] count];
[draggedDownloadLink setValue: [NSNumber numberWithInt: count * 10] forKey: @"order"];
[self insertObject: draggedDownloadLink atArrangedObjectIndexPath: [[self arrangedIndexPathForObject: parentItem] indexPathByAddingIndex: count]];
}
else {
// Sorting by order
[draggedDownloadLink setValue: [NSNumber numberWithInt: (index * 10) - 5] forKey: @"order"];
[self insertObject: draggedDownloadLink atArrangedObjectIndexPath: [[self arrangedIndexPathForObject: parentItem] indexPathByAddingIndex: index]];
[self reorderNode: parentItem];
}
}
[self rearrangeObjects];
[self setSelectedObjects: [NSArray arrayWithObject: draggedDownloadLink]];
//[ov reloadData];
}


Any ideas on why this display problem only strikes every second drag when the application isn't front most? Is there another way to force the NSOutlineView to redisplay the renegade item?

Cheers,

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


  • Prev by Date: Determining when a token is selected
  • Next by Date: Creating an NSTokenField with Images in the tokens
  • Previous by thread: Determining when a token is selected
  • Next by thread: NSOutlineView Drag And Drop NSTreeController
  • Index(es):
    • Date
    • Thread