| 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 |