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

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

Powered by Google App Engine
This is Rietveld 408576698