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

Side by Side Diff: content/browser/tab_contents/web_drag_dest_win.cc

Issue 10014024: TabContents -> WebContentsImpl, part 2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/tab_contents/web_drag_dest_win.h"
6
7 #include <windows.h>
8 #include <shlobj.h>
9
10 #include "content/browser/renderer_host/render_view_host_impl.h"
11 #include "content/browser/tab_contents/web_drag_utils_win.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/browser/web_drag_dest_delegate.h"
14 #include "googleurl/src/gurl.h"
15 #include "net/base/net_util.h"
16 #include "ui/base/clipboard/clipboard_util_win.h"
17 #include "ui/base/dragdrop/os_exchange_data.h"
18 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
19 #include "ui/gfx/point.h"
20 #include "webkit/glue/webdropdata.h"
21 #include "webkit/glue/window_open_disposition.h"
22
23 using WebKit::WebDragOperationNone;
24 using WebKit::WebDragOperationCopy;
25 using WebKit::WebDragOperationLink;
26 using WebKit::WebDragOperationMove;
27 using WebKit::WebDragOperationGeneric;
28 using content::OpenURLParams;
29 using content::Referrer;
30 using content::WebContents;
31
32 namespace {
33
34 // A helper method for getting the preferred drop effect.
35 DWORD GetPreferredDropEffect(DWORD effect) {
36 if (effect & DROPEFFECT_COPY)
37 return DROPEFFECT_COPY;
38 if (effect & DROPEFFECT_LINK)
39 return DROPEFFECT_LINK;
40 if (effect & DROPEFFECT_MOVE)
41 return DROPEFFECT_MOVE;
42 return DROPEFFECT_NONE;
43 }
44
45 } // namespace
46
47 // InterstitialDropTarget is like a ui::DropTarget implementation that
48 // WebDragDest passes through to if an interstitial is showing. Rather than
49 // passing messages on to the renderer, we just check to see if there's a link
50 // in the drop data and handle links as navigations.
51 class InterstitialDropTarget {
52 public:
53 explicit InterstitialDropTarget(WebContents* web_contents)
54 : web_contents_(web_contents) {}
55
56 DWORD OnDragEnter(IDataObject* data_object, DWORD effect) {
57 return ui::ClipboardUtil::HasUrl(data_object) ?
58 GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
59 }
60
61 DWORD OnDragOver(IDataObject* data_object, DWORD effect) {
62 return ui::ClipboardUtil::HasUrl(data_object) ?
63 GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
64 }
65
66 void OnDragLeave(IDataObject* data_object) {
67 }
68
69 DWORD OnDrop(IDataObject* data_object, DWORD effect) {
70 if (!ui::ClipboardUtil::HasUrl(data_object))
71 return DROPEFFECT_NONE;
72
73 std::wstring url;
74 std::wstring title;
75 ui::ClipboardUtil::GetUrl(data_object, &url, &title, true);
76 OpenURLParams params(
77 GURL(url), Referrer(), CURRENT_TAB,
78 content::PAGE_TRANSITION_AUTO_BOOKMARK, false);
79 web_contents_->OpenURL(params);
80 return GetPreferredDropEffect(effect);
81 }
82
83 private:
84 WebContents* web_contents_;
85
86 DISALLOW_COPY_AND_ASSIGN(InterstitialDropTarget);
87 };
88
89 WebDragDest::WebDragDest(HWND source_hwnd, WebContents* web_contents)
90 : ui::DropTarget(source_hwnd),
91 web_contents_(web_contents),
92 current_rvh_(NULL),
93 drag_cursor_(WebDragOperationNone),
94 interstitial_drop_target_(new InterstitialDropTarget(web_contents)),
95 delegate_(NULL) {
96 }
97
98 WebDragDest::~WebDragDest() {
99 }
100
101 DWORD WebDragDest::OnDragEnter(IDataObject* data_object,
102 DWORD key_state,
103 POINT cursor_position,
104 DWORD effects) {
105 current_rvh_ = web_contents_->GetRenderViewHost();
106
107 if (delegate_)
108 delegate_->DragInitialize(web_contents_);
109
110 // Don't pass messages to the renderer if an interstitial page is showing
111 // because we don't want the interstitial page to navigate. Instead,
112 // pass the messages on to a separate interstitial DropTarget handler.
113 if (web_contents_->ShowingInterstitialPage())
114 return interstitial_drop_target_->OnDragEnter(data_object, effects);
115
116 // TODO(tc): PopulateWebDropData can be slow depending on what is in the
117 // IDataObject. Maybe we can do this in a background thread.
118 WebDropData drop_data;
119 WebDropData::PopulateWebDropData(data_object, &drop_data);
120
121 if (drop_data.url.is_empty())
122 ui::OSExchangeDataProviderWin::GetPlainTextURL(data_object, &drop_data.url);
123
124 drag_cursor_ = WebDragOperationNone;
125
126 POINT client_pt = cursor_position;
127 ScreenToClient(GetHWND(), &client_pt);
128 web_contents_->GetRenderViewHost()->DragTargetDragEnter(drop_data,
129 gfx::Point(client_pt.x, client_pt.y),
130 gfx::Point(cursor_position.x, cursor_position.y),
131 web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects));
132
133 if (delegate_)
134 delegate_->OnDragEnter(data_object);
135
136 // We lie here and always return a DROPEFFECT because we don't want to
137 // wait for the IPC call to return.
138 return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_);
139 }
140
141 DWORD WebDragDest::OnDragOver(IDataObject* data_object,
142 DWORD key_state,
143 POINT cursor_position,
144 DWORD effects) {
145 DCHECK(current_rvh_);
146 if (current_rvh_ != web_contents_->GetRenderViewHost())
147 OnDragEnter(data_object, key_state, cursor_position, effects);
148
149 if (web_contents_->ShowingInterstitialPage())
150 return interstitial_drop_target_->OnDragOver(data_object, effects);
151
152 POINT client_pt = cursor_position;
153 ScreenToClient(GetHWND(), &client_pt);
154 web_contents_->GetRenderViewHost()->DragTargetDragOver(
155 gfx::Point(client_pt.x, client_pt.y),
156 gfx::Point(cursor_position.x, cursor_position.y),
157 web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects));
158
159 if (delegate_)
160 delegate_->OnDragOver(data_object);
161
162 return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_);
163 }
164
165 void WebDragDest::OnDragLeave(IDataObject* data_object) {
166 DCHECK(current_rvh_);
167 if (current_rvh_ != web_contents_->GetRenderViewHost())
168 return;
169
170 if (web_contents_->ShowingInterstitialPage()) {
171 interstitial_drop_target_->OnDragLeave(data_object);
172 } else {
173 web_contents_->GetRenderViewHost()->DragTargetDragLeave();
174 }
175
176 if (delegate_)
177 delegate_->OnDragLeave(data_object);
178 }
179
180 DWORD WebDragDest::OnDrop(IDataObject* data_object,
181 DWORD key_state,
182 POINT cursor_position,
183 DWORD effect) {
184 DCHECK(current_rvh_);
185 if (current_rvh_ != web_contents_->GetRenderViewHost())
186 OnDragEnter(data_object, key_state, cursor_position, effect);
187
188 if (web_contents_->ShowingInterstitialPage())
189 interstitial_drop_target_->OnDragOver(data_object, effect);
190
191 if (web_contents_->ShowingInterstitialPage())
192 return interstitial_drop_target_->OnDrop(data_object, effect);
193
194 POINT client_pt = cursor_position;
195 ScreenToClient(GetHWND(), &client_pt);
196 web_contents_->GetRenderViewHost()->DragTargetDrop(
197 gfx::Point(client_pt.x, client_pt.y),
198 gfx::Point(cursor_position.x, cursor_position.y));
199
200 if (delegate_)
201 delegate_->OnDrop(data_object);
202
203 current_rvh_ = NULL;
204
205 // This isn't always correct, but at least it's a close approximation.
206 // For now, we always map a move to a copy to prevent potential data loss.
207 DWORD drop_effect = web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_);
208 return drop_effect != DROPEFFECT_MOVE ? drop_effect : DROPEFFECT_COPY;
209 }
OLDNEW
« no previous file with comments | « content/browser/tab_contents/web_drag_dest_win.h ('k') | content/browser/tab_contents/web_drag_source_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698