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

Side by Side Diff: chrome/browser/tab_contents/web_drag_dest_gtk.cc

Issue 8196001: content: Split web_drag_dest_gtk.cc into chrome/ and content/ parts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix viewgtk compile Created 9 years, 2 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
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/tab_contents/web_drag_dest_gtk.h" 5 #include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/bookmarks/bookmark_node_data.h" 12 #include "chrome/browser/tab_contents/web_drag_dest_delegate_gtk.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
18 #include "chrome/browser/ui/gtk/gtk_util.h"
19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
20 #include "chrome/common/url_constants.h"
21 #include "content/browser/renderer_host/render_view_host.h" 13 #include "content/browser/renderer_host/render_view_host.h"
14 #include "content/browser/tab_contents/drag_utils_gtk.h"
22 #include "content/browser/tab_contents/tab_contents.h" 15 #include "content/browser/tab_contents/tab_contents.h"
16 #include "content/common/url_constants.h"
23 #include "net/base/net_util.h" 17 #include "net/base/net_util.h"
24 #include "ui/base/dragdrop/gtk_dnd_util.h" 18 #include "ui/base/dragdrop/gtk_dnd_util.h"
19 #include "ui/base/gtk/gtk_screen_utils.h"
25 20
26 using WebKit::WebDragOperation; 21 using WebKit::WebDragOperation;
27 using WebKit::WebDragOperationNone; 22 using WebKit::WebDragOperationNone;
28 23
29 namespace {
30
31 // Returns the bookmark target atom, based on the underlying toolkit.
32 //
33 // For GTK, bookmark drag data is encoded as pickle and associated with
34 // ui::CHROME_BOOKMARK_ITEM. See // bookmark_utils::WriteBookmarksToSelection()
35 // for details.
36 // For Views, bookmark drag data is encoded in the same format, and
37 // associated with a custom format. See BookmarkNodeData::Write() for
38 // details.
39 GdkAtom GetBookmarkTargetAtom() {
40 #if defined(TOOLKIT_VIEWS)
41 return BookmarkNodeData::GetBookmarkCustomFormat();
42 #else
43 return ui::GetAtomForTarget(ui::CHROME_BOOKMARK_ITEM);
44 #endif
45 }
46
47 } // namespace
48
49 WebDragDestGtk::WebDragDestGtk(TabContents* tab_contents, GtkWidget* widget) 24 WebDragDestGtk::WebDragDestGtk(TabContents* tab_contents, GtkWidget* widget)
50 : tab_contents_(tab_contents), 25 : tab_contents_(tab_contents),
51 tab_(NULL),
52 widget_(widget), 26 widget_(widget),
53 context_(NULL), 27 context_(NULL),
28 data_requests_(0),
29 delegate_(NULL),
54 method_factory_(this) { 30 method_factory_(this) {
55 gtk_drag_dest_set(widget, static_cast<GtkDestDefaults>(0), 31 gtk_drag_dest_set(widget, static_cast<GtkDestDefaults>(0),
56 NULL, 0, 32 NULL, 0,
57 static_cast<GdkDragAction>(GDK_ACTION_COPY | 33 static_cast<GdkDragAction>(GDK_ACTION_COPY |
58 GDK_ACTION_LINK | 34 GDK_ACTION_LINK |
59 GDK_ACTION_MOVE)); 35 GDK_ACTION_MOVE));
60 g_signal_connect(widget, "drag-motion", 36 g_signal_connect(widget, "drag-motion",
61 G_CALLBACK(OnDragMotionThunk), this); 37 G_CALLBACK(OnDragMotionThunk), this);
62 g_signal_connect(widget, "drag-leave", 38 g_signal_connect(widget, "drag-leave",
63 G_CALLBACK(OnDragLeaveThunk), this); 39 G_CALLBACK(OnDragLeaveThunk), this);
(...skipping 11 matching lines...) Expand all
75 WebDragDestGtk::~WebDragDestGtk() { 51 WebDragDestGtk::~WebDragDestGtk() {
76 if (widget_) { 52 if (widget_) {
77 gtk_drag_dest_unset(widget_); 53 gtk_drag_dest_unset(widget_);
78 g_signal_handler_disconnect(widget_, destroy_handler_); 54 g_signal_handler_disconnect(widget_, destroy_handler_);
79 } 55 }
80 } 56 }
81 57
82 void WebDragDestGtk::UpdateDragStatus(WebDragOperation operation) { 58 void WebDragDestGtk::UpdateDragStatus(WebDragOperation operation) {
83 if (context_) { 59 if (context_) {
84 is_drop_target_ = operation != WebDragOperationNone; 60 is_drop_target_ = operation != WebDragOperationNone;
85 gdk_drag_status(context_, gtk_util::WebDragOpToGdkDragAction(operation), 61 gdk_drag_status(context_, content::WebDragOpToGdkDragAction(operation),
86 drag_over_time_); 62 drag_over_time_);
87 } 63 }
88 } 64 }
89 65
90 void WebDragDestGtk::DragLeave() { 66 void WebDragDestGtk::DragLeave() {
91 tab_contents_->render_view_host()->DragTargetDragLeave(); 67 tab_contents_->render_view_host()->DragTargetDragLeave();
92 68
93 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) 69 if (delegate())
94 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragLeave( 70 delegate()->OnDragLeave();
95 bookmark_drag_data_);
96 } 71 }
97 72
98 gboolean WebDragDestGtk::OnDragMotion(GtkWidget* sender, 73 gboolean WebDragDestGtk::OnDragMotion(GtkWidget* sender,
99 GdkDragContext* context, 74 GdkDragContext* context,
100 gint x, gint y, 75 gint x, gint y,
101 guint time) { 76 guint time) {
102 // Ideally we would want to initialize the the TabContentsWrapper member in
103 // the constructor. We cannot do that as the WebDragDestGtk object is
104 // created during the construction of the TabContents object.
105 // The TabContentsWrapper is created much later.
106 if (!tab_)
107 tab_ = TabContentsWrapper::GetCurrentWrapperForContents(tab_contents_);
108
109 if (context_ != context) { 77 if (context_ != context) {
110 context_ = context; 78 context_ = context;
111 drop_data_.reset(new WebDropData); 79 drop_data_.reset(new WebDropData);
112 bookmark_drag_data_.Clear();
113 is_drop_target_ = false; 80 is_drop_target_ = false;
114 81
82 if (delegate())
83 delegate()->DragInitialize(tab_contents_);
84
115 // text/plain must come before text/uri-list. This is a hack that works in 85 // text/plain must come before text/uri-list. This is a hack that works in
116 // conjunction with OnDragDataReceived. Since some file managers populate 86 // conjunction with OnDragDataReceived. Since some file managers populate
117 // text/plain with file URLs when dragging files, we want to handle 87 // text/plain with file URLs when dragging files, we want to handle
118 // text/uri-list after text/plain so that the plain text can be cleared if 88 // text/uri-list after text/plain so that the plain text can be cleared if
119 // it's a file drag. 89 // it's a file drag.
120 static int supported_targets[] = { 90 static int supported_targets[] = {
121 ui::TEXT_PLAIN, 91 ui::TEXT_PLAIN,
122 ui::TEXT_URI_LIST, 92 ui::TEXT_URI_LIST,
123 ui::TEXT_HTML, 93 ui::TEXT_HTML,
124 ui::NETSCAPE_URL, 94 ui::NETSCAPE_URL,
125 ui::CHROME_NAMED_URL, 95 ui::CHROME_NAMED_URL,
126 // TODO(estade): support image drags? 96 // TODO(estade): support image drags?
127 }; 97 };
128 98
129 // Add the bookmark target as well. 99 // Add the delegate's requested target if applicable. Need to do this here
130 data_requests_ = arraysize(supported_targets) + 1; 100 // since gtk_drag_get_data will dispatch to our drag-data-received.
101 data_requests_ = arraysize(supported_targets) + (delegate() ? 1 : 0);
131 for (size_t i = 0; i < arraysize(supported_targets); ++i) { 102 for (size_t i = 0; i < arraysize(supported_targets); ++i) {
132 gtk_drag_get_data(widget_, context, 103 gtk_drag_get_data(widget_, context,
133 ui::GetAtomForTarget(supported_targets[i]), 104 ui::GetAtomForTarget(supported_targets[i]),
134 time); 105 time);
135 } 106 }
136 107
137 gtk_drag_get_data(widget_, context, GetBookmarkTargetAtom(), time); 108 if (delegate()) {
109 gtk_drag_get_data(widget_, context, delegate()->GetBookmarkTargetAtom(),
110 time);
111 }
138 } else if (data_requests_ == 0) { 112 } else if (data_requests_ == 0) {
139 tab_contents_->render_view_host()-> 113 tab_contents_->render_view_host()->
140 DragTargetDragOver( 114 DragTargetDragOver(
141 gtk_util::ClientPoint(widget_), 115 ui::ClientPoint(widget_),
142 gtk_util::ScreenPoint(widget_), 116 ui::ScreenPoint(widget_),
143 gtk_util::GdkDragActionToWebDragOp(context->actions)); 117 content::GdkDragActionToWebDragOp(context->actions));
144 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) 118
145 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragOver( 119 if (delegate())
146 bookmark_drag_data_); 120 delegate()->OnDragOver();
121
147 drag_over_time_ = time; 122 drag_over_time_ = time;
148 } 123 }
149 124
150 // Pretend we are a drag destination because we don't want to wait for 125 // Pretend we are a drag destination because we don't want to wait for
151 // the renderer to tell us if we really are or not. 126 // the renderer to tell us if we really are or not.
152 return TRUE; 127 return TRUE;
153 } 128 }
154 129
155 void WebDragDestGtk::OnDragDataReceived( 130 void WebDragDestGtk::OnDragDataReceived(
156 GtkWidget* sender, GdkDragContext* context, gint x, gint y, 131 GtkWidget* sender, GdkDragContext* context, gint x, gint y,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } else if (data->target == ui::GetAtomForTarget(ui::CHROME_NAMED_URL)) { 191 } else if (data->target == ui::GetAtomForTarget(ui::CHROME_NAMED_URL)) {
217 ui::ExtractNamedURL(data, &drop_data_->url, &drop_data_->url_title); 192 ui::ExtractNamedURL(data, &drop_data_->url, &drop_data_->url_title);
218 } 193 }
219 } 194 }
220 195
221 // For CHROME_BOOKMARK_ITEM, we have to handle the case where the drag source 196 // For CHROME_BOOKMARK_ITEM, we have to handle the case where the drag source
222 // doesn't have any data available for us. In this case we try to synthesize a 197 // doesn't have any data available for us. In this case we try to synthesize a
223 // URL bookmark. 198 // URL bookmark.
224 // Note that bookmark drag data is encoded in the same format for both 199 // Note that bookmark drag data is encoded in the same format for both
225 // GTK and Views, hence we can share the same logic here. 200 // GTK and Views, hence we can share the same logic here.
226 if (data->target == GetBookmarkTargetAtom()) { 201 if (delegate() && data->target == delegate()->GetBookmarkTargetAtom()) {
227 if (data->data && data->length > 0) { 202 if (data->data && data->length > 0) {
228 Profile* profile = 203 delegate()->OnReceiveDataFromGtk(data);
229 Profile::FromBrowserContext(tab_contents_->browser_context());
230 bookmark_drag_data_.ReadFromVector(
231 bookmark_utils::GetNodesFromSelection(
232 NULL, data,
233 ui::CHROME_BOOKMARK_ITEM,
234 profile, NULL, NULL));
235 bookmark_drag_data_.SetOriginatingProfile(profile);
236 } else { 204 } else {
237 bookmark_drag_data_.ReadFromTuple(drop_data_->url, 205 delegate()->OnReceiveProcessedData(drop_data_->url,
238 drop_data_->url_title); 206 drop_data_->url_title);
239 } 207 }
240 } 208 }
241 209
242 if (data_requests_ == 0) { 210 if (data_requests_ == 0) {
243 // Tell the renderer about the drag. 211 // Tell the renderer about the drag.
244 // |x| and |y| are seemingly arbitrary at this point. 212 // |x| and |y| are seemingly arbitrary at this point.
245 tab_contents_->render_view_host()-> 213 tab_contents_->render_view_host()->
246 DragTargetDragEnter(*drop_data_.get(), 214 DragTargetDragEnter(*drop_data_.get(),
247 gtk_util::ClientPoint(widget_), 215 ui::ClientPoint(widget_),
248 gtk_util::ScreenPoint(widget_), 216 ui::ScreenPoint(widget_),
249 gtk_util::GdkDragActionToWebDragOp(context->actions)); 217 content::GdkDragActionToWebDragOp(context->actions));
250 218
251 // This is non-null if tab_contents_ is showing an ExtensionWebUI with 219 if (delegate())
252 // support for (at the moment experimental) drag and drop extensions. 220 delegate()->OnDragEnter();
253 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) 221
254 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragEnter(
255 bookmark_drag_data_);
256 drag_over_time_ = time; 222 drag_over_time_ = time;
257 } 223 }
258 } 224 }
259 225
260 // The drag has left our widget; forward this information to the renderer. 226 // The drag has left our widget; forward this information to the renderer.
261 void WebDragDestGtk::OnDragLeave(GtkWidget* sender, GdkDragContext* context, 227 void WebDragDestGtk::OnDragLeave(GtkWidget* sender, GdkDragContext* context,
262 guint time) { 228 guint time) {
263 // Set |context_| to NULL to make sure we will recognize the next DragMotion 229 // Set |context_| to NULL to make sure we will recognize the next DragMotion
264 // as an enter. 230 // as an enter.
265 context_ = NULL; 231 context_ = NULL;
266 drop_data_.reset(); 232 drop_data_.reset();
267 // When GTK sends us a drag-drop signal, it is shortly (and synchronously) 233 // When GTK sends us a drag-drop signal, it is shortly (and synchronously)
268 // preceded by a drag-leave. The renderer doesn't like getting the signals 234 // preceded by a drag-leave. The renderer doesn't like getting the signals
269 // in this order so delay telling it about the drag-leave till we are sure 235 // in this order so delay telling it about the drag-leave till we are sure
270 // we are not getting a drop as well. 236 // we are not getting a drop as well.
271 MessageLoop::current()->PostTask(FROM_HERE, 237 MessageLoop::current()->PostTask(FROM_HERE,
272 method_factory_.NewRunnableMethod(&WebDragDestGtk::DragLeave)); 238 method_factory_.NewRunnableMethod(&WebDragDestGtk::DragLeave));
273 } 239 }
274 240
275 // Called by GTK when the user releases the mouse, executing a drop. 241 // Called by GTK when the user releases the mouse, executing a drop.
276 gboolean WebDragDestGtk::OnDragDrop(GtkWidget* sender, GdkDragContext* context, 242 gboolean WebDragDestGtk::OnDragDrop(GtkWidget* sender, GdkDragContext* context,
277 gint x, gint y, guint time) { 243 gint x, gint y, guint time) {
278 // Cancel that drag leave! 244 // Cancel that drag leave!
279 method_factory_.RevokeAll(); 245 method_factory_.RevokeAll();
280 246
281 tab_contents_->render_view_host()-> 247 tab_contents_->render_view_host()->
282 DragTargetDrop(gtk_util::ClientPoint(widget_), 248 DragTargetDrop(ui::ClientPoint(widget_), ui::ScreenPoint(widget_));
283 gtk_util::ScreenPoint(widget_));
284 249
285 // This is non-null if tab_contents_ is showing an ExtensionWebUI with 250 if (delegate())
286 // support for (at the moment experimental) drag and drop extensions. 251 delegate()->OnDrop();
287 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate())
288 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDrop(
289 bookmark_drag_data_);
290
291 // Focus the target browser.
292 Browser* browser = Browser::GetBrowserForController(
293 &tab_contents_->controller(), NULL);
294 if (browser)
295 browser->window()->Show();
296 252
297 // The second parameter is just an educated guess as to whether or not the 253 // The second parameter is just an educated guess as to whether or not the
298 // drag succeeded, but at least we will get the drag-end animation right 254 // drag succeeded, but at least we will get the drag-end animation right
299 // sometimes. 255 // sometimes.
300 gtk_drag_finish(context, is_drop_target_, FALSE, time); 256 gtk_drag_finish(context, is_drop_target_, FALSE, time);
301 257
302 return TRUE; 258 return TRUE;
303 } 259 }
OLDNEW
« no previous file with comments | « chrome/browser/tab_contents/web_drag_dest_gtk.h ('k') | chrome/browser/tab_contents/web_drag_dest_gtk_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698