NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / browser_root_view.cc
blobb5a8fac345e59149e8870fc1f2699fd5de59d4da
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.
5 #include "chrome/browser/ui/views/frame/browser_root_view.h"
7 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
8 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
9 #include "chrome/browser/autocomplete/autocomplete_input.h"
10 #include "chrome/browser/autocomplete/autocomplete_match.h"
11 #include "chrome/browser/defaults.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser_commands.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/browser/ui/views/frame/browser_frame.h"
16 #include "chrome/browser/ui/views/frame/browser_view.h"
17 #include "chrome/browser/ui/views/tabs/tab_strip.h"
18 #include "chrome/browser/ui/views/touch_uma/touch_uma.h"
19 #include "ui/base/dragdrop/drag_drop_types.h"
20 #include "ui/base/dragdrop/os_exchange_data.h"
22 // static
23 const char BrowserRootView::kViewClassName[] =
24 "browser/ui/views/frame/BrowserRootView";
26 BrowserRootView::BrowserRootView(BrowserView* browser_view,
27 views::Widget* widget)
28 : views::internal::RootView(widget),
29 browser_view_(browser_view),
30 forwarding_to_tab_strip_(false) { }
32 bool BrowserRootView::GetDropFormats(
33 int* formats,
34 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) {
35 if (tabstrip() && tabstrip()->visible()) {
36 *formats = ui::OSExchangeData::URL | ui::OSExchangeData::STRING;
37 return true;
39 return false;
42 bool BrowserRootView::AreDropTypesRequired() {
43 return true;
46 bool BrowserRootView::CanDrop(const ui::OSExchangeData& data) {
47 if (!tabstrip() || !tabstrip()->visible())
48 return false;
50 // If there is a URL, we'll allow the drop.
51 if (data.HasURL())
52 return true;
54 // If there isn't a URL, see if we can 'paste and go'.
55 return GetPasteAndGoURL(data, NULL);
58 void BrowserRootView::OnDragEntered(const ui::DropTargetEvent& event) {
59 if (ShouldForwardToTabStrip(event)) {
60 forwarding_to_tab_strip_ = true;
61 scoped_ptr<ui::DropTargetEvent> mapped_event(
62 MapEventToTabStrip(event, event.data()));
63 tabstrip()->OnDragEntered(*mapped_event.get());
67 int BrowserRootView::OnDragUpdated(const ui::DropTargetEvent& event) {
68 if (ShouldForwardToTabStrip(event)) {
69 scoped_ptr<ui::DropTargetEvent> mapped_event(
70 MapEventToTabStrip(event, event.data()));
71 if (!forwarding_to_tab_strip_) {
72 tabstrip()->OnDragEntered(*mapped_event.get());
73 forwarding_to_tab_strip_ = true;
75 return tabstrip()->OnDragUpdated(*mapped_event.get());
76 } else if (forwarding_to_tab_strip_) {
77 forwarding_to_tab_strip_ = false;
78 tabstrip()->OnDragExited();
80 return ui::DragDropTypes::DRAG_NONE;
83 void BrowserRootView::OnDragExited() {
84 if (forwarding_to_tab_strip_) {
85 forwarding_to_tab_strip_ = false;
86 tabstrip()->OnDragExited();
90 int BrowserRootView::OnPerformDrop(const ui::DropTargetEvent& event) {
91 if (!forwarding_to_tab_strip_)
92 return ui::DragDropTypes::DRAG_NONE;
94 // Extract the URL and create a new ui::OSExchangeData containing the URL. We
95 // do this as the TabStrip doesn't know about the autocomplete edit and needs
96 // to know about it to handle 'paste and go'.
97 GURL url;
98 base::string16 title;
99 ui::OSExchangeData mapped_data;
100 if (!event.data().GetURLAndTitle(
101 ui::OSExchangeData::CONVERT_FILENAMES, &url, &title) ||
102 !url.is_valid()) {
103 // The url isn't valid. Use the paste and go url.
104 if (GetPasteAndGoURL(event.data(), &url))
105 mapped_data.SetURL(url, base::string16());
106 // else case: couldn't extract a url or 'paste and go' url. This ends up
107 // passing through an ui::OSExchangeData with nothing in it. We need to do
108 // this so that the tab strip cleans up properly.
109 } else {
110 mapped_data.SetURL(url, base::string16());
112 forwarding_to_tab_strip_ = false;
113 scoped_ptr<ui::DropTargetEvent> mapped_event(
114 MapEventToTabStrip(event, mapped_data));
115 return tabstrip()->OnPerformDrop(*mapped_event);
118 const char* BrowserRootView::GetClassName() const {
119 return kViewClassName;
122 bool BrowserRootView::OnMouseWheel(const ui::MouseWheelEvent& event) {
123 if (browser_defaults::kScrollEventChangesTab) {
124 // Switch to the left/right tab if the wheel-scroll happens over the
125 // tabstrip, or the empty space beside the tabstrip.
126 views::View* hit_view = GetEventHandlerForPoint(event.location());
127 views::NonClientView* non_client = GetWidget()->non_client_view();
128 if (tabstrip()->Contains(hit_view) ||
129 hit_view == non_client->frame_view()) {
130 int scroll_offset = abs(event.y_offset()) > abs(event.x_offset()) ?
131 event.y_offset() : -event.x_offset();
132 Browser* browser = browser_view_->browser();
133 TabStripModel* model = browser->tab_strip_model();
134 // Switch to the next tab only if not at the end of the tab-strip.
135 if (scroll_offset < 0 && model->active_index() + 1 < model->count()) {
136 chrome::SelectNextTab(browser);
137 return true;
140 // Switch to the previous tab only if not at the beginning of the
141 // tab-strip.
142 if (scroll_offset > 0 && model->active_index() > 0) {
143 chrome::SelectPreviousTab(browser);
144 return true;
148 return RootView::OnMouseWheel(event);
151 void BrowserRootView::DispatchGestureEvent(ui::GestureEvent* event) {
152 if (event->type() == ui::ET_GESTURE_TAP &&
153 event->location().y() <= 0 &&
154 event->location().x() <= browser_view_->GetBounds().width()) {
155 TouchUMA::RecordGestureAction(TouchUMA::GESTURE_ROOTVIEWTOP_TAP);
158 RootView::DispatchGestureEvent(event);
161 bool BrowserRootView::ShouldForwardToTabStrip(
162 const ui::DropTargetEvent& event) {
163 if (!tabstrip()->visible())
164 return false;
166 // Allow the drop as long as the mouse is over the tabstrip or vertically
167 // before it.
168 gfx::Point tab_loc_in_host;
169 ConvertPointToTarget(tabstrip(), this, &tab_loc_in_host);
170 return event.y() < tab_loc_in_host.y() + tabstrip()->height();
173 ui::DropTargetEvent* BrowserRootView::MapEventToTabStrip(
174 const ui::DropTargetEvent& event,
175 const ui::OSExchangeData& data) {
176 gfx::Point tab_strip_loc(event.location());
177 ConvertPointToTarget(this, tabstrip(), &tab_strip_loc);
178 return new ui::DropTargetEvent(data, tab_strip_loc, tab_strip_loc,
179 event.source_operations());
182 TabStrip* BrowserRootView::tabstrip() const {
183 return browser_view_->tabstrip();
186 bool BrowserRootView::GetPasteAndGoURL(const ui::OSExchangeData& data,
187 GURL* url) {
188 if (!data.HasString())
189 return false;
191 base::string16 text;
192 if (!data.GetString(&text) || text.empty())
193 return false;
194 text = AutocompleteMatch::SanitizeString(text);
196 AutocompleteMatch match;
197 AutocompleteClassifierFactory::GetForProfile(
198 browser_view_->browser()->profile())->Classify(
199 text, false, false, AutocompleteInput::INVALID_SPEC, &match, NULL);
200 if (!match.destination_url.is_valid())
201 return false;
203 if (url)
204 *url = match.destination_url;
205 return true;