OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/gtk/tab_contents_drag_source.h" | 5 #include "chrome/browser/gtk/tab_contents_drag_source.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "app/gtk_dnd_util.h" | |
10 #include "base/file_util.h" | 9 #include "base/file_util.h" |
11 #include "base/mime_util.h" | 10 #include "base/mime_util.h" |
12 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/download/download_util.h" | 12 #include "chrome/browser/download/download_util.h" |
14 #include "chrome/browser/download/drag_download_file.h" | 13 #include "chrome/browser/download/drag_download_file.h" |
15 #include "chrome/browser/download/drag_download_util.h" | 14 #include "chrome/browser/download/drag_download_util.h" |
16 #include "chrome/browser/gtk/gtk_util.h" | 15 #include "chrome/browser/gtk/gtk_util.h" |
17 #include "chrome/browser/renderer_host/render_view_host.h" | 16 #include "chrome/browser/renderer_host/render_view_host.h" |
18 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | 17 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
19 #include "chrome/browser/tab_contents/tab_contents.h" | 18 #include "chrome/browser/tab_contents/tab_contents.h" |
20 #include "chrome/browser/tab_contents/tab_contents_view.h" | 19 #include "chrome/browser/tab_contents/tab_contents_view.h" |
21 #include "gfx/gtk_util.h" | 20 #include "gfx/gtk_util.h" |
22 #include "net/base/file_stream.h" | 21 #include "net/base/file_stream.h" |
23 #include "net/base/net_util.h" | 22 #include "net/base/net_util.h" |
| 23 #include "ui/base/dragdrop/gtk_dnd_util.h" |
24 #include "webkit/glue/webdropdata.h" | 24 #include "webkit/glue/webdropdata.h" |
25 | 25 |
26 using WebKit::WebDragOperation; | 26 using WebKit::WebDragOperation; |
27 using WebKit::WebDragOperationsMask; | 27 using WebKit::WebDragOperationsMask; |
28 using WebKit::WebDragOperationNone; | 28 using WebKit::WebDragOperationNone; |
29 | 29 |
30 TabContentsDragSource::TabContentsDragSource( | 30 TabContentsDragSource::TabContentsDragSource( |
31 TabContentsView* tab_contents_view) | 31 TabContentsView* tab_contents_view) |
32 : tab_contents_view_(tab_contents_view), | 32 : tab_contents_view_(tab_contents_view), |
33 drag_pixbuf_(NULL), | 33 drag_pixbuf_(NULL), |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 if (drag_context_) { | 75 if (drag_context_) { |
76 NOTREACHED(); | 76 NOTREACHED(); |
77 if (tab_contents()->render_view_host()) | 77 if (tab_contents()->render_view_host()) |
78 tab_contents()->render_view_host()->DragSourceSystemDragEnded(); | 78 tab_contents()->render_view_host()->DragSourceSystemDragEnded(); |
79 return; | 79 return; |
80 } | 80 } |
81 | 81 |
82 int targets_mask = 0; | 82 int targets_mask = 0; |
83 | 83 |
84 if (!drop_data.plain_text.empty()) | 84 if (!drop_data.plain_text.empty()) |
85 targets_mask |= gtk_dnd_util::TEXT_PLAIN; | 85 targets_mask |= ui::TEXT_PLAIN; |
86 if (drop_data.url.is_valid()) { | 86 if (drop_data.url.is_valid()) { |
87 targets_mask |= gtk_dnd_util::TEXT_URI_LIST; | 87 targets_mask |= ui::TEXT_URI_LIST; |
88 targets_mask |= gtk_dnd_util::CHROME_NAMED_URL; | 88 targets_mask |= ui::CHROME_NAMED_URL; |
89 targets_mask |= gtk_dnd_util::NETSCAPE_URL; | 89 targets_mask |= ui::NETSCAPE_URL; |
90 } | 90 } |
91 if (!drop_data.text_html.empty()) | 91 if (!drop_data.text_html.empty()) |
92 targets_mask |= gtk_dnd_util::TEXT_HTML; | 92 targets_mask |= ui::TEXT_HTML; |
93 if (!drop_data.file_contents.empty()) | 93 if (!drop_data.file_contents.empty()) |
94 targets_mask |= gtk_dnd_util::CHROME_WEBDROP_FILE_CONTENTS; | 94 targets_mask |= ui::CHROME_WEBDROP_FILE_CONTENTS; |
95 if (!drop_data.download_metadata.empty() && | 95 if (!drop_data.download_metadata.empty() && |
96 drag_download_util::ParseDownloadMetadata(drop_data.download_metadata, | 96 drag_download_util::ParseDownloadMetadata(drop_data.download_metadata, |
97 &wide_download_mime_type_, | 97 &wide_download_mime_type_, |
98 &download_file_name_, | 98 &download_file_name_, |
99 &download_url_)) { | 99 &download_url_)) { |
100 targets_mask |= gtk_dnd_util::DIRECT_SAVE_FILE; | 100 targets_mask |= ui::DIRECT_SAVE_FILE; |
101 } | 101 } |
102 | 102 |
103 // NOTE: Begin a drag even if no targets present. Otherwise, things like | 103 // NOTE: Begin a drag even if no targets present. Otherwise, things like |
104 // draggable list elements will not work. | 104 // draggable list elements will not work. |
105 | 105 |
106 drop_data_.reset(new WebDropData(drop_data)); | 106 drop_data_.reset(new WebDropData(drop_data)); |
107 | 107 |
108 // The image we get from WebKit makes heavy use of alpha-shading. This looks | 108 // The image we get from WebKit makes heavy use of alpha-shading. This looks |
109 // bad on non-compositing WMs. Fall back to the default drag icon. | 109 // bad on non-compositing WMs. Fall back to the default drag icon. |
110 if (!image.isNull() && gtk_util::IsScreenComposited()) | 110 if (!image.isNull() && gtk_util::IsScreenComposited()) |
111 drag_pixbuf_ = gfx::GdkPixbufFromSkBitmap(&image); | 111 drag_pixbuf_ = gfx::GdkPixbufFromSkBitmap(&image); |
112 image_offset_ = image_offset; | 112 image_offset_ = image_offset; |
113 | 113 |
114 GtkTargetList* list = gtk_dnd_util::GetTargetListFromCodeMask(targets_mask); | 114 GtkTargetList* list = ui::GetTargetListFromCodeMask(targets_mask); |
115 if (targets_mask & gtk_dnd_util::CHROME_WEBDROP_FILE_CONTENTS) { | 115 if (targets_mask & ui::CHROME_WEBDROP_FILE_CONTENTS) { |
116 drag_file_mime_type_ = gdk_atom_intern( | 116 drag_file_mime_type_ = gdk_atom_intern( |
117 mime_util::GetDataMimeType(drop_data.file_contents).c_str(), FALSE); | 117 mime_util::GetDataMimeType(drop_data.file_contents).c_str(), FALSE); |
118 gtk_target_list_add(list, drag_file_mime_type_, | 118 gtk_target_list_add(list, drag_file_mime_type_, |
119 0, gtk_dnd_util::CHROME_WEBDROP_FILE_CONTENTS); | 119 0, ui::CHROME_WEBDROP_FILE_CONTENTS); |
120 } | 120 } |
121 | 121 |
122 drag_failed_ = false; | 122 drag_failed_ = false; |
123 // If we don't pass an event, GDK won't know what event time to start grabbing | 123 // If we don't pass an event, GDK won't know what event time to start grabbing |
124 // mouse events. Technically it's the mouse motion event and not the mouse | 124 // mouse events. Technically it's the mouse motion event and not the mouse |
125 // down event that causes the drag, but there's no reliable way to know | 125 // down event that causes the drag, but there's no reliable way to know |
126 // *which* motion event initiated the drag, so this will have to do. | 126 // *which* motion event initiated the drag, so this will have to do. |
127 // TODO(estade): This can sometimes be very far off, e.g. if the user clicks | 127 // TODO(estade): This can sometimes be very far off, e.g. if the user clicks |
128 // and holds and doesn't start dragging for a long time. I doubt it matters | 128 // and holds and doesn't start dragging for a long time. I doubt it matters |
129 // much, but we should probably look into the possibility of getting the | 129 // much, but we should probably look into the possibility of getting the |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 static_cast<int>(event_motion->y_root)); | 166 static_cast<int>(event_motion->y_root)); |
167 } | 167 } |
168 } | 168 } |
169 | 169 |
170 void TabContentsDragSource::OnDragDataGet(GtkWidget* sender, | 170 void TabContentsDragSource::OnDragDataGet(GtkWidget* sender, |
171 GdkDragContext* context, GtkSelectionData* selection_data, | 171 GdkDragContext* context, GtkSelectionData* selection_data, |
172 guint target_type, guint time) { | 172 guint target_type, guint time) { |
173 const int kBitsPerByte = 8; | 173 const int kBitsPerByte = 8; |
174 | 174 |
175 switch (target_type) { | 175 switch (target_type) { |
176 case gtk_dnd_util::TEXT_PLAIN: { | 176 case ui::TEXT_PLAIN: { |
177 std::string utf8_text = UTF16ToUTF8(drop_data_->plain_text); | 177 std::string utf8_text = UTF16ToUTF8(drop_data_->plain_text); |
178 gtk_selection_data_set_text(selection_data, utf8_text.c_str(), | 178 gtk_selection_data_set_text(selection_data, utf8_text.c_str(), |
179 utf8_text.length()); | 179 utf8_text.length()); |
180 break; | 180 break; |
181 } | 181 } |
182 | 182 |
183 case gtk_dnd_util::TEXT_HTML: { | 183 case ui::TEXT_HTML: { |
184 // TODO(estade): change relative links to be absolute using | 184 // TODO(estade): change relative links to be absolute using |
185 // |html_base_url|. | 185 // |html_base_url|. |
186 std::string utf8_text = UTF16ToUTF8(drop_data_->text_html); | 186 std::string utf8_text = UTF16ToUTF8(drop_data_->text_html); |
187 gtk_selection_data_set(selection_data, | 187 gtk_selection_data_set(selection_data, |
188 gtk_dnd_util::GetAtomForTarget( | 188 ui::GetAtomForTarget(ui::TEXT_HTML), |
189 gtk_dnd_util::TEXT_HTML), | |
190 kBitsPerByte, | 189 kBitsPerByte, |
191 reinterpret_cast<const guchar*>(utf8_text.c_str()), | 190 reinterpret_cast<const guchar*>(utf8_text.c_str()), |
192 utf8_text.length()); | 191 utf8_text.length()); |
193 break; | 192 break; |
194 } | 193 } |
195 | 194 |
196 case gtk_dnd_util::TEXT_URI_LIST: | 195 case ui::TEXT_URI_LIST: |
197 case gtk_dnd_util::CHROME_NAMED_URL: | 196 case ui::CHROME_NAMED_URL: |
198 case gtk_dnd_util::NETSCAPE_URL: { | 197 case ui::NETSCAPE_URL: { |
199 gtk_dnd_util::WriteURLWithName(selection_data, drop_data_->url, | 198 ui::WriteURLWithName(selection_data, drop_data_->url, |
200 drop_data_->url_title, target_type); | 199 drop_data_->url_title, target_type); |
201 break; | 200 break; |
202 } | 201 } |
203 | 202 |
204 case gtk_dnd_util::CHROME_WEBDROP_FILE_CONTENTS: { | 203 case ui::CHROME_WEBDROP_FILE_CONTENTS: { |
205 gtk_selection_data_set( | 204 gtk_selection_data_set( |
206 selection_data, | 205 selection_data, |
207 drag_file_mime_type_, kBitsPerByte, | 206 drag_file_mime_type_, kBitsPerByte, |
208 reinterpret_cast<const guchar*>(drop_data_->file_contents.data()), | 207 reinterpret_cast<const guchar*>(drop_data_->file_contents.data()), |
209 drop_data_->file_contents.length()); | 208 drop_data_->file_contents.length()); |
210 break; | 209 break; |
211 } | 210 } |
212 | 211 |
213 case gtk_dnd_util::DIRECT_SAVE_FILE: { | 212 case ui::DIRECT_SAVE_FILE: { |
214 char status_code = 'E'; | 213 char status_code = 'E'; |
215 | 214 |
216 // Retrieves the full file path (in file URL format) provided by the | 215 // Retrieves the full file path (in file URL format) provided by the |
217 // drop target by reading from the source window's XdndDirectSave0 | 216 // drop target by reading from the source window's XdndDirectSave0 |
218 // property. | 217 // property. |
219 gint file_url_len = 0; | 218 gint file_url_len = 0; |
220 guchar* file_url_value = NULL; | 219 guchar* file_url_value = NULL; |
221 if (gdk_property_get(context->source_window, | 220 if (gdk_property_get(context->source_window, |
222 gtk_dnd_util::GetAtomForTarget( | 221 ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE), |
223 gtk_dnd_util::DIRECT_SAVE_FILE), | 222 ui::GetAtomForTarget(ui::TEXT_PLAIN_NO_CHARSET), |
224 gtk_dnd_util::GetAtomForTarget( | |
225 gtk_dnd_util::TEXT_PLAIN_NO_CHARSET), | |
226 0, | 223 0, |
227 1024, | 224 1024, |
228 FALSE, | 225 FALSE, |
229 NULL, | 226 NULL, |
230 NULL, | 227 NULL, |
231 &file_url_len, | 228 &file_url_len, |
232 &file_url_value) && | 229 &file_url_value) && |
233 file_url_value) { | 230 file_url_value) { |
234 // Convert from the file url to the file path. | 231 // Convert from the file url to the file path. |
235 GURL file_url(std::string(reinterpret_cast<char*>(file_url_value), | 232 GURL file_url(std::string(reinterpret_cast<char*>(file_url_value), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 FilePath generated_download_file_name; | 299 FilePath generated_download_file_name; |
303 download_util::GenerateFileName(download_url_, | 300 download_util::GenerateFileName(download_url_, |
304 content_disposition, | 301 content_disposition, |
305 std::string(), | 302 std::string(), |
306 download_mime_type, | 303 download_mime_type, |
307 &generated_download_file_name); | 304 &generated_download_file_name); |
308 | 305 |
309 // Pass the file name to the drop target by setting the source window's | 306 // Pass the file name to the drop target by setting the source window's |
310 // XdndDirectSave0 property. | 307 // XdndDirectSave0 property. |
311 gdk_property_change(drag_context->source_window, | 308 gdk_property_change(drag_context->source_window, |
312 gtk_dnd_util::GetAtomForTarget( | 309 ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE), |
313 gtk_dnd_util::DIRECT_SAVE_FILE), | 310 ui::GetAtomForTarget(ui::TEXT_PLAIN_NO_CHARSET), |
314 gtk_dnd_util::GetAtomForTarget( | |
315 gtk_dnd_util::TEXT_PLAIN_NO_CHARSET), | |
316 8, | 311 8, |
317 GDK_PROP_MODE_REPLACE, | 312 GDK_PROP_MODE_REPLACE, |
318 reinterpret_cast<const guchar*>( | 313 reinterpret_cast<const guchar*>( |
319 generated_download_file_name.value().c_str()), | 314 generated_download_file_name.value().c_str()), |
320 generated_download_file_name.value().length()); | 315 generated_download_file_name.value().length()); |
321 } | 316 } |
322 | 317 |
323 if (drag_pixbuf_) { | 318 if (drag_pixbuf_) { |
324 gtk_widget_set_size_request(drag_icon_, | 319 gtk_widget_set_size_request(drag_icon_, |
325 gdk_pixbuf_get_width(drag_pixbuf_), | 320 gdk_pixbuf_get_width(drag_pixbuf_), |
(...skipping 16 matching lines...) Expand all Loading... |
342 GdkDragContext* drag_context) { | 337 GdkDragContext* drag_context) { |
343 if (drag_pixbuf_) { | 338 if (drag_pixbuf_) { |
344 g_object_unref(drag_pixbuf_); | 339 g_object_unref(drag_pixbuf_); |
345 drag_pixbuf_ = NULL; | 340 drag_pixbuf_ = NULL; |
346 } | 341 } |
347 | 342 |
348 MessageLoopForUI::current()->RemoveObserver(this); | 343 MessageLoopForUI::current()->RemoveObserver(this); |
349 | 344 |
350 if (!download_url_.is_empty()) { | 345 if (!download_url_.is_empty()) { |
351 gdk_property_delete(drag_context->source_window, | 346 gdk_property_delete(drag_context->source_window, |
352 gtk_dnd_util::GetAtomForTarget( | 347 ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE)); |
353 gtk_dnd_util::DIRECT_SAVE_FILE)); | |
354 } | 348 } |
355 | 349 |
356 if (!drag_failed_) { | 350 if (!drag_failed_) { |
357 gfx::Point root = gtk_util::ScreenPoint(GetContentNativeView()); | 351 gfx::Point root = gtk_util::ScreenPoint(GetContentNativeView()); |
358 gfx::Point client = gtk_util::ClientPoint(GetContentNativeView()); | 352 gfx::Point client = gtk_util::ClientPoint(GetContentNativeView()); |
359 | 353 |
360 if (tab_contents()->render_view_host()) { | 354 if (tab_contents()->render_view_host()) { |
361 tab_contents()->render_view_host()->DragSourceEndedAt( | 355 tab_contents()->render_view_host()->DragSourceEndedAt( |
362 client.x(), client.y(), root.x(), root.y(), | 356 client.x(), client.y(), root.x(), root.y(), |
363 gtk_util::GdkDragActionToWebDragOp(drag_context->action)); | 357 gtk_util::GdkDragActionToWebDragOp(drag_context->action)); |
(...skipping 16 matching lines...) Expand all Loading... |
380 cairo_t* cr = gdk_cairo_create(event->window); | 374 cairo_t* cr = gdk_cairo_create(event->window); |
381 gdk_cairo_rectangle(cr, &event->area); | 375 gdk_cairo_rectangle(cr, &event->area); |
382 cairo_clip(cr); | 376 cairo_clip(cr); |
383 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); | 377 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); |
384 gdk_cairo_set_source_pixbuf(cr, drag_pixbuf_, 0, 0); | 378 gdk_cairo_set_source_pixbuf(cr, drag_pixbuf_, 0, 0); |
385 cairo_paint(cr); | 379 cairo_paint(cr); |
386 cairo_destroy(cr); | 380 cairo_destroy(cr); |
387 | 381 |
388 return TRUE; | 382 return TRUE; |
389 } | 383 } |
OLD | NEW |