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