OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/gtk/custom_drag.h" | 5 #include "chrome/browser/ui/gtk/custom_drag.h" |
6 | 6 |
7 #include "base/files/file_path.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" | |
10 #include "content/public/browser/download_item.h" | |
11 #include "net/base/net_util.h" | |
12 #include "third_party/skia/include/core/SkBitmap.h" | |
13 #include "ui/base/dragdrop/gtk_dnd_util.h" | 7 #include "ui/base/dragdrop/gtk_dnd_util.h" |
14 #include "ui/gfx/gtk_util.h" | |
15 #include "ui/gfx/image/image.h" | 8 #include "ui/gfx/image/image.h" |
16 #include "url/gurl.h" | |
17 | |
18 using content::DownloadItem; | |
19 | |
20 namespace { | |
21 | |
22 const int kDownloadItemCodeMask = ui::TEXT_URI_LIST | ui::CHROME_NAMED_URL; | |
23 const GdkDragAction kDownloadItemDragAction = GDK_ACTION_COPY; | |
24 const GdkDragAction kBookmarkDragAction = | |
25 static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
26 | |
27 } // namespace | |
28 | |
29 // CustomDrag ------------------------------------------------------------------ | |
30 | 9 |
31 CustomDrag::CustomDrag(gfx::Image* icon, int code_mask, GdkDragAction action) | 10 CustomDrag::CustomDrag(gfx::Image* icon, int code_mask, GdkDragAction action) |
32 : drag_widget_(gtk_invisible_new()), | 11 : drag_widget_(gtk_invisible_new()), |
33 image_(icon) { | 12 image_(icon) { |
34 g_signal_connect(drag_widget_, "drag-data-get", | 13 g_signal_connect(drag_widget_, "drag-data-get", |
35 G_CALLBACK(OnDragDataGetThunk), this); | 14 G_CALLBACK(OnDragDataGetThunk), this); |
36 g_signal_connect(drag_widget_, "drag-begin", | 15 g_signal_connect(drag_widget_, "drag-begin", |
37 G_CALLBACK(OnDragBeginThunk), this); | 16 G_CALLBACK(OnDragBeginThunk), this); |
38 g_signal_connect(drag_widget_, "drag-end", | 17 g_signal_connect(drag_widget_, "drag-end", |
39 G_CALLBACK(OnDragEndThunk), this); | 18 G_CALLBACK(OnDragEndThunk), this); |
(...skipping 11 matching lines...) Expand all Loading... |
51 } | 30 } |
52 | 31 |
53 void CustomDrag::OnDragBegin(GtkWidget* widget, GdkDragContext* drag_context) { | 32 void CustomDrag::OnDragBegin(GtkWidget* widget, GdkDragContext* drag_context) { |
54 if (image_) | 33 if (image_) |
55 gtk_drag_set_icon_pixbuf(drag_context, image_->ToGdkPixbuf(), 0, 0); | 34 gtk_drag_set_icon_pixbuf(drag_context, image_->ToGdkPixbuf(), 0, 0); |
56 } | 35 } |
57 | 36 |
58 void CustomDrag::OnDragEnd(GtkWidget* widget, GdkDragContext* drag_context) { | 37 void CustomDrag::OnDragEnd(GtkWidget* widget, GdkDragContext* drag_context) { |
59 delete this; | 38 delete this; |
60 } | 39 } |
61 | |
62 // DownloadItemDrag ------------------------------------------------------------ | |
63 | |
64 // Stores metadata for a drag & drop operation. | |
65 class DownloadItemDrag::DragData { | |
66 public: | |
67 // Constructs a DragData object based on the current state of |item|. | |
68 explicit DragData(const DownloadItem* item); | |
69 | |
70 // 'drag-data-get' signal handler. | |
71 CHROMEGTK_CALLBACK_4(DragData, void, OnDragDataGet, GdkDragContext*, | |
72 GtkSelectionData*, guint, guint); | |
73 | |
74 // Sets up a drag source and connects |drag_data| to 'drag-data-get' on | |
75 // |widget|. If |icon| is non-NULL it will be used as the drag icon. The | |
76 // object pointed to by |drag_data| will be deleted when the signal is | |
77 // disconnected. | |
78 static void AttachToWidget(scoped_ptr<DragData> drag_data, | |
79 GtkWidget* widget, | |
80 gfx::Image* icon); | |
81 | |
82 private: | |
83 // GClosureNotify handler for destroying a DragData object. |data| is assumed | |
84 // to be a DragData*. | |
85 static void OnDestroy(gpointer data, GClosure* closure); | |
86 | |
87 GURL url_; | |
88 string16 display_name_; | |
89 }; | |
90 | |
91 DownloadItemDrag::DragData::DragData(const DownloadItem* item) | |
92 : url_(net::FilePathToFileURL(item->GetTargetFilePath())), | |
93 display_name_(item->GetFileNameToReportUser().LossyDisplayName()) { | |
94 DCHECK_EQ(DownloadItem::COMPLETE, item->GetState()); | |
95 } | |
96 | |
97 void DownloadItemDrag::DragData::OnDragDataGet(GtkWidget* widget, | |
98 GdkDragContext* context, | |
99 GtkSelectionData* selection_data, | |
100 guint target_type, | |
101 guint time) { | |
102 ui::WriteURLWithName(selection_data, url_, display_name_, target_type); | |
103 } | |
104 | |
105 // static | |
106 void DownloadItemDrag::DragData::AttachToWidget(scoped_ptr<DragData> drag_data, | |
107 GtkWidget* widget, | |
108 gfx::Image* icon) { | |
109 gtk_drag_source_set(widget, GDK_BUTTON1_MASK, NULL, 0, | |
110 kDownloadItemDragAction); | |
111 ui::SetSourceTargetListFromCodeMask(widget, kDownloadItemCodeMask); | |
112 | |
113 // Disconnect previous signal handlers, if any. | |
114 g_signal_handlers_disconnect_matched( | |
115 widget, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, | |
116 reinterpret_cast<gpointer>(&OnDragDataGetThunk), | |
117 NULL); | |
118 | |
119 // Connect new signal handlers. | |
120 g_signal_connect_data( | |
121 widget, "drag-data-get", | |
122 G_CALLBACK(&OnDragDataGetThunk), | |
123 reinterpret_cast<gpointer>(drag_data.release()), | |
124 &OnDestroy, | |
125 static_cast<GConnectFlags>(0)); | |
126 | |
127 if (icon) | |
128 gtk_drag_source_set_icon_pixbuf(widget, icon->ToGdkPixbuf()); | |
129 } | |
130 | |
131 // static | |
132 void DownloadItemDrag::DragData::OnDestroy(gpointer data, GClosure* closure) { | |
133 DragData* drag_data = reinterpret_cast<DragData*>(data); | |
134 delete drag_data; | |
135 } | |
136 | |
137 DownloadItemDrag::DownloadItemDrag(const DownloadItem* item, | |
138 gfx::Image* icon) | |
139 : CustomDrag(icon, kDownloadItemCodeMask, kDownloadItemDragAction), | |
140 drag_data_(new DragData(item)) { | |
141 } | |
142 | |
143 DownloadItemDrag::~DownloadItemDrag() { | |
144 } | |
145 | |
146 void DownloadItemDrag::OnDragDataGet( | |
147 GtkWidget* widget, GdkDragContext* context, | |
148 GtkSelectionData* selection_data, | |
149 guint target_type, guint time) { | |
150 drag_data_->OnDragDataGet(widget, context, selection_data, target_type, time); | |
151 } | |
152 | |
153 // static | |
154 void DownloadItemDrag::SetSource(GtkWidget* widget, | |
155 const DownloadItem* item, | |
156 gfx::Image* icon) { | |
157 scoped_ptr<DragData> drag_data(new DragData(item)); | |
158 DragData::AttachToWidget(drag_data.Pass(), widget, icon); | |
159 } | |
160 | |
161 // static | |
162 void DownloadItemDrag::BeginDrag(const DownloadItem* item, gfx::Image* icon) { | |
163 new DownloadItemDrag(item, icon); | |
164 } | |
165 | |
166 // BookmarkDrag ---------------------------------------------------------------- | |
167 | |
168 BookmarkDrag::BookmarkDrag(Profile* profile, | |
169 const std::vector<const BookmarkNode*>& nodes) | |
170 : CustomDrag(NULL, GetCodeMask(false), kBookmarkDragAction), | |
171 profile_(profile), | |
172 nodes_(nodes) {} | |
173 | |
174 BookmarkDrag::~BookmarkDrag() { | |
175 } | |
176 | |
177 void BookmarkDrag::OnDragDataGet(GtkWidget* widget, | |
178 GdkDragContext* context, | |
179 GtkSelectionData* selection_data, | |
180 guint target_type, | |
181 guint time) { | |
182 WriteBookmarksToSelection(nodes_, selection_data, target_type, profile_); | |
183 } | |
184 | |
185 // static | |
186 void BookmarkDrag::BeginDrag(Profile* profile, | |
187 const std::vector<const BookmarkNode*>& nodes) { | |
188 new BookmarkDrag(profile, nodes); | |
189 } | |
OLD | NEW |