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

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

Issue 6358008: [Mac] Organize some files into chrome/browser/ui/cocoa/tab_contents/.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 11 months 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) 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/web_drop_target.h"
6
7 #include "base/sys_string_conversions.h"
8 #include "chrome/browser/bookmarks/bookmark_node_data.h"
9 #include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
10 #include "chrome/browser/renderer_host/render_view_host.h"
11 #include "chrome/browser/tab_contents/tab_contents.h"
12 #import "third_party/mozilla/NSPasteboard+Utils.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 // Call to set whether or not we should allow the drop. Takes effect the
31 // next time |-draggingUpdated:| is called.
32 - (void)setCurrentOperation: (NSDragOperation)operation {
33 current_operation_ = operation;
34 }
35
36 // Given a point in window coordinates and a view in that window, return a
37 // flipped point in the coordinate system of |view|.
38 - (NSPoint)flipWindowPointToView:(const NSPoint&)windowPoint
39 view:(NSView*)view {
40 DCHECK(view);
41 NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
42 NSRect viewFrame = [view frame];
43 viewPoint.y = viewFrame.size.height - viewPoint.y;
44 return viewPoint;
45 }
46
47 // Given a point in window coordinates and a view in that window, return a
48 // flipped point in screen coordinates.
49 - (NSPoint)flipWindowPointToScreen:(const NSPoint&)windowPoint
50 view:(NSView*)view {
51 DCHECK(view);
52 NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
53 NSScreen* screen = [[view window] screen];
54 NSRect screenFrame = [screen frame];
55 screenPoint.y = screenFrame.size.height - screenPoint.y;
56 return screenPoint;
57 }
58
59 // Return YES if the drop site only allows drops that would navigate. If this
60 // is the case, we don't want to pass messages to the renderer because there's
61 // really no point (i.e., there's nothing that cares about the mouse position or
62 // entering and exiting). One example is an interstitial page (e.g., safe
63 // browsing warning).
64 - (BOOL)onlyAllowsNavigation {
65 return tabContents_->showing_interstitial_page();
66 }
67
68 // Messages to send during the tracking of a drag, ususally upon recieving
69 // calls from the view system. Communicates the drag messages to WebCore.
70
71 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info
72 view:(NSView*)view {
73 // Save off the RVH so we can tell if it changes during a drag. If it does,
74 // we need to send a new enter message in draggingUpdated:.
75 currentRVH_ = tabContents_->render_view_host();
76
77 if ([self onlyAllowsNavigation]) {
78 if ([[info draggingPasteboard] containsURLData])
79 return NSDragOperationCopy;
80 return NSDragOperationNone;
81 }
82
83 // If the tab is showing the boomark manager, send BookmarkDrag events
84 RenderViewHostDelegate::BookmarkDrag* dragDelegate =
85 tabContents_->GetBookmarkDragDelegate();
86 BookmarkNodeData dragData;
87 if(dragDelegate && dragData.ReadFromDragClipboard())
88 dragDelegate->OnDragEnter(dragData);
89
90 // Fill out a WebDropData from pasteboard.
91 WebDropData data;
92 [self populateWebDropData:&data fromPasteboard:[info draggingPasteboard]];
93
94 // Create the appropriate mouse locations for WebCore. The draggingLocation
95 // is in window coordinates. Both need to be flipped.
96 NSPoint windowPoint = [info draggingLocation];
97 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
98 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
99 NSDragOperation mask = [info draggingSourceOperationMask];
100 tabContents_->render_view_host()->DragTargetDragEnter(data,
101 gfx::Point(viewPoint.x, viewPoint.y),
102 gfx::Point(screenPoint.x, screenPoint.y),
103 static_cast<WebDragOperationsMask>(mask));
104
105 // We won't know the true operation (whether the drag is allowed) until we
106 // hear back from the renderer. For now, be optimistic:
107 current_operation_ = NSDragOperationCopy;
108 return current_operation_;
109 }
110
111 - (void)draggingExited:(id<NSDraggingInfo>)info {
112 DCHECK(currentRVH_);
113 if (currentRVH_ != tabContents_->render_view_host())
114 return;
115
116 // Nothing to do in the interstitial case.
117
118 tabContents_->render_view_host()->DragTargetDragLeave();
119 }
120
121 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info
122 view:(NSView*)view {
123 DCHECK(currentRVH_);
124 if (currentRVH_ != tabContents_->render_view_host())
125 [self draggingEntered:info view:view];
126
127 if ([self onlyAllowsNavigation]) {
128 if ([[info draggingPasteboard] containsURLData])
129 return NSDragOperationCopy;
130 return NSDragOperationNone;
131 }
132
133 // Create the appropriate mouse locations for WebCore. The draggingLocation
134 // is in window coordinates.
135 NSPoint windowPoint = [info draggingLocation];
136 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
137 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
138 NSDragOperation mask = [info draggingSourceOperationMask];
139 tabContents_->render_view_host()->DragTargetDragOver(
140 gfx::Point(viewPoint.x, viewPoint.y),
141 gfx::Point(screenPoint.x, screenPoint.y),
142 static_cast<WebDragOperationsMask>(mask));
143
144 // If the tab is showing the boomark manager, send BookmarkDrag events
145 RenderViewHostDelegate::BookmarkDrag* dragDelegate =
146 tabContents_->GetBookmarkDragDelegate();
147 BookmarkNodeData dragData;
148 if(dragDelegate && dragData.ReadFromDragClipboard())
149 dragDelegate->OnDragOver(dragData);
150 return current_operation_;
151 }
152
153 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info
154 view:(NSView*)view {
155 if (currentRVH_ != tabContents_->render_view_host())
156 [self draggingEntered:info view:view];
157
158 // Check if we only allow navigation and navigate to a url on the pasteboard.
159 if ([self onlyAllowsNavigation]) {
160 NSPasteboard* pboard = [info draggingPasteboard];
161 if ([pboard containsURLData]) {
162 GURL url;
163 [self populateURL:&url
164 andTitle:NULL
165 fromPasteboard:pboard
166 convertingFilenames:YES];
167 tabContents_->OpenURL(url, GURL(), CURRENT_TAB,
168 PageTransition::AUTO_BOOKMARK);
169 return YES;
170 }
171 return NO;
172 }
173
174 // If the tab is showing the boomark manager, send BookmarkDrag events
175 RenderViewHostDelegate::BookmarkDrag* dragDelegate =
176 tabContents_->GetBookmarkDragDelegate();
177 BookmarkNodeData dragData;
178 if(dragDelegate && dragData.ReadFromDragClipboard())
179 dragDelegate->OnDrop(dragData);
180
181 currentRVH_ = NULL;
182
183 // Create the appropriate mouse locations for WebCore. The draggingLocation
184 // is in window coordinates. Both need to be flipped.
185 NSPoint windowPoint = [info draggingLocation];
186 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
187 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
188 tabContents_->render_view_host()->DragTargetDrop(
189 gfx::Point(viewPoint.x, viewPoint.y),
190 gfx::Point(screenPoint.x, screenPoint.y));
191
192 return YES;
193 }
194
195 // Populate the |url| and |title| with URL data in |pboard|. There may be more
196 // than one, but we only handle dropping the first. |url| must not be |NULL|;
197 // |title| is an optional parameter. Returns |YES| if URL data was obtained from
198 // the pasteboard, |NO| otherwise. If |convertFilenames| is |YES|, the function
199 // will also attempt to convert filenames in |pboard| to file URLs.
200 - (BOOL)populateURL:(GURL*)url
201 andTitle:(string16*)title
202 fromPasteboard:(NSPasteboard*)pboard
203 convertingFilenames:(BOOL)convertFilenames {
204 DCHECK(url);
205 DCHECK(title);
206
207 // Bail out early if there's no URL data.
208 if (![pboard containsURLData])
209 return NO;
210
211 // |-getURLs:andTitles:convertingFilenames:| will already validate URIs so we
212 // don't need to again. The arrays returned are both of NSString's.
213 NSArray* urls = nil;
214 NSArray* titles = nil;
215 [pboard getURLs:&urls andTitles:&titles convertingFilenames:convertFilenames];
216 DCHECK_EQ([urls count], [titles count]);
217 // It's possible that no URLs were actually provided!
218 if (![urls count])
219 return NO;
220 NSString* urlString = [urls objectAtIndex:0];
221 if ([urlString length]) {
222 // Check again just to make sure to not assign NULL into a std::string,
223 // which throws an exception.
224 const char* utf8Url = [urlString UTF8String];
225 if (utf8Url) {
226 *url = GURL(utf8Url);
227 // Extra paranoia check.
228 if (title && [titles count])
229 *title = base::SysNSStringToUTF16([titles objectAtIndex:0]);
230 }
231 }
232 return YES;
233 }
234
235 // Given |data|, which should not be nil, fill it in using the contents of the
236 // given pasteboard.
237 - (void)populateWebDropData:(WebDropData*)data
238 fromPasteboard:(NSPasteboard*)pboard {
239 DCHECK(data);
240 DCHECK(pboard);
241 NSArray* types = [pboard types];
242
243 // Get URL if possible. To avoid exposing file system paths to web content,
244 // filenames in the drag are not converted to file URLs.
245 [self populateURL:&data->url
246 andTitle:&data->url_title
247 fromPasteboard:pboard
248 convertingFilenames:NO];
249
250 // Get plain text.
251 if ([types containsObject:NSStringPboardType]) {
252 data->plain_text =
253 base::SysNSStringToUTF16([pboard stringForType:NSStringPboardType]);
254 }
255
256 // Get HTML. If there's no HTML, try RTF.
257 if ([types containsObject:NSHTMLPboardType]) {
258 data->text_html =
259 base::SysNSStringToUTF16([pboard stringForType:NSHTMLPboardType]);
260 } else if ([types containsObject:NSRTFPboardType]) {
261 NSString* html = [pboard htmlFromRtf];
262 data->text_html = base::SysNSStringToUTF16(html);
263 }
264
265 // Get files.
266 if ([types containsObject:NSFilenamesPboardType]) {
267 NSArray* files = [pboard propertyListForType:NSFilenamesPboardType];
268 if ([files isKindOfClass:[NSArray class]] && [files count]) {
269 for (NSUInteger i = 0; i < [files count]; i++) {
270 NSString* filename = [files objectAtIndex:i];
271 BOOL isDir = NO;
272 BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:filename
273 isDirectory:&isDir];
274 if (exists && !isDir)
275 data->filenames.push_back(base::SysNSStringToUTF16(filename));
276 }
277 }
278 }
279
280 // TODO(pinkerton): Get file contents. http://crbug.com/34661
281 }
282
283 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698