0
votes

I'm using the excellent NSOutlineView subclass PXSourceList in one of my applications. I'm trying to implement drag and drop to my PXSourceList instance. I have:

  1. connected both delegate and data source outlets in IB to my controller
  2. in awakeFromNib in the controller, set self as the delegate and data source
  3. in awakeFromNib in the controller, registered for dragged types
  4. in the controller, implemented the requisite writeItems: validateDrop: acceptDrop: and namesOfPromisedFilesDroppedAtDestination: methods and declared them in the controller's .h file

For some reason, the drag and drop methods implemented in (4) are not firing at all. I've tried:

  • Placing log statements in the drag and drop data source methods - they never get called.
  • Putting a log statement in one of the other data source method that logs the registeredDraggedTypes of the PXSourceList instance - it always returns the proper drag types assigned in awakeFromNib.
  • Taking the PXSourceList view instance and unembedding it from all containing views except the NSWindow instance - no luck there either.
  • Copy-pasting data source code from my application to the sample app that comes with PXSourceList - it all works without modification.
  • Copy-pasting the working code from the example application into the SK source - it doesn't work.

So essentially I'm in a spot where all data source methods get called except the drag-and-drop methods. It's behaving like I haven't registered for dragged types, but 1) I know I have and 2) the instance responds that it is registered for the dragged types that I set.

Any ideas?

1
Basically what you wanted to perform when you drag and drop outside the table or inside the table??Hussain Shabbir

1 Answers

2
votes

Unfortunately, this is a side-effect of how PXSourceList is implemented; if you look inside PXSourceList.m, it makes itself the delegate and data source of itself (since it inherits from NSOutlineView), implements all of the outline view delegate and data source methods, and when each of these is called, it invokes the implementation of the actual delegate and data source which is being used by PXSourceList with the PXSourceListDelegate and PXSourceListDataSource methods. The reasoning behind this when I built PXSourceList was to have a consistent API rather than mixing and matching NSOutlineViewDelegate/DataSource methods with PXSourceListDelegate/DataSource's additional methods (for badges and icons etc).

The 10.7 SDK (which I assume you're using) added some extra drag and drop methods to NSOutlineViewDataSource. Of relevance here in particular, NSOutlineViewDataSource got the additional method -outlineView:pasteboardWriterForItem: added to it, which is an alternative to -outlineView:writeItems:toPasteboard:.

When you start a drag, NSOutlineView queries the data source (by using -respondsToSelector:) to determine which of these methods it implements and which of these to invoke. Given that PXSourceList implements both, and calls the corresponding -sourceList:... methods on the actual data source, NSOutlineView sees both of these methods as being implemented (even if they're not by your data source), and it seems like NSOutlineView chooses to call -outlineView:pasteboardWriterForItem: if both are implemented. Given that you don't have an implementation of sourceList:pasteboardWriterForItem:, the implementation of -outlineView:pasteboardWriterForItem: returns nil and your other methods don't get called (you can see the code here.)

To cut a long story short...

It looks like for now you'll have to implement -sourceList:pasteboardWriterForItem: instead of -sourceList:writeItems:toPasteboard: (or if you're targeting < 10.7, too, implement both; on 10.6 and below, -sourceList:writeItems:toPasteboard: will be called).

I actually have some improvements to PXSourceList in the works which uses the runtime and should fix problems like these, so keep an eye on the project on GitHub!