1
votes

I have a program with a NSOutlineView (that supports single selection only) from which I'd like to be able to drag elements. These elements should either be received as text or files: for instance, dropping the item on a TextEdit window should put text, but dropping the item on the Finder should create a file. I don't want anything to be dropped over my outline view, even it it comes from itself. This seems easy enough, but for some reason, I can't get it to work.

I checked the NSOutlineView drag and drop example from Apple, and I came to implement the following methods (plus a few definitely unrelated ones):

-(BOOL)outlineView:shouldSelectItem: // I don't expect to drag unselectable items
-(NSArray*)outlineView:namesOfPromisedFilesDroppedAtDestination:forDraggedItems:
-(BOOL)outlineView:writeItems:toPasteboard:

However, when I try to drag an item from my outline view, nothing happens. Instead, it just changes the selection following the cursor.

I've put breakpoints in the two last methods, and they never get called, so their implementation is not the immediate issue.

I must be missing something really obvious here.

Also, this is not (yet) a problem, but how am I supposed to provide contents to my promised files?

2

2 Answers

2
votes

I was being stupid and I implemented the methods in the delegate instead of the data source (the two are distinct in my app). Problem solved!

1
votes

Are you using a custom table view cell? The result of NSCell's hitTestForEvent:inRect:ofView: determines whether a dragging operation can be initiated. It also determines whether your outlineView:writeItems:toPasteboard: should be called.

This method should return NSCellHitContentArea to initiate a drag, or NSCellHitTrackableArea to extend or change the selection.

A standard text cell returns NSCellHitContentArea when you click on the actual text of the cell, and NSCellHitTrackableArea when you click outside of the text. This produces the drag behavior you see in Finder's table view.

You can override this method and always return NSCellHitContentArea if you want all areas of the cell to initiate a drag operation.

See Hit Testing for more information.