diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h index 71bc618f1e..b05be27163 100644 --- a/src/MacVim/MMVimController.h +++ b/src/MacVim/MMVimController.h @@ -55,6 +55,8 @@ - (NSDate *)creationDate; - (void)cleanup; - (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force; +- (void)file:(NSString *)filename draggedToTabAtIndex:(NSUInteger)tabIndex; +- (void)filesDraggedToTabBar:(NSArray *)filenames; - (void)dropString:(NSString *)string; - (void)passArguments:(NSDictionary *)args; - (void)sendMessage:(int)msgid data:(NSData *)data; diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 1a198e90f1..f6a0881dd1 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -255,6 +255,29 @@ static BOOL isUnsafeMessage(int msgid); [self sendMessage:DropFilesMsgID data:[args dictionaryAsData]]; } +- (void)file:(NSString *)filename draggedToTabAtIndex:(NSUInteger)tabIndex +{ + NSString *fnEsc = [filename stringByEscapingSpecialFilenameCharacters]; + NSString *input = [NSString stringWithFormat:@":silent " + "tabnext %d |" + "edit! %@", tabIndex + 1, fnEsc]; + [self addVimInput:input]; +} + +- (void)filesDraggedToTabBar:(NSArray *)filenames +{ + NSUInteger i, count = [filenames count]; + NSMutableString *input = [NSMutableString stringWithString:@"" + ":silent! tabnext 9999"]; + for (i = 0; i < count; i++) { + NSString *fn = [filenames objectAtIndex:i]; + NSString *fnEsc = [fn stringByEscapingSpecialFilenameCharacters]; + [input appendFormat:@"|tabedit %@", fnEsc]; + } + [input appendString:@""]; + [self addVimInput:input]; +} + - (void)dropString:(NSString *)string { int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1; diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index 79c134befd..0ebc075a1a 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -132,6 +132,8 @@ enum { [[tabBarControl addTabButton] setTarget:self]; [[tabBarControl addTabButton] setAction:@selector(addNewTab:)]; [tabBarControl setAllowsDragBetweenWindows:NO]; + [tabBarControl registerForDraggedTypes: + [NSArray arrayWithObject:NSFilenamesPboardType]]; [tabBarControl setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; @@ -498,6 +500,40 @@ enum { [vimController sendMessage:DraggedTabMsgID data:data]; } +- (NSDragOperation)tabBarControl:(PSMTabBarControl *)theTabBarControl + draggingEntered:(id )sender + forTabAtIndex:(unsigned)tabIndex +{ + NSPasteboard *pb = [sender draggingPasteboard]; + return [[pb types] containsObject:NSFilenamesPboardType] + ? NSDragOperationCopy + : NSDragOperationNone; +} + +- (BOOL)tabBarControl:(PSMTabBarControl *)theTabBarControl + performDragOperation:(id )sender + forTabAtIndex:(unsigned)tabIndex +{ + NSPasteboard *pb = [sender draggingPasteboard]; + if ([[pb types] containsObject:NSFilenamesPboardType]) { + NSArray *filenames = [pb propertyListForType:NSFilenamesPboardType]; + if ([filenames count] == 0) + return NO; + if (tabIndex != NSNotFound) { + // If dropping on a specific tab, only open one file + [vimController file:[filenames objectAtIndex:0] + draggedToTabAtIndex:tabIndex]; + } else { + // Files were dropped on empty part of tab bar; open them all + [vimController filesDraggedToTabBar:filenames]; + } + return YES; + } else { + return NO; + } +} + + // -- NSView customization --------------------------------------------------- diff --git a/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.h b/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.h index 361c744136..ab5c8566b1 100644 --- a/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.h +++ b/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.h @@ -68,7 +68,9 @@ enum { // drag and drop NSEvent *_lastMouseDownEvent; // keep this for dragging reference - BOOL _allowsDragBetweenWindows; + BOOL _allowsDragBetweenWindows; + BOOL _delegateHandlingDrag; + NSDragOperation _delegateInitialDragOperation; // MVC help IBOutlet id delegate; @@ -121,4 +123,11 @@ enum { - (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem; - (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem; - (void)tabView:(NSTabView *)aTabView didDragTabViewItem:(NSTabViewItem *)tabViewItem toIndex:(int)idx; + +- (NSDragOperation)tabBarControl:(PSMTabBarControl *)theTabBarControl draggingEntered:(id )sender forTabAtIndex:(unsigned)tabIndex; +- (NSDragOperation)tabBarControl:(PSMTabBarControl *)theTabBarControl draggingUpdated:(id )sender forTabAtIndex:(unsigned)tabIndex; +- (void)tabBarControl:(PSMTabBarControl *)theTabBarControl draggingExited:(id )sender forTabAtIndex:(unsigned)tabIndex; +- (BOOL)tabBarControl:(PSMTabBarControl *)theTabBarControl prepareForDragOperation:(id )sender forTabAtIndex:(unsigned)tabIndex; +- (BOOL)tabBarControl:(PSMTabBarControl *)theTabBarControl performDragOperation:(id )sender forTabAtIndex:(unsigned)tabIndex; +- (void)tabBarControl:(PSMTabBarControl *)theTabBarControl concludeDragOperation:(id )sender forTabAtIndex:(unsigned)tabIndex; @end diff --git a/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.m b/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.m index f702ae734a..63663ea0b0 100644 --- a/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.m +++ b/src/MacVim/PSMTabBarControl/source/PSMTabBarControl.m @@ -57,6 +57,8 @@ // convenience - (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame; +- (unsigned)indexOfCellAtPoint:(NSPoint)point; +- (unsigned)indexOfCellAtPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame; - (PSMTabBarCell *)lastVisibleTab; - (int)numberOfVisibleTabs; @@ -98,6 +100,7 @@ // default config _allowsDragBetweenWindows = YES; + _delegateHandlingDrag = NO; _canCloseOnlyTab = NO; _showAddTabButton = NO; _hideForSingleTab = NO; @@ -982,16 +985,28 @@ return YES; } +- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation +{ + [[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation]; +} + // NSDraggingDestination - (NSDragOperation)draggingEntered:(id )sender -{ +{ + NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil]; + _delegateHandlingDrag = NO; if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { if ([sender draggingSource] != self && ![self allowsDragBetweenWindows]) return NSDragOperationNone; - [[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + [[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:point]; return NSDragOperationMove; + } else if (delegate && [delegate respondsToSelector:@selector(tabBarControl:draggingEntered:forTabAtIndex:)]) { + NSDragOperation op = [delegate tabBarControl:self draggingEntered:sender forTabAtIndex:[self indexOfCellAtPoint:point]]; + _delegateHandlingDrag = (op != NSDragOperationNone); + _delegateInitialDragOperation = op; + return op; } return NSDragOperationNone; @@ -999,13 +1014,19 @@ - (NSDragOperation)draggingUpdated:(id )sender { + NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil]; if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { if ([sender draggingSource] != self && ![self allowsDragBetweenWindows]) return NSDragOperationNone; - [[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + [[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:point]; return NSDragOperationMove; + } else if (_delegateHandlingDrag) { + if ([delegate respondsToSelector:@selector(tabBarControl:draggingUpdated:forTabAtIndex:)]) + return [delegate tabBarControl:self draggingUpdated:sender forTabAtIndex:[self indexOfCellAtPoint:point]]; + else + return _delegateInitialDragOperation; } return NSDragOperationNone; @@ -1013,44 +1034,61 @@ - (void)draggingExited:(id )sender { - [[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self]; + if (!_delegateHandlingDrag) { + [[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self]; + } else if ([delegate respondsToSelector:@selector(tabBarControl:draggingExited:forTabAtIndex:)]) { + NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil]; + [delegate tabBarControl:self draggingExited:sender forTabAtIndex:[self indexOfCellAtPoint:point]]; + } } - (BOOL)prepareForDragOperation:(id )sender { + if (_delegateHandlingDrag && [delegate respondsToSelector:@selector(tabBarControl:prepareForDragOperation:forTabAtIndex:)]) { + NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil]; + return [delegate tabBarControl:self prepareForDragOperation:sender forTabAtIndex:[self indexOfCellAtPoint:point]]; + } + return YES; } - (BOOL)performDragOperation:(id )sender { + if (!_delegateHandlingDrag) { #if 1 - // HACK! Used below. - NSTabViewItem *tvi = [[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject]; + // HACK! Used below. + NSTabViewItem *tvi = [[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject]; #endif - [[PSMTabDragAssistant sharedDragAssistant] performDragOperation]; + [[PSMTabDragAssistant sharedDragAssistant] performDragOperation]; #if 1 - // HACK! Notify the delegate that a tab was dragged to a new position. - if (delegate && [delegate respondsToSelector:@selector(tabView:didDragTabViewItem:toIndex:)]) { - int idx = [[self representedTabViewItems] indexOfObject:tvi]; - if (NSNotFound != idx) { - [delegate tabView:[self tabView] didDragTabViewItem:tvi toIndex:idx]; + // HACK! Notify the delegate that a tab was dragged to a new position. + if (delegate && [delegate respondsToSelector:@selector(tabView:didDragTabViewItem:toIndex:)]) { + int idx = [[self representedTabViewItems] indexOfObject:tvi]; + if (NSNotFound != idx) { + [delegate tabView:[self tabView] didDragTabViewItem:tvi toIndex:idx]; + } + } +#endif + } else { + if ([delegate respondsToSelector:@selector(tabBarControl:performDragOperation:forTabAtIndex:)]) { + NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil]; + return [delegate tabBarControl:self performDragOperation:sender forTabAtIndex:[self indexOfCellAtPoint:point]]; + } else { + return NO; } } -#endif return YES; } -- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation -{ - [[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation]; -} - - (void)concludeDragOperation:(id )sender { - + if (_delegateHandlingDrag && [delegate respondsToSelector:@selector(tabBarControl:concludeDragOperation:forTabAtIndex:)]) { + NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil]; + [delegate tabBarControl:self concludeDragOperation:sender forTabAtIndex:[self indexOfCellAtPoint:point]]; + } } #pragma mark - @@ -1357,11 +1395,25 @@ } - (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame +{ + unsigned i = [self indexOfCellAtPoint:point cellFrame:outFrame]; + if (i == NSNotFound) + return nil; + PSMTabBarCell *cell = [_cells objectAtIndex:i]; + return cell; +} + +- (unsigned)indexOfCellAtPoint:(NSPoint)point +{ + return [self indexOfCellAtPoint:point cellFrame:NULL]; +} + +- (unsigned)indexOfCellAtPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame { NSRect aRect = [self genericCellRect]; if(!NSPointInRect(point,aRect)){ - return nil; + return NSNotFound; } int i, cnt = [_cells count]; @@ -1374,11 +1426,11 @@ if(outFrame){ *outFrame = aRect; } - return cell; + return i; } aRect.origin.x += width; } - return nil; + return NSNotFound; } - (PSMTabBarCell *)lastVisibleTab