2
votes

I've subclasses an NSTextView so that I can drop a file and copy the string contents of the file into the view (as opposed to the standard implementation which drops the filepath into the view). The text seems to be dropping correctly, but then is not visible after the drop. I can see that the cursor has moved and can even copy the dropped text out of the view and paste into, for example, TextEdit. I tried adding [self setNeedsDisplay:YES] at the end of my -performDragOperation: method, but the behavior did not change.

Here's the code I've written so far. I imagine this is not the best way to implement this. I'm new to drag and drop implementation in cocoa.

-(NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {

    NSPasteboard *pb = [sender draggingPasteboard];
    NSDragOperation dragOperation = [sender draggingSourceOperationMask];

    if ([[pb types] containsObject:NSFilenamesPboardType]) {
        if (dragOperation & NSDragOperationCopy) {
            return NSDragOperationCopy;
        }
    }
    if ([[pb types] containsObject:NSPasteboardTypeString]) {
        if (dragOperation & NSDragOperationCopy) {
            return NSDragOperationCopy;
        }
    }

    return NSDragOperationNone;

}


-(BOOL)performDragOperation:(id<NSDraggingInfo>)sender {

    NSPasteboard *pb = [sender draggingPasteboard];

    if ( [[pb types] containsObject:NSFilenamesPboardType] ) {
        NSArray *filenames = [pb propertyListForType:NSFilenamesPboardType];

        for (NSString *filename in filenames) {
            NSStringEncoding encoding;
            NSError * error;
            NSString * fileContents = [NSString stringWithContentsOfFile:filename usedEncoding:&encoding error:&error];
            if (error) {
                // handle error
            }
            else {
                [self setString:fileContents];
            }
        }

    }

    else if ( [[pb types] containsObject:NSPasteboardTypeString] ) {
        NSString *draggedString = [pb stringForType:NSPasteboardTypeString];
        [self setString:draggedString];
    }

    return YES;

}
1
A useful pointer, but it relies on the super-class doing most of the heavy lifting, as it already accepts those two pasteboard types. If you are using your own pasteboard type, you will also have to call registerForDraggedTypes, and implement acceptableDragTypes and prepareForDragOperation as well. - Grimxn

1 Answers

0
votes

I had a stub for -drawRect: that had no implementation.

After removing the stub, everything works exactly as intended.