Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: chrome/browser/ui/cocoa/tab_contents/web_drop_target.mm

Issue 8440001: Move Mac's WebDragDest to content. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/tab_contents/web_drop_target.h"
6
7 #include "base/sys_string_conversions.h"
8 #include "content/browser/renderer_host/render_view_host.h"
9 #include "content/browser/tab_contents/tab_contents.h"
10 #include "content/browser/tab_contents/web_drag_dest_delegate.h"
11 #import "third_party/mozilla/NSPasteboard+Utils.h"
12 #import "ui/base/dragdrop/cocoa_dnd_util.h"
13 #include "webkit/glue/webdropdata.h"
14 #include "webkit/glue/window_open_disposition.h"
15
16 using WebKit::WebDragOperationsMask;
17
18 @implementation WebDropTarget
19
20 // |contents| is the TabContents representing this tab, used to communicate
21 // drag&drop messages to WebCore and handle navigation on a successful drop
22 // (if necessary).
23 - (id)initWithTabContents:(TabContents*)contents {
24 if ((self = [super init])) {
25 tabContents_ = contents;
26 }
27 return self;
28 }
29
30 - (void)setDragDelegate:(content::WebDragDestDelegate*)delegate {
31 delegate_ = delegate;
32 }
33
34 // Call to set whether or not we should allow the drop. Takes effect the
35 // next time |-draggingUpdated:| is called.
36 - (void)setCurrentOperation: (NSDragOperation)operation {
37 current_operation_ = operation;
38 }
39
40 // Given a point in window coordinates and a view in that window, return a
41 // flipped point in the coordinate system of |view|.
42 - (NSPoint)flipWindowPointToView:(const NSPoint&)windowPoint
43 view:(NSView*)view {
44 DCHECK(view);
45 NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
46 NSRect viewFrame = [view frame];
47 viewPoint.y = viewFrame.size.height - viewPoint.y;
48 return viewPoint;
49 }
50
51 // Given a point in window coordinates and a view in that window, return a
52 // flipped point in screen coordinates.
53 - (NSPoint)flipWindowPointToScreen:(const NSPoint&)windowPoint
54 view:(NSView*)view {
55 DCHECK(view);
56 NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
57 NSScreen* screen = [[view window] screen];
58 NSRect screenFrame = [screen frame];
59 screenPoint.y = screenFrame.size.height - screenPoint.y;
60 return screenPoint;
61 }
62
63 // Return YES if the drop site only allows drops that would navigate. If this
64 // is the case, we don't want to pass messages to the renderer because there's
65 // really no point (i.e., there's nothing that cares about the mouse position or
66 // entering and exiting). One example is an interstitial page (e.g., safe
67 // browsing warning).
68 - (BOOL)onlyAllowsNavigation {
69 return tabContents_->showing_interstitial_page();
70 }
71
72 // Messages to send during the tracking of a drag, usually upon receiving
73 // calls from the view system. Communicates the drag messages to WebCore.
74
75 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info
76 view:(NSView*)view {
77 // Save off the RVH so we can tell if it changes during a drag. If it does,
78 // we need to send a new enter message in draggingUpdated:.
79 currentRVH_ = tabContents_->render_view_host();
80
81 if ([self onlyAllowsNavigation]) {
82 if ([[info draggingPasteboard] containsURLData])
83 return NSDragOperationCopy;
84 return NSDragOperationNone;
85 }
86
87 if (delegate_) {
88 delegate_->DragInitialize(tabContents_);
89 delegate_->OnDragEnter();
90 }
91
92 // Fill out a WebDropData from pasteboard.
93 WebDropData data;
94 [self populateWebDropData:&data fromPasteboard:[info draggingPasteboard]];
95
96 // Create the appropriate mouse locations for WebCore. The draggingLocation
97 // is in window coordinates. Both need to be flipped.
98 NSPoint windowPoint = [info draggingLocation];
99 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
100 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
101 NSDragOperation mask = [info draggingSourceOperationMask];
102 tabContents_->render_view_host()->DragTargetDragEnter(data,
103 gfx::Point(viewPoint.x, viewPoint.y),
104 gfx::Point(screenPoint.x, screenPoint.y),
105 static_cast<WebDragOperationsMask>(mask));
106
107 // We won't know the true operation (whether the drag is allowed) until we
108 // hear back from the renderer. For now, be optimistic:
109 current_operation_ = NSDragOperationCopy;
110 return current_operation_;
111 }
112
113 - (void)draggingExited:(id<NSDraggingInfo>)info {
114 DCHECK(currentRVH_);
115 if (currentRVH_ != tabContents_->render_view_host())
116 return;
117
118 // Nothing to do in the interstitial case.
119
120 if (delegate_)
121 delegate_->OnDragLeave();
122
123 tabContents_->render_view_host()->DragTargetDragLeave();
124 }
125
126 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info
127 view:(NSView*)view {
128 DCHECK(currentRVH_);
129 if (currentRVH_ != tabContents_->render_view_host())
130 [self draggingEntered:info view:view];
131
132 if ([self onlyAllowsNavigation]) {
133 if ([[info draggingPasteboard] containsURLData])
134 return NSDragOperationCopy;
135 return NSDragOperationNone;
136 }
137
138 // Create the appropriate mouse locations for WebCore. The draggingLocation
139 // is in window coordinates.
140 NSPoint windowPoint = [info draggingLocation];
141 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
142 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
143 NSDragOperation mask = [info draggingSourceOperationMask];
144 tabContents_->render_view_host()->DragTargetDragOver(
145 gfx::Point(viewPoint.x, viewPoint.y),
146 gfx::Point(screenPoint.x, screenPoint.y),
147 static_cast<WebDragOperationsMask>(mask));
148
149 if (delegate_)
150 delegate_->OnDragOver();
151
152 return current_operation_;
153 }
154
155 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info
156 view:(NSView*)view {
157 if (currentRVH_ != tabContents_->render_view_host())
158 [self draggingEntered:info view:view];
159
160 // Check if we only allow navigation and navigate to a url on the pasteboard.
161 if ([self onlyAllowsNavigation]) {
162 NSPasteboard* pboard = [info draggingPasteboard];
163 if ([pboard containsURLData]) {
164 GURL url;
165 ui::PopulateURLAndTitleFromPasteboard(&url, NULL, pboard, YES);
166 tabContents_->OpenURL(url, GURL(), CURRENT_TAB,
167 content::PAGE_TRANSITION_AUTO_BOOKMARK);
168 return YES;
169 }
170 return NO;
171 }
172
173 if (delegate_)
174 delegate_->OnDrop();
175
176 currentRVH_ = NULL;
177
178 // Create the appropriate mouse locations for WebCore. The draggingLocation
179 // is in window coordinates. Both need to be flipped.
180 NSPoint windowPoint = [info draggingLocation];
181 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
182 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
183 tabContents_->render_view_host()->DragTargetDrop(
184 gfx::Point(viewPoint.x, viewPoint.y),
185 gfx::Point(screenPoint.x, screenPoint.y));
186
187 return YES;
188 }
189
190 // Given |data|, which should not be nil, fill it in using the contents of the
191 // given pasteboard.
192 - (void)populateWebDropData:(WebDropData*)data
193 fromPasteboard:(NSPasteboard*)pboard {
194 DCHECK(data);
195 DCHECK(pboard);
196 NSArray* types = [pboard types];
197
198 // Get URL if possible. To avoid exposing file system paths to web content,
199 // filenames in the drag are not converted to file URLs.
200 ui::PopulateURLAndTitleFromPasteboard(&data->url,
201 &data->url_title,
202 pboard,
203 NO);
204
205 // Get plain text.
206 if ([types containsObject:NSStringPboardType]) {
207 data->plain_text =
208 base::SysNSStringToUTF16([pboard stringForType:NSStringPboardType]);
209 }
210
211 // Get HTML. If there's no HTML, try RTF.
212 if ([types containsObject:NSHTMLPboardType]) {
213 data->text_html =
214 base::SysNSStringToUTF16([pboard stringForType:NSHTMLPboardType]);
215 } else if ([types containsObject:NSRTFPboardType]) {
216 NSString* html = [pboard htmlFromRtf];
217 data->text_html = base::SysNSStringToUTF16(html);
218 }
219
220 // Get files.
221 if ([types containsObject:NSFilenamesPboardType]) {
222 NSArray* files = [pboard propertyListForType:NSFilenamesPboardType];
223 if ([files isKindOfClass:[NSArray class]] && [files count]) {
224 for (NSUInteger i = 0; i < [files count]; i++) {
225 NSString* filename = [files objectAtIndex:i];
226 BOOL isDir = NO;
227 BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:filename
228 isDirectory:&isDir];
229 if (exists && !isDir)
230 data->filenames.push_back(base::SysNSStringToUTF16(filename));
231 }
232 }
233 }
234
235 // TODO(pinkerton): Get file contents. http://crbug.com/34661
236 }
237
238 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698