1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import "chrome/browser/ui/cocoa/url_drop_target.h"
6
7#include "base/basictypes.h"
8#import "third_party/mozilla/NSPasteboard+Utils.h"
9
10@interface URLDropTargetHandler(Private)
11
12// Gets the appropriate drag operation given the |NSDraggingInfo|.
13- (NSDragOperation)getDragOperation:(id<NSDraggingInfo>)sender;
14
15// Tell the window controller to hide the drop indicator.
16- (void)hideIndicator;
17
18@end  // @interface URLDropTargetHandler(Private)
19
20@implementation URLDropTargetHandler
21
22+ (NSArray*)handledDragTypes {
23  return [NSArray arrayWithObjects:kWebURLsWithTitlesPboardType,
24                                   NSURLPboardType,
25                                   NSStringPboardType,
26                                   NSFilenamesPboardType,
27                                   nil];
28}
29
30- (id)initWithView:(NSView<URLDropTarget>*)view {
31  if ((self = [super init])) {
32    view_ = view;
33    [view_ registerForDraggedTypes:[URLDropTargetHandler handledDragTypes]];
34  }
35  return self;
36}
37
38// The following four methods implement parts of the |NSDraggingDestination|
39// protocol, which the owner should "forward" to its |URLDropTargetHandler|
40// (us).
41
42- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
43  return [self getDragOperation:sender];
44}
45
46- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
47  NSDragOperation dragOp = [self getDragOperation:sender];
48  if (dragOp == NSDragOperationCopy) {
49    // Just tell the window controller to update the indicator.
50    NSPoint hoverPoint = [view_ convertPoint:[sender draggingLocation]
51                                    fromView:nil];
52    [[view_ urlDropController] indicateDropURLsInView:view_ at:hoverPoint];
53  }
54  return dragOp;
55}
56
57- (void)draggingExited:(id<NSDraggingInfo>)sender {
58  [self hideIndicator];
59}
60
61- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
62  [self hideIndicator];
63
64  NSPasteboard* pboard = [sender draggingPasteboard];
65  NSArray* supportedTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
66  NSString* bestType = [pboard availableTypeFromArray:supportedTypes];
67
68  NSPoint dropPoint =
69      [view_ convertPoint:[sender draggingLocation] fromView:nil];
70  // Tell the window controller about the dropped URL(s).
71  if ([pboard containsURLData]) {
72    NSArray* urls = nil;
73    NSArray* titles;  // discarded
74    [pboard getURLs:&urls andTitles:&titles convertingFilenames:YES];
75
76    if ([urls count]) {
77      [[view_ urlDropController] dropURLs:urls inView:view_ at:dropPoint];
78      return YES;
79    }
80  } else if (NSString* text = [pboard stringForType:bestType]) {
81    // This does not include any URLs, so treat it as plain text if we can
82    // get NSString.
83    [[view_ urlDropController] dropText:text inView:view_ at:dropPoint];
84    return YES;
85  }
86
87  return NO;
88}
89
90@end  // @implementation URLDropTargetHandler
91
92@implementation URLDropTargetHandler(Private)
93
94- (NSDragOperation)getDragOperation:(id<NSDraggingInfo>)sender {
95  NSPasteboard* pboard = [sender draggingPasteboard];
96  NSArray *supportedTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
97  NSString *bestType = [pboard availableTypeFromArray:supportedTypes];
98  if (![pboard containsURLData] && ![pboard stringForType:bestType])
99    return NSDragOperationNone;
100
101  // Only allow the copy operation.
102  return [sender draggingSourceOperationMask] & NSDragOperationCopy;
103}
104
105- (void)hideIndicator {
106  [[view_ urlDropController] hideDropURLsIndicatorInView:view_];
107}
108
109@end  // @implementation URLDropTargetHandler(Private)
110