Table View to register to accept drop

I have a table view that bound to an array controller and I can add and remove items to the table list in my application by clicking the buttons that I have created, so I know that bit is functioning ok,

What I can’t seem to grasp is how to get it to register for ‘on drop’ events in ASS it was easy to just tick the drop checkbox in IB and write the routine to process the drop.

How would you go about doing that in ASOC

I’ve looked through the post here but have yet to find a solution thats easy to understand, I get that i need to register for pasteboard and set the types, but where.

What I need is a way to receive the drop and get the file name of the dropped object, then I can process the info from there.

Any help appreciated.

There’s a fair bit of work involved – have a look in Xcode help for a document called “Using Drag and Drop in Tables”.

Ok In my applicationWillFinishLaunching_ I have added

set aTableViewDragTypes to NSArray's arrayWithObject_("NSFilenamesPboardType", missing value)
		my TableView's registerForDraggedTypes_(aTableViewDragTypes)

And I have also written three (currently empty) routines called

on tableView_writeRowsWithIndexes_toPasteboard()
...
on tableView_validateDrop_proposedRow_proposedDropOperation()
...
on tableView_acceptDrop_row_dropOperation()
...

but I still can’t understand how to get it to call those three routines when there is a drop operation.

In AS I would use

on drop the Object ...

Do I need something like that somewhere in my script, but some new way of saying it.

I haven’t seen any example of doing this from the applescript class. I tried for a long while and gave up. It should be possible but I don’t think it is. With Craig’s help though, I set it up in OBJ-c and it works fine. I can send you the class files if you like.

Rob

Hey Rob,

That would be a great help if you could - Thanks.

I just added drag-and-drop to the Florida example I’ve pointed to before.

To on applicationWillFinishLaunching_, I added:

		my tableView's setDataSource_(me)
		my tableView's registerForDraggedTypes_({"NSFilenamesPboardType"})

I then added two handlers:

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

	on tableView_acceptDrop_row_dropOperation_(tv, info, theRow, proposedOp)
		log "accept"
		-- get stuff from pasteboard
		set pb to info's draggingPasteboard()
		set theFiles to pb's propertyListForType_("NSFilenamesPboardType")
		set filePath to item 1 of (theFiles as list)
		-- we could check value of proposedOp, to see whether to insert or replace row; let's just insert
		tell arrayController to insertObject_atArrangedObjectIndex_({firstName:filePath, lastName:filePath, isAlumni:false}, theRow)
		return true
	end tableView_acceptDrop_row_dropOperation_

Seems to work fine. You only need tableView_writeRowsWithIndexes_toPasteboard_ if you want to support dragging from a table. Also note that I added this to a table that uses bindings (hence the setDatasource_), and it still works fine.

That’s great Shane,

I didn’t set the datasource in the script - maybe that’s why mine didn’t work. This is way simpler than going with the OBJ-C classes.

If I have two registered table views in

on tableView_acceptDrop_row_dropOperation_(tv, info, theRow, proposedOp)

would I identify them through the tv variable?

Thanks, Rob

Yep.

Both ways working great thanks.

Actually it would be better to use the 10.6 form like this:

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

And then change one of the other handlers to:

on tableView_acceptDrop_row_dropOperation_(tv, info, theRow, proposedOp)
	-- get stuff from pasteboard
	set pb to info's draggingPasteboard()
	set imageURLs to pb's readObjectsForClasses_options_({current application's |NSURL|}, missing value)
	set draggedURL to item 1 of (imageURLs as list)
	set filePath to draggedURL's |path|()
        ...

By replacing missing value in there with a list of file type UTIs, you can limit the type of file accepted.