From 31d4006d7793100435aaf331f5e48e2762656ca9 Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Mon, 6 Aug 2007 13:23:35 +0000 Subject: [PATCH] Added rudimentary support for drag and drop of files on window. git-svn-id: http://macvim.googlecode.com/svn/trunk@90 96c4425d-ca35-0410-94e5-3396d5c13a8f --- MMBackend.m | 55 ++++++++++++++++++++++++++++++++++++++++ MMTextView.m | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ MacVim.h | 1 + 3 files changed, 127 insertions(+) diff --git a/MMBackend.m b/MMBackend.m index c30214419a..b82e17a117 100644 --- a/MMBackend.m +++ b/MMBackend.m @@ -1075,6 +1075,61 @@ static int specialKeyToNSKey(int key); } } else if (VimShouldCloseMsgID == msgid) { gui_shell_closed(); + } else if (DropFilesMsgID == msgid) { +#ifdef FEAT_DND + const void *bytes = [data bytes]; + int n = *((int*)bytes); bytes += sizeof(int); + +#if 0 + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + + char_u **fnames = (char_u **)alloc(n * sizeof(char_u *)); + if (fnames) { + const void *end = [data bytes] + [data length]; + int i = 0; + while (bytes < end && i < n) { + int len = *((int*)bytes); bytes += sizeof(int); + fnames[i++] = vim_strnsave((char_u*)bytes, len); + bytes += len; + } + + // NOTE! This function will free 'fnames'. + gui_handle_drop(col, row, 0, fnames, i < n ? i : n); + } +#else + // HACK! I'm not sure how to get Vim to open a list of files in tabs, + // so instead I create a ':tab drop' command with all the files to open + // and execute it. + NSMutableString *cmd = [NSMutableString stringWithString:@":tab drop"]; + + const void *end = [data bytes] + [data length]; + int i; + for (i = 0; i < n && bytes < end; ++i) { + int len = *((int*)bytes); bytes += sizeof(int); + NSString *file = [NSString stringWithUTF8String:bytes]; + bytes += len; + + [cmd appendString:@" "]; + [cmd appendString:file]; + } + + // By going to the last tabpage we ensure that the new tabs will appear + // last (if this call is left out, the taborder becomes messy). + goto_tabpage(9999); + + do_cmdline_cmd((char_u*)[cmd UTF8String]); + +#if 1 + // This code was taken from the end of gui_handle_drop(). + update_screen(NOT_VALID); + setcursor(); + out_flush(); + gui_update_cursor(FALSE, FALSE); + gui_mch_flush(); +#endif +#endif +#endif // FEAT_DND } else { NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid); } diff --git a/MMTextView.m b/MMTextView.m index fbe3990c77..a373079cf4 100644 --- a/MMTextView.m +++ b/MMTextView.m @@ -259,6 +259,77 @@ } #endif +#if 1 +- (NSArray *)acceptableDragTypes +{ + return [NSArray arrayWithObjects:NSFilenamesPboardType, nil]; +} + +- (BOOL)performDragOperation:(id )sender +{ + NSPasteboard *pboard = [sender draggingPasteboard]; + + if ( [[pboard types] containsObject:NSFilenamesPboardType] ) { + NSArray *files = [pboard propertyListForType:NSFilenamesPboardType]; + int i, numberOfFiles = [files count]; + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&numberOfFiles length:sizeof(int)]; + +#if 0 + int row, col; + NSPoint pt = [self convertPoint:[sender draggingLocation] fromView:nil]; + if (![self convertPoint:pt toRow:&row column:&col]) + return NO; + + [data appendBytes:&row length:sizeof(int)]; + [data appendBytes:&col length:sizeof(int)]; +#endif + + for (i = 0; i < numberOfFiles; ++i) { + NSString *file = [files objectAtIndex:i]; + int len = [file lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + if (len > 0) { + ++len; // append NUL as well + [data appendBytes:&len length:sizeof(int)]; + [data appendBytes:[file UTF8String] length:len]; + } + } + + [[self vimController] sendMessage:DropFilesMsgID data:data wait:NO]; + return YES; + } + + return NO; +} + +- (NSDragOperation)draggingEntered:(id )sender +{ + NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; + NSPasteboard *pboard = [sender draggingPasteboard]; + + if ( [[pboard types] containsObject:NSFilenamesPboardType] + && (sourceDragMask & NSDragOperationCopy) ) + return NSDragOperationCopy; + + return NSDragOperationNone; +} + +- (NSDragOperation)draggingUpdated:(id )sender +{ + NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; + NSPasteboard *pboard = [sender draggingPasteboard]; + + if ( [[pboard types] containsObject:NSFilenamesPboardType] + && (sourceDragMask & NSDragOperationCopy) ) + return NSDragOperationCopy; + + return NSDragOperationNone; +} + +#endif + @end // MMTextView diff --git a/MacVim.h b/MacVim.h index 187ab7af9d..f0032b7ac4 100644 --- a/MacVim.h +++ b/MacVim.h @@ -90,6 +90,7 @@ enum { VimShouldCloseMsgID, SetDefaultColorsMsgID, ExecuteActionMsgID, + DropFilesMsgID, };