OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/frame/browser_root_view.h" | 5 #include "chrome/browser/views/frame/browser_root_view.h" |
6 | 6 |
7 #include "app/drag_drop_types.h" | 7 #include "app/drag_drop_types.h" |
8 #include "app/os_exchange_data.h" | 8 #include "app/os_exchange_data.h" |
| 9 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
| 10 #include "chrome/browser/autocomplete/autocomplete_edit_view.h" |
| 11 #include "chrome/browser/location_bar.h" |
9 #include "chrome/browser/views/frame/browser_view.h" | 12 #include "chrome/browser/views/frame/browser_view.h" |
10 #include "chrome/browser/views/frame/browser_frame.h" | 13 #include "chrome/browser/views/frame/browser_frame.h" |
11 #include "chrome/browser/views/tabs/tab_strip_wrapper.h" | 14 #include "chrome/browser/views/tabs/tab_strip_wrapper.h" |
12 | 15 |
13 BrowserRootView::BrowserRootView(views::Widget* widget) | 16 BrowserRootView::BrowserRootView(BrowserView* browser_view, |
| 17 views::Widget* widget) |
14 : views::RootView(widget), | 18 : views::RootView(widget), |
15 tabstrip_(NULL), | 19 browser_view_(browser_view), |
16 forwarding_to_tab_strip_(false) { | 20 forwarding_to_tab_strip_(false) { |
17 } | 21 } |
18 | 22 |
19 bool BrowserRootView::GetDropFormats( | 23 bool BrowserRootView::GetDropFormats( |
20 int* formats, | 24 int* formats, |
21 std::set<OSExchangeData::CustomFormat>* custom_formats) { | 25 std::set<OSExchangeData::CustomFormat>* custom_formats) { |
22 if (tabstrip_ && tabstrip_->GetView()->IsVisible() && | 26 if (tabstrip() && tabstrip()->GetView()->IsVisible() && |
23 !tabstrip_->IsAnimating()) { | 27 !tabstrip()->IsAnimating()) { |
24 *formats = OSExchangeData::URL; | 28 *formats = OSExchangeData::URL | OSExchangeData::STRING; |
25 return true; | 29 return true; |
26 } | 30 } |
27 return false; | 31 return false; |
28 } | 32 } |
29 | 33 |
| 34 bool BrowserRootView::AreDropTypesRequired() { |
| 35 return true; |
| 36 } |
| 37 |
30 bool BrowserRootView::CanDrop(const OSExchangeData& data) { | 38 bool BrowserRootView::CanDrop(const OSExchangeData& data) { |
31 return (tabstrip_ && tabstrip_->GetView()->IsVisible() && | 39 if (!tabstrip() || !tabstrip()->GetView()->IsVisible() || |
32 !tabstrip_->IsAnimating()); | 40 tabstrip()->IsAnimating()) |
| 41 return false; |
| 42 |
| 43 // If there is a URL, we'll allow the drop. |
| 44 if (data.HasURL()) |
| 45 return true; |
| 46 |
| 47 // If there isn't a URL, see if we can 'paste and go'. |
| 48 return GetPasteAndGoURL(data, NULL); |
33 } | 49 } |
34 | 50 |
35 void BrowserRootView::OnDragEntered(const views::DropTargetEvent& event) { | 51 void BrowserRootView::OnDragEntered(const views::DropTargetEvent& event) { |
36 if (ShouldForwardToTabStrip(event)) { | 52 if (ShouldForwardToTabStrip(event)) { |
37 forwarding_to_tab_strip_ = true; | 53 forwarding_to_tab_strip_ = true; |
38 scoped_ptr<views::DropTargetEvent> mapped_event(MapEventToTabStrip(event)); | 54 scoped_ptr<views::DropTargetEvent> mapped_event( |
39 tabstrip_->GetView()->OnDragEntered(*mapped_event.get()); | 55 MapEventToTabStrip(event, event.GetData())); |
| 56 tabstrip()->GetView()->OnDragEntered(*mapped_event.get()); |
40 } | 57 } |
41 } | 58 } |
42 | 59 |
43 int BrowserRootView::OnDragUpdated(const views::DropTargetEvent& event) { | 60 int BrowserRootView::OnDragUpdated(const views::DropTargetEvent& event) { |
44 if (ShouldForwardToTabStrip(event)) { | 61 if (ShouldForwardToTabStrip(event)) { |
45 scoped_ptr<views::DropTargetEvent> mapped_event( | 62 scoped_ptr<views::DropTargetEvent> mapped_event( |
46 MapEventToTabStrip(event)); | 63 MapEventToTabStrip(event, event.GetData())); |
47 if (!forwarding_to_tab_strip_) { | 64 if (!forwarding_to_tab_strip_) { |
48 tabstrip_->GetView()->OnDragEntered(*mapped_event.get()); | 65 tabstrip()->GetView()->OnDragEntered(*mapped_event.get()); |
49 forwarding_to_tab_strip_ = true; | 66 forwarding_to_tab_strip_ = true; |
50 } | 67 } |
51 return tabstrip_->GetView()->OnDragUpdated(*mapped_event.get()); | 68 return tabstrip()->GetView()->OnDragUpdated(*mapped_event.get()); |
52 } else if (forwarding_to_tab_strip_) { | 69 } else if (forwarding_to_tab_strip_) { |
53 forwarding_to_tab_strip_ = false; | 70 forwarding_to_tab_strip_ = false; |
54 tabstrip_->GetView()->OnDragExited(); | 71 tabstrip()->GetView()->OnDragExited(); |
55 } | 72 } |
56 return DragDropTypes::DRAG_NONE; | 73 return DragDropTypes::DRAG_NONE; |
57 } | 74 } |
58 | 75 |
59 void BrowserRootView::OnDragExited() { | 76 void BrowserRootView::OnDragExited() { |
60 if (forwarding_to_tab_strip_) { | 77 if (forwarding_to_tab_strip_) { |
61 forwarding_to_tab_strip_ = false; | 78 forwarding_to_tab_strip_ = false; |
62 tabstrip_->GetView()->OnDragExited(); | 79 tabstrip()->GetView()->OnDragExited(); |
63 } | 80 } |
64 } | 81 } |
65 | 82 |
66 int BrowserRootView::OnPerformDrop(const views::DropTargetEvent& event) { | 83 int BrowserRootView::OnPerformDrop(const views::DropTargetEvent& event) { |
67 if (forwarding_to_tab_strip_) { | 84 if (!forwarding_to_tab_strip_) |
68 forwarding_to_tab_strip_ = false; | 85 return DragDropTypes::DRAG_NONE; |
69 scoped_ptr<views::DropTargetEvent> mapped_event( | 86 |
70 MapEventToTabStrip(event)); | 87 // Extract the URL and create a new OSExchangeData containing the URL. We do |
71 return tabstrip_->GetView()->OnPerformDrop(*mapped_event.get()); | 88 // this as the TabStrip doesn't know about the autocomplete edit and neeeds |
| 89 // to know about it to handle 'paste and go'. |
| 90 GURL url; |
| 91 std::wstring title; |
| 92 OSExchangeData mapped_data; |
| 93 if (!event.GetData().GetURLAndTitle(&url, &title) || !url.is_valid()) { |
| 94 // The url isn't valid. Use the paste and go url. |
| 95 if (GetPasteAndGoURL(event.GetData(), &url)) |
| 96 mapped_data.SetURL(url, std::wstring()); |
| 97 // else case: couldn't extract a url or 'paste and go' url. This ends up |
| 98 // passing through an OSExchangeData with nothing in it. We need to do this |
| 99 // so that the tab strip cleans up properly. |
| 100 } else { |
| 101 mapped_data.SetURL(url, std::wstring()); |
72 } | 102 } |
73 return DragDropTypes::DRAG_NONE; | 103 forwarding_to_tab_strip_ = false; |
| 104 scoped_ptr<views::DropTargetEvent> mapped_event( |
| 105 MapEventToTabStrip(event, mapped_data)); |
| 106 return tabstrip()->GetView()->OnPerformDrop(*mapped_event); |
74 } | 107 } |
75 | 108 |
76 bool BrowserRootView::ShouldForwardToTabStrip( | 109 bool BrowserRootView::ShouldForwardToTabStrip( |
77 const views::DropTargetEvent& event) { | 110 const views::DropTargetEvent& event) { |
78 if (!tabstrip_->GetView()->IsVisible()) | 111 if (!tabstrip()->GetView()->IsVisible()) |
79 return false; | 112 return false; |
80 | 113 |
81 // Allow the drop as long as the mouse is over the tabstrip or vertically | 114 // Allow the drop as long as the mouse is over the tabstrip or vertically |
82 // before it. | 115 // before it. |
83 gfx::Point tab_loc_in_host; | 116 gfx::Point tab_loc_in_host; |
84 ConvertPointToView(tabstrip_->GetView(), this, &tab_loc_in_host); | 117 ConvertPointToView(tabstrip()->GetView(), this, &tab_loc_in_host); |
85 return event.y() < tab_loc_in_host.y() + tabstrip_->GetView()->height(); | 118 return event.y() < tab_loc_in_host.y() + tabstrip()->GetView()->height(); |
86 } | 119 } |
87 | 120 |
88 views::DropTargetEvent* BrowserRootView::MapEventToTabStrip( | 121 views::DropTargetEvent* BrowserRootView::MapEventToTabStrip( |
89 const views::DropTargetEvent& event) { | 122 const views::DropTargetEvent& event, |
| 123 const OSExchangeData& data) { |
90 gfx::Point tab_strip_loc(event.location()); | 124 gfx::Point tab_strip_loc(event.location()); |
91 ConvertPointToView(this, tabstrip_->GetView(), &tab_strip_loc); | 125 ConvertPointToView(this, tabstrip()->GetView(), &tab_strip_loc); |
92 return new views::DropTargetEvent(event.GetData(), tab_strip_loc.x(), | 126 return new views::DropTargetEvent(data, tab_strip_loc.x(), |
93 tab_strip_loc.y(), | 127 tab_strip_loc.y(), |
94 event.GetSourceOperations()); | 128 event.GetSourceOperations()); |
95 } | 129 } |
| 130 |
| 131 TabStripWrapper* BrowserRootView::tabstrip() const { |
| 132 return browser_view_->tabstrip(); |
| 133 } |
| 134 |
| 135 bool BrowserRootView::GetPasteAndGoURL(const OSExchangeData& data, |
| 136 GURL* url) { |
| 137 if (!data.HasString()) |
| 138 return false; |
| 139 |
| 140 LocationBar* location_bar = browser_view_->GetLocationBar(); |
| 141 if (!location_bar) |
| 142 return false; |
| 143 |
| 144 AutocompleteEditView* edit = location_bar->location_entry(); |
| 145 if (!edit) |
| 146 return false; |
| 147 |
| 148 std::wstring text; |
| 149 if (!data.GetString(&text) || text.empty() || |
| 150 !edit->model()->CanPasteAndGo(text)) { |
| 151 return false; |
| 152 } |
| 153 if (url) |
| 154 *url = edit->model()->paste_and_go_url(); |
| 155 return true; |
| 156 } |
OLD | NEW |