| 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 |