| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 #include "chrome/browser/ui/gtk/download/download_item_drag.h" | |
| 6 | |
| 7 #include "base/files/file_path.h" | |
| 8 #include "base/strings/utf_string_conversions.h" | |
| 9 #include "chrome/browser/download/drag_download_item.h" | |
| 10 #include "content/public/browser/download_item.h" | |
| 11 #include "net/base/filename_util.h" | |
| 12 #include "ui/base/dragdrop/gtk_dnd_util.h" | |
| 13 #include "ui/gfx/image/image.h" | |
| 14 #include "url/gurl.h" | |
| 15 | |
| 16 using content::DownloadItem; | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 const int kDownloadItemCodeMask = ui::TEXT_URI_LIST | ui::CHROME_NAMED_URL; | |
| 21 const GdkDragAction kDownloadItemDragAction = GDK_ACTION_COPY; | |
| 22 | |
| 23 } // namespace | |
| 24 | |
| 25 // Stores metadata for a drag & drop operation. | |
| 26 class DownloadItemDrag::DragData { | |
| 27 public: | |
| 28 // Constructs a DragData object based on the current state of |item|. | |
| 29 explicit DragData(const DownloadItem* item); | |
| 30 | |
| 31 // Sets up a drag source and connects |drag_data| to 'drag-data-get' on | |
| 32 // |widget|. If |icon| is non-NULL it will be used as the drag icon. The | |
| 33 // object pointed to by |drag_data| will be deleted when the signal is | |
| 34 // disconnected. | |
| 35 static void AttachToWidget(scoped_ptr<DragData> drag_data, | |
| 36 GtkWidget* widget, | |
| 37 gfx::Image* icon); | |
| 38 | |
| 39 // 'drag-data-get' signal handler. | |
| 40 CHROMEGTK_CALLBACK_4(DragData, void, OnDragDataGet, GdkDragContext*, | |
| 41 GtkSelectionData*, guint, guint); | |
| 42 | |
| 43 private: | |
| 44 // GClosureNotify handler for destroying a DragData object. |data| is assumed | |
| 45 // to be a DragData*. | |
| 46 static void OnDestroy(gpointer data, GClosure* closure); | |
| 47 | |
| 48 GURL url_; | |
| 49 base::string16 display_name_; | |
| 50 }; | |
| 51 | |
| 52 DownloadItemDrag::DragData::DragData(const DownloadItem* item) | |
| 53 : url_(net::FilePathToFileURL(item->GetTargetFilePath())), | |
| 54 display_name_(item->GetFileNameToReportUser().LossyDisplayName()) { | |
| 55 DCHECK_EQ(DownloadItem::COMPLETE, item->GetState()); | |
| 56 } | |
| 57 | |
| 58 // static | |
| 59 void DownloadItemDrag::DragData::AttachToWidget(scoped_ptr<DragData> drag_data, | |
| 60 GtkWidget* widget, | |
| 61 gfx::Image* icon) { | |
| 62 gtk_drag_source_set( | |
| 63 widget, GDK_BUTTON1_MASK, NULL, 0, kDownloadItemDragAction); | |
| 64 ui::SetSourceTargetListFromCodeMask(widget, kDownloadItemCodeMask); | |
| 65 | |
| 66 // Disconnect previous signal handlers, if any. | |
| 67 g_signal_handlers_disconnect_matched( | |
| 68 widget, | |
| 69 G_SIGNAL_MATCH_FUNC, | |
| 70 0, | |
| 71 0, | |
| 72 NULL, | |
| 73 reinterpret_cast<gpointer>(&OnDragDataGetThunk), | |
| 74 NULL); | |
| 75 | |
| 76 // Connect new signal handlers. | |
| 77 g_signal_connect_data(widget, | |
| 78 "drag-data-get", | |
| 79 G_CALLBACK(&OnDragDataGetThunk), | |
| 80 reinterpret_cast<gpointer>(drag_data.release()), | |
| 81 &OnDestroy, | |
| 82 static_cast<GConnectFlags>(0)); | |
| 83 | |
| 84 if (icon) | |
| 85 gtk_drag_source_set_icon_pixbuf(widget, icon->ToGdkPixbuf()); | |
| 86 } | |
| 87 | |
| 88 void DownloadItemDrag::DragData::OnDragDataGet(GtkWidget* widget, | |
| 89 GdkDragContext* context, | |
| 90 GtkSelectionData* selection_data, | |
| 91 guint target_type, | |
| 92 guint time) { | |
| 93 ui::WriteURLWithName(selection_data, url_, display_name_, target_type); | |
| 94 } | |
| 95 | |
| 96 // static | |
| 97 void DownloadItemDrag::DragData::OnDestroy(gpointer data, GClosure* closure) { | |
| 98 DragData* drag_data = reinterpret_cast<DragData*>(data); | |
| 99 delete drag_data; | |
| 100 } | |
| 101 | |
| 102 // DownloadItemDrag ------------------------------------------------------------ | |
| 103 | |
| 104 // static | |
| 105 void DownloadItemDrag::SetSource(GtkWidget* widget, | |
| 106 const DownloadItem* item, | |
| 107 gfx::Image* icon) { | |
| 108 scoped_ptr<DragData> drag_data(new DragData(item)); | |
| 109 DragData::AttachToWidget(drag_data.Pass(), widget, icon); | |
| 110 } | |
| 111 | |
| 112 DownloadItemDrag::DownloadItemDrag(const DownloadItem* item, gfx::Image* icon) | |
| 113 : CustomDrag(icon, kDownloadItemCodeMask, kDownloadItemDragAction), | |
| 114 drag_data_(new DragData(item)) {} | |
| 115 | |
| 116 DownloadItemDrag::~DownloadItemDrag() {} | |
| 117 | |
| 118 void DownloadItemDrag::OnDragDataGet(GtkWidget* widget, | |
| 119 GdkDragContext* context, | |
| 120 GtkSelectionData* selection_data, | |
| 121 guint target_type, | |
| 122 guint time) { | |
| 123 drag_data_->OnDragDataGet(widget, context, selection_data, target_type, time); | |
| 124 } | |
| 125 | |
| 126 void DragDownloadItem(const content::DownloadItem* download, | |
| 127 gfx::Image* icon, | |
| 128 gfx::NativeView view) { | |
| 129 // This starts the drag process, the lifetime of this object is tied to the | |
| 130 // system drag. | |
| 131 new DownloadItemDrag(download, icon); | |
| 132 } | |
| OLD | NEW |