172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_root_view.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/utf_string_conversions.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete_classifier.h"
10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/autocomplete/autocomplete_match.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/omnibox/location_bar.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/frame/browser_frame.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/tabs/tab_strip.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/accessibility/accessible_view_state.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/drag_drop_types.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/os_exchange_data.h"
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserRootView::BrowserRootView(BrowserView* browser_view,
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 views::Widget* widget)
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : views::RootView(widget),
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser_view_(browser_view),
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      forwarding_to_tab_strip_(false) { }
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserRootView::GetDropFormats(
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int* formats,
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      std::set<ui::OSExchangeData::CustomFormat>* custom_formats) {
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tabstrip() && tabstrip()->IsVisible()) {
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    *formats = ui::OSExchangeData::URL | ui::OSExchangeData::STRING;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserRootView::AreDropTypesRequired() {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool BrowserRootView::CanDrop(const ui::OSExchangeData& data) {
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!tabstrip() || !tabstrip()->IsVisible())
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If there is a URL, we'll allow the drop.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (data.HasURL())
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If there isn't a URL, see if we can 'paste and go'.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return GetPasteAndGoURL(data, NULL);
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserRootView::OnDragEntered(const views::DropTargetEvent& event) {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ShouldForwardToTabStrip(event)) {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    forwarding_to_tab_strip_ = true;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<views::DropTargetEvent> mapped_event(
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        MapEventToTabStrip(event, event.data()));
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip()->OnDragEntered(*mapped_event.get());
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BrowserRootView::OnDragUpdated(const views::DropTargetEvent& event) {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ShouldForwardToTabStrip(event)) {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<views::DropTargetEvent> mapped_event(
6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        MapEventToTabStrip(event, event.data()));
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!forwarding_to_tab_strip_) {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tabstrip()->OnDragEntered(*mapped_event.get());
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      forwarding_to_tab_strip_ = true;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return tabstrip()->OnDragUpdated(*mapped_event.get());
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (forwarding_to_tab_strip_) {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    forwarding_to_tab_strip_ = false;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip()->OnDragExited();
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return ui::DragDropTypes::DRAG_NONE;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserRootView::OnDragExited() {
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (forwarding_to_tab_strip_) {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    forwarding_to_tab_strip_ = false;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip()->OnDragExited();
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BrowserRootView::OnPerformDrop(const views::DropTargetEvent& event) {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!forwarding_to_tab_strip_)
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return ui::DragDropTypes::DRAG_NONE;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Extract the URL and create a new ui::OSExchangeData containing the URL. We
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // do this as the TabStrip doesn't know about the autocomplete edit and needs
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to know about it to handle 'paste and go'.
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url;
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  string16 title;
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui::OSExchangeData mapped_data;
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!event.data().GetURLAndTitle(&url, &title) || !url.is_valid()) {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The url isn't valid. Use the paste and go url.
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (GetPasteAndGoURL(event.data(), &url))
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      mapped_data.SetURL(url, string16());
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // else case: couldn't extract a url or 'paste and go' url. This ends up
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // passing through an ui::OSExchangeData with nothing in it. We need to do
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // this so that the tab strip cleans up properly.
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    mapped_data.SetURL(url, string16());
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  forwarding_to_tab_strip_ = false;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<views::DropTargetEvent> mapped_event(
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MapEventToTabStrip(event, mapped_data));
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return tabstrip()->OnPerformDrop(*mapped_event);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserRootView::GetAccessibleState(ui::AccessibleViewState* state) {
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RootView::GetAccessibleState(state);
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state->name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserRootView::ShouldForwardToTabStrip(
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const views::DropTargetEvent& event) {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!tabstrip()->IsVisible())
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Allow the drop as long as the mouse is over the tabstrip or vertically
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // before it.
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Point tab_loc_in_host;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ConvertPointToView(tabstrip(), this, &tab_loc_in_host);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return event.y() < tab_loc_in_host.y() + tabstrip()->height();
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochviews::DropTargetEvent* BrowserRootView::MapEventToTabStrip(
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const views::DropTargetEvent& event,
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const ui::OSExchangeData& data) {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Point tab_strip_loc(event.location());
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ConvertPointToView(this, tabstrip(), &tab_strip_loc);
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new views::DropTargetEvent(data, tab_strip_loc.x(),
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    tab_strip_loc.y(),
13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                    event.source_operations());
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenAbstractTabStripView* BrowserRootView::tabstrip() const {
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser_view_->tabstrip();
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool BrowserRootView::GetPasteAndGoURL(const ui::OSExchangeData& data,
14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       GURL* url) {
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!data.HasString())
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  string16 text;
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!data.GetString(&text) || text.empty())
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutocompleteMatch match;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_view_->browser()->profile()->GetAutocompleteClassifier()->Classify(
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      text, string16(), false, &match, NULL);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!match.destination_url.is_valid())
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (url)
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *url = match.destination_url;
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
162