Finder and other apps won't accept drag from NSImageView

Discussion in 'Mac Programming' started by benkenobi, Mar 26, 2011.

  1. benkenobi macrumors member

    Joined:
    May 27, 2009
    #1
    I've been trying to make it so that an image can be dragged out of NSImageView and onto Finder etc(the destination).

    I've went over the documentation for drag and drop many times but everything seems to be in place. I even copied a sample which does just about the same thing as my program and it still won't show a green + sign when dragging over Finder. The plus sign shows only when I drag over the NSImageView

    The code here is copied over from the sample program which works without a problem. :confused: Can anyone give a hint on what might be missing?
    Code:
    @implementation MAImageView
    
    - (id)initWithCoder:(NSCoder *)coder
    {
        /*------------------------------------------------------
         Init method called for Interface Builder objects
         --------------------------------------------------------*/
        if(self==[super initWithCoder:coder]){
            //register for all the image types we can display
            [self registerForDraggedTypes:[NSImage imagePasteboardTypes]];
        }
        return self;
    }
    
    -(BOOL) acceptsFirstMouse:(NSEvent *)theEvent{
        return YES;
    }
    
    -(void)mouseDown:(NSEvent *)theEvent{
    
        /*------------------------------------------------------
         catch mouse down events in order to start drag
         --------------------------------------------------------*/
        //get the Pasteboard used for drag and drop operations
        NSPasteboard* dragPasteboard=[NSPasteboard pasteboardWithName:NSDragPboard];
        //create a new image for our semi-transparent drag image
        NSImage* dragImage=[[NSImage alloc] initWithSize:[[self image] size]]; 
        //add the image types we can send the data as(we'll send the actual data when it's requested)
        [dragPasteboard declareTypes:[NSArray arrayWithObject: NSTIFFPboardType] owner:self];
        
        [dragImage lockFocus];//draw inside of our dragImage
        //draw our original image as 50% transparent
        [[self image] dissolveToPoint: NSZeroPoint fraction: .5];
        [dragImage unlockFocus];//finished drawing
        [dragImage setScalesWhenResized:YES];//we want the image to resize
        [dragImage setSize:[self bounds].size];//change to the size we are displaying
        //execute the drag
        [self dragImage: dragImage//image to be displayed under the mouse
                     at: [self bounds].origin//point to start drawing drag image
                 offset: NSZeroSize//no offset, drag starts at mousedown location
                  event:theEvent//mousedown event
             pasteboard:dragPasteboard//pasteboard to pass to receiver
                 source: self//object where the image is coming from
              slideBack: YES];//if the drag fails slide the icon back
        [dragImage release];//done with our dragImage
          
    
    }
    
    - (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
    {
        /*------------------------------------------------------
         method called by pasteboard to support promised 
         drag types.
         --------------------------------------------------------*/
        //sender has accepted the drag and now we need to send the data for the type we promised
        if([type compare: NSTIFFPboardType]==NSOrderedSame){
            //set data for TIFF type on the pasteboard as requested
            [sender setData:[[self image] TIFFRepresentation] forType:NSTIFFPboardType];
        }else if([type compare: NSPDFPboardType]==NSOrderedSame){
            [sender setData:[self dataWithPDFInsideRect:[self bounds]] forType:NSPDFPboardType];
        }
    }
    
    - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal{
        return NSDragOperationGeneric;//destination object is in a different application.
    }
        
    }
    
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Does the Finder support the types you are offering? I would expect the Finder only accepts files, or possibly file names, not image data. i.e. the Finder will accept an image if it's a file but it will not create a file for you from image data.

    What happens if you promise the type NSFileContentsPboardType? Do you get messages in pasteboard:provideDataForType: ?
     
  3. benkenobi, Mar 26, 2011
    Last edited: Mar 26, 2011

    benkenobi thread starter macrumors member

    Joined:
    May 27, 2009
    #3
    EDIT: works with Finder now!

    Changed: return NSDragOperationGeneric; to return NSDragOperationCopy;
    Code:
    - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal{
        if(!isLocal){
            return NSDragOperationCopy;//destination object is in a different application.
        }else{
            return NSDragOperationNone;
        }
        
    }
    


    Making progess.

    I rewrote the code so it's all done with file names like you suggested. I can drop into texteditor and other programs but not Finder. hmm

    Code:
    -(void)mouseDown:(NSEvent *)theEvent{
        NSURL *fileURL;
        NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
        
        //get fileURL of dragged image
        [[self image] initWithPasteboard:pboard];
        fileURL=[NSURL URLFromPasteboard:pboard];
        
        NSString *filePath1= [fileURL path];
        
        NSImage *dragImage;
        NSPoint dragPosition;
        
        // Write data to the pasteboard
        NSArray *fileList = [NSArray arrayWithObjects:filePath1, nil];
        pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
        [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType]
                       owner:nil];
        [pboard setPropertyList:fileList forType:NSFilenamesPboardType];
        
        // Start the drag operation
        dragImage = [[NSWorkspace sharedWorkspace] iconForFile:filePath1];
        dragPosition = [self convertPoint:[theEvent locationInWindow]
                                 fromView:nil];
        dragPosition.x -= 16;
        dragPosition.y -= 16;
        [self dragImage:dragImage
                     at:dragPosition
                 offset:NSZeroSize
                  event:theEvent
             pasteboard:pboard
                 source:self
              slideBack:YES];
        
    
    }
    
     

Share This Page