Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag and Drop — Only Folders Accepted

I'm writing a custom view that needs to accept folder drops. The condition is: only directories are accepted, so when user drags a file nothing should happen.

I've registered my view with:

[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];

And the basic dragging protocol methods are already implemented. For testing purposes:

- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
{
    NSLog("@Drag Entered");
    return NSDragOperationCopy;
}

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

- (void)draggingExited:(id<NSDraggingInfo>)sender
{
    NSLog(@"Dragging Exited");
}

- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender { return YES; }
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender    { return YES; }

So it works almost correctly: the cursor gets a plus sign when dragging over the view. However I'd like to avoid that if the item is a regular file.

I'll probably need to do that with NSFileManager (though I wonder if there is an easier way) once I get the dragged path, but the question is where. I've tried to include the test right in the draggingEntered: method returning NSDragOperationNone with no success. I'm following a snippet from Apple documentation:

{
    NSPasteboard *pboard = [sender draggingPasteboard];

    if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
        NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
        int numberOfFiles = [files count];
        // Perform operation using the list of files
    }
    return YES;
}

Where should I implement this test, so the cursor stays the same if a file is dragged instead?

like image 694
sidyll Avatar asked Jun 01 '11 22:06

sidyll


1 Answers

You should implement the test in -draggingEntered: and return NSDragOperationNone if the pasteboard contains a file.

However, since you have also implemented ‑draggingUpdated:, you'll need to add the test for folder types to that method also.

At present you're always returning NSDragOperationCopy in ‑draggingUpdated: without testing for the file type, which means that as soon as the mouse moves inside your dragging destination, the cursor will change to a copy cursor no matter what you do in ‑draggingEntered:.

Note that implementing ‑draggingUpdated: is optional. If you aren't implementing a complex view with multiple possible dragging destinations then you don't need to implement it, just ‑draggingEntered: and ‑draggingExited:.

like image 186
Rob Keniger Avatar answered Sep 28 '22 01:09

Rob Keniger