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

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

Issue 137403005: Remove some code inside USE_AURA and OS_WIN ifdefs. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 6 years, 11 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/web_contents/web_drag_dest_win.h"
6
7 #include <windows.h>
8 #include <shlobj.h>
9
10 #include "base/win/win_util.h"
11 #include "content/browser/renderer_host/render_view_host_impl.h"
12 #include "content/browser/web_contents/web_drag_utils_win.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/browser/web_contents_delegate.h"
15 #include "content/public/browser/web_drag_dest_delegate.h"
16 #include "content/public/common/drop_data.h"
17 #include "net/base/net_util.h"
18 #include "third_party/WebKit/public/web/WebInputEvent.h"
19 #include "ui/base/clipboard/clipboard_util_win.h"
20 #include "ui/base/dragdrop/os_exchange_data.h"
21 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
22 #include "ui/base/window_open_disposition.h"
23 #include "ui/gfx/point.h"
24 #include "url/gurl.h"
25
26 using blink::WebDragOperationNone;
27 using blink::WebDragOperationCopy;
28 using blink::WebDragOperationLink;
29 using blink::WebDragOperationMove;
30 using blink::WebDragOperationGeneric;
31
32 namespace content {
33 namespace {
34
35 const unsigned short kHighBitMaskShort = 0x8000;
36
37 // A helper method for getting the preferred drop effect.
38 DWORD GetPreferredDropEffect(DWORD effect) {
39 if (effect & DROPEFFECT_COPY)
40 return DROPEFFECT_COPY;
41 if (effect & DROPEFFECT_LINK)
42 return DROPEFFECT_LINK;
43 if (effect & DROPEFFECT_MOVE)
44 return DROPEFFECT_MOVE;
45 return DROPEFFECT_NONE;
46 }
47
48 int GetModifierFlags() {
49 int modifier_state = 0;
50 if (base::win::IsShiftPressed())
51 modifier_state |= blink::WebInputEvent::ShiftKey;
52 if (base::win::IsCtrlPressed())
53 modifier_state |= blink::WebInputEvent::ControlKey;
54 if (base::win::IsAltPressed())
55 modifier_state |= blink::WebInputEvent::AltKey;
56 if (::GetKeyState(VK_LWIN) & kHighBitMaskShort)
57 modifier_state |= blink::WebInputEvent::MetaKey;
58 if (::GetKeyState(VK_RWIN) & kHighBitMaskShort)
59 modifier_state |= blink::WebInputEvent::MetaKey;
60 return modifier_state;
61 }
62
63 // Helper method for converting Window's specific IDataObject to a DropData
64 // object.
65 void PopulateDropData(IDataObject* data_object, DropData* drop_data) {
66 base::string16 url_str;
67 if (ui::ClipboardUtil::GetUrl(
68 data_object, &url_str, &drop_data->url_title, false)) {
69 GURL test_url(url_str);
70 if (test_url.is_valid())
71 drop_data->url = test_url;
72 }
73 std::vector<base::string16> filenames;
74 ui::ClipboardUtil::GetFilenames(data_object, &filenames);
75 for (size_t i = 0; i < filenames.size(); ++i)
76 drop_data->filenames.push_back(
77 DropData::FileInfo(filenames[i], base::string16()));
78 base::string16 text;
79 ui::ClipboardUtil::GetPlainText(data_object, &text);
80 if (!text.empty()) {
81 drop_data->text = base::NullableString16(text, false);
82 }
83 base::string16 html;
84 std::string html_base_url;
85 ui::ClipboardUtil::GetHtml(data_object, &html, &html_base_url);
86 if (!html.empty()) {
87 drop_data->html = base::NullableString16(html, false);
88 }
89 if (!html_base_url.empty()) {
90 drop_data->html_base_url = GURL(html_base_url);
91 }
92 ui::ClipboardUtil::GetWebCustomData(data_object, &drop_data->custom_data);
93 }
94
95 } // namespace
96
97 // InterstitialDropTarget is like a ui::DropTargetWin implementation that
98 // WebDragDest passes through to if an interstitial is showing. Rather than
99 // passing messages on to the renderer, we just check to see if there's a link
100 // in the drop data and handle links as navigations.
101 class InterstitialDropTarget {
102 public:
103 explicit InterstitialDropTarget(WebContents* web_contents)
104 : web_contents_(web_contents) {}
105
106 DWORD OnDragEnter(IDataObject* data_object, DWORD effect) {
107 return ui::ClipboardUtil::HasUrl(data_object) ?
108 GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
109 }
110
111 DWORD OnDragOver(IDataObject* data_object, DWORD effect) {
112 return ui::ClipboardUtil::HasUrl(data_object) ?
113 GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
114 }
115
116 void OnDragLeave(IDataObject* data_object) {
117 }
118
119 DWORD OnDrop(IDataObject* data_object, DWORD effect) {
120 if (!ui::ClipboardUtil::HasUrl(data_object))
121 return DROPEFFECT_NONE;
122
123 std::wstring url;
124 std::wstring title;
125 ui::ClipboardUtil::GetUrl(data_object, &url, &title, true);
126 OpenURLParams params(GURL(url), Referrer(), CURRENT_TAB,
127 PAGE_TRANSITION_AUTO_BOOKMARK, false);
128 web_contents_->OpenURL(params);
129 return GetPreferredDropEffect(effect);
130 }
131
132 private:
133 WebContents* web_contents_;
134
135 DISALLOW_COPY_AND_ASSIGN(InterstitialDropTarget);
136 };
137
138 WebDragDest::WebDragDest(HWND source_hwnd, WebContents* web_contents)
139 : ui::DropTargetWin(source_hwnd),
140 web_contents_(web_contents),
141 current_rvh_(NULL),
142 drag_cursor_(WebDragOperationNone),
143 interstitial_drop_target_(new InterstitialDropTarget(web_contents)),
144 delegate_(NULL),
145 canceled_(false) {
146 }
147
148 WebDragDest::~WebDragDest() {
149 }
150
151 DWORD WebDragDest::OnDragEnter(IDataObject* data_object,
152 DWORD key_state,
153 POINT cursor_position,
154 DWORD effects) {
155 current_rvh_ = web_contents_->GetRenderViewHost();
156
157 // TODO(tc): PopulateDropData can be slow depending on what is in the
158 // IDataObject. Maybe we can do this in a background thread.
159 scoped_ptr<DropData> drop_data;
160 drop_data.reset(new DropData());
161 PopulateDropData(data_object, drop_data.get());
162
163 if (drop_data->url.is_empty())
164 ui::OSExchangeDataProviderWin::GetPlainTextURL(data_object,
165 &drop_data->url);
166
167 // Give the delegate an opportunity to cancel the drag.
168 canceled_ = !web_contents_->GetDelegate()->CanDragEnter(
169 web_contents_,
170 *drop_data,
171 WinDragOpMaskToWebDragOpMask(effects));
172 if (canceled_)
173 return DROPEFFECT_NONE;
174
175 if (delegate_)
176 delegate_->DragInitialize(web_contents_);
177
178 // Don't pass messages to the renderer if an interstitial page is showing
179 // because we don't want the interstitial page to navigate. Instead,
180 // pass the messages on to a separate interstitial DropTarget handler.
181 if (web_contents_->ShowingInterstitialPage())
182 return interstitial_drop_target_->OnDragEnter(data_object, effects);
183
184 drop_data_.swap(drop_data);
185 drag_cursor_ = WebDragOperationNone;
186
187 POINT client_pt = cursor_position;
188 ScreenToClient(GetHWND(), &client_pt);
189 web_contents_->GetRenderViewHost()->DragTargetDragEnter(*drop_data_,
190 gfx::Point(client_pt.x, client_pt.y),
191 gfx::Point(cursor_position.x, cursor_position.y),
192 WinDragOpMaskToWebDragOpMask(effects),
193 GetModifierFlags());
194
195 if (delegate_)
196 delegate_->OnDragEnter(data_object);
197
198 // We lie here and always return a DROPEFFECT because we don't want to
199 // wait for the IPC call to return.
200 return WebDragOpToWinDragOp(drag_cursor_);
201 }
202
203 DWORD WebDragDest::OnDragOver(IDataObject* data_object,
204 DWORD key_state,
205 POINT cursor_position,
206 DWORD effects) {
207 DCHECK(current_rvh_);
208 if (current_rvh_ != web_contents_->GetRenderViewHost())
209 OnDragEnter(data_object, key_state, cursor_position, effects);
210
211 if (canceled_)
212 return DROPEFFECT_NONE;
213
214 if (web_contents_->ShowingInterstitialPage())
215 return interstitial_drop_target_->OnDragOver(data_object, effects);
216
217 POINT client_pt = cursor_position;
218 ScreenToClient(GetHWND(), &client_pt);
219 web_contents_->GetRenderViewHost()->DragTargetDragOver(
220 gfx::Point(client_pt.x, client_pt.y),
221 gfx::Point(cursor_position.x, cursor_position.y),
222 WinDragOpMaskToWebDragOpMask(effects),
223 GetModifierFlags());
224
225 if (delegate_)
226 delegate_->OnDragOver(data_object);
227
228 return WebDragOpToWinDragOp(drag_cursor_);
229 }
230
231 void WebDragDest::OnDragLeave(IDataObject* data_object) {
232 DCHECK(current_rvh_);
233 if (current_rvh_ != web_contents_->GetRenderViewHost())
234 return;
235
236 if (canceled_)
237 return;
238
239 if (web_contents_->ShowingInterstitialPage()) {
240 interstitial_drop_target_->OnDragLeave(data_object);
241 } else {
242 web_contents_->GetRenderViewHost()->DragTargetDragLeave();
243 }
244
245 if (delegate_)
246 delegate_->OnDragLeave(data_object);
247
248 drop_data_.reset();
249 }
250
251 DWORD WebDragDest::OnDrop(IDataObject* data_object,
252 DWORD key_state,
253 POINT cursor_position,
254 DWORD effect) {
255 DCHECK(current_rvh_);
256 if (current_rvh_ != web_contents_->GetRenderViewHost())
257 OnDragEnter(data_object, key_state, cursor_position, effect);
258
259 if (web_contents_->ShowingInterstitialPage())
260 interstitial_drop_target_->OnDragOver(data_object, effect);
261
262 if (web_contents_->ShowingInterstitialPage())
263 return interstitial_drop_target_->OnDrop(data_object, effect);
264
265 POINT client_pt = cursor_position;
266 ScreenToClient(GetHWND(), &client_pt);
267 web_contents_->GetRenderViewHost()->DragTargetDrop(
268 gfx::Point(client_pt.x, client_pt.y),
269 gfx::Point(cursor_position.x, cursor_position.y),
270 GetModifierFlags());
271
272 if (delegate_)
273 delegate_->OnDrop(data_object);
274
275 current_rvh_ = NULL;
276
277 // This isn't always correct, but at least it's a close approximation.
278 // For now, we always map a move to a copy to prevent potential data loss.
279 DWORD drop_effect = WebDragOpToWinDragOp(drag_cursor_);
280 DWORD result = drop_effect != DROPEFFECT_MOVE ? drop_effect : DROPEFFECT_COPY;
281
282 drop_data_.reset();
283 return result;
284 }
285
286 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698