browser_root_view.cc revision dc0f95d653279beabeb9817299e2902918ba123e
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" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/drag_drop_types.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/os_exchange_data.h" 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserRootView::BrowserRootView(BrowserView* browser_view, 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::Widget* widget) 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : views::RootView(widget), 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_view_(browser_view), 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forwarding_to_tab_strip_(false) { 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetAccessibleName(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserRootView::GetDropFormats( 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* formats, 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tabstrip() && tabstrip()->IsVisible() && !tabstrip()->IsAnimating()) { 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *formats = ui::OSExchangeData::URL | ui::OSExchangeData::STRING; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserRootView::AreDropTypesRequired() { 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool BrowserRootView::CanDrop(const ui::OSExchangeData& data) { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!tabstrip() || !tabstrip()->IsVisible() || tabstrip()->IsAnimating()) 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If there is a URL, we'll allow the drop. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.HasURL()) 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If there isn't a URL, see if we can 'paste and go'. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GetPasteAndGoURL(data, NULL); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserRootView::OnDragEntered(const views::DropTargetEvent& event) { 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ShouldForwardToTabStrip(event)) { 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forwarding_to_tab_strip_ = true; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<views::DropTargetEvent> mapped_event( 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MapEventToTabStrip(event, event.data())); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip()->OnDragEntered(*mapped_event.get()); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BrowserRootView::OnDragUpdated(const views::DropTargetEvent& event) { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ShouldForwardToTabStrip(event)) { 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<views::DropTargetEvent> mapped_event( 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MapEventToTabStrip(event, event.data())); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!forwarding_to_tab_strip_) { 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip()->OnDragEntered(*mapped_event.get()); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forwarding_to_tab_strip_ = true; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return tabstrip()->OnDragUpdated(*mapped_event.get()); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (forwarding_to_tab_strip_) { 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forwarding_to_tab_strip_ = false; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip()->OnDragExited(); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserRootView::OnDragExited() { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (forwarding_to_tab_strip_) { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forwarding_to_tab_strip_ = false; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip()->OnDragExited(); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BrowserRootView::OnPerformDrop(const views::DropTargetEvent& event) { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!forwarding_to_tab_strip_) 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Extract the URL and create a new ui::OSExchangeData containing the URL. We 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // do this as the TabStrip doesn't know about the autocomplete edit and needs 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to know about it to handle 'paste and go'. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen string16 title; 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::OSExchangeData mapped_data; 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!event.data().GetURLAndTitle(&url, &title) || !url.is_valid()) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The url isn't valid. Use the paste and go url. 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (GetPasteAndGoURL(event.data(), &url)) 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mapped_data.SetURL(url, string16()); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // else case: couldn't extract a url or 'paste and go' url. This ends up 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // passing through an ui::OSExchangeData with nothing in it. We need to do 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // this so that the tab strip cleans up properly. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mapped_data.SetURL(url, string16()); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forwarding_to_tab_strip_ = false; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<views::DropTargetEvent> mapped_event( 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MapEventToTabStrip(event, mapped_data)); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return tabstrip()->OnPerformDrop(*mapped_event); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserRootView::ShouldForwardToTabStrip( 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const views::DropTargetEvent& event) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!tabstrip()->IsVisible()) 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow the drop as long as the mouse is over the tabstrip or vertically 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // before it. 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point tab_loc_in_host; 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConvertPointToView(tabstrip(), this, &tab_loc_in_host); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return event.y() < tab_loc_in_host.y() + tabstrip()->height(); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochviews::DropTargetEvent* BrowserRootView::MapEventToTabStrip( 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const views::DropTargetEvent& event, 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const ui::OSExchangeData& data) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point tab_strip_loc(event.location()); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConvertPointToView(this, tabstrip(), &tab_strip_loc); 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new views::DropTargetEvent(data, tab_strip_loc.x(), 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_strip_loc.y(), 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event.source_operations()); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBaseTabStrip* BrowserRootView::tabstrip() const { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return browser_view_->tabstrip(); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool BrowserRootView::GetPasteAndGoURL(const ui::OSExchangeData& data, 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GURL* url) { 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!data.HasString()) 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen string16 text; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!data.GetString(&text) || text.empty()) 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutocompleteMatch match; 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_view_->browser()->profile()->GetAutocompleteClassifier()->Classify( 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen text, string16(), false, &match, NULL); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!match.destination_url.is_valid()) 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url) 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *url = match.destination_url; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 158