4 #import "DragDestinationTextView.h"
7 @implementation DragDestinationTextView
10 // ==========================================================
11 // Overridden drag and drop methods
12 // ==========================================================
14 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
16 // We're only interested in files here, let the superclass handle everything else
18 if (![self dragIsFile:sender]) {
19 return [super draggingEntered:sender];
22 // It is a file, highlight drop target
25 [[NSColor selectedControlColor] set];
26 NSFrameRectWithWidth([self visibleRect], 2.5);
28 [[self window] flushWindow];
30 return NSDragOperationGeneric;
36 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender {
40 // We're only interested in files here, let the superclass handle everything else
42 if (![self dragIsFile:sender]) {
43 return [super draggingUpdated:sender];
47 /* some code to handle the case where a user drags the mouse around an edge of the
48 * text field, triggering an autoscroll. If we don't do anything, our highlight frame
49 * would get scrolled along with the content and then redrawn immediately which
50 * obviously looks messy.
51 * Instead we check if the visible rectangle has moved since the last
52 * invocation. If it did, we just clear the frame and do no drawing.
53 * If the frame didn't move, we will draw the frame.
55 currentRect = [self visibleRect];
57 if (!NSEqualRects(currentRect, previousRect)) {
59 previousRect = currentRect;
60 [self setNeedsDisplay:YES];
65 [[NSColor selectedControlColor] set];
66 NSFrameRectWithWidth(currentRect, 2);
68 [[self window] flushWindow];
72 return NSDragOperationGeneric;
78 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender {
80 if (![self dragIsFile:sender]) {
81 return [super prepareForDragOperation:sender];
90 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
95 if (![self dragIsFile:sender]) {
96 return [super performDragOperation:sender];
99 filename = [self getFileForDrag:sender];
100 result = [[self delegate] handleDroppedFile:filename forTextView:self];
103 [self setNeedsDisplay:YES];
111 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender {
113 if (![self dragIsFile:sender]) {
114 [super concludeDragOperation:sender];
118 [self setNeedsDisplay:YES];
124 - (void)draggingExited:(id <NSDraggingInfo>)sender {
126 if (![self dragIsFile:sender]) {
127 [super draggingExited:sender];
131 [self setNeedsDisplay:YES];
141 // ==========================================================
142 // Helper methods to find out if a given NSDraggingInfo refers to a file drag
143 // ==========================================================
145 - (BOOL)dragIsFile:(id <NSDraggingInfo>)sender {
150 NSString *dragFilename = [self getFileForDrag:sender];
152 if (dragFilename == nil) {
156 fileExists = [[NSFileManager defaultManager] fileExistsAtPath:dragFilename isDirectory:&isDirectory];
158 return (fileExists && (!isDirectory));
163 - (NSString *)getFileForDrag:(id <NSDraggingInfo>)sender {
165 NSPasteboard *pb = [sender draggingPasteboard];
166 NSString *availableType = [pb availableTypeFromArray:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
167 NSString *availableTypeString = [pb availableTypeFromArray:[NSArray arrayWithObjects:NSStringPboardType, nil]];
168 NSString *dragFilename;
171 if (availableType == nil) {
175 if (availableTypeString != nil) {
183 props = [pb propertyListForType:availableType];
184 dragFilename = [props objectAtIndex:0];