Skip to content

Instantly share code, notes, and snippets.

@vigorouscoding
Last active August 17, 2020 16:45
Show Gist options
  • Save vigorouscoding/4659678 to your computer and use it in GitHub Desktop.
Save vigorouscoding/4659678 to your computer and use it in GitHub Desktop.
NSImageView subclass to get the filename of the dropped image and to disable deleting and cutting the image. The class sends a "KSImageDroppedNotification" with the image filename in the userinfo dictionary. I got the idea from: http://www.cocoabuilder.com/archive/cocoa/121824-how-do-capture-the-filename-of-an-image-dropped-in-an-nsimageview.html
#import <Cocoa/Cocoa.h>
@interface KSImageView : NSImageView
@end
#import "KSImageView.h"
@implementation KSImageView
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
BOOL acceptsDrag = [super performDragOperation:sender];
if (acceptsDrag) {
NSPasteboard *pboard = [sender draggingPasteboard];
NSString *plist = [pboard stringForType:NSFilenamesPboardType];
if (plist) {
NSArray *files = [NSPropertyListSerialization propertyListFromData:[plist dataUsingEncoding:NSUTF8StringEncoding]
mutabilityOption:NSPropertyListImmutable
format:nil
errorDescription:nil];
if ([files count] == 1) {
NSDictionary *userInfo = @{@"imageFileName" : [[files objectAtIndex: 0] lastPathComponent]};
[[NSNotificationCenter defaultCenter] postNotificationName:@"KSImageDroppedNotification"
object:nil
userInfo:userInfo];
}
}
}
return acceptsDrag;
}
- (void) delete:(id)sender {
}
- (void) cut:(id)sender {
}
@end
@aral
Copy link

aral commented Jan 6, 2015

Also works in concludeDragOperation:

Here’s a quick Swift version:

import Cocoa

let IndieImageDroppedNotification:String = "IndieImageDroppedNotification"

class IndieImageView: NSImageView {

    override func concludeDragOperation(sender: NSDraggingInfo?) {
        super.concludeDragOperation(sender)

        if let plist = sender?.draggingPasteboard().stringForType(NSFilenamesPboardType) {
            if let data = plist.dataUsingEncoding(NSUTF8StringEncoding) {
                if let files:NSArray = NSPropertyListSerialization.propertyListFromData(data, mutabilityOption: .Immutable, format: nil, errorDescription: nil) as? NSArray {
                    if files.count == 1 {
                        println("File: \(files[0].lastPathComponent)")
                        let userInfo = ["imageFileName": files[0].lastPathComponent]
                        NSNotificationCenter.defaultCenter().postNotification(NSNotification(name: IndieImageDroppedNotification, object: self))
                    }
                }
            }
        }
    }

}

Oh, and I found that I couldn’t manipulate the image in the same frame so if you want to do anything to it, wait one stack frame :)

@klaas
Copy link

klaas commented Nov 9, 2015

Thanks for the swift version!

@grantkemp
Copy link

Hi - it looks like you are using the wrong method to push the notification as you aren't including the userInfo. Try use the method with with the userinfo overloader.

Great job- would be interesting to see if there was a way to detect if the image was pasted into using the menu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment