Drag and Drop

Hi All,
I’ve tried to look over the Drag and Drop documentation, and related posts here, and I came up with the following, what I thought of as a summary of what would be needed to use drag and drop to read files dropped on any NSObject:

	on applicationWillFinishLaunching_(aNotification)
		myObject's registerForDraggedTypes_({"public.file-url"})
	end applicationWillFinishLaunching_
	
	on draggingEntered_(sender)
		log "entered"
		set pb to sender's draggingPasteboard()
		set theOptions to {NSPasteboardURLReadingFileURLsOnlyKey:1}
		return pb's canReadObjectForClasses_options_({current application's |NSURL|}, theOptions)
	end draggingEntered_
	
	on performDragOperation_(sender)
		log "perform"
		-- Get the file paths
		set pb to sender's draggingPasteboard()
		set theOptions to {NSPasteboardURLReadingFileURLsOnlyKey:1}
		set theURLs to pb's readObjectsForClasses_options_({current application's |NSURL|}, theOptions)
		log theURLs
		return true
	end performDragOperation_

I also made myObject a delagate of my script. The above works great for my main window, but I can’t seem to get it to work for any other script objects. The dragging entered handler won’t get called. I saw something about text fields needing to be made the first responder, but I couln’t get this to work for a table view either. Thanks in advance for any help.

Text views need no code – they accept file drag and drop as long as they are the active field.

For tables, you need to implement some of the methods of the NSTableViewDataSource Protocol, and set a dataSource. tableView:validateDrop:proposedRow:proposedDropOperation: and tableView:acceptDrop:row:dropOperation: are the two methods that matter. You also have to register for dragging, just as you are doing.

This should get you started:

on applicationWillFinishLaunching_(aNotification)
	my tableView's setDataSource_(me)
	my tableView's registerForDraggedTypes_({"public.file-url"})
end applicationWillFinishLaunching_

on tableView_validateDrop_proposedRow_proposedDropOperation_(tv, info, theRow, proposedOp)
	return current application's NSDragOperationLink
end tableView_validateDrop_proposedRow_proposedDropOperation_

on tableView_acceptDrop_row_dropOperation_(tv, info, theRow, proposedOp)
	-- get stuff from pasteboard
	set pb to info's draggingPasteboard()
	set theURLs to pb's readObjectsForClasses_options_({current application's |NSURL|}, missing value)
	set draggedURL to item 1 of (theURLs as list)
	set filePath to draggedURL's |path|()
	--  check value of proposedOp, to see whether to insert or replace row, then do it;
        -- How will depend on the table
	return true
end tableView_acceptDrop_row_dropOperation_

Hi Shane,
Thanks for the response, though as usual, I ran into some difficulties. I tried to get a text field to work, but it looks like it needs to be editable, and the text field I’m using is not. I also tried your starter code for the table view. I think I had actually tried it from another posting, probably yours :). It would work, but the weird thing is that instead of the usual green “+”, the cursor changed to a curved arrow that you see for making aliases via drag and drop in the finder. Also, it was doing more than I needed it to. Same with the text field. I don’t need the drop to interact with the drop target to display the dropped files. I was just looking to create a “drop zone” that doesn’t necessarily list the contents of the drop. Like having an open handler, but instead of dragging to the app icon, the user drops the files to some designated are in the app’s gui.

The code I posted above, when I set the main window to register drags, does exactly what I was looking for - generate a list of files that are then processed by other handlers before information is displayed in the text field and the table. It’s just that, it seems strange to have the whole main window receive drops. So I thought the above should also work for the classes that inherit from NSWindow and NSView. For example, I have an app that I use an NSBox object as a drop area, but I can’t get that same functionality in ASOC.

Any further hints would be greatly appreciated.

Your code will work fine for a view, but because views don’t have delegates, you will have to make your view a subclass of NSView, and add the handlers to the subclass.

Woo hoo! That worked. For anyone else trying to do the same, and you’re even more of a newbie than me, here is what I did. Just to experiment I created an NSBox object in my gui and then in the delegate script I entered:

script MSDropBox
	property parent : class "NSBox"
	
	on draggingEntered_(sender)
		log "entered"
		set pb to sender's draggingPasteboard()
		set theOptions to {NSPasteboardURLReadingFileURLsOnlyKey:1}
		return pb's canReadObjectForClasses_options_({current application's |NSURL|}, theOptions)
	end draggingEntered_
	
	on performDragOperation_(sender)
		log "perform"
		-- Get the file paths
		set pb to sender's draggingPasteboard()
		set theOptions to {NSPasteboardURLReadingFileURLsOnlyKey:1}
		set theURLs to pb's readObjectsForClasses_options_({current application's |NSURL|}, theOptions)
		log theURLs
		return true
	end performDragOperation_
end script

I also added this code to the applicationWillFinishLaunching_ handler:

		my dropBox's registerForDraggedTypes_({"public.file-url"})

where drop box has been connected to the box in IB. In interface builder I changed the class of my box from NSBox to MSDropBox. That was it.

Curiously, I could not get this to work with an NSTableView (the performDragOperation was ignored), but it did work for the NSScrollView of the table.

Hi
i try to make an application with a drag and drop file list
here is a simple project of the used method project

i want make it a list of file where i can remove an entry and drag some additionnal files (here the list is remove at every drag&drop operation)

I try also to use this list to an applescript
the problem is applescript don’t identificate entry as files so that don’t work with
how i can make the filelist to dropped_items variables

repeat with currentItem in dropped_items
--blabla
end repeat

thanks for your help
regards

The code earlier in this thread will give you the drag-and-drop part.

However, if you are new to AppleScriptObjC, which it sounds like, you should probably start with something a little less ambitious, or at least build your app in stages. Drag-and-drop is a bit complicated.

Sorry to revive an old post but I needed to learn this, and so I uploaded a demo project. Snow Leopard, XCode 3.1x, 2001-07-21 is the date. Lets you drop a file onto a box in the UI and then it shows the first file name in a different text box.

http://www.paveglio.com/postimages/DragOnDropTest.zip

SuperMacGuy! Thanks !!! I have been searching for a working example for months, I have only ever found snippets of code and had no idea how to pull all the drag/drop elements together. You App worked like a charm. Now that I see how all the connections work together, everything makes sense.

PS - I am an old MacroMedia lingo programmer who learned AppleScript easily, but boy, I finding AppleScriptObjC
a challenge ( lack of documentation is my biggest problem)

Anyway, thanks again!

You are welcome!
I find so many demo apps (from Apple especially) try to blend 5 different example methods together.
Once I figured it out, I felt it would be helpful for others to see just the basic mechanics of DnD.

Chris