+2006-05-04 Eric Seidel <eseidel@apple.com>
+
+ Reviewed by timo.
+
+ Add drag & drop support to <input type="file">
+ http://bugzilla.opendarwin.org/show_bug.cgi?id=8733
+
+ Test: manual/input-type-file-drag-drop.html
+
+ * kwq/KWQFileButton.mm:
+ (-[WebFileChooserButton initWithWidget::]):
+ (-[WebCoreFileButton initWithWidget:]):
+ (-[WebCoreFileButton drawRect:]):
+ (-[WebCoreFileButton updateLabel]):
+ (-[WebCoreFileButton setFilename:]):
+ (-[WebCoreFileButton changeFilename:]):
+ (-[WebCoreFileButton chooseFilename:]):
+ (validFilenameFromPasteboard):
+ (-[WebCoreFileButton draggingEntered:]):
+ (-[WebCoreFileButton draggingExited:]):
+ (-[WebCoreFileButton performDragOperation:]):
+
2006-05-04 Beth Dakin <bdakin@apple.com>
Reviewed by Hyatt.
NSString *_label;
BOOL _inNextValidKeyView;
KWQFileButton *_widget;
+ BOOL _isCurrentDragTarget;
}
- (void)setFilename:(NSString *)filename;
- (void)performClick;
self = [super init];
if (!self)
return nil;
+ [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
_widget = widget;
return self;
[NSGraphicsContext saveGraphicsState];
NSRectClip(NSIntersectionRect(bounds, rect));
+
+ if (_isCurrentDragTarget) {
+ [[NSColor colorWithCalibratedWhite:0.0 alpha:0.25f] set];
+ NSRectFillUsingOperation([self bounds], NSCompositeSourceOver);
+ }
float left = NSMaxX([_button frame]) + AFTER_BUTTON_SPACING;
[_label release];
NSString *label;
- if ([_filename length]) {
+ if ([_filename length])
label = _filename;
- } else {
+ else
label = [[WebCoreViewFactory sharedFactory] fileButtonNoFileSelectedLabel];
- }
float left = NSMaxX([_button frame]) + AFTER_BUTTON_SPACING;
- if (_icon) {
+ if (_icon)
left += ICON_WIDTH + ICON_FILENAME_SPACING;
- }
float labelWidth = [self bounds].size.width - left;
_label = labelWidth <= 0 ? nil : [[WebCoreStringTruncator centerTruncateString:
_filename = copy;
[_icon release];
- if ([_filename length] == 0 || [_filename characterAtIndex:0] != '/') {
+ if ([_filename length] == 0 || [_filename characterAtIndex:0] != '/')
_icon = nil;
- } else {
+ else {
_icon = [[[NSWorkspace sharedWorkspace] iconForFile:_filename] retain];
// I'm not sure why this has any effect, but including this line of code seems to make
// the image appear right-side-up. As far as I know, the drawInRect method used above
[bridge runOpenPanelForFileButtonWithResultListener:self];
}
-- (void)chooseFilename:(NSString *)filename
+- (void)changeFilename:(NSString *)filename
{
// The != check here makes sure we don't consider a change from nil to nil as a change.
if (_filename != filename && ![_filename isEqualToString:filename]) {
if (_widget)
_widget->filenameChanged(DeprecatedString::fromNSString(filename));
}
+}
+
+- (void)chooseFilename:(NSString *)filename
+{
+ [self changeFilename:filename];
WebCoreFrameBridge *bridge = FrameMac::bridgeForWidget(_widget);
[bridge release];
}
[_button performClick:nil];
}
+static NSString *validFilenameFromPasteboard(NSPasteboard* pBoard)
+{
+ NSArray *filenames = [pBoard propertyListForType:NSFilenamesPboardType];
+ if ([filenames count] == 1) {
+ NSString *filename = [filenames objectAtIndex:0];
+ NSDictionary *fileAttributes = [[NSFileManager defaultManager] fileAttributesAtPath:filename traverseLink:YES];
+ if ([[fileAttributes fileType] isEqualToString:NSFileTypeRegular])
+ return filename;
+ }
+ return nil;
+}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ if (validFilenameFromPasteboard([sender draggingPasteboard])) {
+ _isCurrentDragTarget = YES;
+ [self setNeedsDisplay:YES];
+ return NSDragOperationCopy;
+ }
+ return NSDragOperationNone;
+}
+
+- (void)draggingExited:(id <NSDraggingInfo>)sender
+{
+ if (_isCurrentDragTarget) {
+ _isCurrentDragTarget = NO;
+ [self setNeedsDisplay:YES];
+ }
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ _isCurrentDragTarget = NO;
+ NSString *filename = validFilenameFromPasteboard([sender draggingPasteboard]);
+ if (filename) {
+ [self changeFilename:filename];
+ [self setNeedsDisplay:YES];
+ return YES;
+ }
+ return NO;
+}
+
@end
@implementation WebFileChooserButton