OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/views/tab_contents/tab_contents_view_win.h" | 5 #include "chrome/browser/views/tab_contents/tab_contents_view_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "app/gfx/canvas_paint.h" | 9 #include "app/gfx/canvas_paint.h" |
10 #include "app/os_exchange_data.h" | 10 #include "app/os_exchange_data.h" |
11 #include "app/os_exchange_data_provider_win.h" | |
12 #include "base/file_path.h" | 11 #include "base/file_path.h" |
13 #include "base/keyboard_codes.h" | 12 #include "base/keyboard_codes.h" |
14 #include "base/time.h" | 13 #include "base/time.h" |
15 #include "base/win_util.h" | 14 #include "base/win_util.h" |
16 #include "chrome/browser/bookmarks/bookmark_drag_data.h" | |
17 #include "chrome/browser/browser.h" // TODO(beng): this dependency is awful. | 15 #include "chrome/browser/browser.h" // TODO(beng): this dependency is awful. |
18 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
19 #include "chrome/browser/download/download_request_manager.h" | 17 #include "chrome/browser/download/download_request_manager.h" |
20 #include "chrome/browser/renderer_host/render_process_host.h" | 18 #include "chrome/browser/renderer_host/render_process_host.h" |
21 #include "chrome/browser/renderer_host/render_view_host.h" | 19 #include "chrome/browser/renderer_host/render_view_host.h" |
22 #include "chrome/browser/renderer_host/render_view_host_factory.h" | 20 #include "chrome/browser/renderer_host/render_view_host_factory.h" |
23 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" | 21 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" |
24 #include "chrome/browser/tab_contents/interstitial_page.h" | 22 #include "chrome/browser/tab_contents/interstitial_page.h" |
25 #include "chrome/browser/tab_contents/tab_contents.h" | 23 #include "chrome/browser/tab_contents/tab_contents.h" |
26 #include "chrome/browser/tab_contents/tab_contents_delegate.h" | 24 #include "chrome/browser/tab_contents/tab_contents_delegate.h" |
27 #include "chrome/browser/tab_contents/web_drag_source_win.h" | |
28 #include "chrome/browser/tab_contents/web_drop_target_win.h" | 25 #include "chrome/browser/tab_contents/web_drop_target_win.h" |
29 #include "chrome/browser/views/sad_tab_view.h" | 26 #include "chrome/browser/views/sad_tab_view.h" |
30 #include "chrome/browser/views/tab_contents/render_view_context_menu_win.h" | 27 #include "chrome/browser/views/tab_contents/render_view_context_menu_win.h" |
31 #include "chrome/common/url_constants.h" | 28 #include "chrome/browser/views/tab_contents/tab_contents_drag_win.h" |
32 #include "net/base/net_util.h" | |
33 #include "views/focus/view_storage.h" | 29 #include "views/focus/view_storage.h" |
34 #include "views/screen.h" | 30 #include "views/screen.h" |
35 #include "views/widget/root_view.h" | 31 #include "views/widget/root_view.h" |
36 #include "webkit/glue/webdropdata.h" | |
37 | 32 |
38 using WebKit::WebDragOperation; | 33 using WebKit::WebDragOperation; |
39 using WebKit::WebDragOperationNone; | 34 using WebKit::WebDragOperationNone; |
40 using WebKit::WebDragOperationsMask; | 35 using WebKit::WebDragOperationsMask; |
41 using WebKit::WebInputEvent; | 36 using WebKit::WebInputEvent; |
42 | 37 |
43 // static | 38 // static |
44 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { | 39 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { |
45 return new TabContentsViewWin(tab_contents); | 40 return new TabContentsViewWin(tab_contents); |
46 } | 41 } |
47 | 42 |
48 TabContentsViewWin::TabContentsViewWin(TabContents* tab_contents) | 43 TabContentsViewWin::TabContentsViewWin(TabContents* tab_contents) |
49 : TabContentsView(tab_contents), | 44 : TabContentsView(tab_contents), |
50 focus_manager_(NULL), | 45 focus_manager_(NULL), |
51 close_tab_after_drag_ends_(false), | 46 close_tab_after_drag_ends_(false), |
52 sad_tab_(NULL) { | 47 sad_tab_(NULL) { |
53 last_focused_view_storage_id_ = | 48 last_focused_view_storage_id_ = |
54 views::ViewStorage::GetSharedInstance()->CreateStorageID(); | 49 views::ViewStorage::GetSharedInstance()->CreateStorageID(); |
55 } | 50 } |
56 | 51 |
57 TabContentsViewWin::~TabContentsViewWin() { | 52 TabContentsViewWin::~TabContentsViewWin() { |
58 // Makes sure to remove any stored view we may still have in the ViewStorage. | 53 // Makes sure to remove any stored view we may still have in the ViewStorage. |
59 // | 54 // |
60 // It is possible the view went away before us, so we only do this if the | 55 // It is possible the view went away before us, so we only do this if the |
61 // view is registered. | 56 // view is registered. |
62 views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); | 57 views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); |
63 if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) | 58 if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) |
64 view_storage->RemoveView(last_focused_view_storage_id_); | 59 view_storage->RemoveView(last_focused_view_storage_id_); |
65 | |
66 DCHECK(!drag_source_.get()); | |
67 } | 60 } |
68 | 61 |
69 void TabContentsViewWin::Unparent() { | 62 void TabContentsViewWin::Unparent() { |
70 // Remember who our FocusManager is, we won't be able to access it once | 63 // Remember who our FocusManager is, we won't be able to access it once |
71 // unparented. | 64 // unparented. |
72 focus_manager_ = views::WidgetWin::GetFocusManager(); | 65 focus_manager_ = views::WidgetWin::GetFocusManager(); |
73 // Note that we do not DCHECK on focus_manager_ as it may be NULL when used | 66 // Note that we do not DCHECK on focus_manager_ as it may be NULL when used |
74 // with an external tab container. | 67 // with an external tab container. |
75 ::SetParent(GetNativeView(), NULL); | 68 ::SetParent(GetNativeView(), NULL); |
76 } | 69 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 gfx::NativeWindow TabContentsViewWin::GetTopLevelNativeWindow() const { | 118 gfx::NativeWindow TabContentsViewWin::GetTopLevelNativeWindow() const { |
126 return ::GetAncestor(GetNativeView(), GA_ROOT); | 119 return ::GetAncestor(GetNativeView(), GA_ROOT); |
127 } | 120 } |
128 | 121 |
129 void TabContentsViewWin::GetContainerBounds(gfx::Rect* out) const { | 122 void TabContentsViewWin::GetContainerBounds(gfx::Rect* out) const { |
130 GetBounds(out, false); | 123 GetBounds(out, false); |
131 } | 124 } |
132 | 125 |
133 void TabContentsViewWin::StartDragging(const WebDropData& drop_data, | 126 void TabContentsViewWin::StartDragging(const WebDropData& drop_data, |
134 WebDragOperationsMask ops) { | 127 WebDragOperationsMask ops) { |
135 OSExchangeData data; | 128 drag_handler_ = new TabContentsDragWin(this); |
| 129 drag_handler_->StartDragging(drop_data, ops); |
| 130 } |
136 | 131 |
137 // TODO(tc): Generate an appropriate drag image. | 132 void TabContentsViewWin::EndDragging() { |
138 | |
139 // We set the file contents before the URL because the URL also sets file | |
140 // contents (to a .URL shortcut). We want to prefer file content data over a | |
141 // shortcut so we add it first. | |
142 if (!drop_data.file_contents.empty()) { | |
143 // Images without ALT text will only have a file extension so we need to | |
144 // synthesize one from the provided extension and URL. | |
145 FilePath file_name(drop_data.file_description_filename); | |
146 file_name = file_name.BaseName().RemoveExtension(); | |
147 if (file_name.value().empty()) { | |
148 // Retrieve the name from the URL. | |
149 file_name = net::GetSuggestedFilename(drop_data.url, "", "", FilePath()); | |
150 if (file_name.value().size() + drop_data.file_extension.size() + 1 > | |
151 MAX_PATH) { | |
152 file_name = FilePath(file_name.value().substr( | |
153 0, MAX_PATH - drop_data.file_extension.size() - 2)); | |
154 } | |
155 } | |
156 file_name = file_name.ReplaceExtension(drop_data.file_extension); | |
157 data.SetFileContents(file_name.value(), drop_data.file_contents); | |
158 } | |
159 if (!drop_data.text_html.empty()) | |
160 data.SetHtml(drop_data.text_html, drop_data.html_base_url); | |
161 if (drop_data.url.is_valid()) { | |
162 if (drop_data.url.SchemeIs(chrome::kJavaScriptScheme)) { | |
163 // We don't want to allow javascript URLs to be dragged to the desktop, | |
164 // but we do want to allow them to be added to the bookmarks bar | |
165 // (bookmarklets). So we create a fake bookmark entry (BookmarkDragData | |
166 // object) which explorer.exe cannot handle, and write the entry to data. | |
167 BookmarkDragData::Element bm_elt; | |
168 bm_elt.is_url = true; | |
169 bm_elt.url = drop_data.url; | |
170 bm_elt.title = drop_data.url_title; | |
171 | |
172 BookmarkDragData bm_drag_data; | |
173 bm_drag_data.elements.push_back(bm_elt); | |
174 | |
175 // Pass in NULL as the profile so that the bookmark always adds the url | |
176 // rather than trying to move an existing url. | |
177 bm_drag_data.Write(NULL, &data); | |
178 } else { | |
179 data.SetURL(drop_data.url, drop_data.url_title); | |
180 } | |
181 } | |
182 if (!drop_data.plain_text.empty()) | |
183 data.SetString(drop_data.plain_text); | |
184 | |
185 drag_source_ = new WebDragSource(GetNativeView(), tab_contents()); | |
186 | |
187 DWORD effects; | |
188 | |
189 // We need to enable recursive tasks on the message loop so we can get | |
190 // updates while in the system DoDragDrop loop. | |
191 bool old_state = MessageLoop::current()->NestableTasksAllowed(); | |
192 MessageLoop::current()->SetNestableTasksAllowed(true); | |
193 DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source_, | |
194 DROPEFFECT_COPY | DROPEFFECT_LINK, &effects); | |
195 // TODO(snej): Use 'ops' param instead of hardcoding dropeffects | |
196 MessageLoop::current()->SetNestableTasksAllowed(old_state); | |
197 | |
198 drag_source_ = NULL; | |
199 if (close_tab_after_drag_ends_) { | 133 if (close_tab_after_drag_ends_) { |
200 close_tab_timer_.Start(base::TimeDelta::FromMilliseconds(0), this, | 134 close_tab_timer_.Start(base::TimeDelta::FromMilliseconds(0), this, |
201 &TabContentsViewWin::CloseTab); | 135 &TabContentsViewWin::CloseTab); |
202 } | 136 } |
203 | 137 |
204 if (tab_contents()->render_view_host()) | 138 if (tab_contents()->render_view_host()) |
205 tab_contents()->render_view_host()->DragSourceSystemDragEnded(); | 139 tab_contents()->render_view_host()->DragSourceSystemDragEnded(); |
| 140 |
| 141 drag_handler_ = NULL; |
206 } | 142 } |
207 | 143 |
208 void TabContentsViewWin::OnDestroy() { | 144 void TabContentsViewWin::OnDestroy() { |
209 if (drop_target_.get()) { | 145 if (drop_target_.get()) { |
210 RevokeDragDrop(GetNativeView()); | 146 RevokeDragDrop(GetNativeView()); |
211 drop_target_ = NULL; | 147 drop_target_ = NULL; |
212 } | 148 } |
213 } | 149 } |
214 | 150 |
215 void TabContentsViewWin::SetPageTitle(const std::wstring& title) { | 151 void TabContentsViewWin::SetPageTitle(const std::wstring& title) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 // no longer be focusable (e.g. if the location bar was focused and then | 257 // no longer be focusable (e.g. if the location bar was focused and then |
322 // we switched to fullscreen mode). In that case we default to the | 258 // we switched to fullscreen mode). In that case we default to the |
323 // default focus. | 259 // default focus. |
324 SetInitialFocus(); | 260 SetInitialFocus(); |
325 } | 261 } |
326 view_storage->RemoveView(last_focused_view_storage_id_); | 262 view_storage->RemoveView(last_focused_view_storage_id_); |
327 } | 263 } |
328 } | 264 } |
329 | 265 |
330 bool TabContentsViewWin::IsDoingDrag() const { | 266 bool TabContentsViewWin::IsDoingDrag() const { |
331 return drag_source_.get() != NULL; | 267 return drag_handler_.get() != NULL; |
332 } | 268 } |
333 | 269 |
334 void TabContentsViewWin::CancelDragAndCloseTab() { | 270 void TabContentsViewWin::CancelDragAndCloseTab() { |
335 DCHECK(IsDoingDrag()); | 271 DCHECK(IsDoingDrag()); |
336 // We can't close the tab while we're in the drag and | 272 // We can't close the tab while we're in the drag and |
337 // |drag_source_->CancelDrag()| is async. Instead, set a flag to cancel | 273 // |drag_handler_->CancelDrag()| is async. Instead, set a flag to cancel |
338 // the drag and when the drag nested message loop ends, close the tab. | 274 // the drag and when the drag nested message loop ends, close the tab. |
339 drag_source_->CancelDrag(); | 275 drag_handler_->CancelDrag(); |
340 close_tab_after_drag_ends_ = true; | 276 close_tab_after_drag_ends_ = true; |
341 } | 277 } |
342 | 278 |
343 void TabContentsViewWin::UpdateDragCursor(WebDragOperation operation) { | 279 void TabContentsViewWin::UpdateDragCursor(WebDragOperation operation) { |
344 drop_target_->set_is_drop_target(operation != WebDragOperationNone); | 280 drop_target_->set_is_drop_target(operation != WebDragOperationNone); |
345 } | 281 } |
346 | 282 |
347 void TabContentsViewWin::GotFocus() { | 283 void TabContentsViewWin::GotFocus() { |
348 if (tab_contents()->delegate()) | 284 if (tab_contents()->delegate()) |
349 tab_contents()->delegate()->TabContentsFocused(tab_contents()); | 285 tab_contents()->delegate()->TabContentsFocused(tab_contents()); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 } | 542 } |
607 return false; | 543 return false; |
608 } | 544 } |
609 | 545 |
610 void TabContentsViewWin::WheelZoom(int distance) { | 546 void TabContentsViewWin::WheelZoom(int distance) { |
611 if (tab_contents()->delegate()) { | 547 if (tab_contents()->delegate()) { |
612 bool zoom_in = distance > 0; | 548 bool zoom_in = distance > 0; |
613 tab_contents()->delegate()->ContentsZoomChange(zoom_in); | 549 tab_contents()->delegate()->ContentsZoomChange(zoom_in); |
614 } | 550 } |
615 } | 551 } |
OLD | NEW |