OLD | NEW |
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_drop_target_win.h" | 5 #include "chrome/browser/tab_contents/web_drop_target_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <shlobj.h> | 8 #include <shlobj.h> |
9 | 9 |
10 #include "chrome/browser/bookmarks/bookmark_node_data.h" | 10 #include "chrome/browser/tab_contents/web_drag_bookmark_handler_win.h" |
11 #include "chrome/browser/tab_contents/web_drag_utils_win.h" | 11 #include "chrome/browser/tab_contents/web_drag_utils_win.h" |
12 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" | |
13 #include "chrome/browser/ui/browser.h" | |
14 #include "chrome/browser/ui/browser_window.h" | |
15 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
16 #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/web_drag_dest_delegate.h" |
17 #include "content/public/browser/web_contents.h" | 14 #include "content/public/browser/web_contents.h" |
18 #include "googleurl/src/gurl.h" | 15 #include "googleurl/src/gurl.h" |
19 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
20 #include "ui/base/clipboard/clipboard_util_win.h" | 17 #include "ui/base/clipboard/clipboard_util_win.h" |
21 #include "ui/base/dragdrop/os_exchange_data.h" | 18 #include "ui/base/dragdrop/os_exchange_data.h" |
22 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" | 19 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
23 #include "ui/gfx/point.h" | 20 #include "ui/gfx/point.h" |
24 #include "webkit/glue/webdropdata.h" | 21 #include "webkit/glue/webdropdata.h" |
25 #include "webkit/glue/window_open_disposition.h" | 22 #include "webkit/glue/window_open_disposition.h" |
26 | 23 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 83 |
87 private: | 84 private: |
88 WebContents* web_contents_; | 85 WebContents* web_contents_; |
89 | 86 |
90 DISALLOW_COPY_AND_ASSIGN(InterstitialDropTarget); | 87 DISALLOW_COPY_AND_ASSIGN(InterstitialDropTarget); |
91 }; | 88 }; |
92 | 89 |
93 WebDropTarget::WebDropTarget(HWND source_hwnd, WebContents* web_contents) | 90 WebDropTarget::WebDropTarget(HWND source_hwnd, WebContents* web_contents) |
94 : ui::DropTarget(source_hwnd), | 91 : ui::DropTarget(source_hwnd), |
95 web_contents_(web_contents), | 92 web_contents_(web_contents), |
96 tab_(NULL), | |
97 current_rvh_(NULL), | 93 current_rvh_(NULL), |
98 drag_cursor_(WebDragOperationNone), | 94 drag_cursor_(WebDragOperationNone), |
99 interstitial_drop_target_(new InterstitialDropTarget(web_contents)) { | 95 interstitial_drop_target_(new InterstitialDropTarget(web_contents)), |
| 96 delegate_(new WebDragBookmarkHandlerWin()) { |
100 } | 97 } |
101 | 98 |
102 WebDropTarget::~WebDropTarget() { | 99 WebDropTarget::~WebDropTarget() { |
| 100 // TODO(jam): this will be owned by chrome when it moves, so no scoped |
| 101 // pointer. |
| 102 if (delegate_) |
| 103 delete delegate_; |
103 } | 104 } |
104 | 105 |
105 DWORD WebDropTarget::OnDragEnter(IDataObject* data_object, | 106 DWORD WebDropTarget::OnDragEnter(IDataObject* data_object, |
106 DWORD key_state, | 107 DWORD key_state, |
107 POINT cursor_position, | 108 POINT cursor_position, |
108 DWORD effects) { | 109 DWORD effects) { |
109 current_rvh_ = web_contents_->GetRenderViewHost(); | 110 current_rvh_ = web_contents_->GetRenderViewHost(); |
110 | 111 |
111 if (!tab_) | 112 if (delegate_) |
112 tab_ = TabContentsWrapper::GetCurrentWrapperForContents(web_contents_); | 113 delegate_->DragInitialize(web_contents_); |
113 | 114 |
114 // Don't pass messages to the renderer if an interstitial page is showing | 115 // Don't pass messages to the renderer if an interstitial page is showing |
115 // because we don't want the interstitial page to navigate. Instead, | 116 // because we don't want the interstitial page to navigate. Instead, |
116 // pass the messages on to a separate interstitial DropTarget handler. | 117 // pass the messages on to a separate interstitial DropTarget handler. |
117 if (web_contents_->ShowingInterstitialPage()) | 118 if (web_contents_->ShowingInterstitialPage()) |
118 return interstitial_drop_target_->OnDragEnter(data_object, effects); | 119 return interstitial_drop_target_->OnDragEnter(data_object, effects); |
119 | 120 |
120 // TODO(tc): PopulateWebDropData can be slow depending on what is in the | 121 // TODO(tc): PopulateWebDropData can be slow depending on what is in the |
121 // IDataObject. Maybe we can do this in a background thread. | 122 // IDataObject. Maybe we can do this in a background thread. |
122 WebDropData drop_data; | 123 WebDropData drop_data; |
123 WebDropData::PopulateWebDropData(data_object, &drop_data); | 124 WebDropData::PopulateWebDropData(data_object, &drop_data); |
124 | 125 |
125 if (drop_data.url.is_empty()) | 126 if (drop_data.url.is_empty()) |
126 ui::OSExchangeDataProviderWin::GetPlainTextURL(data_object, &drop_data.url); | 127 ui::OSExchangeDataProviderWin::GetPlainTextURL(data_object, &drop_data.url); |
127 | 128 |
128 drag_cursor_ = WebDragOperationNone; | 129 drag_cursor_ = WebDragOperationNone; |
129 | 130 |
130 POINT client_pt = cursor_position; | 131 POINT client_pt = cursor_position; |
131 ScreenToClient(GetHWND(), &client_pt); | 132 ScreenToClient(GetHWND(), &client_pt); |
132 web_contents_->GetRenderViewHost()->DragTargetDragEnter(drop_data, | 133 web_contents_->GetRenderViewHost()->DragTargetDragEnter(drop_data, |
133 gfx::Point(client_pt.x, client_pt.y), | 134 gfx::Point(client_pt.x, client_pt.y), |
134 gfx::Point(cursor_position.x, cursor_position.y), | 135 gfx::Point(cursor_position.x, cursor_position.y), |
135 web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects)); | 136 web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects)); |
136 | 137 |
137 // This is non-null if web_contents_ is showing an ExtensionWebUI with | 138 if (delegate_) |
138 // support for (at the moment experimental) drag and drop extensions. | 139 delegate_->OnDragEnter(data_object); |
139 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) { | |
140 ui::OSExchangeData os_exchange_data( | |
141 new ui::OSExchangeDataProviderWin(data_object)); | |
142 BookmarkNodeData bookmark_drag_data; | |
143 if (bookmark_drag_data.Read(os_exchange_data)) | |
144 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragEnter( | |
145 bookmark_drag_data); | |
146 } | |
147 | 140 |
148 // We lie here and always return a DROPEFFECT because we don't want to | 141 // We lie here and always return a DROPEFFECT because we don't want to |
149 // wait for the IPC call to return. | 142 // wait for the IPC call to return. |
150 return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_); | 143 return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_); |
151 } | 144 } |
152 | 145 |
153 DWORD WebDropTarget::OnDragOver(IDataObject* data_object, | 146 DWORD WebDropTarget::OnDragOver(IDataObject* data_object, |
154 DWORD key_state, | 147 DWORD key_state, |
155 POINT cursor_position, | 148 POINT cursor_position, |
156 DWORD effects) { | 149 DWORD effects) { |
157 DCHECK(current_rvh_); | 150 DCHECK(current_rvh_); |
158 if (current_rvh_ != web_contents_->GetRenderViewHost()) | 151 if (current_rvh_ != web_contents_->GetRenderViewHost()) |
159 OnDragEnter(data_object, key_state, cursor_position, effects); | 152 OnDragEnter(data_object, key_state, cursor_position, effects); |
160 | 153 |
161 if (web_contents_->ShowingInterstitialPage()) | 154 if (web_contents_->ShowingInterstitialPage()) |
162 return interstitial_drop_target_->OnDragOver(data_object, effects); | 155 return interstitial_drop_target_->OnDragOver(data_object, effects); |
163 | 156 |
164 POINT client_pt = cursor_position; | 157 POINT client_pt = cursor_position; |
165 ScreenToClient(GetHWND(), &client_pt); | 158 ScreenToClient(GetHWND(), &client_pt); |
166 web_contents_->GetRenderViewHost()->DragTargetDragOver( | 159 web_contents_->GetRenderViewHost()->DragTargetDragOver( |
167 gfx::Point(client_pt.x, client_pt.y), | 160 gfx::Point(client_pt.x, client_pt.y), |
168 gfx::Point(cursor_position.x, cursor_position.y), | 161 gfx::Point(cursor_position.x, cursor_position.y), |
169 web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects)); | 162 web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects)); |
170 | 163 |
171 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) { | 164 if (delegate_) |
172 ui::OSExchangeData os_exchange_data( | 165 delegate_->OnDragOver(data_object); |
173 new ui::OSExchangeDataProviderWin(data_object)); | |
174 BookmarkNodeData bookmark_drag_data; | |
175 if (bookmark_drag_data.Read(os_exchange_data)) | |
176 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragOver( | |
177 bookmark_drag_data); | |
178 } | |
179 | 166 |
180 return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_); | 167 return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_); |
181 } | 168 } |
182 | 169 |
183 void WebDropTarget::OnDragLeave(IDataObject* data_object) { | 170 void WebDropTarget::OnDragLeave(IDataObject* data_object) { |
184 DCHECK(current_rvh_); | 171 DCHECK(current_rvh_); |
185 if (current_rvh_ != web_contents_->GetRenderViewHost()) | 172 if (current_rvh_ != web_contents_->GetRenderViewHost()) |
186 return; | 173 return; |
187 | 174 |
188 if (web_contents_->ShowingInterstitialPage()) { | 175 if (web_contents_->ShowingInterstitialPage()) { |
189 interstitial_drop_target_->OnDragLeave(data_object); | 176 interstitial_drop_target_->OnDragLeave(data_object); |
190 } else { | 177 } else { |
191 web_contents_->GetRenderViewHost()->DragTargetDragLeave(); | 178 web_contents_->GetRenderViewHost()->DragTargetDragLeave(); |
192 } | 179 } |
193 | 180 |
194 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) { | 181 if (delegate_) |
195 ui::OSExchangeData os_exchange_data( | 182 delegate_->OnDragLeave(data_object); |
196 new ui::OSExchangeDataProviderWin(data_object)); | |
197 BookmarkNodeData bookmark_drag_data; | |
198 if (bookmark_drag_data.Read(os_exchange_data)) | |
199 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragLeave( | |
200 bookmark_drag_data); | |
201 } | |
202 } | 183 } |
203 | 184 |
204 DWORD WebDropTarget::OnDrop(IDataObject* data_object, | 185 DWORD WebDropTarget::OnDrop(IDataObject* data_object, |
205 DWORD key_state, | 186 DWORD key_state, |
206 POINT cursor_position, | 187 POINT cursor_position, |
207 DWORD effect) { | 188 DWORD effect) { |
208 DCHECK(current_rvh_); | 189 DCHECK(current_rvh_); |
209 if (current_rvh_ != web_contents_->GetRenderViewHost()) | 190 if (current_rvh_ != web_contents_->GetRenderViewHost()) |
210 OnDragEnter(data_object, key_state, cursor_position, effect); | 191 OnDragEnter(data_object, key_state, cursor_position, effect); |
211 | 192 |
212 if (web_contents_->ShowingInterstitialPage()) | 193 if (web_contents_->ShowingInterstitialPage()) |
213 interstitial_drop_target_->OnDragOver(data_object, effect); | 194 interstitial_drop_target_->OnDragOver(data_object, effect); |
214 | 195 |
215 if (web_contents_->ShowingInterstitialPage()) | 196 if (web_contents_->ShowingInterstitialPage()) |
216 return interstitial_drop_target_->OnDrop(data_object, effect); | 197 return interstitial_drop_target_->OnDrop(data_object, effect); |
217 | 198 |
218 POINT client_pt = cursor_position; | 199 POINT client_pt = cursor_position; |
219 ScreenToClient(GetHWND(), &client_pt); | 200 ScreenToClient(GetHWND(), &client_pt); |
220 web_contents_->GetRenderViewHost()->DragTargetDrop( | 201 web_contents_->GetRenderViewHost()->DragTargetDrop( |
221 gfx::Point(client_pt.x, client_pt.y), | 202 gfx::Point(client_pt.x, client_pt.y), |
222 gfx::Point(cursor_position.x, cursor_position.y)); | 203 gfx::Point(cursor_position.x, cursor_position.y)); |
223 | 204 |
224 if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) { | 205 if (delegate_) |
225 ui::OSExchangeData os_exchange_data( | 206 delegate_->OnDrop(data_object); |
226 new ui::OSExchangeDataProviderWin(data_object)); | |
227 BookmarkNodeData bookmark_drag_data; | |
228 if (bookmark_drag_data.Read(os_exchange_data)) | |
229 tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDrop( | |
230 bookmark_drag_data); | |
231 } | |
232 | 207 |
233 current_rvh_ = NULL; | 208 current_rvh_ = NULL; |
234 | 209 |
235 // Focus the target browser. | |
236 Browser* browser = Browser::GetBrowserForController( | |
237 &web_contents_->GetController(), NULL); | |
238 if (browser) | |
239 browser->window()->Show(); | |
240 | |
241 // This isn't always correct, but at least it's a close approximation. | 210 // This isn't always correct, but at least it's a close approximation. |
242 // For now, we always map a move to a copy to prevent potential data loss. | 211 // For now, we always map a move to a copy to prevent potential data loss. |
243 DWORD drop_effect = web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_); | 212 DWORD drop_effect = web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_); |
244 return drop_effect != DROPEFFECT_MOVE ? drop_effect : DROPEFFECT_COPY; | 213 return drop_effect != DROPEFFECT_MOVE ? drop_effect : DROPEFFECT_COPY; |
245 } | 214 } |
OLD | NEW |