Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accepting dragged files on a Cocoa application

I have a simple application that handles marketing information. What I did was to call

NSInteger result  = [openPanel runModalForDirectory:nil file:nil types:fileTypes];

When the user clicks on the File->Open menu. Now I was asked to add drag and drop capabilities to the app so the user can drag a file to it instead on having to go to the menu or pressing command+o to open a file.

Before you tell me to go read the documentation I already check Apple's Intro to drag and drop and other documents. Still I can't figure out what to do.

I'm an old Unix C programmer that need to copy with this and some of the assumptions at the Apple's document don't make sense to me.

In short, what do I need to add to my app to:

  1. Enable drag and drop
  2. Handle that dragged file

As a note, I should handle only one file at a time.

Thanks for the help

like image 468
Mr Aleph Avatar asked Dec 19 '11 20:12

Mr Aleph


1 Answers

Well, you need to implement the NSDraggingDestination protocol, which I presume you've read already. You can implement it in either a specific view or the entire window -- it sounds like you are accepting application-level file drags so you probably want the entire window to accept the drag. Regardless, once you get it working you'll see how to customize it further.

Subclass NSWindow. The first step is to specify what kinds of drags you are interested in.

Tell your custom window that it's interested in filenames:

- (void)awakeFromNib {
    [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
}

Tell OS X what kind of cursor to display:

- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender {
    return NSDragOperationCopy;
}

- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
    return NSDragOperationCopy;
}

Do the drag:

- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
    NSPasteboard *pboard = [sender draggingPasteboard];
    NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];

    if (1 == filenames.count)
        if ([[NSApp delegate] respondsToSelector:@selector(application:openFile:)])
            return [[NSApp delegate] application:NSApp openFile:[filenames lastObject]];

    return NO;
}

This is the bare minimum to get it working.

like image 115
Francis McGrew Avatar answered Nov 01 '22 03:11

Francis McGrew