diff options
Diffstat (limited to 'chrome/browser/views/frame/browser_root_view.cc')
-rw-r--r-- | chrome/browser/views/frame/browser_root_view.cc | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/chrome/browser/views/frame/browser_root_view.cc b/chrome/browser/views/frame/browser_root_view.cc new file mode 100644 index 0000000..d2985dd --- /dev/null +++ b/chrome/browser/views/frame/browser_root_view.cc @@ -0,0 +1,154 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/frame/browser_root_view.h" + +#include "app/drag_drop_types.h" +#include "app/l10n_util.h" +#include "app/os_exchange_data.h" +#include "chrome/browser/autocomplete/autocomplete.h" +#include "chrome/browser/autocomplete/autocomplete_classifier.h" +#include "chrome/browser/location_bar.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/views/frame/browser_view.h" +#include "chrome/browser/views/frame/browser_frame.h" +#include "chrome/browser/views/tabs/tab_strip.h" +#include "grit/chromium_strings.h" + +BrowserRootView::BrowserRootView(BrowserView* browser_view, + views::Widget* widget) + : views::RootView(widget), + browser_view_(browser_view), + forwarding_to_tab_strip_(false) { + SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME)); +} + +bool BrowserRootView::GetDropFormats( + int* formats, + std::set<OSExchangeData::CustomFormat>* custom_formats) { + if (tabstrip() && tabstrip()->IsVisible() && !tabstrip()->IsAnimating()) { + *formats = OSExchangeData::URL | OSExchangeData::STRING; + return true; + } + return false; +} + +bool BrowserRootView::AreDropTypesRequired() { + return true; +} + +bool BrowserRootView::CanDrop(const OSExchangeData& data) { + if (!tabstrip() || !tabstrip()->IsVisible() || tabstrip()->IsAnimating()) + return false; + + // If there is a URL, we'll allow the drop. + if (data.HasURL()) + return true; + + // If there isn't a URL, see if we can 'paste and go'. + return GetPasteAndGoURL(data, NULL); +} + +void BrowserRootView::OnDragEntered(const views::DropTargetEvent& event) { + if (ShouldForwardToTabStrip(event)) { + forwarding_to_tab_strip_ = true; + scoped_ptr<views::DropTargetEvent> mapped_event( + MapEventToTabStrip(event, event.GetData())); + tabstrip()->OnDragEntered(*mapped_event.get()); + } +} + +int BrowserRootView::OnDragUpdated(const views::DropTargetEvent& event) { + if (ShouldForwardToTabStrip(event)) { + scoped_ptr<views::DropTargetEvent> mapped_event( + MapEventToTabStrip(event, event.GetData())); + if (!forwarding_to_tab_strip_) { + tabstrip()->OnDragEntered(*mapped_event.get()); + forwarding_to_tab_strip_ = true; + } + return tabstrip()->OnDragUpdated(*mapped_event.get()); + } else if (forwarding_to_tab_strip_) { + forwarding_to_tab_strip_ = false; + tabstrip()->OnDragExited(); + } + return DragDropTypes::DRAG_NONE; +} + +void BrowserRootView::OnDragExited() { + if (forwarding_to_tab_strip_) { + forwarding_to_tab_strip_ = false; + tabstrip()->OnDragExited(); + } +} + +int BrowserRootView::OnPerformDrop(const views::DropTargetEvent& event) { + if (!forwarding_to_tab_strip_) + return DragDropTypes::DRAG_NONE; + + // Extract the URL and create a new OSExchangeData containing the URL. We do + // this as the TabStrip doesn't know about the autocomplete edit and neeeds + // to know about it to handle 'paste and go'. + GURL url; + std::wstring title; + OSExchangeData mapped_data; + if (!event.GetData().GetURLAndTitle(&url, &title) || !url.is_valid()) { + // The url isn't valid. Use the paste and go url. + if (GetPasteAndGoURL(event.GetData(), &url)) + mapped_data.SetURL(url, std::wstring()); + // else case: couldn't extract a url or 'paste and go' url. This ends up + // passing through an OSExchangeData with nothing in it. We need to do this + // so that the tab strip cleans up properly. + } else { + mapped_data.SetURL(url, std::wstring()); + } + forwarding_to_tab_strip_ = false; + scoped_ptr<views::DropTargetEvent> mapped_event( + MapEventToTabStrip(event, mapped_data)); + return tabstrip()->OnPerformDrop(*mapped_event); +} + +bool BrowserRootView::ShouldForwardToTabStrip( + const views::DropTargetEvent& event) { + if (!tabstrip()->IsVisible()) + return false; + + // Allow the drop as long as the mouse is over the tabstrip or vertically + // before it. + gfx::Point tab_loc_in_host; + ConvertPointToView(tabstrip(), this, &tab_loc_in_host); + return event.y() < tab_loc_in_host.y() + tabstrip()->height(); +} + +views::DropTargetEvent* BrowserRootView::MapEventToTabStrip( + const views::DropTargetEvent& event, + const OSExchangeData& data) { + gfx::Point tab_strip_loc(event.location()); + ConvertPointToView(this, tabstrip(), &tab_strip_loc); + return new views::DropTargetEvent(data, tab_strip_loc.x(), + tab_strip_loc.y(), + event.GetSourceOperations()); +} + +BaseTabStrip* BrowserRootView::tabstrip() const { + return browser_view_->tabstrip(); +} + +bool BrowserRootView::GetPasteAndGoURL(const OSExchangeData& data, GURL* url) { + if (!data.HasString()) + return false; + + std::wstring text; + if (!data.GetString(&text) || text.empty()) + return false; + + AutocompleteMatch match; + browser_view_->browser()->profile()->GetAutocompleteClassifier()->Classify( + text, std::wstring(), &match, NULL); + if (!match.destination_url.is_valid()) + return false; + + if (url) + *url = match.destination_url; + return true; +} |