diff options
Diffstat (limited to 'chrome/browser/views')
374 files changed, 560 insertions, 76652 deletions
diff --git a/chrome/browser/views/PRESUBMIT.py b/chrome/browser/views/PRESUBMIT.py deleted file mode 100755 index 0a3657e..0000000 --- a/chrome/browser/views/PRESUBMIT.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/python -# 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. - -"""Chromium presubmit script for src/chrome/browser/view. - -See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts -for more details on the presubmit API built into gcl. -""" - -def GetPreferredTrySlaves(): - return ['linux_view', 'linux_chromeos'] diff --git a/chrome/browser/views/about_chrome_view.cc b/chrome/browser/views/about_chrome_view.cc deleted file mode 100644 index f16f651..0000000 --- a/chrome/browser/views/about_chrome_view.cc +++ /dev/null @@ -1,819 +0,0 @@ -// 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/about_chrome_view.h" - -#include <algorithm> -#include <string> -#include <vector> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/callback.h" -#include "base/i18n/rtl.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "base/win/windows_version.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/platform_util.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/views/accessible_view_helper.h" -#include "chrome/browser/views/window.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_version_info.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "gfx/canvas.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "views/controls/textfield/textfield.h" -#include "views/controls/throbber.h" -#include "views/standard_layout.h" -#include "views/view_text_utils.h" -#include "views/widget/widget.h" -#include "views/window/window.h" -#include "webkit/glue/webkit_glue.h" - -#if defined(OS_WIN) -#include <commdlg.h> - -#include "base/win_util.h" -#include "chrome/browser/views/restart_message_box.h" -#include "chrome/installer/util/install_util.h" -#endif - -namespace { -// The pixel width of the version text field. Ideally, we'd like to have the -// bounds set to the edge of the icon. However, the icon is not a view but a -// part of the background, so we have to hard code the width to make sure -// the version field doesn't overlap it. -const int kVersionFieldWidth = 195; - -// These are used as placeholder text around the links in the text in the about -// dialog. -const wchar_t* kBeginLink = L"BEGIN_LINK"; -const wchar_t* kEndLink = L"END_LINK"; -const wchar_t* kBeginLinkChr = L"BEGIN_LINK_CHR"; -const wchar_t* kBeginLinkOss = L"BEGIN_LINK_OSS"; -const wchar_t* kEndLinkChr = L"END_LINK_CHR"; -const wchar_t* kEndLinkOss = L"END_LINK_OSS"; - -// The background bitmap used to draw the background color for the About box -// and the separator line (this is the image we will draw the logo on top of). -static const SkBitmap* kBackgroundBmp = NULL; - -// Returns a substring from |text| between start and end. -std::wstring StringSubRange(const std::wstring& text, size_t start, - size_t end) { - DCHECK(end > start); - return text.substr(start, end - start); -} - -} // namespace - -namespace browser { - - // Declared in browser_dialogs.h so that others don't - // need to depend on our .h. - views::Window* ShowAboutChromeView(gfx::NativeWindow parent, - Profile* profile) { - views::Window* about_chrome_window = - browser::CreateViewsWindow(parent, - gfx::Rect(), - new AboutChromeView(profile)); - about_chrome_window->Show(); - return about_chrome_window; - } - -} // namespace browser - -//////////////////////////////////////////////////////////////////////////////// -// AboutChromeView, public: - -AboutChromeView::AboutChromeView(Profile* profile) - : profile_(profile), - about_dlg_background_logo_(NULL), - about_title_label_(NULL), - version_label_(NULL), -#if defined(OS_CHROMEOS) - os_version_label_(NULL), -#endif - copyright_label_(NULL), - main_text_label_(NULL), - main_text_label_height_(0), - chromium_url_(NULL), - open_source_url_(NULL), - terms_of_service_url_(NULL), - restart_button_visible_(false), - chromium_url_appears_first_(true), - text_direction_is_rtl_(false) { - DCHECK(profile); -#if defined(OS_CHROMEOS) - loader_.GetVersion(&consumer_, - NewCallback(this, &AboutChromeView::OnOSVersion), true); -#endif - Init(); - -#if defined(OS_WIN) || defined(OS_CHROMEOS) - google_updater_ = new GoogleUpdate(); - google_updater_->set_status_listener(this); -#endif - - if (kBackgroundBmp == NULL) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - kBackgroundBmp = rb.GetBitmapNamed(IDR_ABOUT_BACKGROUND_COLOR); - } -} - -AboutChromeView::~AboutChromeView() { -#if defined(OS_WIN) || defined(OS_CHROMEOS) - // The Google Updater will hold a pointer to us until it reports status, so we - // need to let it know that we will no longer be listening. - if (google_updater_) - google_updater_->set_status_listener(NULL); -#endif -} - -void AboutChromeView::Init() { - text_direction_is_rtl_ = base::i18n::IsRTL(); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - chrome::VersionInfo version_info; - if (!version_info.is_valid()) { - NOTREACHED() << L"Failed to initialize about window"; - return; - } - - current_version_ = ASCIIToWide(version_info.Version()); - - std::string version_modifier = platform_util::GetVersionStringModifier(); - if (!version_modifier.empty()) - version_details_ += L" " + ASCIIToWide(version_modifier); - -#if !defined(GOOGLE_CHROME_BUILD) - version_details_ += L" ("; - version_details_ += ASCIIToWide(version_info.LastChange()); - version_details_ += L")"; -#endif - - // Views we will add to the *parent* of this dialog, since it will display - // next to the buttons which we don't draw ourselves. - throbber_.reset(new views::Throbber(50, true)); - throbber_->set_parent_owned(false); - throbber_->SetVisible(false); - - SkBitmap* success_image = rb.GetBitmapNamed(IDR_UPDATE_UPTODATE); - success_indicator_.SetImage(*success_image); - success_indicator_.set_parent_owned(false); - - SkBitmap* update_available_image = rb.GetBitmapNamed(IDR_UPDATE_AVAILABLE); - update_available_indicator_.SetImage(*update_available_image); - update_available_indicator_.set_parent_owned(false); - - SkBitmap* timeout_image = rb.GetBitmapNamed(IDR_UPDATE_FAIL); - timeout_indicator_.SetImage(*timeout_image); - timeout_indicator_.set_parent_owned(false); - - update_label_.SetVisible(false); - update_label_.set_parent_owned(false); - - // Regular view controls we draw by ourself. First, we add the background - // image for the dialog. We have two different background bitmaps, one for - // LTR UIs and one for RTL UIs. We load the correct bitmap based on the UI - // layout of the view. - about_dlg_background_logo_ = new views::ImageView(); - SkBitmap* about_background_logo = rb.GetBitmapNamed(base::i18n::IsRTL() ? - IDR_ABOUT_BACKGROUND_RTL : IDR_ABOUT_BACKGROUND); - - about_dlg_background_logo_->SetImage(*about_background_logo); - AddChildView(about_dlg_background_logo_); - - // Add the dialog labels. - about_title_label_ = new views::Label( - l10n_util::GetString(IDS_PRODUCT_NAME)); - about_title_label_->SetFont(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont).DeriveFont(18)); - about_title_label_->SetColor(SK_ColorBLACK); - AddChildView(about_title_label_); - - // This is a text field so people can copy the version number from the dialog. - version_label_ = new views::Textfield(); - version_label_->SetText(WideToUTF16Hack(current_version_ + version_details_)); - version_label_->SetReadOnly(true); - version_label_->RemoveBorder(); - version_label_->SetTextColor(SK_ColorBLACK); - version_label_->SetBackgroundColor(SK_ColorWHITE); - version_label_->SetFont(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont)); - AddChildView(version_label_); - -#if defined(OS_CHROMEOS) - os_version_label_ = new views::Textfield(views::Textfield::STYLE_MULTILINE); - os_version_label_->SetReadOnly(true); - os_version_label_->RemoveBorder(); - os_version_label_->SetTextColor(SK_ColorBLACK); - os_version_label_->SetBackgroundColor(SK_ColorWHITE); - os_version_label_->SetFont(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont)); - AddChildView(os_version_label_); -#endif - - // The copyright URL portion of the main label. - copyright_label_ = new views::Label( - l10n_util::GetString(IDS_ABOUT_VERSION_COPYRIGHT)); - copyright_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(copyright_label_); - - main_text_label_ = new views::Label(L""); - - // Figure out what to write in the main label of the About box. - std::wstring text = l10n_util::GetString(IDS_ABOUT_VERSION_LICENSE); - - chromium_url_appears_first_ = - text.find(kBeginLinkChr) < text.find(kBeginLinkOss); - - size_t link1 = text.find(kBeginLink); - DCHECK(link1 != std::wstring::npos); - size_t link1_end = text.find(kEndLink, link1); - DCHECK(link1_end != std::wstring::npos); - size_t link2 = text.find(kBeginLink, link1_end); - DCHECK(link2 != std::wstring::npos); - size_t link2_end = text.find(kEndLink, link2); - DCHECK(link1_end != std::wstring::npos); - - main_label_chunk1_ = text.substr(0, link1); - main_label_chunk2_ = StringSubRange(text, link1_end + wcslen(kEndLinkOss), - link2); - main_label_chunk3_ = text.substr(link2_end + wcslen(kEndLinkOss)); - - // The Chromium link within the main text of the dialog. - chromium_url_ = new views::Link( - StringSubRange(text, text.find(kBeginLinkChr) + wcslen(kBeginLinkChr), - text.find(kEndLinkChr))); - AddChildView(chromium_url_); - chromium_url_->SetController(this); - - // The Open Source link within the main text of the dialog. - open_source_url_ = new views::Link( - StringSubRange(text, text.find(kBeginLinkOss) + wcslen(kBeginLinkOss), - text.find(kEndLinkOss))); - AddChildView(open_source_url_); - open_source_url_->SetController(this); - - // Add together all the strings in the dialog for the purpose of calculating - // the height of the dialog. The space for the Terms of Service string is not - // included (it is added later, if needed). - std::wstring full_text = main_label_chunk1_ + chromium_url_->GetText() + - main_label_chunk2_ + open_source_url_->GetText() + - main_label_chunk3_; - - dialog_dimensions_ = views::Window::GetLocalizedContentsSize( - IDS_ABOUT_DIALOG_WIDTH_CHARS, - IDS_ABOUT_DIALOG_MINIMUM_HEIGHT_LINES); - - // Create a label and add the full text so we can query it for the height. - views::Label dummy_text(full_text); - dummy_text.SetMultiLine(true); - gfx::Font font = - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); - - // Add up the height of the various elements on the page. - int height = about_background_logo->height() + - kRelatedControlVerticalSpacing + - // Copyright line. - font.GetHeight() + - // Main label. - dummy_text.GetHeightForWidth( - dialog_dimensions_.width() - (2 * kPanelHorizMargin)) + - kRelatedControlVerticalSpacing; - -#if defined(GOOGLE_CHROME_BUILD) - std::vector<size_t> url_offsets; - text = l10n_util::GetStringF(IDS_ABOUT_TERMS_OF_SERVICE, - std::wstring(), - std::wstring(), - &url_offsets); - - main_label_chunk4_ = text.substr(0, url_offsets[0]); - main_label_chunk5_ = text.substr(url_offsets[0]); - - // The Terms of Service URL at the bottom. - terms_of_service_url_ = - new views::Link(l10n_util::GetString(IDS_TERMS_OF_SERVICE)); - AddChildView(terms_of_service_url_); - terms_of_service_url_->SetController(this); - - // Add the Terms of Service line and some whitespace. - height += font.GetHeight() + kRelatedControlVerticalSpacing; -#endif - - // Use whichever is greater (the calculated height or the specified minimum - // height). - dialog_dimensions_.set_height(std::max(height, dialog_dimensions_.height())); -} - -//////////////////////////////////////////////////////////////////////////////// -// AboutChromeView, views::View implementation: - -gfx::Size AboutChromeView::GetPreferredSize() { - return dialog_dimensions_; -} - -void AboutChromeView::Layout() { - gfx::Size panel_size = GetPreferredSize(); - - // Background image for the dialog. - gfx::Size sz = about_dlg_background_logo_->GetPreferredSize(); - // Used to position main text below. - int background_image_height = sz.height(); - about_dlg_background_logo_->SetBounds(panel_size.width() - sz.width(), 0, - sz.width(), sz.height()); - - // First label goes to the top left corner. - sz = about_title_label_->GetPreferredSize(); - about_title_label_->SetBounds(kPanelHorizMargin, kPanelVertMargin, - sz.width(), sz.height()); - - // Then we have the version number right below it. - sz = version_label_->GetPreferredSize(); - version_label_->SetBounds(kPanelHorizMargin, - about_title_label_->y() + - about_title_label_->height() + - kRelatedControlVerticalSpacing, - kVersionFieldWidth, - sz.height()); - -#if defined(OS_CHROMEOS) - // Then we have the version number right below it. - sz = os_version_label_->GetPreferredSize(); - os_version_label_->SetBounds( - kPanelHorizMargin, - version_label_->y() + - version_label_->height() + - kRelatedControlVerticalSpacing, - kVersionFieldWidth, - sz.height()); -#endif - - // For the width of the main text label we want to use up the whole panel - // width and remaining height, minus a little margin on each side. - int y_pos = background_image_height + kRelatedControlVerticalSpacing; - sz.set_width(panel_size.width() - 2 * kPanelHorizMargin); - - // Draw the text right below the background image. - copyright_label_->SetBounds(kPanelHorizMargin, - y_pos, - sz.width(), - sz.height()); - - // Then the main_text_label. - main_text_label_->SetBounds(kPanelHorizMargin, - copyright_label_->y() + - copyright_label_->height(), - sz.width(), - main_text_label_height_); - - // Get the y-coordinate of our parent so we can position the text left of the - // buttons at the bottom. - gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false); - - sz = throbber_->GetPreferredSize(); - int throbber_topleft_x = kPanelHorizMargin; - int throbber_topleft_y = parent_bounds.bottom() - sz.height() - - kButtonVEdgeMargin - 3; - throbber_->SetBounds(throbber_topleft_x, throbber_topleft_y, - sz.width(), sz.height()); - - // This image is hidden (see ViewHierarchyChanged) and displayed on demand. - sz = success_indicator_.GetPreferredSize(); - success_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y, - sz.width(), sz.height()); - - // This image is hidden (see ViewHierarchyChanged) and displayed on demand. - sz = update_available_indicator_.GetPreferredSize(); - update_available_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y, - sz.width(), sz.height()); - - // This image is hidden (see ViewHierarchyChanged) and displayed on demand. - sz = timeout_indicator_.GetPreferredSize(); - timeout_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y, - sz.width(), sz.height()); - - // The update label should be at the bottom of the screen, to the right of - // the throbber. We specify width to the end of the dialog because it contains - // variable length messages. - sz = update_label_.GetPreferredSize(); - int update_label_x = throbber_->x() + throbber_->width() + - kRelatedControlHorizontalSpacing; - update_label_.SetHorizontalAlignment(views::Label::ALIGN_LEFT); - update_label_.SetBounds(update_label_x, - throbber_topleft_y + 1, - parent_bounds.width() - update_label_x, - sz.height()); - - if (!accessible_view_helper_.get()) - accessible_view_helper_.reset( - new AccessibleViewHelper(GetParent(), profile_)); -} - - -void AboutChromeView::Paint(gfx::Canvas* canvas) { - views::View::Paint(canvas); - - // Draw the background image color (and the separator) across the dialog. - // This will become the background for the logo image at the top of the - // dialog. - canvas->TileImageInt(*kBackgroundBmp, 0, 0, - dialog_dimensions_.width(), kBackgroundBmp->height()); - - gfx::Font font = - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); - - const gfx::Rect label_bounds = main_text_label_->bounds(); - - views::Link* link1 = - chromium_url_appears_first_ ? chromium_url_ : open_source_url_; - views::Link* link2 = - chromium_url_appears_first_ ? open_source_url_ : chromium_url_; - gfx::Rect* rect1 = chromium_url_appears_first_ ? - &chromium_url_rect_ : &open_source_url_rect_; - gfx::Rect* rect2 = chromium_url_appears_first_ ? - &open_source_url_rect_ : &chromium_url_rect_; - - // This struct keeps track of where to write the next word (which x,y - // pixel coordinate). This struct is updated after drawing text and checking - // if we need to wrap. - gfx::Size position; - // Draw the first text chunk and position the Chromium url. - view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_, - main_label_chunk1_, link1, rect1, &position, text_direction_is_rtl_, - label_bounds, font); - // Draw the second text chunk and position the Open Source url. - view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_, - main_label_chunk2_, link2, rect2, &position, text_direction_is_rtl_, - label_bounds, font); - // Draw the third text chunk (which has no URL associated with it). - view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_, - main_label_chunk3_, NULL, NULL, &position, text_direction_is_rtl_, - label_bounds, font); - -#if defined(GOOGLE_CHROME_BUILD) - // Insert a line break and some whitespace. - position.set_width(0); - position.Enlarge(0, font.GetHeight() + kRelatedControlVerticalSpacing); - - // And now the Terms of Service and position the TOS url. - view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_, - main_label_chunk4_, terms_of_service_url_, &terms_of_service_url_rect_, - &position, text_direction_is_rtl_, label_bounds, font); - // The last text chunk doesn't have a URL associated with it. - view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_, - main_label_chunk5_, NULL, NULL, &position, text_direction_is_rtl_, - label_bounds, font); - - // Position the TOS URL within the main label. - terms_of_service_url_->SetBounds(terms_of_service_url_rect_.x(), - terms_of_service_url_rect_.y(), - terms_of_service_url_rect_.width(), - terms_of_service_url_rect_.height()); -#endif - - // Position the URLs within the main label. First position the Chromium URL - // within the main label. - chromium_url_->SetBounds(chromium_url_rect_.x(), - chromium_url_rect_.y(), - chromium_url_rect_.width(), - chromium_url_rect_.height()); - // Then position the Open Source URL within the main label. - open_source_url_->SetBounds(open_source_url_rect_.x(), - open_source_url_rect_.y(), - open_source_url_rect_.width(), - open_source_url_rect_.height()); - - // Save the height so we can set the bounds correctly. - main_text_label_height_ = position.height() + font.GetHeight(); -} - -void AboutChromeView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - // Since we want some of the controls to show up in the same visual row - // as the buttons, which are provided by the framework, we must add the - // buttons to the non-client view, which is the parent of this view. - // Similarly, when we're removed from the view hierarchy, we must take care - // to remove these items as well. - if (child == this) { - if (is_add) { - parent->AddChildView(&update_label_); - parent->AddChildView(throbber_.get()); - parent->AddChildView(&success_indicator_); - success_indicator_.SetVisible(false); - parent->AddChildView(&update_available_indicator_); - update_available_indicator_.SetVisible(false); - parent->AddChildView(&timeout_indicator_); - timeout_indicator_.SetVisible(false); - -#if defined(OS_WIN) - // On-demand updates for Chrome don't work in Vista RTM when UAC is turned - // off. So, in this case we just want the About box to not mention - // on-demand updates. Silent updates (in the background) should still - // work as before - enabling UAC or installing the latest service pack - // for Vista is another option. - int service_pack_major = 0, service_pack_minor = 0; - base::win::GetServicePackLevel(&service_pack_major, &service_pack_minor); - if (win_util::UserAccountControlIsEnabled() || - base::win::GetVersion() == base::win::VERSION_XP || - (base::win::GetVersion() == base::win::VERSION_VISTA && - service_pack_major >= 1) || - base::win::GetVersion() > base::win::VERSION_VISTA) { - UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR); - // CheckForUpdate(false, ...) means don't upgrade yet. - google_updater_->CheckForUpdate(false, window()); - } -#elif defined(OS_CHROMEOS) - UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR); - // CheckForUpdate(false, ...) means don't upgrade yet. - google_updater_->CheckForUpdate(false, window()); -#endif - } else { - parent->RemoveChildView(&update_label_); - parent->RemoveChildView(throbber_.get()); - parent->RemoveChildView(&success_indicator_); - parent->RemoveChildView(&update_available_indicator_); - parent->RemoveChildView(&timeout_indicator_); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// AboutChromeView, views::DialogDelegate implementation: - -std::wstring AboutChromeView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return l10n_util::GetString(IDS_RESTART_AND_UPDATE); - } else if (button == MessageBoxFlags::DIALOGBUTTON_CANCEL) { - if (restart_button_visible_) - return l10n_util::GetString(IDS_NOT_NOW); - // The OK button (which is the default button) has been re-purposed to be - // 'Restart Now' so we want the Cancel button should have the label - // OK but act like a Cancel button in all other ways. - return l10n_util::GetString(IDS_OK); - } - - NOTREACHED(); - return L""; -} - -std::wstring AboutChromeView::GetWindowTitle() const { - return l10n_util::GetString(IDS_ABOUT_CHROME_TITLE); -} - -bool AboutChromeView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK && !restart_button_visible_) - return false; - - return true; -} - -bool AboutChromeView::IsDialogButtonVisible( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK && !restart_button_visible_) - return false; - - return true; -} - -// (on ChromeOS) the default focus is ending up in the version field when -// the update button is hidden. This forces the focus to always be on the -// OK button (which is the dialog cancel button, see GetDialogButtonLabel -// above). -int AboutChromeView::GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -bool AboutChromeView::CanResize() const { - return false; -} - -bool AboutChromeView::CanMaximize() const { - return false; -} - -bool AboutChromeView::IsAlwaysOnTop() const { - return false; -} - -bool AboutChromeView::HasAlwaysOnTopMenu() const { - return false; -} - -bool AboutChromeView::IsModal() const { - return true; -} - -bool AboutChromeView::Accept() { -#if defined(OS_WIN) || defined(OS_CHROMEOS) - // Set the flag to restore the last session on shutdown. - PrefService* pref_service = g_browser_process->local_state(); - pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true); - BrowserList::CloseAllBrowsersAndExit(); -#endif - - return true; -} - -views::View* AboutChromeView::GetContentsView() { - return this; -} - -//////////////////////////////////////////////////////////////////////////////// -// AboutChromeView, views::LinkController implementation: - -void AboutChromeView::LinkActivated(views::Link* source, - int event_flags) { - GURL url; - if (source == terms_of_service_url_) - url = GURL(chrome::kAboutTermsURL); - else if (source == chromium_url_) - url = GURL(l10n_util::GetStringUTF16(IDS_CHROMIUM_PROJECT_URL)); - else if (source == open_source_url_) - url = GURL(chrome::kAboutCreditsURL); - else - NOTREACHED() << "Unknown link source"; - - Browser* browser = BrowserList::GetLastActive(); -#if defined(OS_CHROMEOS) - browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); -#else - browser->OpenURL(url, GURL(), NEW_WINDOW, PageTransition::LINK); -#endif -} - -#if defined(OS_CHROMEOS) -void AboutChromeView::OnOSVersion( - chromeos::VersionLoader::Handle handle, - std::string version) { - - // This is a hack to "wrap" the very long Test Build version after - // the version number, the remaining text won't be visible but can - // be selected, copied, pasted. - std::string::size_type pos = version.find(" (Test Build"); - if (pos != std::string::npos) - version.replace(pos, 1, "\n"); - - os_version_label_->SetText(UTF8ToUTF16(version)); -} -#endif - -#if defined(OS_WIN) || defined(OS_CHROMEOS) -//////////////////////////////////////////////////////////////////////////////// -// AboutChromeView, GoogleUpdateStatusListener implementation: - -void AboutChromeView::OnReportResults(GoogleUpdateUpgradeResult result, - GoogleUpdateErrorCode error_code, - const std::wstring& version) { - // Drop the last reference to the object so that it gets cleaned up here. - google_updater_ = NULL; - - // Make a note of which version Google Update is reporting is the latest - // version. - new_version_available_ = version; - UpdateStatus(result, error_code); -} -//////////////////////////////////////////////////////////////////////////////// -// AboutChromeView, private: - -void AboutChromeView::UpdateStatus(GoogleUpdateUpgradeResult result, - GoogleUpdateErrorCode error_code) { -#if !defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) - // For Chromium builds it would show an error message. - // But it looks weird because in fact there is no error, - // just the update server is not available for non-official builds. - return; -#endif - bool show_success_indicator = false; - bool show_update_available_indicator = false; - bool show_timeout_indicator = false; - bool show_throbber = false; - bool show_update_label = true; // Always visible, except at start. - - switch (result) { - case UPGRADE_STARTED: - UserMetrics::RecordAction(UserMetricsAction("Upgrade_Started"), profile_); - show_throbber = true; - update_label_.SetText(l10n_util::GetString(IDS_UPGRADE_STARTED)); - break; - case UPGRADE_CHECK_STARTED: - UserMetrics::RecordAction(UserMetricsAction("UpgradeCheck_Started"), - profile_); - show_throbber = true; - update_label_.SetText(l10n_util::GetString(IDS_UPGRADE_CHECK_STARTED)); - break; - case UPGRADE_IS_AVAILABLE: - UserMetrics::RecordAction( - UserMetricsAction("UpgradeCheck_UpgradeIsAvailable"), profile_); - DCHECK(!google_updater_); // Should have been nulled out already. - google_updater_ = new GoogleUpdate(); - google_updater_->set_status_listener(this); - UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR); - // CheckForUpdate(true,...) means perform upgrade if new version found. - google_updater_->CheckForUpdate(true, window()); - // TODO(seanparent): Need to see if this code needs to change to - // force a machine restart. - return; - case UPGRADE_ALREADY_UP_TO_DATE: { - // The extra version check is necessary on Windows because the application - // may be already up to date on disk though the running app is still - // out of date. Chrome OS doesn't quite have this issue since the - // OS/App are updated together. If a newer version of the OS has been - // staged then UPGRADE_SUCESSFUL will be returned. -#if defined(OS_WIN) - // Google Update reported that Chrome is up-to-date. Now make sure that we - // are running the latest version and if not, notify the user by falling - // into the next case of UPGRADE_SUCCESSFUL. - scoped_ptr<installer::Version> installed_version( - InstallUtil::GetChromeVersion(false)); - scoped_ptr<installer::Version> running_version( - installer::Version::GetVersionFromString(current_version_)); - if (!installed_version.get() || - !installed_version->IsHigherThan(running_version.get())) { -#endif - UserMetrics::RecordAction( - UserMetricsAction("UpgradeCheck_AlreadyUpToDate"), profile_); -#if defined(OS_CHROMEOS) - std::wstring update_label_text = - l10n_util::GetStringF(IDS_UPGRADE_ALREADY_UP_TO_DATE, - l10n_util::GetString(IDS_PRODUCT_NAME)); -#else - std::wstring update_label_text = - l10n_util::GetStringF(IDS_UPGRADE_ALREADY_UP_TO_DATE, - l10n_util::GetString(IDS_PRODUCT_NAME), - current_version_); -#endif - if (base::i18n::IsRTL()) { - update_label_text.push_back( - static_cast<wchar_t>(base::i18n::kLeftToRightMark)); - } - update_label_.SetText(update_label_text); - show_success_indicator = true; - break; -#if defined(OS_WIN) - } -#endif - // No break here as we want to notify user about upgrade if there is one. - } - case UPGRADE_SUCCESSFUL: { - if (result == UPGRADE_ALREADY_UP_TO_DATE) - UserMetrics::RecordAction( - UserMetricsAction("UpgradeCheck_AlreadyUpgraded"), profile_); - else - UserMetrics::RecordAction(UserMetricsAction("UpgradeCheck_Upgraded"), - profile_); - restart_button_visible_ = true; - const std::wstring& update_string = - l10n_util::GetStringF(IDS_UPGRADE_SUCCESSFUL_RESTART, - l10n_util::GetString(IDS_PRODUCT_NAME)); - update_label_.SetText(update_string); - show_success_indicator = true; - break; - } - case UPGRADE_ERROR: - UserMetrics::RecordAction(UserMetricsAction("UpgradeCheck_Error"), - profile_); - restart_button_visible_ = false; - update_label_.SetText(l10n_util::GetStringF(IDS_UPGRADE_ERROR, - UTF8ToWide(base::IntToString(error_code)))); - show_timeout_indicator = true; - break; - default: - NOTREACHED(); - } - - success_indicator_.SetVisible(show_success_indicator); - update_available_indicator_.SetVisible(show_update_available_indicator); - timeout_indicator_.SetVisible(show_timeout_indicator); - update_label_.SetVisible(show_update_label); - throbber_->SetVisible(show_throbber); - if (show_throbber) - throbber_->Start(); - else - throbber_->Stop(); - - // We have updated controls on the parent, so we need to update its layout. - View* parent = GetParent(); - parent->Layout(); - - // Check button may have appeared/disappeared. We cannot call this during - // ViewHierarchyChanged because the |window()| pointer hasn't been set yet. - if (window()) - GetDialogClientView()->UpdateDialogButtons(); -} - -#endif diff --git a/chrome/browser/views/about_chrome_view.h b/chrome/browser/views/about_chrome_view.h index 828c4e6..cb2a7dd6 100644 --- a/chrome/browser/views/about_chrome_view.h +++ b/chrome/browser/views/about_chrome_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,168 +6,8 @@ #define CHROME_BROWSER_VIEWS_ABOUT_CHROME_VIEW_H_ #pragma once -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/link.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -#if defined(OS_WIN) || defined(OS_CHROMEOS) -#include "chrome/browser/google/google_update.h" -#endif -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/version_loader.h" -#endif - -namespace views { -class Textfield; -class Throbber; -class Window; -} - -class AccessibleViewHelper; -class Profile; - -//////////////////////////////////////////////////////////////////////////////// -// -// The AboutChromeView class is responsible for drawing the UI controls of the -// About Chrome dialog that allows the user to see what version is installed -// and check for updates. -// -//////////////////////////////////////////////////////////////////////////////// -class AboutChromeView : public views::View, - public views::DialogDelegate, - public views::LinkController -#if defined(OS_WIN) || defined(OS_CHROMEOS) - , public GoogleUpdateStatusListener -#endif - { - public: - explicit AboutChromeView(Profile* profile); - virtual ~AboutChromeView(); - - // Initialize the controls on the dialog. - void Init(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // Overridden from views::DialogDelegate: - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool IsDialogButtonVisible( - MessageBoxFlags::DialogButton button) const; - virtual int GetDefaultDialogButton() const; - virtual bool CanResize() const; - virtual bool CanMaximize() const; - virtual bool IsAlwaysOnTop() const; - virtual bool HasAlwaysOnTopMenu() const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool Accept(); - virtual views::View* GetContentsView(); - - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); -#if defined(OS_WIN) || defined(OS_CHROMEOS) - // Overridden from GoogleUpdateStatusListener: - virtual void OnReportResults(GoogleUpdateUpgradeResult result, - GoogleUpdateErrorCode error_code, - const std::wstring& version); -#endif - - private: -#if defined(OS_WIN) || defined(OS_CHROMEOS) - // Update the UI to show the status of the upgrade. - void UpdateStatus(GoogleUpdateUpgradeResult result, - GoogleUpdateErrorCode error_code); -#endif - -#if defined(OS_CHROMEOS) - // Callback from chromeos::VersionLoader giving the version. - void OnOSVersion(chromeos::VersionLoader::Handle handle, - std::string version); -#endif - - - Profile* profile_; - - // UI elements on the dialog. - views::ImageView* about_dlg_background_logo_; - views::Label* about_title_label_; - views::Textfield* version_label_; -#if defined(OS_CHROMEOS) - views::Textfield* os_version_label_; -#endif - views::Label* copyright_label_; - views::Label* main_text_label_; - int main_text_label_height_; - views::Link* chromium_url_; - gfx::Rect chromium_url_rect_; - views::Link* open_source_url_; - gfx::Rect open_source_url_rect_; - views::Link* terms_of_service_url_; - gfx::Rect terms_of_service_url_rect_; - // UI elements we add to the parent view. - scoped_ptr<views::Throbber> throbber_; - views::ImageView success_indicator_; - views::ImageView update_available_indicator_; - views::ImageView timeout_indicator_; - views::Label update_label_; - - // The dialog dimensions. - gfx::Size dialog_dimensions_; - - // Keeps track of the visible state of the Restart Now button. - bool restart_button_visible_; - - // The text to display as the main label of the About box. We draw this text - // word for word with the help of the WordIterator, and make room for URLs - // which are drawn using views::Link. See also |url_offsets_|. - std::wstring main_label_chunk1_; - std::wstring main_label_chunk2_; - std::wstring main_label_chunk3_; - std::wstring main_label_chunk4_; - std::wstring main_label_chunk5_; - // Determines the order of the two links we draw in the main label. - bool chromium_url_appears_first_; - -#if defined(OS_WIN) || defined(OS_CHROMEOS) - // The class that communicates with Google Update to find out if an update is - // available and asks it to start an upgrade. - scoped_refptr<GoogleUpdate> google_updater_; -#endif - - // Our current version. - std::wstring current_version_; - - // Additional information about the version (channel and build number). - std::wstring version_details_; - - // The version Google Update reports is available to us. - std::wstring new_version_available_; - - // Whether text direction is left-to-right or right-to-left. - bool text_direction_is_rtl_; - -#if defined(OS_CHROMEOS) - // Handles asynchronously loading the version. - chromeos::VersionLoader loader_; - - // Used to request the version. - CancelableRequestConsumer consumer_; -#endif - - scoped_ptr<AccessibleViewHelper> accessible_view_helper_; - - DISALLOW_COPY_AND_ASSIGN(AboutChromeView); -}; +#include "chrome/browser/ui/views/about_chrome_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_ABOUT_CHROME_VIEW_H_ + diff --git a/chrome/browser/views/about_ipc_dialog.cc b/chrome/browser/views/about_ipc_dialog.cc deleted file mode 100644 index 358e28f..0000000 --- a/chrome/browser/views/about_ipc_dialog.cc +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (c) 2009 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. - -// Need to include this before any other file because it defines -// IPC_MESSAGE_LOG_ENABLED. We need to use it to define -// IPC_MESSAGE_MACROS_LOG_ENABLED so render_messages.h will generate the -// ViewMsgLog et al. functions. -#include "ipc/ipc_message.h" - -#ifdef IPC_MESSAGE_LOG_ENABLED -#define IPC_MESSAGE_MACROS_LOG_ENABLED - -#include "chrome/browser/views/about_ipc_dialog.h" - -#include <set> - -#include "base/string_util.h" -#include "base/thread.h" -#include "base/time.h" -#include "base/utf_string_conversions.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/browser_process.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/devtools_messages.h" -#include "chrome/common/plugin_messages.h" -#include "chrome/common/render_messages.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_job.h" -#include "net/url_request/url_request_job_tracker.h" -#include "views/grid_layout.h" -#include "views/controls/button/text_button.h" -#include "views/controls/native/native_view_host.h" -#include "views/standard_layout.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -namespace { - -// We don't localize this UI since this is a developer-only feature. -const wchar_t kStartTrackingLabel[] = L"Start tracking"; -const wchar_t kStopTrackingLabel[] = L"Stop tracking"; -const wchar_t kClearLabel[] = L"Clear"; -const wchar_t kFilterLabel[] = L"Filter..."; - -enum { - kTimeColumn = 0, - kChannelColumn, - kMessageColumn, - kFlagsColumn, - kDispatchColumn, - kProcessColumn, - kParamsColumn, -}; - -// This class registers the browser IPC logger functions with IPC::Logging. -class RegisterLoggerFuncs { - public: - RegisterLoggerFuncs() { - IPC::Logging::SetLoggerFunctions(g_log_function_mapping); - } -}; - -RegisterLoggerFuncs g_register_logger_funcs; - -// The singleton dialog box. This is non-NULL when a dialog is active so we -// know not to create a new one. -AboutIPCDialog* active_dialog = NULL; - -std::set<int> disabled_messages; - -// Settings dialog ------------------------------------------------------------- - -bool init_done = false; -HWND settings_dialog = NULL; - -// Settings lists. -struct Settings { - CListViewCtrl* view; - CListViewCtrl* view_host; - CListViewCtrl* plugin; - CListViewCtrl* plugin_host; - CListViewCtrl* npobject; - CListViewCtrl* plugin_process; - CListViewCtrl* plugin_process_host; - CListViewCtrl* devtools_agent; - CListViewCtrl* devtools_client; - -} settings_views = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - -void CreateColumn(uint32 start, uint32 end, HWND hwnd, - CListViewCtrl** control) { - DCHECK(*control == NULL); - *control = new CListViewCtrl(hwnd); - CListViewCtrl* control_ptr = *control; - control_ptr->SetViewType(LVS_REPORT); - control_ptr->SetExtendedListViewStyle(LVS_EX_CHECKBOXES); - control_ptr->ModifyStyle(0, LVS_SORTASCENDING | LVS_NOCOLUMNHEADER); - control_ptr->InsertColumn(0, L"id", LVCFMT_LEFT, 230); - - for (uint32 i = start; i < end; i++) { - std::string name; - IPC::Logging::GetMessageText(i, &name, NULL, NULL); - std::wstring wname = UTF8ToWide(name); - - int index = control_ptr->InsertItem( - LVIF_TEXT | LVIF_PARAM, 0, wname.c_str(), 0, 0, 0, i); - - control_ptr->SetItemText(index, 0, wname.c_str()); - - if (disabled_messages.find(i) == disabled_messages.end()) - control_ptr->SetCheckState(index, TRUE); - } -} - -void OnCheck(int id, bool checked) { - if (!init_done) - return; - - if (checked) - disabled_messages.erase(id); - else - disabled_messages.insert(id); -} - - -void CheckButtons(CListViewCtrl* control, bool check) { - int count = control->GetItemCount(); - for (int i = 0; i < count; ++i) - control->SetCheckState(i, check); -} - -void InitDialog(HWND hwnd) { - CreateColumn(ViewStart, ViewEnd, ::GetDlgItem(hwnd, IDC_View), - &settings_views.view); - CreateColumn(ViewHostStart, ViewHostEnd, ::GetDlgItem(hwnd, IDC_ViewHost), - &settings_views.view_host); - CreateColumn(PluginStart, PluginEnd, ::GetDlgItem(hwnd, IDC_Plugin), - &settings_views.plugin); - CreateColumn(PluginHostStart, PluginHostEnd, - ::GetDlgItem(hwnd, IDC_PluginHost), - &settings_views.plugin_host); - CreateColumn(NPObjectStart, NPObjectEnd, ::GetDlgItem(hwnd, IDC_NPObject), - &settings_views.npobject); - CreateColumn(PluginProcessStart, PluginProcessEnd, - ::GetDlgItem(hwnd, IDC_PluginProcess), - &settings_views.plugin_process); - CreateColumn(PluginProcessHostStart, PluginProcessHostEnd, - ::GetDlgItem(hwnd, IDC_PluginProcessHost), - &settings_views.plugin_process_host); - CreateColumn(DevToolsAgentStart, DevToolsAgentEnd, - ::GetDlgItem(hwnd, IDC_DevToolsAgent), - &settings_views.devtools_agent); - CreateColumn(DevToolsClientStart, DevToolsClientEnd, - ::GetDlgItem(hwnd, IDC_DevToolsClient), - &settings_views.devtools_client); - init_done = true; -} - -void CloseDialog() { - delete settings_views.view; - delete settings_views.view_host; - delete settings_views.plugin_host; - delete settings_views.npobject; - delete settings_views.plugin_process; - delete settings_views.plugin_process_host; - delete settings_views.devtools_agent; - delete settings_views.devtools_client; - settings_views.view = NULL; - settings_views.view_host = NULL; - settings_views.plugin = NULL; - settings_views.plugin_host = NULL; - settings_views.npobject = NULL; - settings_views.plugin_process = NULL; - settings_views.plugin_process_host = NULL; - settings_views.devtools_agent = NULL; - settings_views.devtools_client = NULL; - - init_done = false; - - ::DestroyWindow(settings_dialog); - settings_dialog = NULL; - - /* The old version of this code stored the last settings in the preferences. - But with this dialog, there currently isn't an easy way to get the profile - to asave in the preferences. - Profile* current_profile = profile(); - if (!current_profile) - return; - PrefService* prefs = current_profile->GetPrefs(); - if (!prefs->FindPreference(prefs::kIpcDisabledMessages)) - return; - ListValue* list = prefs->GetMutableList(prefs::kIpcDisabledMessages); - list->Clear(); - for (std::set<int>::const_iterator itr = disabled_messages_.begin(); - itr != disabled_messages_.end(); - ++itr) { - list->Append(Value::CreateIntegerValue(*itr)); - } - */ -} - -void OnButtonClick(int id) { - switch (id) { - case IDC_ViewAll: - CheckButtons(settings_views.view, true); - break; - case IDC_ViewNone: - CheckButtons(settings_views.view, false); - break; - case IDC_ViewHostAll: - CheckButtons(settings_views.view_host, true); - break; - case IDC_ViewHostNone: - CheckButtons(settings_views.view_host, false); - break; - case IDC_PluginAll: - CheckButtons(settings_views.plugin, true); - break; - case IDC_PluginNone: - CheckButtons(settings_views.plugin, false); - break; - case IDC_PluginHostAll: - CheckButtons(settings_views.plugin_host, true); - break; - case IDC_PluginHostNone: - CheckButtons(settings_views.plugin_host, false); - break; - case IDC_NPObjectAll: - CheckButtons(settings_views.npobject, true); - break; - case IDC_NPObjectNone: - CheckButtons(settings_views.npobject, false); - break; - } -} - -INT_PTR CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - switch (msg) { - case WM_INITDIALOG: - InitDialog(hwnd); - return FALSE; // Don't set keyboard focus. - case WM_SYSCOMMAND: - if (wparam == SC_CLOSE) { - CloseDialog(); - return FALSE; - } - break; - case WM_NOTIFY: { - NMLISTVIEW* info = reinterpret_cast<NM_LISTVIEW*>(lparam); - if ((wparam == IDC_View || wparam == IDC_ViewHost || - wparam == IDC_Plugin || - wparam == IDC_PluginHost || wparam == IDC_NPObject || - wparam == IDC_PluginProcess || wparam == IDC_PluginProcessHost) && - info->hdr.code == LVN_ITEMCHANGED) { - if (info->uChanged & LVIF_STATE) { - bool checked = (info->uNewState >> 12) == 2; - OnCheck(static_cast<int>(info->lParam), checked); - } - return FALSE; - } - break; - } - case WM_COMMAND: - if (HIWORD(wparam) == BN_CLICKED) - OnButtonClick(LOWORD(wparam)); - break; - } - return FALSE; -} - -void RunSettingsDialog(HWND parent) { - if (settings_dialog) - return; - HINSTANCE module_handle = GetModuleHandle(chrome::kBrowserResourcesDll); - settings_dialog = CreateDialog(module_handle, - MAKEINTRESOURCE(IDD_IPC_SETTINGS), - NULL, - &DialogProc); - ::ShowWindow(settings_dialog, SW_SHOW); -} - -} // namespace - -// AboutIPCDialog -------------------------------------------------------------- - -AboutIPCDialog::AboutIPCDialog() - : track_toggle_(NULL), - clear_button_(NULL), - filter_button_(NULL), - table_(NULL), - tracking_(false) { - SetupControls(); - IPC::Logging::current()->SetConsumer(this); -} - -AboutIPCDialog::~AboutIPCDialog() { - active_dialog = NULL; - IPC::Logging::current()->SetConsumer(NULL); -} - -// static -void AboutIPCDialog::RunDialog() { - if (!active_dialog) { - active_dialog = new AboutIPCDialog; - views::Window::CreateChromeWindow(NULL, gfx::Rect(), active_dialog)->Show(); - } else { - // TOOD(brettw) it would be nice to focus the existing window. - } -} - -void AboutIPCDialog::SetupControls() { - views::GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - track_toggle_ = new views::TextButton(this, kStartTrackingLabel); - clear_button_ = new views::TextButton(this, kClearLabel); - filter_button_ = new views::TextButton(this, kFilterLabel); - - table_ = new views::NativeViewHost; - - static const int first_column_set = 1; - views::ColumnSet* column_set = layout->AddColumnSet(first_column_set); - column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, - 33.33f, views::GridLayout::FIXED, 0, 0); - column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, - 33.33f, views::GridLayout::FIXED, 0, 0); - column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, - 33.33f, views::GridLayout::FIXED, 0, 0); - - static const int table_column_set = 2; - column_set = layout->AddColumnSet(table_column_set); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, - 100.0f, views::GridLayout::FIXED, 0, 0); - - layout->StartRow(0, first_column_set); - layout->AddView(track_toggle_); - layout->AddView(clear_button_); - layout->AddView(filter_button_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(1.0f, table_column_set); - layout->AddView(table_); -} - -gfx::Size AboutIPCDialog::GetPreferredSize() { - return gfx::Size(800, 400); -} - -views::View* AboutIPCDialog::GetContentsView() { - return this; -} - -int AboutIPCDialog::GetDialogButtons() const { - // Don't want OK or Cancel. - return 0; -} - -std::wstring AboutIPCDialog::GetWindowTitle() const { - return L"about:ipc"; -} - -void AboutIPCDialog::Layout() { - if (!message_list_.m_hWnd) { - HWND parent_window = GetRootView()->GetWidget()->GetNativeView(); - - RECT rect = {0, 0, 10, 10}; - HWND list_hwnd = message_list_.Create(parent_window, - rect, NULL, WS_CHILD | WS_VISIBLE | LVS_SORTASCENDING); - message_list_.SetViewType(LVS_REPORT); - message_list_.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); - - int column_index = 0; - message_list_.InsertColumn(kTimeColumn, L"time", LVCFMT_LEFT, 80); - message_list_.InsertColumn(kChannelColumn, L"channel", LVCFMT_LEFT, 110); - message_list_.InsertColumn(kMessageColumn, L"message", LVCFMT_LEFT, 240); - message_list_.InsertColumn(kFlagsColumn, L"flags", LVCFMT_LEFT, 50); - message_list_.InsertColumn(kDispatchColumn, L"dispatch (ms)", LVCFMT_RIGHT, - 80); - message_list_.InsertColumn(kProcessColumn, L"process (ms)", LVCFMT_RIGHT, - 80); - message_list_.InsertColumn(kParamsColumn, L"parameters", LVCFMT_LEFT, 500); - - table_->Attach(list_hwnd); - } - - View::Layout(); -} - -void AboutIPCDialog::Log(const IPC::LogData& data) { - if (disabled_messages.find(data.type) != disabled_messages.end()) - return; // Message type is filtered out. - - base::Time sent = base::Time::FromInternalValue(data.sent); - base::Time::Exploded exploded; - sent.LocalExplode(&exploded); - if (exploded.hour > 12) - exploded.hour -= 12; - - std::wstring sent_str = StringPrintf(L"%02d:%02d:%02d.%03d", - exploded.hour, exploded.minute, exploded.second, exploded.millisecond); - - int count = message_list_.GetItemCount(); - int index = message_list_.InsertItem(count, sent_str.c_str()); - - message_list_.SetItemText(index, kTimeColumn, sent_str.c_str()); - message_list_.SetItemText(index, kChannelColumn, - ASCIIToWide(data.channel).c_str()); - - std::string message_name; - IPC::Logging::GetMessageText(data.type, &message_name, NULL, NULL); - message_list_.SetItemText(index, kMessageColumn, - UTF8ToWide(message_name).c_str()); - message_list_.SetItemText(index, kFlagsColumn, - UTF8ToWide(data.flags).c_str()); - - int64 time_to_send = (base::Time::FromInternalValue(data.receive) - - sent).InMilliseconds(); - // time can go backwards by a few ms (see Time), don't show that. - time_to_send = std::max(static_cast<int>(time_to_send), 0); - std::wstring temp = StringPrintf(L"%d", time_to_send); - message_list_.SetItemText(index, kDispatchColumn, temp.c_str()); - - int64 time_to_process = (base::Time::FromInternalValue(data.dispatch) - - base::Time::FromInternalValue(data.receive)).InMilliseconds(); - time_to_process = std::max(static_cast<int>(time_to_process), 0); - temp = StringPrintf(L"%d", time_to_process); - message_list_.SetItemText(index, kProcessColumn, temp.c_str()); - - message_list_.SetItemText(index, kParamsColumn, - UTF8ToWide(data.params).c_str()); - message_list_.EnsureVisible(index, FALSE); -} - -bool AboutIPCDialog::CanResize() const { - return true; -} - -void AboutIPCDialog::ButtonPressed( - views::Button* button, const views::Event& event) { - if (button == track_toggle_) { - if (tracking_) { - track_toggle_->SetText(kStartTrackingLabel); - tracking_ = false; - g_browser_process->SetIPCLoggingEnabled(false); - } else { - track_toggle_->SetText(kStopTrackingLabel); - tracking_ = true; - g_browser_process->SetIPCLoggingEnabled(true); - } - track_toggle_->SchedulePaint(); - } else if (button == clear_button_) { - message_list_.DeleteAllItems(); - } else if (button == filter_button_) { - RunSettingsDialog(GetRootView()->GetWidget()->GetNativeView()); - } -} - -#endif // IPC_MESSAGE_LOG_ENABLED diff --git a/chrome/browser/views/about_ipc_dialog.h b/chrome/browser/views/about_ipc_dialog.h index 9594c8b..13c1255 100644 --- a/chrome/browser/views/about_ipc_dialog.h +++ b/chrome/browser/views/about_ipc_dialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,74 +6,8 @@ #define CHROME_BROWSER_VIEWS_ABOUT_IPC_DIALOG_H_ #pragma once -#if defined(OS_WIN) && defined(IPC_MESSAGE_LOG_ENABLED) - -#include <atlbase.h> -#include <atlapp.h> -#include <atlwin.h> -#include <atlctrls.h> - -#include "base/singleton.h" -#include "ipc/ipc_logging.h" -#include "views/controls/button/button.h" -#include "views/controls/table/table_view.h" -#include "views/window/dialog_delegate.h" - - -class Profile; -namespace views { -class NativeViewHost; -class TextButton; -} // namespace views - -class AboutIPCDialog : public views::DialogDelegate, - public views::ButtonListener, - public IPC::Logging::Consumer, - public views::View { - public: - // This dialog is a singleton. If the dialog is already opened, it won't do - // anything, so you can just blindly call this function all you want. - static void RunDialog(); - - virtual ~AboutIPCDialog(); - - private: - friend struct DefaultSingletonTraits<AboutIPCDialog>; - - AboutIPCDialog(); - - // Sets up all UI controls for the dialog. - void SetupControls(); - - // views::View overrides. - virtual gfx::Size GetPreferredSize(); - virtual views::View* GetContentsView(); - virtual int GetDialogButtons() const; - virtual std::wstring GetWindowTitle() const; - virtual void Layout(); - - // IPC::Logging::Consumer implementation. - virtual void Log(const IPC::LogData& data); - - // views::WindowDelegate (via view::DialogDelegate). - virtual bool CanResize() const; - - // views::ButtonListener. - virtual void ButtonPressed(views::Button* button, const views::Event& event); - - WTL::CListViewCtrl message_list_; - - views::TextButton* track_toggle_; - views::TextButton* clear_button_; - views::TextButton* filter_button_; - views::NativeViewHost* table_; - - // Set to true when we're tracking network status. - bool tracking_; - - DISALLOW_COPY_AND_ASSIGN(AboutIPCDialog); -}; - -#endif // OS_WIN && IPC_MESSAGE_LOG_ENABLED +#include "chrome/browser/ui/views/about_ipc_dialog.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_ABOUT_IPC_DIALOG_H_ + diff --git a/chrome/browser/views/accelerator_table_gtk.cc b/chrome/browser/views/accelerator_table_gtk.cc deleted file mode 100644 index 261420e..0000000 --- a/chrome/browser/views/accelerator_table_gtk.cc +++ /dev/null @@ -1,159 +0,0 @@ -// 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/accelerator_table_gtk.h" - -#include "app/keyboard_codes.h" -#include "base/basictypes.h" -#include "chrome/app/chrome_command_ids.h" - -namespace browser { - -// NOTE: Keep this list in the same (mostly-alphabetical) order as -// the Windows accelerators in ../../app/chrome_dll.rc. -const AcceleratorMapping kAcceleratorMap[] = { - // Keycode Shift Ctrl Alt Command ID - { app::VKEY_A, true, true, false, IDC_AUTOFILL_DEFAULT }, - { app::VKEY_LEFT, false, false, true, IDC_BACK }, - { app::VKEY_BACK, false, false, false, IDC_BACK }, -#if defined(OS_CHROMEOS) - { app::VKEY_F1, false, false, false, IDC_BACK }, -#endif - { app::VKEY_D, false, true, false, IDC_BOOKMARK_PAGE }, - { app::VKEY_D, true, true, false, IDC_BOOKMARK_ALL_TABS }, - { app::VKEY_DELETE, true, true, false, IDC_CLEAR_BROWSING_DATA }, -#if !defined(OS_CHROMEOS) - { app::VKEY_F4, false, true, false, IDC_CLOSE_TAB }, -#endif - { app::VKEY_W, false, true, false, IDC_CLOSE_TAB }, - { app::VKEY_W, true, true, false, IDC_CLOSE_WINDOW }, -#if !defined(OS_CHROMEOS) - { app::VKEY_F4, false, false, true, IDC_CLOSE_WINDOW }, -#endif - { app::VKEY_Q, true, true, false, IDC_EXIT }, - { app::VKEY_F, false, true, false, IDC_FIND }, - { app::VKEY_G, false, true, false, IDC_FIND_NEXT }, -#if !defined(OS_CHROMEOS) - { app::VKEY_F3, false, false, false, IDC_FIND_NEXT }, -#endif - { app::VKEY_G, true, true, false, IDC_FIND_PREVIOUS }, -#if !defined(OS_CHROMEOS) - { app::VKEY_F3, true, false, false, IDC_FIND_PREVIOUS }, -#endif -#if defined(OS_CHROMEOS) - { app::VKEY_S, true, false, true, IDC_FOCUS_CHROMEOS_STATUS }, -#endif - { app::VKEY_D, false, false, true, IDC_FOCUS_LOCATION }, - { app::VKEY_L, false, true, false, IDC_FOCUS_LOCATION }, -#if !defined(OS_CHROMEOS) - { app::VKEY_F10, false, false, false, IDC_FOCUS_MENU_BAR }, -#endif - { app::VKEY_MENU, false, false, false, IDC_FOCUS_MENU_BAR }, -#if !defined(OS_CHROMEOS) - { app::VKEY_F6, false, false, false, IDC_FOCUS_NEXT_PANE }, -#endif -#if defined(OS_CHROMEOS) - { app::VKEY_F2, false, true, false, IDC_FOCUS_NEXT_PANE }, -#endif -#if !defined(OS_CHROMEOS) - { app::VKEY_F6, true, false, false, IDC_FOCUS_PREVIOUS_PANE }, -#endif -#if defined(OS_CHROMEOS) - { app::VKEY_F1, false, true, false, IDC_FOCUS_PREVIOUS_PANE }, -#endif - { app::VKEY_K, false, true, false, IDC_FOCUS_SEARCH }, - { app::VKEY_E, false, true, false, IDC_FOCUS_SEARCH }, - { app::VKEY_BROWSER_SEARCH, false, false, false, IDC_FOCUS_SEARCH }, - { app::VKEY_T, true, false, true, IDC_FOCUS_TOOLBAR }, - { app::VKEY_B, true, false, true, IDC_FOCUS_BOOKMARKS }, - { app::VKEY_RIGHT, false, false, true, IDC_FORWARD }, - { app::VKEY_BACK, true, false, false, IDC_FORWARD }, -#if defined(OS_CHROMEOS) - { app::VKEY_F2, false, false, false, IDC_FORWARD }, -#endif -#if !defined(OS_CHROMEOS) - { app::VKEY_F11, false, false, false, IDC_FULLSCREEN }, -#endif -#if defined(OS_CHROMEOS) - { app::VKEY_F4, false, false, false, IDC_FULLSCREEN }, -#endif -#if !defined(OS_CHROMEOS) - { app::VKEY_F1, false, false, false, IDC_HELP_PAGE }, -#endif -#if defined(OS_CHROMEOS) - { app::VKEY_OEM_2, false, true, false, IDC_HELP_PAGE }, - { app::VKEY_OEM_2, true, true, false, IDC_HELP_PAGE }, -#endif - { app::VKEY_I, true, true, false, IDC_DEV_TOOLS }, - { app::VKEY_J, true, true, false, IDC_DEV_TOOLS_CONSOLE }, - { app::VKEY_C, true, true, false, IDC_DEV_TOOLS_INSPECT }, - { app::VKEY_N, true, true, false, IDC_NEW_INCOGNITO_WINDOW }, - { app::VKEY_T, false, true, false, IDC_NEW_TAB }, - { app::VKEY_N, false, true, false, IDC_NEW_WINDOW }, - { app::VKEY_O, false, true, false, IDC_OPEN_FILE }, - { app::VKEY_P, false, true, false, IDC_PRINT}, - { app::VKEY_R, false, true, false, IDC_RELOAD }, - { app::VKEY_R, true, true, false, IDC_RELOAD_IGNORING_CACHE }, -#if !defined(OS_CHROMEOS) - { app::VKEY_F5, false, false, false, IDC_RELOAD }, - { app::VKEY_F5, false, true, false, IDC_RELOAD_IGNORING_CACHE }, - { app::VKEY_F5, true, false, false, IDC_RELOAD_IGNORING_CACHE }, -#endif -#if defined(OS_CHROMEOS) - { app::VKEY_F3, false, false, false, IDC_RELOAD }, - { app::VKEY_F3, false, true, false, IDC_RELOAD_IGNORING_CACHE }, - { app::VKEY_F3, true, false, false, IDC_RELOAD_IGNORING_CACHE }, -#endif - { app::VKEY_HOME, false, false, true, IDC_HOME }, - { app::VKEY_T, true, true, false, IDC_RESTORE_TAB }, - { app::VKEY_S, false, true, false, IDC_SAVE_PAGE }, -#if defined(OS_CHROMEOS) - { app::VKEY_LWIN, false, false, false, IDC_SEARCH }, -#endif - { app::VKEY_9, false, true, false, IDC_SELECT_LAST_TAB }, - { app::VKEY_NUMPAD9, false, true, false, IDC_SELECT_LAST_TAB }, - { app::VKEY_TAB, false, true, false, IDC_SELECT_NEXT_TAB }, - { app::VKEY_NEXT, false, true, false, IDC_SELECT_NEXT_TAB }, - { app::VKEY_TAB, true, true, false, IDC_SELECT_PREVIOUS_TAB }, - { app::VKEY_PRIOR, false, true, false, IDC_SELECT_PREVIOUS_TAB }, - { app::VKEY_1, false, true, false, IDC_SELECT_TAB_0 }, - { app::VKEY_NUMPAD1, false, true, false, IDC_SELECT_TAB_0 }, - { app::VKEY_2, false, true, false, IDC_SELECT_TAB_1 }, - { app::VKEY_NUMPAD2, false, true, false, IDC_SELECT_TAB_1 }, - { app::VKEY_3, false, true, false, IDC_SELECT_TAB_2 }, - { app::VKEY_NUMPAD3, false, true, false, IDC_SELECT_TAB_2 }, - { app::VKEY_4, false, true, false, IDC_SELECT_TAB_3 }, - { app::VKEY_NUMPAD4, false, true, false, IDC_SELECT_TAB_3 }, - { app::VKEY_5, false, true, false, IDC_SELECT_TAB_4 }, - { app::VKEY_NUMPAD5, false, true, false, IDC_SELECT_TAB_4 }, - { app::VKEY_6, false, true, false, IDC_SELECT_TAB_5 }, - { app::VKEY_NUMPAD6, false, true, false, IDC_SELECT_TAB_5 }, - { app::VKEY_7, false, true, false, IDC_SELECT_TAB_6 }, - { app::VKEY_NUMPAD7, false, true, false, IDC_SELECT_TAB_6 }, - { app::VKEY_8, false, true, false, IDC_SELECT_TAB_7 }, - { app::VKEY_NUMPAD8, false, true, false, IDC_SELECT_TAB_7 }, - { app::VKEY_B, true, true, false, IDC_SHOW_BOOKMARK_BAR }, - { app::VKEY_J, false, true, false, IDC_SHOW_DOWNLOADS }, - { app::VKEY_H, false, true, false, IDC_SHOW_HISTORY }, - { app::VKEY_F, false, false, true, IDC_SHOW_APP_MENU}, - { app::VKEY_E, false, false, true, IDC_SHOW_APP_MENU}, - { app::VKEY_ESCAPE, false, false, false, IDC_STOP }, -#if defined(OS_CHROMEOS) - { app::VKEY_F5, false, false, false, IDC_SYSTEM_OPTIONS }, -#endif - { app::VKEY_ESCAPE, true, false, false, IDC_TASK_MANAGER }, - { app::VKEY_U, false, true, false, IDC_VIEW_SOURCE }, - { app::VKEY_OEM_MINUS, false, true, false, IDC_ZOOM_MINUS }, - { app::VKEY_OEM_MINUS, true, true, false, IDC_ZOOM_MINUS }, - { app::VKEY_SUBTRACT, false, true, false, IDC_ZOOM_MINUS }, - { app::VKEY_0, false, true, false, IDC_ZOOM_NORMAL }, - { app::VKEY_NUMPAD0, false, true, false, IDC_ZOOM_NORMAL }, - { app::VKEY_OEM_PLUS, false, true, false, IDC_ZOOM_PLUS }, - { app::VKEY_OEM_PLUS, true, true, false, IDC_ZOOM_PLUS }, - { app::VKEY_ADD, false, true, false, IDC_ZOOM_PLUS }, -}; - -const size_t kAcceleratorMapLength = arraysize(kAcceleratorMap); - -} // namespace browser diff --git a/chrome/browser/views/accelerator_table_gtk.h b/chrome/browser/views/accelerator_table_gtk.h index bbab634..1b3a20a 100644 --- a/chrome/browser/views/accelerator_table_gtk.h +++ b/chrome/browser/views/accelerator_table_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,27 +6,8 @@ #define CHROME_BROWSER_VIEWS_ACCELERATOR_TABLE_GTK_H_ #pragma once -#include <stdio.h> - -#include "app/keyboard_codes.h" - -// This contains the list of accelerators for the Linux toolkit_view -// implementation. -namespace browser { - - struct AcceleratorMapping { - app::KeyboardCode keycode; - bool shift_pressed; - bool ctrl_pressed; - bool alt_pressed; - int command_id; - }; - - // The list of accelerators. - extern const AcceleratorMapping kAcceleratorMap[]; - - // The numbers of elements in kAcceleratorMap. - extern const size_t kAcceleratorMapLength; -} +#include "chrome/browser/ui/views/accelerator_table_gtk.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_ACCELERATOR_TABLE_GTK_H_ + diff --git a/chrome/browser/views/accessibility_event_router_views.cc b/chrome/browser/views/accessibility_event_router_views.cc deleted file mode 100644 index 4b1ad00..0000000 --- a/chrome/browser/views/accessibility_event_router_views.cc +++ /dev/null @@ -1,305 +0,0 @@ -// 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/accessibility_event_router_views.h" - -#include "base/basictypes.h" -#include "base/callback.h" -#include "base/message_loop.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/extensions/extension_accessibility_api.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/profile_manager.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "chrome/common/notification_type.h" -#include "views/accessibility/accessibility_types.h" -#include "views/controls/button/custom_button.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/button/native_button.h" -#include "views/controls/link.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/controls/menu/submenu_view.h" -#include "views/view.h" - -#if defined(OS_WIN) -#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" -#endif - -using views::FocusManager; - -AccessibilityEventRouterViews::AccessibilityEventRouterViews() - : most_recent_profile_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { -} - -AccessibilityEventRouterViews::~AccessibilityEventRouterViews() { -} - -// static -AccessibilityEventRouterViews* AccessibilityEventRouterViews::GetInstance() { - return Singleton<AccessibilityEventRouterViews>::get(); -} - -bool AccessibilityEventRouterViews::AddViewTree( - views::View* view, Profile* profile) { - if (view_tree_profile_map_[view] != NULL) - return false; - - view_tree_profile_map_[view] = profile; - return true; -} - -void AccessibilityEventRouterViews::RemoveViewTree(views::View* view) { - DCHECK(view_tree_profile_map_.find(view) != - view_tree_profile_map_.end()); - view_tree_profile_map_.erase(view); -} - -void AccessibilityEventRouterViews::IgnoreView(views::View* view) { - view_info_map_[view].ignore = true; -} - -void AccessibilityEventRouterViews::SetViewName( - views::View* view, std::string name) { - view_info_map_[view].name = name; -} - -void AccessibilityEventRouterViews::RemoveView(views::View* view) { - DCHECK(view_info_map_.find(view) != view_info_map_.end()); - view_info_map_.erase(view); -} - -void AccessibilityEventRouterViews::HandleAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type) { - if (!ExtensionAccessibilityEventRouter::GetInstance()-> - IsAccessibilityEnabled()) { - return; - } - - switch (event_type) { - case AccessibilityTypes::EVENT_FOCUS: - DispatchAccessibilityNotification( - view, NotificationType::ACCESSIBILITY_CONTROL_FOCUSED); - break; - case AccessibilityTypes::EVENT_MENUSTART: - case AccessibilityTypes::EVENT_MENUPOPUPSTART: - DispatchAccessibilityNotification( - view, NotificationType::ACCESSIBILITY_MENU_OPENED); - break; - case AccessibilityTypes::EVENT_MENUEND: - case AccessibilityTypes::EVENT_MENUPOPUPEND: - DispatchAccessibilityNotification( - view, NotificationType::ACCESSIBILITY_MENU_CLOSED); - break; - case AccessibilityTypes::EVENT_TEXT_CHANGED: - case AccessibilityTypes::EVENT_SELECTION_CHANGED: - DispatchAccessibilityNotification( - view, NotificationType::ACCESSIBILITY_TEXT_CHANGED); - break; - case AccessibilityTypes::EVENT_VALUE_CHANGED: - DispatchAccessibilityNotification( - view, NotificationType::ACCESSIBILITY_CONTROL_ACTION); - break; - case AccessibilityTypes::EVENT_ALERT: - case AccessibilityTypes::EVENT_NAME_CHANGED: - // TODO(dmazzoni): re-evaluate this list later and see - // if supporting any of these would be useful feature requests or - // they'd just be superfluous. - NOTIMPLEMENTED(); - break; - } -} - -// -// Private methods -// - -void AccessibilityEventRouterViews::FindView( - views::View* view, Profile** profile, bool* is_accessible) { - *is_accessible = false; - - // First see if it's a descendant of an accessible view. - for (base::hash_map<views::View*, Profile*>::const_iterator iter = - view_tree_profile_map_.begin(); - iter != view_tree_profile_map_.end(); - ++iter) { - if (iter->first->IsParentOf(view)) { - *is_accessible = true; - if (profile) - *profile = iter->second; - break; - } - } - - if (!*is_accessible) - return; - - // Now make sure it's not marked as a widget to be ignored. - base::hash_map<views::View*, ViewInfo>::const_iterator iter = - view_info_map_.find(view); - if (iter != view_info_map_.end() && iter->second.ignore) - *is_accessible = false; -} - -std::string AccessibilityEventRouterViews::GetViewName(views::View* view) { - std::string name; - - // First see if we have a name registered for this view. - base::hash_map<views::View*, ViewInfo>::const_iterator iter = - view_info_map_.find(view); - if (iter != view_info_map_.end()) - name = iter->second.name; - - // Otherwise ask the view for its accessible name. - if (name.empty()) { - std::wstring wname; - view->GetAccessibleName(&wname); - name = WideToUTF8(wname); - } - - return name; -} - -void AccessibilityEventRouterViews::DispatchAccessibilityNotification( - views::View* view, NotificationType type) { - Profile* profile = NULL; - bool is_accessible; - FindView(view, &profile, &is_accessible); - - // Special case: a menu isn't associated with any particular top-level - // window, so menu events get routed to the profile of the most recent - // event that was associated with a window, which should be the window - // that triggered opening the menu. - bool is_menu_event = IsMenuEvent(view, type); - if (is_menu_event && !profile && most_recent_profile_) { - profile = most_recent_profile_; - is_accessible = true; - } - - if (!is_accessible) - return; - - most_recent_profile_ = profile; - - std::string class_name = view->GetClassName(); - - if (class_name == views::MenuButton::kViewClassName || - type == NotificationType::ACCESSIBILITY_MENU_OPENED || - type == NotificationType::ACCESSIBILITY_MENU_CLOSED) { - SendMenuNotification(view, type, profile); - } else if (is_menu_event) { - SendMenuItemNotification(view, type, profile); - } else if (class_name == views::CustomButton::kViewClassName || - class_name == views::NativeButton::kViewClassName || - class_name == views::TextButton::kViewClassName) { - SendButtonNotification(view, type, profile); - } else if (class_name == views::Link::kViewClassName) { - SendLinkNotification(view, type, profile); - } else if (class_name == LocationBarView::kViewClassName) { - SendLocationBarNotification(view, type, profile); - } else { - class_name += " "; - } -} - -void AccessibilityEventRouterViews::SendButtonNotification( - views::View* view, NotificationType type, Profile* profile) { - AccessibilityButtonInfo info(profile, GetViewName(view)); - SendAccessibilityNotification(type, &info); -} - -void AccessibilityEventRouterViews::SendLinkNotification( - views::View* view, NotificationType type, Profile* profile) { - AccessibilityLinkInfo info(profile, GetViewName(view)); - SendAccessibilityNotification(type, &info); -} - -void AccessibilityEventRouterViews::SendMenuNotification( - views::View* view, NotificationType type, Profile* profile) { - AccessibilityMenuInfo info(profile, GetViewName(view)); - SendAccessibilityNotification(type, &info); -} - -void AccessibilityEventRouterViews::SendMenuItemNotification( - views::View* view, NotificationType type, Profile* profile) { - std::string name = GetViewName(view); - - bool has_submenu = false; - int index = -1; - int count = -1; - - if (view->GetClassName() == views::MenuItemView::kViewClassName) - has_submenu = static_cast<views::MenuItemView*>(view)->HasSubmenu(); - - views::View* parent_menu = view->GetParent(); - while (parent_menu != NULL && parent_menu->GetClassName() != - views::SubmenuView::kViewClassName) { - parent_menu = parent_menu->GetParent(); - } - if (parent_menu) { - count = 0; - RecursiveGetMenuItemIndexAndCount(parent_menu, view, &index, &count); - } - - AccessibilityMenuItemInfo info(profile, name, has_submenu, index, count); - SendAccessibilityNotification(type, &info); -} - -void AccessibilityEventRouterViews::RecursiveGetMenuItemIndexAndCount( - views::View* menu, views::View* item, int* index, int* count) { - for (int i = 0; i < menu->GetChildViewCount(); ++i) { - views::View* child = menu->GetChildViewAt(i); - int previous_count = *count; - RecursiveGetMenuItemIndexAndCount(child, item, index, count); - if (child->GetClassName() == views::MenuItemView::kViewClassName && - *count == previous_count) { - if (item == child) - *index = *count; - (*count)++; - } else if (child->GetClassName() == views::TextButton::kViewClassName) { - if (item == child) - *index = *count; - (*count)++; - } - } -} - -bool AccessibilityEventRouterViews::IsMenuEvent( - views::View* view, NotificationType type) { - if (type == NotificationType::ACCESSIBILITY_MENU_OPENED || - type == NotificationType::ACCESSIBILITY_MENU_CLOSED) - return true; - - while (view) { - AccessibilityTypes::Role role = view->GetAccessibleRole(); - if (role == AccessibilityTypes::ROLE_MENUITEM || - role == AccessibilityTypes::ROLE_MENUPOPUP) { - return true; - } - view = view->GetParent(); - } - - return false; -} - -void AccessibilityEventRouterViews::SendLocationBarNotification( - views::View* view, NotificationType type, Profile* profile) { -#if defined(OS_WIN) - // This particular method isn't needed on Linux/Views, we get text - // notifications directly from GTK. - std::string name = GetViewName(view); - LocationBarView* location_bar = static_cast<LocationBarView*>(view); - AutocompleteEditViewWin* location_entry = - static_cast<AutocompleteEditViewWin*>(location_bar->location_entry()); - - std::string value = WideToUTF8(location_entry->GetText()); - std::wstring::size_type selection_start; - std::wstring::size_type selection_end; - location_entry->GetSelectionBounds(&selection_start, &selection_end); - - AccessibilityTextBoxInfo info(profile, name, false); - info.SetValue(value, selection_start, selection_end); - SendAccessibilityNotification(type, &info); -#endif -} diff --git a/chrome/browser/views/accessibility_event_router_views.h b/chrome/browser/views/accessibility_event_router_views.h index 8e2b7b5..e3850b2 100644 --- a/chrome/browser/views/accessibility_event_router_views.h +++ b/chrome/browser/views/accessibility_event_router_views.h @@ -6,149 +6,8 @@ #define CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ #pragma once -#include <string> - -#include "base/basictypes.h" -#include "base/gtest_prod_util.h" -#include "base/hash_tables.h" -#include "base/singleton.h" -#include "base/task.h" -#include "chrome/browser/accessibility_events.h" -#include "views/accessibility/accessibility_types.h" - -class Profile; -namespace views { -class View; -} - -// Allows us to use (View*) in a hash_map with gcc. -#if defined(COMPILER_GCC) -namespace __gnu_cxx { -template<> -struct hash<views::View*> { - size_t operator()(views::View* view) const { - return reinterpret_cast<size_t>(view); - } -}; -} // namespace __gnu_cxx -#endif // defined(COMPILER_GCC) - -// NOTE: This class is part of the Accessibility Extension API, which lets -// extensions receive accessibility events. It's distinct from code that -// implements platform accessibility APIs like MSAA or ATK. -// -// Singleton class that adds listeners to many views, then sends an -// accessibility notification whenever a relevant event occurs in an -// accessible view. -// -// Views are not accessible by default. When you register a root widget, -// that widget and all of its descendants will start sending accessibility -// event notifications. You can then override the default behavior for -// specific descendants using other methods. -// -// You can use Profile::PauseAccessibilityEvents to prevent a flurry -// of accessibility events when a window is being created or initialized. -class AccessibilityEventRouterViews { - public: - // Internal information about a particular view to override the - // information we get directly from the view. - struct ViewInfo { - ViewInfo() : ignore(false) {} - - // If nonempty, will use this name instead of the view's label. - std::string name; - - // If true, will ignore this widget and not send accessibility events. - bool ignore; - }; - - // Get the single instance of this class. - static AccessibilityEventRouterViews* GetInstance(); - - // Start sending accessibility events for this view and all of its - // descendants. Notifications will go to the specified profile. - // Returns true on success, false if "view" was already registered. - // It is the responsibility of the caller to call RemoveViewTree if - // this view is ever deleted; consider using AccessibleViewHelper. - bool AddViewTree(views::View* view, Profile* profile); - - // Stop sending accessibility events for this view and all of its - // descendants. - void RemoveViewTree(views::View* view); - - // Don't send any events for this view. - void IgnoreView(views::View* view); - - // Use the following string as the name of this view, instead of the - // gtk label associated with the view. - void SetViewName(views::View* view, std::string name); - - // Forget all information about this view. - void RemoveView(views::View* view); - - // Handle an accessibility event generated by a view. - void HandleAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type); - - private: - AccessibilityEventRouterViews(); - virtual ~AccessibilityEventRouterViews(); - - friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>; - FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest, - TestFocusNotification); - - // Given a view, determine if it's part of a view tree that's mapped to - // a profile and if so, if it's marked as accessible. - void FindView(views::View* view, Profile** profile, bool* is_accessible); - - // Checks the type of the view and calls one of the more specific - // Send*Notification methods, below. - void DispatchAccessibilityNotification( - views::View* view, NotificationType type); - - // Return the name of a view. - std::string GetViewName(views::View* view); - - // Each of these methods constructs an AccessibilityControlInfo object - // and sends a notification of a specific accessibility event. - void SendButtonNotification( - views::View* view, NotificationType type, Profile* profile); - void SendLinkNotification( - views::View* view, NotificationType type, Profile* profile); - void SendMenuNotification( - views::View* view, NotificationType type, Profile* profile); - void SendMenuItemNotification( - views::View* view, NotificationType type, Profile* profile); - void SendLocationBarNotification( - views::View* view, NotificationType type, Profile* profile); - - // Return true if it's an event on a menu. - bool IsMenuEvent(views::View* view, NotificationType type); - - // Recursively explore all menu items of |menu| and return in |count| - // the total number of items, and in |index| the 0-based index of - // |item|, if found. Initialize |count| to zero before calling this - // method. |index| will be unchanged if the item is not found, so - // initialize it to -1 to detect this case. - void RecursiveGetMenuItemIndexAndCount( - views::View* menu, views::View* item, int* index, int* count); - - // The set of all view tree roots; only descendants of these will generate - // accessibility notifications. - base::hash_map<views::View*, Profile*> view_tree_profile_map_; - - // Extra information about specific views. - base::hash_map<views::View*, ViewInfo> view_info_map_; - - // The profile associated with the most recent window event - used to - // figure out where to route a few events that can't be directly traced - // to a window with a profile (like menu events). - Profile* most_recent_profile_; - - // Used to defer handling of some events until the next time - // through the event loop. - ScopedRunnableMethodFactory<AccessibilityEventRouterViews> method_factory_; -}; +#include "chrome/browser/ui/views/accessibility_event_router_views.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ + diff --git a/chrome/browser/views/accessibility_event_router_views_unittest.cc b/chrome/browser/views/accessibility_event_router_views_unittest.cc deleted file mode 100644 index 7e51ab2..0000000 --- a/chrome/browser/views/accessibility_event_router_views_unittest.cc +++ /dev/null @@ -1,174 +0,0 @@ -// 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 <string> - -#include "base/message_loop.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/extensions/extension_accessibility_api.h" -#include "chrome/browser/views/accessibility_event_router_views.h" -#include "chrome/browser/views/accessible_view_helper.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "chrome/test/testing_profile.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "views/controls/button/native_button.h" -#include "views/grid_layout.h" -#include "views/views_delegate.h" -#include "views/widget/root_view.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#elif defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -#if defined(TOOLKIT_VIEWS) - -class AccessibilityViewsDelegate : public views::ViewsDelegate { - public: - AccessibilityViewsDelegate() {} - virtual ~AccessibilityViewsDelegate() {} - - // Overridden from views::ViewsDelegate: - virtual Clipboard* GetClipboard() const { return NULL; } - virtual void SaveWindowPlacement(const std::wstring& window_name, - const gfx::Rect& bounds, - bool maximized) { - } - virtual bool GetSavedWindowBounds(const std::wstring& window_name, - gfx::Rect* bounds) const { - return false; - } - virtual bool GetSavedMaximizedState(const std::wstring& window_name, - bool* maximized) const { - return false; - } - virtual void NotifyAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type) { - AccessibilityEventRouterViews::GetInstance()->HandleAccessibilityEvent( - view, event_type); - } -#if defined(OS_WIN) - virtual HICON GetDefaultWindowIcon() const { - return NULL; - } -#endif - virtual void AddRef() {} - virtual void ReleaseRef() {} - - DISALLOW_COPY_AND_ASSIGN(AccessibilityViewsDelegate); -}; - -class AccessibilityEventRouterViewsTest - : public testing::Test, - public NotificationObserver { - public: - virtual void SetUp() { - views::ViewsDelegate::views_delegate = new AccessibilityViewsDelegate(); - } - - virtual void TearDown() { - delete views::ViewsDelegate::views_delegate; - views::ViewsDelegate::views_delegate = NULL; - } - - views::Widget* CreateWidget() { -#if defined(OS_WIN) - return new views::WidgetWin(); -#elif defined(OS_LINUX) - return new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW); -#endif - } - - protected: - // Implement NotificationObserver::Observe and store information about a - // ACCESSIBILITY_CONTROL_FOCUSED event. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - ASSERT_EQ(type.value, NotificationType::ACCESSIBILITY_CONTROL_FOCUSED); - const AccessibilityControlInfo* info = - Details<const AccessibilityControlInfo>(details).ptr(); - focus_event_count_++; - last_control_name_ = info->name(); - } - - MessageLoopForUI message_loop_; - int focus_event_count_; - std::string last_control_name_; -}; - -TEST_F(AccessibilityEventRouterViewsTest, TestFocusNotification) { - const char kButton1ASCII[] = "Button1"; - const char kButton2ASCII[] = "Button2"; - const char kButton3ASCII[] = "Button3"; - const char kButton3NewASCII[] = "Button3"; - - // Create a window and layout. - views::Widget* window = CreateWidget(); - window->Init(NULL, gfx::Rect(0, 0, 100, 100)); - views::RootView* root_view = window->GetRootView(); - views::GridLayout* layout = new views::GridLayout(root_view); - root_view->SetLayoutManager(layout); - views::ColumnSet* column_set = layout->AddColumnSet(0); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, - views::GridLayout::USE_PREF, 0, 0); - - // Add 3 buttons. - views::NativeButton* button1 = new views::NativeButton( - NULL, ASCIIToWide(kButton1ASCII)); - layout->StartRow(0, 0); - layout->AddView(button1); - views::NativeButton* button2 = new views::NativeButton( - NULL, ASCIIToWide(kButton2ASCII)); - layout->StartRow(0, 0); - layout->AddView(button2); - views::NativeButton* button3 = new views::NativeButton( - NULL, ASCIIToWide(kButton3ASCII)); - layout->StartRow(0, 0); - layout->AddView(button3); - - // Set focus to the first button initially. - button1->RequestFocus(); - - // Start listening to ACCESSIBILITY_CONTROL_FOCUSED notifications. - NotificationRegistrar registrar; - registrar.Add(this, - NotificationType::ACCESSIBILITY_CONTROL_FOCUSED, - NotificationService::AllSources()); - - // Switch on accessibility event notifications. - TestingProfile profile; - ExtensionAccessibilityEventRouter* accessibility_event_router = - ExtensionAccessibilityEventRouter::GetInstance(); - accessibility_event_router->SetAccessibilityEnabled(true); - - // Create an AccessibleViewHelper for this window, which will send - // accessibility notifications for all events that happen in child views. - AccessibleViewHelper accessible_view_helper(root_view, &profile); - accessible_view_helper.SetViewName(button3, std::string(kButton3NewASCII)); - - // Advance focus to the next button and test that we got the - // expected notification with the name of button 2. - views::FocusManager* focus_manager = window->GetFocusManager(); - focus_event_count_ = 0; - focus_manager->AdvanceFocus(false); - EXPECT_EQ(1, focus_event_count_); - EXPECT_EQ(kButton2ASCII, last_control_name_); - - // Advance to button 3. Expect the new accessible name we assigned. - focus_manager->AdvanceFocus(false); - EXPECT_EQ(2, focus_event_count_); - EXPECT_EQ(kButton3NewASCII, last_control_name_); - - // Advance to button 1 and check the notification. - focus_manager->AdvanceFocus(false); - EXPECT_EQ(3, focus_event_count_); - EXPECT_EQ(kButton1ASCII, last_control_name_); -} - -#endif // defined(TOOLKIT_VIEWS) diff --git a/chrome/browser/views/accessible_pane_view.cc b/chrome/browser/views/accessible_pane_view.cc deleted file mode 100644 index b876940..0000000 --- a/chrome/browser/views/accessible_pane_view.cc +++ /dev/null @@ -1,251 +0,0 @@ -// 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 "base/logging.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "chrome/browser/views/accessible_pane_view.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/native/native_view_host.h" -#include "views/focus/focus_search.h" -#include "views/focus/view_storage.h" -#include "views/widget/tooltip_manager.h" -#include "views/widget/widget.h" - -AccessiblePaneView::AccessiblePaneView() - : pane_has_focus_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), - focus_manager_(NULL), - home_key_(app::VKEY_HOME, false, false, false), - end_key_(app::VKEY_END, false, false, false), - escape_key_(app::VKEY_ESCAPE, false, false, false), - left_key_(app::VKEY_LEFT, false, false, false), - right_key_(app::VKEY_RIGHT, false, false, false), - last_focused_view_storage_id_(-1) { - focus_search_.reset(new views::FocusSearch(this, true, true)); -} - -AccessiblePaneView::~AccessiblePaneView() { - if (pane_has_focus_) { - focus_manager_->RemoveFocusChangeListener(this); - } -} - -bool AccessiblePaneView::SetPaneFocus(int view_storage_id, - views::View* initial_focus) { - if (!IsVisible()) - return false; - - // Save the storage id to the last focused view. This would be used to request - // focus to the view when the traversal is ended. - last_focused_view_storage_id_ = view_storage_id; - - if (!focus_manager_) - focus_manager_ = GetFocusManager(); - - // Use the provided initial focus if it's visible and enabled, otherwise - // use the first focusable child. - if (!initial_focus || - !IsParentOf(initial_focus) || - !initial_focus->IsVisible() || - !initial_focus->IsEnabled()) { - initial_focus = GetFirstFocusableChild(); - } - - // Return false if there are no focusable children. - if (!initial_focus) - return false; - - // Set focus to the initial view. If it's a location bar, use a special - // method that tells it to select all, also. - if (initial_focus->GetClassName() == LocationBarView::kViewClassName) { - static_cast<LocationBarView*>(initial_focus)->FocusLocation(true); - } else { - focus_manager_->SetFocusedView(initial_focus); - } - - // If we already have pane focus, we're done. - if (pane_has_focus_) - return true; - - // Otherwise, set accelerators and start listening for focus change events. - pane_has_focus_ = true; - focus_manager_->RegisterAccelerator(home_key_, this); - focus_manager_->RegisterAccelerator(end_key_, this); - focus_manager_->RegisterAccelerator(escape_key_, this); - focus_manager_->RegisterAccelerator(left_key_, this); - focus_manager_->RegisterAccelerator(right_key_, this); - focus_manager_->AddFocusChangeListener(this); - - return true; -} - -bool AccessiblePaneView::SetPaneFocusAndFocusDefault( - int view_storage_id) { - return SetPaneFocus(view_storage_id, GetDefaultFocusableChild()); -} - -void AccessiblePaneView::RemovePaneFocus() { - focus_manager_->RemoveFocusChangeListener(this); - pane_has_focus_ = false; - - focus_manager_->UnregisterAccelerator(home_key_, this); - focus_manager_->UnregisterAccelerator(end_key_, this); - focus_manager_->UnregisterAccelerator(escape_key_, this); - focus_manager_->UnregisterAccelerator(left_key_, this); - focus_manager_->UnregisterAccelerator(right_key_, this); -} - -void AccessiblePaneView::LocationBarSelectAll() { - views::View* focused_view = GetFocusManager()->GetFocusedView(); - if (focused_view && - focused_view->GetClassName() == LocationBarView::kViewClassName) { - static_cast<LocationBarView*>(focused_view)->SelectAll(); - } -} - -void AccessiblePaneView::RestoreLastFocusedView() { - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - views::View* last_focused_view = - view_storage->RetrieveView(last_focused_view_storage_id_); - if (last_focused_view) { - focus_manager_->SetFocusedViewWithReason( - last_focused_view, views::FocusManager::kReasonFocusRestore); - } else { - // Focus the location bar - views::View* view = GetAncestorWithClassName(BrowserView::kViewClassName); - if (view) { - BrowserView* browser_view = static_cast<BrowserView*>(view); - browser_view->SetFocusToLocationBar(false); - } - } -} - -views::View* AccessiblePaneView::GetFirstFocusableChild() { - FocusTraversable* dummy_focus_traversable; - views::View* dummy_focus_traversable_view; - return focus_search_->FindNextFocusableView( - NULL, false, views::FocusSearch::DOWN, false, - &dummy_focus_traversable, &dummy_focus_traversable_view); -} - -views::View* AccessiblePaneView::GetLastFocusableChild() { - FocusTraversable* dummy_focus_traversable; - views::View* dummy_focus_traversable_view; - return focus_search_->FindNextFocusableView( - this, true, views::FocusSearch::DOWN, false, - &dummy_focus_traversable, &dummy_focus_traversable_view); -} - -//////////////////////////////////////////////////////////////////////////////// -// View overrides: - -views::FocusTraversable* AccessiblePaneView::GetPaneFocusTraversable() { - if (pane_has_focus_) - return this; - else - return NULL; -} - -bool AccessiblePaneView::AcceleratorPressed( - const views::Accelerator& accelerator) { - // Special case: don't handle any accelerators for the location bar, - // so that it behaves exactly the same whether you focus it with Ctrl+L - // or F6 or Alt+D or Alt+Shift+T. - views::View* focused_view = focus_manager_->GetFocusedView(); - if ((focused_view->GetClassName() == LocationBarView::kViewClassName || - focused_view->GetClassName() == views::NativeViewHost::kViewClassName)) { - return false; - } - - switch (accelerator.GetKeyCode()) { - case app::VKEY_ESCAPE: - RemovePaneFocus(); - RestoreLastFocusedView(); - return true; - case app::VKEY_LEFT: - focus_manager_->AdvanceFocus(true); - return true; - case app::VKEY_RIGHT: - focus_manager_->AdvanceFocus(false); - return true; - case app::VKEY_HOME: - focus_manager_->SetFocusedViewWithReason( - GetFirstFocusableChild(), views::FocusManager::kReasonFocusTraversal); - return true; - case app::VKEY_END: - focus_manager_->SetFocusedViewWithReason( - GetLastFocusableChild(), views::FocusManager::kReasonFocusTraversal); - return true; - default: - return false; - } -} - -void AccessiblePaneView::SetVisible(bool flag) { - if (IsVisible() && !flag && pane_has_focus_) { - RemovePaneFocus(); - RestoreLastFocusedView(); - } - View::SetVisible(flag); -} - -AccessibilityTypes::Role AccessiblePaneView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PANE; -} - -//////////////////////////////////////////////////////////////////////////////// -// FocusChangeListener overrides: - -void AccessiblePaneView::FocusWillChange(views::View* focused_before, - views::View* focused_now) { - if (!focused_now) - return; - - views::FocusManager::FocusChangeReason reason = - focus_manager_->focus_change_reason(); - - if (focused_now->GetClassName() == LocationBarView::kViewClassName && - reason == views::FocusManager::kReasonFocusTraversal) { - // Tabbing to the location bar should select all. Defer so that it happens - // after the focus. - MessageLoop::current()->PostTask( - FROM_HERE, method_factory_.NewRunnableMethod( - &AccessiblePaneView::LocationBarSelectAll)); - } - - if (!IsParentOf(focused_now) || - reason == views::FocusManager::kReasonDirectFocusChange) { - // We should remove pane focus (i.e. make most of the controls - // not focusable again) either because the focus is leaving the pane, - // or because the focus changed within the pane due to the user - // directly focusing to a specific view (e.g., clicking on it). - // - // Defer rather than calling RemovePaneFocus right away, because we can't - // remove |this| as a focus change listener while FocusManager is in the - // middle of iterating over the list of listeners. - MessageLoop::current()->PostTask( - FROM_HERE, method_factory_.NewRunnableMethod( - &AccessiblePaneView::RemovePaneFocus)); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// FocusTraversable overrides: - -views::FocusSearch* AccessiblePaneView::GetFocusSearch() { - DCHECK(pane_has_focus_); - return focus_search_.get(); -} - -views::FocusTraversable* AccessiblePaneView::GetFocusTraversableParent() { - DCHECK(pane_has_focus_); - return NULL; -} - -views::View* AccessiblePaneView::GetFocusTraversableParentView() { - DCHECK(pane_has_focus_); - return NULL; -} diff --git a/chrome/browser/views/accessible_pane_view.h b/chrome/browser/views/accessible_pane_view.h index f31f59b..8a2ebb1 100644 --- a/chrome/browser/views/accessible_pane_view.h +++ b/chrome/browser/views/accessible_pane_view.h @@ -6,95 +6,8 @@ #define CHROME_BROWSER_VIEWS_ACCESSIBLE_PANE_VIEW_H_ #pragma once -#include "base/hash_tables.h" -#include "base/scoped_ptr.h" -#include "base/task.h" -#include "views/focus/focus_manager.h" -#include "views/view.h" - -namespace views { -class FocusSearch; -} - -// This class provides keyboard access to any view that extends it, typically -// a toolbar. The user sets focus to a control in this view by pressing -// F6 to traverse all panes, or by pressing a shortcut that jumps directly -// to this pane. -class AccessiblePaneView : public views::View, - public views::FocusChangeListener, - public views::FocusTraversable { - public: - AccessiblePaneView(); - virtual ~AccessiblePaneView(); - - // Set focus to the pane with complete keyboard access. - // Focus will be restored to the ViewStorage with id |view_storage_id| - // if the user escapes. If |initial_focus| is not NULL, that control will get - // the initial focus, if it's enabled and focusable. Returns true if - // the pane was able to receive focus. - virtual bool SetPaneFocus(int view_storage_id, View* initial_focus); - - // Set focus to the pane with complete keyboard access, with the - // focus initially set to the default child. Focus will be restored - // to the ViewStorage with id |view_storage_id| if the user escapes. - // Returns true if the pane was able to receive focus. - virtual bool SetPaneFocusAndFocusDefault(int view_storage_id); - - // Overridden from views::View: - virtual FocusTraversable* GetPaneFocusTraversable(); - virtual bool AcceleratorPressed(const views::Accelerator& accelerator); - virtual void SetVisible(bool flag); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // Overridden from views::FocusChangeListener: - virtual void FocusWillChange(View* focused_before, - View* focused_now); - - // Overridden from views::FocusTraversable: - virtual views::FocusSearch* GetFocusSearch(); - virtual FocusTraversable* GetFocusTraversableParent(); - virtual View* GetFocusTraversableParentView(); - - protected: - // A subclass can override this to provide a default focusable child - // other than the first focusable child. - virtual views::View* GetDefaultFocusableChild() { return NULL; } - - // Remove pane focus. - virtual void RemovePaneFocus(); - - // Select all text in the location bar - virtual void LocationBarSelectAll(); - - void RestoreLastFocusedView(); - - View* GetFirstFocusableChild(); - View* GetLastFocusableChild(); - - bool pane_has_focus_; - - ScopedRunnableMethodFactory<AccessiblePaneView> method_factory_; - - // Save the focus manager rather than calling GetFocusManager(), - // so that we can remove focus listeners in the destructor. - views::FocusManager* focus_manager_; - - // Our custom focus search implementation that traps focus in this - // pane and traverses all views that are focusable for accessibility, - // not just those that are normally focusable. - scoped_ptr<views::FocusSearch> focus_search_; - - // Registered accelerators - views::Accelerator home_key_; - views::Accelerator end_key_; - views::Accelerator escape_key_; - views::Accelerator left_key_; - views::Accelerator right_key_; - - // Last focused view that issued this traversal. - int last_focused_view_storage_id_; - - DISALLOW_COPY_AND_ASSIGN(AccessiblePaneView); -}; +#include "chrome/browser/ui/views/accessible_pane_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_ACCESSIBLE_PANE_VIEW_H_ + diff --git a/chrome/browser/views/accessible_view_helper.cc b/chrome/browser/views/accessible_view_helper.cc deleted file mode 100644 index 65caf36..0000000 --- a/chrome/browser/views/accessible_view_helper.cc +++ /dev/null @@ -1,89 +0,0 @@ -// 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/accessible_view_helper.h" - -#include "app/l10n_util.h" -#include "chrome/browser/accessibility_events.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/accessibility_event_router_views.h" -#include "chrome/common/notification_service.h" -#include "views/controls/native/native_view_host.h" -#include "views/widget/widget.h" -#include "views/view.h" - -AccessibleViewHelper::AccessibleViewHelper( - views::View* view_tree, Profile* profile) - : accessibility_event_router_(AccessibilityEventRouterViews::GetInstance()), - profile_(profile), - view_tree_(view_tree) { - if (!accessibility_event_router_->AddViewTree(view_tree_, profile)) - view_tree_ = NULL; - -#if defined(OS_LINUX) - GtkWidget* widget = view_tree->GetWidget()->GetNativeView(); - widget_helper_.reset(new AccessibleWidgetHelper(widget, profile)); -#endif -} - -AccessibleViewHelper::~AccessibleViewHelper() { - if (!window_title_.empty()) { - AccessibilityWindowInfo info(profile_, window_title_); - NotificationService::current()->Notify( - NotificationType::ACCESSIBILITY_WINDOW_CLOSED, - Source<Profile>(profile_), - Details<AccessibilityWindowInfo>(&info)); - } - - if (view_tree_) { - accessibility_event_router_->RemoveViewTree(view_tree_); - for (std::vector<views::View*>::iterator iter = managed_views_.begin(); - iter != managed_views_.end(); - ++iter) { - accessibility_event_router_->RemoveView(*iter); - } - } -} - -void AccessibleViewHelper::SendOpenWindowNotification( - const std::string& window_title) { - window_title_ = window_title; - AccessibilityWindowInfo info(profile_, window_title); - NotificationService::current()->Notify( - NotificationType::ACCESSIBILITY_WINDOW_OPENED, - Source<Profile>(profile_), - Details<AccessibilityWindowInfo>(&info)); -} - -void AccessibleViewHelper::SetViewName(views::View* view, std::string name) { - if (!view_tree_) - return; - - accessibility_event_router_->SetViewName(view, name); - managed_views_.push_back(view); - - #if defined(OS_LINUX) - gfx::NativeView native_view = GetNativeView(view); - if (native_view) - widget_helper_->SetWidgetName(native_view, name); - #endif -} - -void AccessibleViewHelper::SetViewName(views::View* view, int string_id) { - const std::string name = l10n_util::GetStringUTF8(string_id); - SetViewName(view, name); -} - -gfx::NativeView AccessibleViewHelper::GetNativeView(views::View* view) const { - if (view->GetClassName() == views::NativeViewHost::kViewClassName) - return static_cast<views::NativeViewHost*>(view)->native_view(); - - for (int i = 0; i < view->GetChildViewCount(); i++) { - gfx::NativeView native_view = GetNativeView(view->GetChildViewAt(i)); - if (native_view) - return native_view; - } - - return NULL; -} diff --git a/chrome/browser/views/accessible_view_helper.h b/chrome/browser/views/accessible_view_helper.h index 3309c0f..e02fde1 100644 --- a/chrome/browser/views/accessible_view_helper.h +++ b/chrome/browser/views/accessible_view_helper.h @@ -6,78 +6,8 @@ #define CHROME_BROWSER_VIEWS_ACCESSIBLE_VIEW_HELPER_H_ #pragma once -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/singleton.h" -#include "chrome/browser/accessibility_events.h" -#include "gfx/native_widget_types.h" - -#if defined(OS_LINUX) -#include "chrome/browser/gtk/accessible_widget_helper_gtk.h" -#endif - -class AccessibilityEventRouterViews; -class Profile; -namespace views { -class View; -} - -// NOTE: This class is part of the Accessibility Extension API, which lets -// extensions receive accessibility events. It's distinct from code that -// implements platform accessibility APIs like MSAA or ATK. -// -// Helper class that helps to manage the accessibility information for a -// view and all of its descendants. Create an instance of this class for -// the root of a tree of views (like a dialog) that should send accessibility -// events for all of its descendants. -// -// Most controls have default behavior for accessibility; when this needs -// to be augmented, call one of the methods below to ignore a particular -// view or change its details. -// -// All of the information managed by this class is registered with the -// (global) AccessibilityEventRouterViews and unregistered when this object is -// destroyed. -class AccessibleViewHelper { - public: - // Constructs an AccessibleViewHelper that makes the given view and all - // of its descendants accessible for the lifetime of this object, - // sending accessibility notifications to the given profile. - AccessibleViewHelper(views::View* view_tree, Profile* profile); - - virtual ~AccessibleViewHelper(); - - // Sends a notification that a new window was opened now, and a - // corresponding close window notification when this object - // goes out of scope. - void SendOpenWindowNotification(const std::string& window_title); - - // Uses the following string as the name of this view, instead of - // view->GetAccessibleName(). - void SetViewName(views::View* view, std::string name); - - // Uses the following string id as the name of this view, instead of - // view->GetAccessibleName(). - void SetViewName(views::View* view, int string_id); - - private: - // Returns a native view if the given view has a native view in it. - gfx::NativeView GetNativeView(views::View* view) const; - - AccessibilityEventRouterViews* accessibility_event_router_; - Profile* profile_; - views::View* view_tree_; - std::string window_title_; - std::vector<views::View*> managed_views_; - -#if defined(OS_LINUX) - scoped_ptr<AccessibleWidgetHelper> widget_helper_; -#endif - - DISALLOW_COPY_AND_ASSIGN(AccessibleViewHelper); -}; +#include "chrome/browser/ui/views/accessible_view_helper.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_ACCESSIBLE_VIEW_HELPER_H_ + diff --git a/chrome/browser/views/app_launched_animation_win.cc b/chrome/browser/views/app_launched_animation_win.cc deleted file mode 100644 index 50efc5d..0000000 --- a/chrome/browser/views/app_launched_animation_win.cc +++ /dev/null @@ -1,135 +0,0 @@ -// 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/app_launched_animation.h" - -#include "app/animation.h" -#include "app/slide_animation.h" -#include "chrome/browser/extensions/image_loading_tracker.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/extension_icon_set.h" -#include "chrome/common/extensions/extension_resource.h" -#include "gfx/rect.h" -#include "views/controls/image_view.h" -#include "views/widget/widget_win.h" - -namespace { - -// Start at 1, end at 0 -// 0ms You click the icon -// 0ms The launcher and contents begins to fade out, the icon -// you clicked does not (stays opaque) -// 0ms The app begins loading behind the launcher -// +100ms The app icon begins to fade out. -// +200ms The launcher finishes fading out -// +350ms The app icon finishes fading out - -// How long the fade should take. -static const int kDurationMS = 250; - -// The delay before the fade out should start. -static const int kDelayMS = 100; - -// AppLaunchedAnimation creates an animation. It loads the icon for the -// extension and once the image is loaded the animation starts. The icon fades -// out after a short delay. -class AppLaunchedAnimationWin : public AnimationDelegate, - public ImageLoadingTracker::Observer, - public views::ImageView { - public: - AppLaunchedAnimationWin(const Extension* extension, const gfx::Rect& rect); - - private: - // AnimationDelegate - virtual void AnimationProgressed(const Animation* animation); - virtual void AnimationCanceled(const Animation* animation); - virtual void AnimationEnded(const Animation* animation); - - // We use a HWND for the popup so that it may float above any HWNDs in our UI. - views::WidgetWin* popup_; - - // The rect to use for the popup. - gfx::Rect rect_; - - // Used for loading extension application icon. - ImageLoadingTracker app_icon_loader_; - - // ImageLoadingTracker::Observer. - virtual void OnImageLoaded(SkBitmap* image, ExtensionResource resource, - int index); - - // Hover animation. - scoped_ptr<SlideAnimation> animation_; - - DISALLOW_COPY_AND_ASSIGN(AppLaunchedAnimationWin); -}; - -AppLaunchedAnimationWin::AppLaunchedAnimationWin(const Extension* extension, - const gfx::Rect& rect) - : popup_(NULL), - rect_(rect), - ALLOW_THIS_IN_INITIALIZER_LIST(app_icon_loader_(this)) { - DCHECK(extension); - app_icon_loader_.LoadImage( - extension, - extension->GetIconResource(Extension::EXTENSION_ICON_LARGE, - ExtensionIconSet::MATCH_EXACTLY), - rect_.size(), - ImageLoadingTracker::DONT_CACHE); -} - -void AppLaunchedAnimationWin::AnimationCanceled(const Animation* animation) { - AnimationEnded(animation); -} - -void AppLaunchedAnimationWin::AnimationEnded(const Animation* animation) { - popup_->Close(); -} - -void AppLaunchedAnimationWin::AnimationProgressed(const Animation* animation) { - // GetCurrentValue goes from 1 to 0 since we are hiding. - const double current_value = 1.0 - animation->GetCurrentValue(); - const double current_time = current_value * (kDelayMS + kDurationMS); - - double opacity = 1.0 - - std::max(0.0, static_cast<double>(current_time - kDelayMS)) / - static_cast<double>(kDurationMS); - - popup_->SetOpacity(static_cast<SkColor>(opacity * 255.0)); - SchedulePaint(); -} - -void AppLaunchedAnimationWin::OnImageLoaded(SkBitmap* image, - ExtensionResource resource, - int index) { - if (image) { - SetImage(image); - - popup_ = new views::WidgetWin; - popup_->set_window_style(WS_POPUP); - popup_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | - WS_EX_TRANSPARENT); - popup_->SetOpacity(static_cast<SkColor>(255)); - - popup_->Init(NULL, rect_); - popup_->SetContentsView(this); - popup_->Show(); - - // Start animation. - animation_.reset(new SlideAnimation(this)); - animation_->SetSlideDuration(kDelayMS + kDurationMS); - animation_->SetTweenType(Tween::LINEAR); - animation_->Reset(1.0); - animation_->Hide(); - } -} - -} // namespace - -// static -void AppLaunchedAnimation::Show(const Extension* extension, - const gfx::Rect& rect) { - // The animation will delete itself when it's finished. - new AppLaunchedAnimationWin(extension, rect); -} diff --git a/chrome/browser/views/appcache_info_view.cc b/chrome/browser/views/appcache_info_view.cc deleted file mode 100644 index 03d3919..0000000 --- a/chrome/browser/views/appcache_info_view.cc +++ /dev/null @@ -1,40 +0,0 @@ -// 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/appcache_info_view.h" - -#include "base/i18n/time_formatting.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "grit/generated_resources.h" - -namespace { -const int kInfoLabelIds[] = { - IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL, - IDS_COOKIES_SIZE_LABEL, - IDS_COOKIES_COOKIE_CREATED_LABEL, - IDS_COOKIES_LAST_ACCESSED_LABEL -}; -} // namespace - -AppCacheInfoView::AppCacheInfoView() - : GenericInfoView(ARRAYSIZE(kInfoLabelIds), kInfoLabelIds) { -} - -void AppCacheInfoView::SetAppCacheInfo(const appcache::AppCacheInfo* info) { - DCHECK(info); - string16 manifest_url = - UTF8ToUTF16(info->manifest_url.spec()); - string16 size = - FormatBytes(info->size, GetByteDisplayUnits(info->size), true); - string16 creation_date = - base::TimeFormatFriendlyDateAndTime(info->creation_time); - string16 last_access_date = - base::TimeFormatFriendlyDateAndTime(info->last_access_time); - int row = 0; - SetValue(row++, manifest_url); - SetValue(row++, size); - SetValue(row++, creation_date); - SetValue(row++, last_access_date); -} diff --git a/chrome/browser/views/appcache_info_view.h b/chrome/browser/views/appcache_info_view.h index e943425..991b819 100644 --- a/chrome/browser/views/appcache_info_view.h +++ b/chrome/browser/views/appcache_info_view.h @@ -6,19 +6,8 @@ #define CHROME_BROWSER_VIEWS_APPCACHE_INFO_VIEW_H_ #pragma once -#include "chrome/browser/views/generic_info_view.h" -#include "chrome/browser/browsing_data_appcache_helper.h" - -// AppCacheInfoView -// Displays a tabular grid of AppCache information. -class AppCacheInfoView : public GenericInfoView { - public: - AppCacheInfoView(); - void SetAppCacheInfo(const appcache::AppCacheInfo* info); - - private: - DISALLOW_COPY_AND_ASSIGN(AppCacheInfoView); -}; +#include "chrome/browser/ui/views/appcache_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_APPCACHE_INFO_VIEW_H_ diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc deleted file mode 100644 index bfd7321..0000000 --- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc +++ /dev/null @@ -1,1191 +0,0 @@ -// 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/autocomplete/autocomplete_popup_contents_view.h" - -#include "app/bidi_line_iterator.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/theme_provider.h" -#include "app/text_elider.h" -#include "base/compiler_specific.h" -#include "base/i18n/rtl.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/autocomplete/autocomplete_edit_view.h" -#include "chrome/browser/autocomplete/autocomplete_match.h" -#include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/instant/instant_opt_in.h" -#include "chrome/browser/views/bubble_border.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "gfx/canvas_skia.h" -#include "gfx/color_utils.h" -#include "gfx/insets.h" -#include "gfx/path.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkShader.h" -#include "unicode/ubidi.h" -#include "views/controls/button/text_button.h" -#include "views/controls/label.h" -#include "views/grid_layout.h" -#include "views/painter.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include <objidl.h> -#include <commctrl.h> -#include <dwmapi.h> - -#include "app/win_util.h" -#endif - -#if defined(OS_LINUX) -#include "chrome/browser/gtk/gtk_util.h" -#include "gfx/skia_utils_gtk.h" -#endif - -namespace { - -enum ResultViewState { - NORMAL = 0, - SELECTED, - HOVERED, - NUM_STATES -}; - -enum ColorKind { - BACKGROUND = 0, - TEXT, - DIMMED_TEXT, - URL, - NUM_KINDS -}; - -SkColor GetColor(ResultViewState state, ColorKind kind) { - static bool initialized = false; - static SkColor colors[NUM_STATES][NUM_KINDS]; - if (!initialized) { -#if defined(OS_WIN) - colors[NORMAL][BACKGROUND] = color_utils::GetSysSkColor(COLOR_WINDOW); - colors[SELECTED][BACKGROUND] = color_utils::GetSysSkColor(COLOR_HIGHLIGHT); - colors[NORMAL][TEXT] = color_utils::GetSysSkColor(COLOR_WINDOWTEXT); - colors[SELECTED][TEXT] = color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); -#elif defined(OS_LINUX) - GdkColor bg_color, selected_bg_color, text_color, selected_text_color; - gtk_util::GetTextColors( - &bg_color, &selected_bg_color, &text_color, &selected_text_color); - colors[NORMAL][BACKGROUND] = gfx::GdkColorToSkColor(bg_color); - colors[SELECTED][BACKGROUND] = gfx::GdkColorToSkColor(selected_bg_color); - colors[NORMAL][TEXT] = gfx::GdkColorToSkColor(text_color); - colors[SELECTED][TEXT] = gfx::GdkColorToSkColor(selected_text_color); -#else - // TODO(beng): source from theme provider. - colors[NORMAL][BACKGROUND] = SK_ColorWHITE; - colors[SELECTED][BACKGROUND] = SK_ColorBLUE; - colors[NORMAL][TEXT] = SK_ColorBLACK; - colors[SELECTED][TEXT] = SK_ColorWHITE; -#endif - colors[HOVERED][BACKGROUND] = - color_utils::AlphaBlend(colors[SELECTED][BACKGROUND], - colors[NORMAL][BACKGROUND], 64); - colors[HOVERED][TEXT] = colors[NORMAL][TEXT]; - for (int i = 0; i < NUM_STATES; ++i) { - colors[i][DIMMED_TEXT] = - color_utils::AlphaBlend(colors[i][TEXT], colors[i][BACKGROUND], 128); - colors[i][URL] = color_utils::GetReadableColor(SkColorSetRGB(0, 128, 0), - colors[i][BACKGROUND]); - } - initialized = true; - } - - return colors[state][kind]; -} - -const wchar_t kEllipsis[] = L"\x2026"; - -const SkAlpha kGlassPopupAlpha = 240; -const SkAlpha kOpaquePopupAlpha = 255; -// The minimum distance between the top and bottom of the icon and the top or -// bottom of the row. "Minimum" is used because the vertical padding may be -// larger, depending on the size of the text. -const int kIconVerticalPadding = 2; -// The minimum distance between the top and bottom of the text and the top or -// bottom of the row. See comment about the use of "minimum" for -// kIconVerticalPadding. -const int kTextVerticalPadding = 3; -// The size delta between the font used for the edit and the result rows. Passed -// to gfx::Font::DeriveFont. -#if !defined(OS_CHROMEOS) -const int kEditFontAdjust = -1; -#else -// Don't adjust font on chromeos as it becomes too small. -const int kEditFontAdjust = 0; -#endif - -// Horizontal padding between the buttons on the opt in promo. -const int kOptInButtonPadding = 2; - -// Padding around the opt in view. -const int kOptInLeftPadding = 12; -const int kOptInRightPadding = 6; -const int kOptInTopPadding = 6; -const int kOptInBottomPadding = 3; - -// Padding between the top of the opt-in view and the separator. -const int kOptInSeparatorSpacing = 2; - -// Border for instant opt-in buttons. Consists of two 9 patch painters: one for -// the normal state, the other for the pressed state. -class OptInButtonBorder : public views::Border { - public: - OptInButtonBorder() { - border_painter_.reset(CreatePainter(IDR_OPT_IN_BUTTON)); - border_pushed_painter_.reset(CreatePainter(IDR_OPT_IN_BUTTON_P)); - } - - virtual void Paint(const views::View& view, gfx::Canvas* canvas) const { - views::Painter* painter; - if (static_cast<const views::CustomButton&>(view).state() == - views::CustomButton::BS_PUSHED) { - painter = border_pushed_painter_.get(); - } else { - painter = border_painter_.get(); - } - painter->Paint(view.width(), view.height(), canvas); - } - - virtual void GetInsets(gfx::Insets* insets) const { - insets->Set(3, 8, 3, 8); - } - - private: - // Creates 9 patch painter from the image with the id |image_id|. - views::Painter* CreatePainter(int image_id) { - SkBitmap* image = - ResourceBundle::GetSharedInstance().GetBitmapNamed(image_id); - int w = image->width() / 2; - if (image->width() % 2 == 0) - w--; - int h = image->height() / 2; - if (image->height() % 2 == 0) - h--; - gfx::Insets insets(h, w, h, w); - return views::Painter::CreateImagePainter(*image, insets, true); - } - - scoped_ptr<views::Painter> border_painter_; - scoped_ptr<views::Painter> border_pushed_painter_; - - DISALLOW_COPY_AND_ASSIGN(OptInButtonBorder); -}; - -} // namespace - -class AutocompletePopupContentsView::InstantOptInView - : public views::View, - public views::ButtonListener { - public: - InstantOptInView(AutocompletePopupContentsView* contents_view, - const gfx::Font& label_font, - const gfx::Font& button_font) - : contents_view_(contents_view) { - views::Label* label = - new views::Label(l10n_util::GetString(IDS_INSTANT_OPT_IN_LABEL)); - label->SetFont(label_font); - - views::GridLayout* layout = new views::GridLayout(this); - layout->SetInsets(kOptInTopPadding, kOptInLeftPadding, - kOptInBottomPadding, kOptInRightPadding); - SetLayoutManager(layout); - - const int first_column_set = 1; - views::GridLayout::Alignment v_align = views::GridLayout::CENTER; - views::ColumnSet* column_set = layout->AddColumnSet(first_column_set); - column_set->AddColumn(views::GridLayout::TRAILING, v_align, 1, - views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::CENTER, v_align, 0, - views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kOptInButtonPadding); - column_set->AddColumn(views::GridLayout::CENTER, v_align, 0, - views::GridLayout::USE_PREF, 0, 0); - column_set->LinkColumnSizes(2, 4, -1); - layout->StartRow(0, first_column_set); - layout->AddView(label); - layout->AddView(CreateButton(IDS_INSTANT_OPT_IN_ENABLE, button_font)); - layout->AddView(CreateButton(IDS_INSTANT_OPT_IN_NO_THANKS, button_font)); - } - - virtual void ButtonPressed(views::Button* sender, const views::Event& event) { - contents_view_->UserPressedOptIn( - sender->tag() == IDS_INSTANT_OPT_IN_ENABLE); - // WARNING: we've been deleted. - } - - virtual void Paint(gfx::Canvas* canvas) { - SkColor line_color = color_utils::AlphaBlend(GetColor(NORMAL, DIMMED_TEXT), - GetColor(NORMAL, BACKGROUND), - 48); - canvas->DrawLineInt( - line_color, 0, kOptInSeparatorSpacing, width(), kOptInSeparatorSpacing); - } - - private: - // Creates and returns a button configured for the opt-in promo. - views::View* CreateButton(int id, const gfx::Font& font) { - // NOTE: we can't use NativeButton as the popup is a layered window and - // native buttons don't draw in layered windows. - // TODO: these buttons look crap. Figure out the right border/background to - // use. - views::TextButton* button = - new views::TextButton(this, l10n_util::GetString(id)); - button->set_border(new OptInButtonBorder()); - button->SetNormalHasBorder(true); - button->set_tag(id); - button->SetFont(font); - button->set_animate_on_state_change(false); - return button; - } - - AutocompletePopupContentsView* contents_view_; - - DISALLOW_COPY_AND_ASSIGN(InstantOptInView); -}; - -class AutocompleteResultView : public views::View { - public: - AutocompleteResultView(AutocompleteResultViewModel* model, - int model_index, - const gfx::Font& font, - const gfx::Font& bold_font); - virtual ~AutocompleteResultView(); - - // Updates the match used to paint the contents of this result view. We copy - // the match so that we can continue to paint the last result even after the - // model has changed. - void set_match(const AutocompleteMatch& match) { match_ = match; } - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - // Returns the preferred height for a single row. - static int GetPreferredHeight(const gfx::Font& font, - const gfx::Font& bold_font); - - private: - // Precalculated data used to draw the portion of a match classification that - // fits entirely within one run. - struct ClassificationData { - std::wstring text; - const gfx::Font* font; - SkColor color; - int pixel_width; - }; - typedef std::vector<ClassificationData> Classifications; - - // Precalculated data used to draw a complete visual run within the match. - // This will include all or part of at leasdt one, and possibly several, - // classifications. - struct RunData { - size_t run_start; // Offset within the match text where this run begins. - int visual_order; // Where this run occurs in visual order. The earliest - // run drawn is run 0. - bool is_rtl; - int pixel_width; - Classifications classifications; // Classification pieces within this run, - // in logical order. - }; - typedef std::vector<RunData> Runs; - - // Predicate functions for use when sorting the runs. - static bool SortRunsLogically(const RunData& lhs, const RunData& rhs); - static bool SortRunsVisually(const RunData& lhs, const RunData& rhs); - - ResultViewState GetState() const; - - const SkBitmap* GetIcon() const; - - // Draws the specified |text| into the canvas, using highlighting provided by - // |classifications|. If |force_dim| is true, ACMatchClassification::DIM is - // added to all of the classifications. Returns the x position to the right - // of the string. - int DrawString(gfx::Canvas* canvas, - const std::wstring& text, - const ACMatchClassifications& classifications, - bool force_dim, - int x, - int y); - - // Elides |runs| to fit in |remaining_width|. The runs in |runs| should be in - // logical order. - // - // When we need to elide a run, the ellipsis will be placed at the end of that - // run. This means that if we elide a run whose visual direction is opposite - // that of the drawing context, the ellipsis will not be at the "end" of the - // drawn string. For example, if in an LTR context we have the LTR run - // "LTR_STRING" and the RTL run "RTL_STRING", the unelided text would be drawn - // like: - // LTR_STRING GNIRTS_LTR - // If we need to elide the RTL run, then it will be drawn like: - // LTR_STRING ...RTS_LTR - // Instead of: - // LTR_STRING RTS_LTR... - void Elide(Runs* runs, int remaining_width) const; - - // This row's model and model index. - AutocompleteResultViewModel* model_; - size_t model_index_; - - const gfx::Font normal_font_; - const gfx::Font bold_font_; - - // Width of the ellipsis in the normal font. - int ellipsis_width_; - - // A context used for mirroring regions. - class MirroringContext; - scoped_ptr<MirroringContext> mirroring_context_; - - // Layout rects for various sub-components of the view. - gfx::Rect icon_bounds_; - gfx::Rect text_bounds_; - - static int icon_size_; - - AutocompleteMatch match_; - - DISALLOW_COPY_AND_ASSIGN(AutocompleteResultView); -}; - -// static -int AutocompleteResultView::icon_size_ = 0; - -// This class is a utility class for calculations affected by whether the result -// view is horizontally mirrored. The drawing functions can be written as if -// all drawing occurs left-to-right, and then use this class to get the actual -// coordinates to begin drawing onscreen. -class AutocompleteResultView::MirroringContext { - public: - MirroringContext() : center_(0), right_(0) {} - - // Tells the mirroring context to use the provided range as the physical - // bounds of the drawing region. When coordinate mirroring is needed, the - // mirror point will be the center of this range. - void Initialize(int x, int width) { - center_ = x + width / 2; - right_ = x + width; - } - - // Given a logical range within the drawing region, returns the coordinate of - // the possibly-mirrored "left" side. (This functions exactly like - // View::MirroredLeftPointForRect().) - int mirrored_left_coord(int left, int right) const { - return base::i18n::IsRTL() ? (center_ + (center_ - right)) : left; - } - - // Given a logical coordinate within the drawing region, returns the remaining - // width available. - int remaining_width(int x) const { - return right_ - x; - } - - private: - int center_; - int right_; - - DISALLOW_COPY_AND_ASSIGN(MirroringContext); -}; - -AutocompleteResultView::AutocompleteResultView( - AutocompleteResultViewModel* model, - int model_index, - const gfx::Font& font, - const gfx::Font& bold_font) - : model_(model), - model_index_(model_index), - normal_font_(font), - bold_font_(bold_font), - ellipsis_width_(font.GetStringWidth(kEllipsis)), - mirroring_context_(new MirroringContext()), - match_(NULL, 0, false, AutocompleteMatch::URL_WHAT_YOU_TYPED) { - CHECK(model_index >= 0); - if (icon_size_ == 0) { - icon_size_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( - AutocompleteMatch::TypeToIcon(AutocompleteMatch::URL_WHAT_YOU_TYPED))-> - width(); - } -} - -AutocompleteResultView::~AutocompleteResultView() { -} - -void AutocompleteResultView::Paint(gfx::Canvas* canvas) { - const ResultViewState state = GetState(); - if (state != NORMAL) - canvas->AsCanvasSkia()->drawColor(GetColor(state, BACKGROUND)); - - // Paint the icon. - canvas->DrawBitmapInt(*GetIcon(), MirroredLeftPointForRect(icon_bounds_), - icon_bounds_.y()); - - // Paint the text. - int x = MirroredLeftPointForRect(text_bounds_); - mirroring_context_->Initialize(x, text_bounds_.width()); - x = DrawString(canvas, match_.contents, match_.contents_class, false, x, - text_bounds_.y()); - - // Paint the description. - // TODO(pkasting): Because we paint in multiple separate pieces, we can wind - // up with no space even for an ellipsis for one or both of these pieces. - // Instead, we should paint the entire match as a single long string. This - // would also let us use a more properly-localizable string than we get with - // just the IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR. - if (!match_.description.empty()) { - std::wstring separator = - l10n_util::GetString(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR); - ACMatchClassifications classifications; - classifications.push_back( - ACMatchClassification(0, ACMatchClassification::NONE)); - x = DrawString(canvas, separator, classifications, true, x, - text_bounds_.y()); - - DrawString(canvas, match_.description, match_.description_class, true, x, - text_bounds_.y()); - } -} - -void AutocompleteResultView::Layout() { - icon_bounds_.SetRect(LocationBarView::kEdgeItemPadding, - (height() - icon_size_) / 2, icon_size_, icon_size_); - int text_x = icon_bounds_.right() + LocationBarView::kItemPadding; - int font_height = std::max(normal_font_.GetHeight(), bold_font_.GetHeight()); - text_bounds_.SetRect(text_x, std::max(0, (height() - font_height) / 2), - std::max(bounds().width() - text_x - LocationBarView::kEdgeItemPadding, - 0), font_height); -} - -gfx::Size AutocompleteResultView::GetPreferredSize() { - return gfx::Size(0, GetPreferredHeight(normal_font_, bold_font_)); -} - -// static -int AutocompleteResultView::GetPreferredHeight( - const gfx::Font& font, - const gfx::Font& bold_font) { - int text_height = std::max(font.GetHeight(), bold_font.GetHeight()) + - (kTextVerticalPadding * 2); - int icon_height = icon_size_ + (kIconVerticalPadding * 2); - return std::max(icon_height, text_height); -} - -// static -bool AutocompleteResultView::SortRunsLogically(const RunData& lhs, - const RunData& rhs) { - return lhs.run_start < rhs.run_start; -} - -// static -bool AutocompleteResultView::SortRunsVisually(const RunData& lhs, - const RunData& rhs) { - return lhs.visual_order < rhs.visual_order; -} - -ResultViewState AutocompleteResultView::GetState() const { - if (model_->IsSelectedIndex(model_index_)) - return SELECTED; - return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; -} - -const SkBitmap* AutocompleteResultView::GetIcon() const { - const SkBitmap* bitmap = model_->GetSpecialIcon(model_index_); - if (bitmap) - return bitmap; - - int icon = match_.starred ? - IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type); - if (model_->IsSelectedIndex(model_index_)) { - switch (icon) { - case IDR_OMNIBOX_HTTP: icon = IDR_OMNIBOX_HTTP_SELECTED; break; - case IDR_OMNIBOX_HISTORY: icon = IDR_OMNIBOX_HISTORY_SELECTED; break; - case IDR_OMNIBOX_SEARCH: icon = IDR_OMNIBOX_SEARCH_SELECTED; break; - case IDR_OMNIBOX_MORE: icon = IDR_OMNIBOX_MORE_SELECTED; break; - case IDR_OMNIBOX_STAR: icon = IDR_OMNIBOX_STAR_SELECTED; break; - default: NOTREACHED(); break; - } - } - return ResourceBundle::GetSharedInstance().GetBitmapNamed(icon); -} - -int AutocompleteResultView::DrawString( - gfx::Canvas* canvas, - const std::wstring& text, - const ACMatchClassifications& classifications, - bool force_dim, - int x, - int y) { - if (text.empty()) - return x; - - // Check whether or not this text is a URL. URLs are always displayed LTR - // regardless of locale. - bool is_url = true; - for (ACMatchClassifications::const_iterator i(classifications.begin()); - i != classifications.end(); ++i) { - if (!(i->style & ACMatchClassification::URL)) { - is_url = false; - break; - } - } - - // Split the text into visual runs. We do this first so that we don't need to - // worry about whether our eliding might change the visual display in - // unintended ways, e.g. by removing directional markings or by adding an - // ellipsis that's not enclosed in appropriate markings. - BiDiLineIterator bidi_line; - if (!bidi_line.Open(text, base::i18n::IsRTL(), is_url)) - return x; - const int num_runs = bidi_line.CountRuns(); - Runs runs; - for (int run = 0; run < num_runs; ++run) { - int run_start_int = 0, run_length_int = 0; - // The index we pass to GetVisualRun corresponds to the position of the run - // in the displayed text. For example, the string "Google in HEBREW" (where - // HEBREW is text in the Hebrew language) has two runs: "Google in " which - // is an LTR run, and "HEBREW" which is an RTL run. In an LTR context, the - // run "Google in " has the index 0 (since it is the leftmost run - // displayed). In an RTL context, the same run has the index 1 because it - // is the rightmost run. This is why the order in which we traverse the - // runs is different depending on the locale direction. - const UBiDiDirection run_direction = bidi_line.GetVisualRun( - (base::i18n::IsRTL() && !is_url) ? (num_runs - run - 1) : run, - &run_start_int, &run_length_int); - DCHECK_GT(run_length_int, 0); - runs.push_back(RunData()); - RunData* current_run = &runs.back(); - current_run->run_start = run_start_int; - const size_t run_end = current_run->run_start + run_length_int; - current_run->visual_order = run; - current_run->is_rtl = !is_url && (run_direction == UBIDI_RTL); - current_run->pixel_width = 0; - - // Compute classifications for this run. - for (size_t i = 0; i < classifications.size(); ++i) { - const size_t text_start = - std::max(classifications[i].offset, current_run->run_start); - if (text_start >= run_end) - break; // We're past the last classification in the run. - - const size_t text_end = (i < (classifications.size() - 1)) ? - std::min(classifications[i + 1].offset, run_end) : run_end; - if (text_end <= current_run->run_start) - continue; // We haven't reached the first classification in the run. - - current_run->classifications.push_back(ClassificationData()); - ClassificationData* current_data = - ¤t_run->classifications.back(); - current_data->text = text.substr(text_start, text_end - text_start); - - // Calculate style-related data. - const int style = classifications[i].style; - const bool use_bold_font = !!(style & ACMatchClassification::MATCH); - current_data->font = &(use_bold_font ? bold_font_ : normal_font_); - const ResultViewState state = GetState(); - if (style & ACMatchClassification::URL) - current_data->color = GetColor(state, URL); - else if (style & ACMatchClassification::DIM) - current_data->color = GetColor(state, DIMMED_TEXT); - else - current_data->color = GetColor(state, force_dim ? DIMMED_TEXT : TEXT); - current_data->pixel_width = - current_data->font->GetStringWidth(current_data->text); - current_run->pixel_width += current_data->pixel_width; - } - DCHECK(!current_run->classifications.empty()); - } - DCHECK(!runs.empty()); - - // Sort into logical order so we can elide logically. - std::sort(runs.begin(), runs.end(), &SortRunsLogically); - - // Now determine what to elide, if anything. Several subtle points: - // * Because we have the run data, we can get edge cases correct, like - // whether to place an ellipsis before or after the end of a run when the - // text needs to be elided at the run boundary. - // * The "or one before it" comments below refer to cases where an earlier - // classification fits completely, but leaves too little space for an - // ellipsis that turns out to be needed later. These cases are commented - // more completely in Elide(). - int remaining_width = mirroring_context_->remaining_width(x); - for (Runs::iterator i(runs.begin()); i != runs.end(); ++i) { - if (i->pixel_width > remaining_width) { - // This run or one before it needs to be elided. - for (Classifications::iterator j(i->classifications.begin()); - j != i->classifications.end(); ++j) { - if (j->pixel_width > remaining_width) { - // This classification or one before it needs to be elided. Erase all - // further classifications and runs so Elide() can simply reverse- - // iterate over everything to find the specific classification to - // elide. - i->classifications.erase(++j, i->classifications.end()); - runs.erase(++i, runs.end()); - Elide(&runs, remaining_width); - break; - } - remaining_width -= j->pixel_width; - } - break; - } - remaining_width -= i->pixel_width; - } - - // Sort back into visual order so we can display the runs correctly. - std::sort(runs.begin(), runs.end(), &SortRunsVisually); - - // Draw the runs. - for (Runs::iterator i(runs.begin()); i != runs.end(); ++i) { - const bool reverse_visible_order = (i->is_rtl != base::i18n::IsRTL()); - int flags = gfx::Canvas::NO_ELLIPSIS; // We've already elided. - if (reverse_visible_order) { - std::reverse(i->classifications.begin(), i->classifications.end()); - if (i->is_rtl) - flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY; - } - for (Classifications::const_iterator j(i->classifications.begin()); - j != i->classifications.end(); ++j) { - int left = mirroring_context_->mirrored_left_coord(x, x + j->pixel_width); - canvas->DrawStringInt(j->text, *j->font, j->color, left, y, - j->pixel_width, j->font->GetHeight(), flags); - x += j->pixel_width; - } - } - - return x; -} - -void AutocompleteResultView::Elide(Runs* runs, int remaining_width) const { - // The complexity of this function is due to edge cases like the following: - // We have 100 px of available space, an initial classification that takes 86 - // px, and a font that has a 15 px wide ellipsis character. Now if the first - // classification is followed by several very narrow classifications (e.g. 3 - // px wide each), we don't know whether we need to elide or not at the time we - // see the first classification -- it depends on how many subsequent - // classifications follow, and some of those may be in the next run (or - // several runs!). This is why instead we let our caller move forward until - // we know we definitely need to elide, and then in this function we move - // backward again until we find a string that we can successfully do the - // eliding on. - bool first_classification = true; - for (Runs::reverse_iterator i(runs->rbegin()); i != runs->rend(); ++i) { - for (Classifications::reverse_iterator j(i->classifications.rbegin()); - j != i->classifications.rend(); ++j) { - if (!first_classification) { - // For all but the first classification we consider, we need to append - // an ellipsis, since there isn't enough room to draw it after this - // classification. - j->text += kEllipsis; - - // We also add this classification's width (sans ellipsis) back to the - // available width since we want to consider the available space we'll - // have when we draw this classification. - remaining_width += j->pixel_width; - } - first_classification = false; - - // Can we fit at least an ellipsis? - std::wstring elided_text(UTF16ToWideHack( - gfx::ElideText(WideToUTF16Hack(j->text), *j->font, remaining_width, - false))); - Classifications::reverse_iterator prior_classification(j); - ++prior_classification; - const bool on_first_classification = - (prior_classification == i->classifications.rend()); - if (elided_text.empty() && (remaining_width >= ellipsis_width_) && - on_first_classification) { - // Edge case: This classification is bold, we can't fit a bold ellipsis - // but we can fit a normal one, and this is the first classification in - // the run. We should display a lone normal ellipsis, because appending - // one to the end of the previous run might put it in the wrong visual - // location (if the previous run is reversed from the normal visual - // order). - // NOTE: If this isn't the first classification in the run, we don't - // need to bother with this; see note below. - elided_text = kEllipsis; - } - if (!elided_text.empty()) { - // Success. Elide this classification and stop. - j->text = elided_text; - - // If we could only fit an ellipsis, then only make it bold if there was - // an immediate prior classification in this run that was also bold, or - // it will look orphaned. - if ((elided_text.length() == 1) && - (on_first_classification || - (prior_classification->font == &normal_font_))) - j->font = &normal_font_; - - j->pixel_width = j->font->GetStringWidth(elided_text); - - // Erase any other classifications that come after the elided one. - i->classifications.erase(j.base(), i->classifications.end()); - runs->erase(i.base(), runs->end()); - return; - } - - // We couldn't fit an ellipsis. Move back one classification, - // append an ellipsis, and try again. - // NOTE: In the edge case that a bold ellipsis doesn't fit but a - // normal one would, and we reach here, then there is a previous - // classification in this run, and so either: - // * It's normal, and will be able to draw successfully with the - // ellipsis we'll append to it, or - // * It is also bold, in which case we don't want to fall back - // to a normal ellipsis anyway (see comment above). - } - } - - // We couldn't draw anything. - runs->clear(); -} - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupContentsView, public: - -AutocompletePopupContentsView::AutocompletePopupContentsView( - const gfx::Font& font, - AutocompleteEditView* edit_view, - AutocompleteEditModel* edit_model, - Profile* profile, - const views::View* location_bar) - : model_(new AutocompletePopupModel(this, edit_model, profile)), - edit_view_(edit_view), - location_bar_(location_bar), - result_font_(font.DeriveFont(kEditFontAdjust)), - result_bold_font_(result_font_.DeriveFont(0, gfx::Font::BOLD)), - ignore_mouse_drag_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)), - opt_in_view_(NULL) { - // The following little dance is required because set_border() requires a - // pointer to a non-const object. - BubbleBorder* bubble_border = new BubbleBorder(BubbleBorder::NONE); - bubble_border_ = bubble_border; - set_border(bubble_border); -} - -AutocompletePopupContentsView::~AutocompletePopupContentsView() { - // We don't need to do anything with |popup_| here. The OS either has already - // closed the window, in which case it's been deleted, or it will soon, in - // which case there's nothing we need to do. -} - -gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { - if (!size_animation_.is_animating()) - return target_bounds_; - - gfx::Rect current_frame_bounds = start_bounds_; - int total_height_delta = target_bounds_.height() - start_bounds_.height(); - // Round |current_height_delta| instead of truncating so we won't leave single - // white pixels at the bottom of the popup as long when animating very small - // height differences. - int current_height_delta = static_cast<int>( - size_animation_.GetCurrentValue() * total_height_delta - 0.5); - current_frame_bounds.set_height( - current_frame_bounds.height() + current_height_delta); - return current_frame_bounds; -} - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupContentsView, AutocompletePopupView overrides: - -bool AutocompletePopupContentsView::IsOpen() const { - return (popup_ != NULL); -} - -void AutocompletePopupContentsView::InvalidateLine(size_t line) { - GetChildViewAt(static_cast<int>(line))->SchedulePaint(); -} - -void AutocompletePopupContentsView::UpdatePopupAppearance() { - if (model_->result().empty()) { - // No matches, close any existing popup. - if (popup_ != NULL) { - size_animation_.Stop(); - // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack - // triggered by the popup receiving a message (e.g. LBUTTONUP), and - // destroying the popup would cause us to read garbage when we unwind back - // to that level. - popup_->Close(); // This will eventually delete the popup. - popup_.reset(); - } - return; - } - - // Update the match cached by each row, in the process of doing so make sure - // we have enough row views. - int total_child_height = 0; - size_t child_rv_count = GetChildViewCount(); - if (opt_in_view_) { - DCHECK(child_rv_count > 0); - child_rv_count--; - } - for (size_t i = 0; i < model_->result().size(); ++i) { - AutocompleteResultView* result_view; - if (i >= child_rv_count) { - result_view = - new AutocompleteResultView(this, i, result_font_, result_bold_font_); - AddChildView(static_cast<int>(i), result_view); - } else { - result_view = static_cast<AutocompleteResultView*>(GetChildViewAt(i)); - result_view->SetVisible(true); - } - result_view->set_match(GetMatchAtIndex(i)); - total_child_height += result_view->GetPreferredSize().height(); - } - for (size_t i = model_->result().size(); i < child_rv_count; ++i) - GetChildViewAt(i)->SetVisible(false); - - if (!opt_in_view_ && browser::ShouldShowInstantOptIn(model_->profile())) { - opt_in_view_ = new InstantOptInView(this, result_bold_font_, result_font_); - AddChildView(opt_in_view_); - } - - if (opt_in_view_) - total_child_height += opt_in_view_->GetPreferredSize().height(); - - gfx::Rect new_target_bounds = CalculateTargetBounds(total_child_height); - - // If we're animating and our target height changes, reset the animation. - // NOTE: If we just reset blindly on _every_ update, then when the user types - // rapidly we could get "stuck" trying repeatedly to animate shrinking by the - // last few pixels to get to one visible result. - if (new_target_bounds.height() != target_bounds_.height()) - size_animation_.Reset(); - target_bounds_ = new_target_bounds; - - if (popup_ == NULL) { - // If the popup is currently closed, we need to create it. - popup_ = (new AutocompletePopupClass(edit_view_, this))->AsWeakPtr(); - } else { - // Animate the popup shrinking, but don't animate growing larger since that - // would make the popup feel less responsive. - GetWidget()->GetBounds(&start_bounds_, true); - if (target_bounds_.height() < start_bounds_.height()) - size_animation_.Show(); - else - start_bounds_ = target_bounds_; - popup_->SetBounds(GetPopupBounds()); - } - - SchedulePaint(); -} - -gfx::Rect AutocompletePopupContentsView::GetTargetBounds() { - return target_bounds_; -} - -void AutocompletePopupContentsView::PaintUpdatesNow() { - // TODO(beng): remove this from the interface. -} - -void AutocompletePopupContentsView::OnDragCanceled() { - ignore_mouse_drag_ = true; -} - -AutocompletePopupModel* AutocompletePopupContentsView::GetModel() { - return model_.get(); -} - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupContentsView, AutocompleteResultViewModel implementation: - -bool AutocompletePopupContentsView::IsSelectedIndex(size_t index) const { - return HasMatchAt(index) ? index == model_->selected_line() : false; -} - -bool AutocompletePopupContentsView::IsHoveredIndex(size_t index) const { - return HasMatchAt(index) ? index == model_->hovered_line() : false; -} - -const SkBitmap* AutocompletePopupContentsView::GetSpecialIcon( - size_t index) const { - if (!HasMatchAt(index)) - return NULL; - return model_->GetSpecialIconForMatch(GetMatchAtIndex(index)); -} - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupContentsView, AnimationDelegate implementation: - -void AutocompletePopupContentsView::AnimationProgressed( - const Animation* animation) { - // We should only be running the animation when the popup is already visible. - DCHECK(popup_ != NULL); - popup_->SetBounds(GetPopupBounds()); -} - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupContentsView, views::View overrides: - -void AutocompletePopupContentsView::Paint(gfx::Canvas* canvas) { - // We paint our children in an unconventional way. - // - // Because the border of this view creates an anti-aliased round-rect region - // for the contents, we need to render our rectangular result child views into - // this round rect region. We can't use a simple clip because clipping is - // 1-bit and we get nasty jagged edges. - // - // Instead, we paint all our children into a second canvas and use that as a - // shader to fill a path representing the round-rect clipping region. This - // yields a nice anti-aliased edge. - gfx::CanvasSkia contents_canvas(width(), height(), true); - contents_canvas.drawColor(GetColor(NORMAL, BACKGROUND)); - View::PaintChildren(&contents_canvas); - // We want the contents background to be slightly transparent so we can see - // the blurry glass effect on DWM systems behind. We do this _after_ we paint - // the children since they paint text, and GDI will reset this alpha data if - // we paint text after this call. - MakeCanvasTransparent(&contents_canvas); - - // Now paint the contents of the contents canvas into the actual canvas. - SkPaint paint; - paint.setAntiAlias(true); - - SkShader* shader = SkShader::CreateBitmapShader( - contents_canvas.getDevice()->accessBitmap(false), - SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode); - paint.setShader(shader); - shader->unref(); - - gfx::Path path; - MakeContentsPath(&path, GetLocalBounds(false)); - canvas->AsCanvasSkia()->drawPath(path, paint); - - // Now we paint the border, so it will be alpha-blended atop the contents. - // This looks slightly better in the corners than drawing the contents atop - // the border. - PaintBorder(canvas); -} - -void AutocompletePopupContentsView::Layout() { - UpdateBlurRegion(); - - // Size our children to the available content area. - gfx::Rect contents_rect = GetLocalBounds(false); - int child_count = GetChildViewCount(); - int top = contents_rect.y(); - for (int i = 0; i < child_count; ++i) { - View* v = GetChildViewAt(i); - if (v->IsVisible()) { - v->SetBounds(contents_rect.x(), top, contents_rect.width(), - v->GetPreferredSize().height()); - top = v->bounds().bottom(); - } - } - - // We need to manually schedule a paint here since we are a layered window and - // won't implicitly require painting until we ask for one. - SchedulePaint(); -} - - -void AutocompletePopupContentsView::OnMouseEntered( - const views::MouseEvent& event) { - model_->SetHoveredLine(GetIndexForPoint(event.location())); -} - -void AutocompletePopupContentsView::OnMouseMoved( - const views::MouseEvent& event) { - model_->SetHoveredLine(GetIndexForPoint(event.location())); -} - -void AutocompletePopupContentsView::OnMouseExited( - const views::MouseEvent& event) { - model_->SetHoveredLine(AutocompletePopupModel::kNoMatch); -} - -bool AutocompletePopupContentsView::OnMousePressed( - const views::MouseEvent& event) { - ignore_mouse_drag_ = false; // See comment on |ignore_mouse_drag_| in header. - if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) { - size_t index = GetIndexForPoint(event.location()); - model_->SetHoveredLine(index); - if (HasMatchAt(index) && event.IsLeftMouseButton()) - model_->SetSelectedLine(index, false); - } - return true; -} - -void AutocompletePopupContentsView::OnMouseReleased( - const views::MouseEvent& event, - bool canceled) { - if (canceled || ignore_mouse_drag_) { - ignore_mouse_drag_ = false; - return; - } - - size_t index = GetIndexForPoint(event.location()); - if (event.IsOnlyMiddleMouseButton()) - OpenIndex(index, NEW_BACKGROUND_TAB); - else if (event.IsOnlyLeftMouseButton()) - OpenIndex(index, CURRENT_TAB); -} - -bool AutocompletePopupContentsView::OnMouseDragged( - const views::MouseEvent& event) { - if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) { - size_t index = GetIndexForPoint(event.location()); - model_->SetHoveredLine(index); - if (!ignore_mouse_drag_ && HasMatchAt(index) && event.IsLeftMouseButton()) - model_->SetSelectedLine(index, false); - } - return true; -} - -views::View* AutocompletePopupContentsView::GetViewForPoint( - const gfx::Point& point) { - // If there is no opt in view, then we want all mouse events. Otherwise let - // any descendants of the opt-in view get mouse events. - if (!opt_in_view_) - return this; - - views::View* child = views::View::GetViewForPoint(point); - views::View* ancestor = child; - while (ancestor && ancestor != opt_in_view_) - ancestor = ancestor->GetParent(); - return ancestor ? child : this; -} - - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupContentsView, private: - -bool AutocompletePopupContentsView::HasMatchAt(size_t index) const { - return index < model_->result().size(); -} - -const AutocompleteMatch& AutocompletePopupContentsView::GetMatchAtIndex( - size_t index) const { - return model_->result().match_at(index); -} - -void AutocompletePopupContentsView::MakeContentsPath( - gfx::Path* path, - const gfx::Rect& bounding_rect) { - SkRect rect; - rect.set(SkIntToScalar(bounding_rect.x()), - SkIntToScalar(bounding_rect.y()), - SkIntToScalar(bounding_rect.right()), - SkIntToScalar(bounding_rect.bottom())); - - SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); - path->addRoundRect(rect, radius, radius); -} - -void AutocompletePopupContentsView::UpdateBlurRegion() { -#if defined(OS_WIN) - // We only support background blurring on Vista with Aero-Glass enabled. - if (!win_util::ShouldUseVistaFrame() || !GetWidget()) - return; - - // Provide a blurred background effect within the contents region of the - // popup. - DWM_BLURBEHIND bb = {0}; - bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; - bb.fEnable = true; - - // Translate the contents rect into widget coordinates, since that's what - // DwmEnableBlurBehindWindow expects a region in. - gfx::Rect contents_rect = GetLocalBounds(false); - gfx::Point origin(contents_rect.origin()); - views::View::ConvertPointToWidget(this, &origin); - contents_rect.set_origin(origin); - - gfx::Path contents_path; - MakeContentsPath(&contents_path, contents_rect); - ScopedGDIObject<HRGN> popup_region; - popup_region.Set(contents_path.CreateNativeRegion()); - bb.hRgnBlur = popup_region.Get(); - DwmEnableBlurBehindWindow(GetWidget()->GetNativeView(), &bb); -#endif -} - -void AutocompletePopupContentsView::MakeCanvasTransparent( - gfx::Canvas* canvas) { - // Allow the window blur effect to show through the popup background. - SkAlpha alpha = GetThemeProvider()->ShouldUseNativeFrame() ? - kGlassPopupAlpha : kOpaquePopupAlpha; - canvas->AsCanvasSkia()->drawColor( - SkColorSetA(GetColor(NORMAL, BACKGROUND), alpha), - SkXfermode::kDstIn_Mode); -} - -void AutocompletePopupContentsView::OpenIndex( - size_t index, - WindowOpenDisposition disposition) { - if (!HasMatchAt(index)) - return; - - const AutocompleteMatch& match = model_->result().match_at(index); - // OpenURL() may close the popup, which will clear the result set and, by - // extension, |match| and its contents. So copy the relevant strings out to - // make sure they stay alive until the call completes. - const GURL url(match.destination_url); - std::wstring keyword; - const bool is_keyword_hint = model_->GetKeywordForMatch(match, &keyword); - edit_view_->OpenURL(url, disposition, match.transition, GURL(), index, - is_keyword_hint ? std::wstring() : keyword); -} - -size_t AutocompletePopupContentsView::GetIndexForPoint( - const gfx::Point& point) { - if (!HitTest(point)) - return AutocompletePopupModel::kNoMatch; - - int nb_match = model_->result().size(); - DCHECK(nb_match <= GetChildViewCount()); - for (int i = 0; i < nb_match; ++i) { - views::View* child = GetChildViewAt(i); - gfx::Point point_in_child_coords(point); - View::ConvertPointToView(this, child, &point_in_child_coords); - if (child->HitTest(point_in_child_coords)) - return i; - } - return AutocompletePopupModel::kNoMatch; -} - -gfx::Rect AutocompletePopupContentsView::CalculateTargetBounds(int h) { - gfx::Rect location_bar_bounds(gfx::Point(), location_bar_->size()); - const views::Border* border = location_bar_->border(); - if (border) { - // Adjust for the border so that the bubble and location bar borders are - // aligned. - gfx::Insets insets; - border->GetInsets(&insets); - location_bar_bounds.Inset(insets.left(), 0, insets.right(), 0); - } else { - // The normal location bar is drawn using a background graphic that includes - // the border, so we inset by enough to make the edges line up, and the - // bubble appear at the same height as the Star bubble. - location_bar_bounds.Inset(LocationBarView::kNormalHorizontalEdgeThickness, - 0); - } - gfx::Point location_bar_origin(location_bar_bounds.origin()); - views::View::ConvertPointToScreen(location_bar_, &location_bar_origin); - location_bar_bounds.set_origin(location_bar_origin); - return bubble_border_->GetBounds( - location_bar_bounds, gfx::Size(location_bar_bounds.width(), h)); -} - -void AutocompletePopupContentsView::UserPressedOptIn(bool opt_in) { - delete opt_in_view_; - opt_in_view_ = NULL; - browser::UserPickedInstantOptIn(location_bar_->GetWindow()->GetNativeWindow(), - model_->profile(), opt_in); - UpdatePopupAppearance(); -} diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h index 9a3e2bc..770818d 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h +++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h @@ -6,172 +6,8 @@ #define CHROME_BROWSER_VIEWS_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_CONTENTS_VIEW_H_ #pragma once -#include "app/slide_animation.h" -#include "chrome/browser/autocomplete/autocomplete.h" -#include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/autocomplete/autocomplete_popup_view.h" -#include "gfx/font.h" -#include "views/view.h" -#include "webkit/glue/window_open_disposition.h" - -#if defined(OS_WIN) -#include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" -#else -#include "chrome/browser/views/autocomplete/autocomplete_popup_gtk.h" -#endif - -class AutocompleteEditModel; -class AutocompleteEditViewWin; -struct AutocompleteMatch; -class BubbleBorder; -class Profile; - -// An interface implemented by an object that provides data to populate -// individual result views. -class AutocompleteResultViewModel { - public: - // Returns true if the index is selected. - virtual bool IsSelectedIndex(size_t index) const = 0; - - // Returns true if the index is hovered. - virtual bool IsHoveredIndex(size_t index) const = 0; - - // Returns the special-case icon we should use for the given index, or NULL - // if we should use the default icon. - virtual const SkBitmap* GetSpecialIcon(size_t index) const = 0; -}; - -// A view representing the contents of the autocomplete popup. -class AutocompletePopupContentsView : public views::View, - public AutocompleteResultViewModel, - public AutocompletePopupView, - public AnimationDelegate { - public: - AutocompletePopupContentsView(const gfx::Font& font, - AutocompleteEditView* edit_view, - AutocompleteEditModel* edit_model, - Profile* profile, - const views::View* location_bar); - virtual ~AutocompletePopupContentsView(); - - // Returns the bounds the popup should be shown at. This is the display bounds - // and includes offsets for the dropshadow which this view's border renders. - gfx::Rect GetPopupBounds() const; - - // Overridden from AutocompletePopupView: - virtual bool IsOpen() const; - virtual void InvalidateLine(size_t line); - virtual void UpdatePopupAppearance(); - virtual gfx::Rect GetTargetBounds(); - virtual void PaintUpdatesNow(); - virtual void OnDragCanceled(); - virtual AutocompletePopupModel* GetModel(); - - // Overridden from AutocompleteResultViewModel: - virtual bool IsSelectedIndex(size_t index) const; - virtual bool IsHoveredIndex(size_t index) const; - virtual const SkBitmap* GetSpecialIcon(size_t index) const; - - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation); - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void PaintChildren(gfx::Canvas* canvas) { - // We paint our children inside Paint(). - } - virtual void Layout(); - virtual void OnMouseEntered(const views::MouseEvent& event); - virtual void OnMouseMoved(const views::MouseEvent& event); - virtual void OnMouseExited(const views::MouseEvent& event); - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - virtual bool OnMouseDragged(const views::MouseEvent& event); - virtual views::View* GetViewForPoint(const gfx::Point& point); - - private: -#if defined(OS_WIN) - typedef AutocompletePopupWin AutocompletePopupClass; -#else - typedef AutocompletePopupGtk AutocompletePopupClass; -#endif - class InstantOptInView; - - // Returns true if the model has a match at the specified index. - bool HasMatchAt(size_t index) const; - - // Returns the match at the specified index within the popup model. - const AutocompleteMatch& GetMatchAtIndex(size_t index) const; - - // Fill a path for the contents' roundrect. |bounding_rect| is the rect that - // bounds the path. - void MakeContentsPath(gfx::Path* path, const gfx::Rect& bounding_rect); - - // Updates the window's blur region for the current size. - void UpdateBlurRegion(); - - // Makes the contents of the canvas slightly transparent. - void MakeCanvasTransparent(gfx::Canvas* canvas); - - // Called when the line at the specified index should be opened with the - // provided disposition. - void OpenIndex(size_t index, WindowOpenDisposition disposition); - - // Find the index of the match under the given |point|, specified in window - // coordinates. Returns AutocompletePopupModel::kNoMatch if there isn't a - // match at the specified point. - size_t GetIndexForPoint(const gfx::Point& point); - - // Returns the target bounds given the specified content height. - gfx::Rect CalculateTargetBounds(int h); - - // Invoked if the user clicks on one of the opt-in buttons. Removes the opt-in - // view. - void UserPressedOptIn(bool opt_in); - - // The popup that contains this view. We create this, but it deletes itself - // when its window is destroyed. This is a WeakPtr because it's possible for - // the OS to destroy the window and thus delete this object before we're - // deleted, or without our knowledge. - base::WeakPtr<AutocompletePopupClass> popup_; - - // The provider of our result set. - scoped_ptr<AutocompletePopupModel> model_; - - // The edit view that invokes us. - AutocompleteEditView* edit_view_; - - // An object that the popup positions itself against. - const views::View* location_bar_; - - // Our border, which can compute our desired bounds. - const BubbleBorder* bubble_border_; - - // The font that we should use for result rows. This is based on the font used - // by the edit that created us. - gfx::Font result_font_; - - // The font used for portions that match the input. - gfx::Font result_bold_font_; - - // If the user cancels a dragging action (i.e. by pressing ESC), we don't have - // a convenient way to release mouse capture. Instead we use this flag to - // simply ignore all remaining drag events, and the eventual mouse release - // event. Since OnDragCanceled() can be called when we're not dragging, this - // flag is reset to false on a mouse pressed event, to make sure we don't - // erroneously ignore the next drag. - bool ignore_mouse_drag_; - - // The popup sizes vertically using an animation when the popup is getting - // shorter (not larger, that makes it look "slow"). - SlideAnimation size_animation_; - gfx::Rect start_bounds_; - gfx::Rect target_bounds_; - - // If non-NULL the instant opt-in-view is visible. - views::View* opt_in_view_; - - DISALLOW_COPY_AND_ASSIGN(AutocompletePopupContentsView); -}; +#include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_CONTENTS_VIEW_H_ + diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_gtk.cc b/chrome/browser/views/autocomplete/autocomplete_popup_gtk.cc deleted file mode 100644 index 4bb7f09..0000000 --- a/chrome/browser/views/autocomplete/autocomplete_popup_gtk.cc +++ /dev/null @@ -1,37 +0,0 @@ -// 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/autocomplete/autocomplete_popup_gtk.h" - -#include "chrome/browser/autocomplete/autocomplete_edit_view.h" -#include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/gtk/gtk_util.h" -#include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" -#include "gfx/insets.h" - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupGtk, public: - -AutocompletePopupGtk::AutocompletePopupGtk( - AutocompleteEditView* edit_view, - AutocompletePopupContentsView* contents) - : WidgetGtk(WidgetGtk::TYPE_POPUP) { - // Create the popup. - MakeTransparent(); - WidgetGtk::Init(gtk_widget_get_parent(edit_view->GetNativeView()), - contents->GetPopupBounds()); - // The contents is owned by the LocationBarView. - contents->set_parent_owned(false); - SetContentsView(contents); - - Show(); - - // Restack the popup window directly above the browser's toplevel window. - GtkWidget* toplevel = gtk_widget_get_toplevel(edit_view->GetNativeView()); - DCHECK(GTK_WIDGET_TOPLEVEL(toplevel)); - gtk_util::StackPopupWindow(GetNativeView(), toplevel); -} - -AutocompletePopupGtk::~AutocompletePopupGtk() { -} diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_gtk.h b/chrome/browser/views/autocomplete/autocomplete_popup_gtk.h index 461420a..f3a156f 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_gtk.h +++ b/chrome/browser/views/autocomplete/autocomplete_popup_gtk.h @@ -6,23 +6,8 @@ #define CHROME_BROWSER_VIEWS_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_GTK_H_ #pragma once -#include "base/weak_ptr.h" -#include "views/widget/widget_gtk.h" - -class AutocompleteEditView; -class AutocompletePopupContentsView; - -class AutocompletePopupGtk - : public views::WidgetGtk, - public base::SupportsWeakPtr<AutocompletePopupGtk> { - public: - // Creates the popup and shows it. |edit_view| is the edit that created us. - AutocompletePopupGtk(AutocompleteEditView* edit_view, - AutocompletePopupContentsView* contents); - virtual ~AutocompletePopupGtk(); - - private: - DISALLOW_COPY_AND_ASSIGN(AutocompletePopupGtk); -}; +#include "chrome/browser/ui/views/autocomplete/autocomplete_popup_gtk.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_GTK_H_ + diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_win.cc b/chrome/browser/views/autocomplete/autocomplete_popup_win.cc deleted file mode 100644 index e720108..0000000 --- a/chrome/browser/views/autocomplete/autocomplete_popup_win.cc +++ /dev/null @@ -1,46 +0,0 @@ -// 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/autocomplete/autocomplete_popup_win.h" - -#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" -#include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" -#include "gfx/insets.h" - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupWin, public: - -AutocompletePopupWin::AutocompletePopupWin( - AutocompleteEditView* edit_view, - AutocompletePopupContentsView* contents) { - // Create the popup. - set_window_style(WS_POPUP | WS_CLIPCHILDREN); - set_window_ex_style(WS_EX_TOOLWINDOW | WS_EX_LAYERED); - WidgetWin::Init(GetAncestor(edit_view->GetNativeView(), GA_ROOT), - contents->GetPopupBounds()); - // The contents is owned by the LocationBarView. - contents->set_parent_owned(false); - SetContentsView(contents); - - // When an IME is attached to the rich-edit control, retrieve its window - // handle and show this popup window under the IME windows. - // Otherwise, show this popup window under top-most windows. - // TODO(hbono): http://b/1111369 if we exclude this popup window from the - // display area of IME windows, this workaround becomes unnecessary. - HWND ime_window = ImmGetDefaultIMEWnd(edit_view->GetNativeView()); - SetWindowPos(ime_window ? ime_window : HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW); -} - -AutocompletePopupWin::~AutocompletePopupWin() { -} - -//////////////////////////////////////////////////////////////////////////////// -// AutocompletePopupWin, WidgetWin overrides: - -LRESULT AutocompletePopupWin::OnMouseActivate(HWND window, UINT hit_test, - UINT mouse_message) { - return MA_NOACTIVATE; -} diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_win.h b/chrome/browser/views/autocomplete/autocomplete_popup_win.h index cf6a364..68fa02c 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_win.h +++ b/chrome/browser/views/autocomplete/autocomplete_popup_win.h @@ -6,28 +6,8 @@ #define CHROME_BROWSER_VIEWS_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_WIN_H_ #pragma once -#include "base/weak_ptr.h" -#include "views/widget/widget_win.h" - -class AutocompleteEditView; -class AutocompletePopupContentsView; - -class AutocompletePopupWin - : public views::WidgetWin, - public base::SupportsWeakPtr<AutocompletePopupWin> { - public: - // Creates the popup and shows it. |edit_view| is the edit that created us. - AutocompletePopupWin(AutocompleteEditView* edit_view, - AutocompletePopupContentsView* contents); - virtual ~AutocompletePopupWin(); - - private: - // Overridden from WidgetWin: - virtual LRESULT OnMouseActivate(HWND window, - UINT hit_test, - UINT mouse_message); - - DISALLOW_COPY_AND_ASSIGN(AutocompletePopupWin); -}; +#include "chrome/browser/ui/views/autocomplete/autocomplete_popup_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_WIN_H_ + diff --git a/chrome/browser/views/autofill_profiles_view_win.cc b/chrome/browser/views/autofill_profiles_view_win.cc deleted file mode 100644 index 414e0ba..0000000 --- a/chrome/browser/views/autofill_profiles_view_win.cc +++ /dev/null @@ -1,1327 +0,0 @@ -// 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/autofill_profiles_view_win.h" - -#include <vsstyle.h> -#include <vssym32.h> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/message_loop.h" -#include "base/string16.h" -#include "base/string_number_conversions.h" -#include "base/time.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/autofill/autofill_manager.h" -#include "chrome/browser/autofill/phone_number.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/list_background.h" -#include "chrome/browser/window_sizer.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas.h" -#include "gfx/native_theme_win.h" -#include "gfx/size.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "views/border.h" -#include "views/controls/button/image_button.h" -#include "views/controls/button/native_button.h" -#include "views/controls/button/radio_button.h" -#include "views/controls/button/text_button.h" -#include "views/controls/label.h" -#include "views/controls/scroll_view.h" -#include "views/controls/separator.h" -#include "views/controls/table/table_view.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -namespace { - -// padding on the sides of AutoFill settings dialog. -const int kDialogPadding = 7; - -// Insets for subview controls. -const int kSubViewHorizotalInsets = 18; -const int kSubViewVerticalInsets = 5; - -}; // namespace - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, static data: -AutoFillProfilesView* AutoFillProfilesView::instance_ = NULL; - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, public: -AutoFillProfilesView::AutoFillProfilesView( - AutoFillDialogObserver* observer, - PersonalDataManager* personal_data_manager, - Profile* profile, - PrefService* preferences, - AutoFillProfile* imported_profile, - CreditCard* imported_credit_card) - : observer_(observer), - personal_data_manager_(personal_data_manager), - profile_(profile), - preferences_(preferences), - enable_auto_fill_button_(NULL), - add_address_button_(NULL), - add_credit_card_button_(NULL), - edit_button_(NULL), - remove_button_(NULL), - scroll_view_(NULL), - focus_manager_(NULL), - child_dialog_opened_(false) { - DCHECK(preferences_); - enable_auto_fill_.Init(prefs::kAutoFillEnabled, preferences_, this); - if (imported_profile) { - profiles_set_.push_back(EditableSetInfo(imported_profile)); - } - if (imported_credit_card) { - credit_card_set_.push_back( - EditableSetInfo(imported_credit_card)); - } - personal_data_manager_->SetObserver(this); -} - -AutoFillProfilesView::~AutoFillProfilesView() { - // Clear model as it gets deleted before the view. - if (scroll_view_) - scroll_view_->SetModel(NULL); - - if (personal_data_manager_) - personal_data_manager_->RemoveObserver(this); -} - -// TODO: get rid of imported_profile and imported_credit_card. -int AutoFillProfilesView::Show(gfx::NativeWindow parent, - AutoFillDialogObserver* observer, - PersonalDataManager* personal_data_manager, - Profile* profile, - PrefService* preferences, - AutoFillProfile* imported_profile, - CreditCard* imported_credit_card) { - if (!instance_) { - instance_ = new AutoFillProfilesView(observer, personal_data_manager, - profile, preferences, imported_profile, imported_credit_card); - - // |instance_| will get deleted once Close() is called. - views::Window::CreateChromeWindow(parent, gfx::Rect(), instance_); - } - if (!instance_->window()->IsVisible()) - instance_->window()->Show(); - else - instance_->window()->Activate(); - return 0; -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, protected: -void AutoFillProfilesView::AddClicked(int group_type) { - scoped_ptr<EditableSetInfo> info; - std::vector<EditableSetInfo>::iterator it = profiles_set_.end(); - int added_item_index = -1; - if (group_type == ContentListTableModel::kAddressGroup) { - AutoFillProfile address; - info.reset(new EditableSetInfo(&address)); - } else if (group_type == ContentListTableModel::kCreditCardGroup) { - CreditCard credit_card; - info.reset(new EditableSetInfo(&credit_card)); - } else { - NOTREACHED(); - } - EditableSetViewContents *edit_view = new - EditableSetViewContents(this, true, *info); - views::Window::CreateChromeWindow(window()->GetNativeWindow(), gfx::Rect(), - edit_view); - edit_view->window()->Show(); -} - -void AutoFillProfilesView::EditClicked() { - int index = scroll_view_->FirstSelectedRow(); - if (index == -1) - return; // Happens if user double clicks and the table is empty. - DCHECK(index >= 0); - DCHECK(index < static_cast<int>(profiles_set_.size() + - credit_card_set_.size())); - std::vector<EditableSetInfo>::iterator it; - if (index < static_cast<int>(profiles_set_.size())) - it = profiles_set_.begin() + index; - else - it = credit_card_set_.begin() + (index - profiles_set_.size()); - - EditableSetViewContents *edit_view = new - EditableSetViewContents(this, false, *it); - views::Window::CreateChromeWindow(window()->GetNativeWindow(), gfx::Rect(), - edit_view); - edit_view->window()->Show(); -} - -void AutoFillProfilesView::DeleteClicked() { - DCHECK_GT(scroll_view_->SelectedRowCount(), 0); - int last_view_row = -1; - for (views::TableView::iterator i = scroll_view_->SelectionBegin(); - i != scroll_view_->SelectionEnd(); ++i) { - last_view_row = scroll_view_->ModelToView(*i); - table_model_->RemoveItem(*i); - } - if (last_view_row >= table_model_->RowCount()) - last_view_row = table_model_->RowCount() - 1; - if (last_view_row >= 0) - scroll_view_->Select(scroll_view_->ViewToModel(last_view_row)); - UpdateWidgetState(); - SaveData(); -} - -void AutoFillProfilesView::EditAccepted(EditableSetInfo* data, - bool new_item) { - DCHECK(data); - std::vector<EditableSetInfo>::iterator it; - it = data->is_address ? profiles_set_.begin() : credit_card_set_.begin(); - std::vector<EditableSetInfo>::iterator end_it; - end_it = data->is_address ? profiles_set_.end() : credit_card_set_.end(); - for (; it != end_it; ++it) { - if (it->guid() == data->guid()) { - *it = *data; - break; - } - if (new_item) { - if (data->is_address) { - if (it->address.Compare(data->address) == 0) - break; - } else { - if (it->credit_card.Compare(data->credit_card) == 0) - break; - } - } - } - if (it == end_it) { - if (data->is_address) - profiles_set_.push_back(*data); - else - credit_card_set_.push_back(*data); - } - UpdateWidgetState(); - SaveData(); -} - -void AutoFillProfilesView::UpdateWidgetState() { - bool autofill_enabled = enable_auto_fill_.GetValue(); - enable_auto_fill_button_->SetChecked(autofill_enabled); - enable_auto_fill_button_->SetEnabled(!enable_auto_fill_.IsManaged()); - scroll_view_->SetEnabled(autofill_enabled); - add_address_button_->SetEnabled(personal_data_manager_->IsDataLoaded() && - !child_dialog_opened_ && autofill_enabled); - add_credit_card_button_->SetEnabled(personal_data_manager_->IsDataLoaded() && - !child_dialog_opened_ && - autofill_enabled); - - int selected_row_count = scroll_view_->SelectedRowCount(); - edit_button_->SetEnabled(selected_row_count == 1 && !child_dialog_opened_ && - autofill_enabled); - remove_button_->SetEnabled(selected_row_count > 0 && !child_dialog_opened_ && - autofill_enabled); -} - -void AutoFillProfilesView::ChildWindowOpened() { - child_dialog_opened_ = true; - UpdateWidgetState(); -} - -void AutoFillProfilesView::ChildWindowClosed() { - child_dialog_opened_ = false; - UpdateWidgetState(); -} - -SkBitmap* AutoFillProfilesView::GetWarningBitmap(bool good) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - return rb.GetBitmapNamed(good ? IDR_INPUT_GOOD : IDR_INPUT_ALERT); -} - - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, views::View implementations -void AutoFillProfilesView::Layout() { - View::Layout(); -} - -gfx::Size AutoFillProfilesView::GetPreferredSize() { - return views::Window::GetLocalizedContentsSize( - IDS_AUTOFILL_DIALOG_WIDTH_CHARS, - IDS_AUTOFILL_DIALOG_HEIGHT_LINES); -} - -void AutoFillProfilesView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, views::DialogDelegate implementations: -int AutoFillProfilesView::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring AutoFillProfilesView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return std::wstring(); - default: - break; - } - NOTREACHED(); - return std::wstring(); -} - -views::View* AutoFillProfilesView::GetExtraView() { - // The dialog sizes the extra view to fill the entire available space. - // We use a container to lay it out properly. - views::View* link_container = new views::View(); - views::GridLayout* layout = new views::GridLayout(link_container); - link_container->SetLayoutManager(layout); - - views::ColumnSet* column_set = layout->AddColumnSet(0); - column_set->AddPaddingColumn(0, kDialogPadding); - column_set->AddColumn(views::GridLayout::LEADING, - views::GridLayout::LEADING, 0, - views::GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, 0); - views::Link* link = new views::Link( - l10n_util::GetString(IDS_AUTOFILL_LEARN_MORE)); - link->SetController(this); - layout->AddView(link); - - return link_container; -} - -bool AutoFillProfilesView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return true; - default: - break; - } - NOTREACHED(); - return false; -} - - -std::wstring AutoFillProfilesView::GetWindowTitle() const { - return l10n_util::GetString(IDS_AUTOFILL_OPTIONS_TITLE); -} - -void AutoFillProfilesView::WindowClosing() { - focus_manager_->RemoveFocusChangeListener(this); - instance_ = NULL; -} - -views::View* AutoFillProfilesView::GetContentsView() { - return this; -} - -bool AutoFillProfilesView::Cancel() { - // No way to cancel - we save back all the info always. - return Accept(); -} - -bool AutoFillProfilesView::Accept() { - return true; -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, views::ButtonListener implementations: -void AutoFillProfilesView::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == add_address_button_) { - AddClicked(ContentListTableModel::kAddressGroup); - } else if (sender == add_credit_card_button_) { - AddClicked(ContentListTableModel::kCreditCardGroup); - } else if (sender == edit_button_) { - EditClicked(); - } else if (sender == remove_button_) { - DeleteClicked(); - } else if (sender == enable_auto_fill_button_) { - bool enabled = enable_auto_fill_button_->checked(); - UserMetricsAction action(enabled ? "Options_FormAutofill_Enable" : - "Options_FormAutofill_Disable"); - UserMetrics::RecordAction(action, profile_); - enable_auto_fill_.SetValueIfNotManaged(enabled); - preferences_->ScheduleSavePersistentPrefs(); - UpdateWidgetState(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, views::LinkController implementations: -void AutoFillProfilesView::LinkActivated(views::Link* source, int event_flags) { - Browser* browser = BrowserList::GetLastActive(); - if (!browser || !browser->GetSelectedTabContents()) - browser = Browser::Create(profile_); - browser->OpenAutoFillHelpTabAndActivate(); -} - - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, views::FocusChangeListener implementations: -void AutoFillProfilesView::FocusWillChange(views::View* focused_before, - views::View* focused_now) { - if (focused_now) { - focused_now->ScrollRectToVisible(gfx::Rect(focused_now->width(), - focused_now->height())); - } -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, views::TableViewObserver implementations: -void AutoFillProfilesView::OnSelectionChanged() { - UpdateWidgetState(); -} - -void AutoFillProfilesView::OnDoubleClick() { - if (!child_dialog_opened_) - EditClicked(); -} - - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, PersonalDataManager::Observer implementations. -void AutoFillProfilesView::OnPersonalDataLoaded() { - GetData(); -} - -void AutoFillProfilesView::OnPersonalDataChanged() { - profiles_set_.clear(); - for (std::vector<AutoFillProfile*>::const_iterator address_it = - personal_data_manager_->profiles().begin(); - address_it != personal_data_manager_->profiles().end(); - ++address_it) { - profiles_set_.push_back(EditableSetInfo(*address_it)); - } - - credit_card_set_.clear(); - for (std::vector<CreditCard*>::const_iterator cc_it = - personal_data_manager_->credit_cards().begin(); - cc_it != personal_data_manager_->credit_cards().end(); - ++cc_it) { - credit_card_set_.push_back(EditableSetInfo(*cc_it)); - } - - if (table_model_.get()) - table_model_->Refresh(); - - // Update state only if buttons already created. - if (add_address_button_) { - UpdateWidgetState(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, NotificationObserver implementation. -void AutoFillProfilesView::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); - const std::string* pref_name = Details<std::string>(details).ptr(); - if (!pref_name || *pref_name == prefs::kAutoFillEnabled) - UpdateWidgetState(); -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView, private: -void AutoFillProfilesView::Init() { - GetData(); - - enable_auto_fill_button_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_AUTOFILL_ENABLE)); - enable_auto_fill_button_->set_listener(this); - - table_model_.reset(new ContentListTableModel(&profiles_set_, - &credit_card_set_)); - std::vector<TableColumn> columns; - columns.push_back(TableColumn()); - scroll_view_ = new views::TableView(table_model_.get(), columns, - views::TEXT_ONLY, false, true, true); - scroll_view_->SetObserver(this); - - add_address_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_AUTOFILL_ADD_ADDRESS_BUTTON)); - add_credit_card_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_AUTOFILL_ADD_CREDITCARD_BUTTON)); - edit_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_AUTOFILL_EDIT_BUTTON)); - remove_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_AUTOFILL_DELETE_BUTTON)); - - views::GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int table_with_buttons_column_view_set_id = 0; - views::ColumnSet* column_set = - layout->AddColumnSet(table_with_buttons_column_view_set_id); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, - views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 0, - views::GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, table_with_buttons_column_view_set_id); - layout->AddView(enable_auto_fill_button_, 3, 1, views::GridLayout::FILL, - views::GridLayout::FILL); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, table_with_buttons_column_view_set_id); - layout->AddView(scroll_view_, 1, 8, views::GridLayout::FILL, - views::GridLayout::FILL); - layout->AddView(add_address_button_); - - layout->StartRowWithPadding(0, table_with_buttons_column_view_set_id, 0, - kRelatedControlVerticalSpacing); - layout->SkipColumns(2); - layout->AddView(add_credit_card_button_); - - layout->StartRowWithPadding(0, table_with_buttons_column_view_set_id, 0, - kRelatedControlVerticalSpacing); - layout->SkipColumns(2); - layout->AddView(edit_button_); - - layout->StartRowWithPadding(0, table_with_buttons_column_view_set_id, 0, - kRelatedControlVerticalSpacing); - layout->SkipColumns(2); - layout->AddView(remove_button_); - - layout->AddPaddingRow(1, table_with_buttons_column_view_set_id); - - - focus_manager_ = GetFocusManager(); - focus_manager_->AddFocusChangeListener(this); - - UpdateWidgetState(); -} - -void AutoFillProfilesView::GetData() { - if (!personal_data_manager_->IsDataLoaded()) { - return; - } - bool imported_data_present = !profiles_set_.empty() || - !credit_card_set_.empty(); - if (!imported_data_present) { - profiles_set_.reserve(personal_data_manager_->profiles().size()); - for (std::vector<AutoFillProfile*>::const_iterator address_it = - personal_data_manager_->profiles().begin(); - address_it != personal_data_manager_->profiles().end(); - ++address_it) { - profiles_set_.push_back(EditableSetInfo(*address_it)); - } - } - - if (!imported_data_present) { - credit_card_set_.reserve(personal_data_manager_->credit_cards().size()); - for (std::vector<CreditCard*>::const_iterator cc_it = - personal_data_manager_->credit_cards().begin(); - cc_it != personal_data_manager_->credit_cards().end(); - ++cc_it) { - credit_card_set_.push_back(EditableSetInfo(*cc_it)); - } - } - - if (table_model_.get()) - table_model_->Refresh(); - - // Update state only if buttons already created. - if (add_address_button_) { - UpdateWidgetState(); - } -} - -bool AutoFillProfilesView::IsDataReady() const { - return personal_data_manager_->IsDataLoaded(); -} - -void AutoFillProfilesView::SaveData() { - std::vector<AutoFillProfile> profiles; - profiles.reserve(profiles_set_.size()); - std::vector<EditableSetInfo>::iterator it; - for (it = profiles_set_.begin(); it != profiles_set_.end(); ++it) { - profiles.push_back(it->address); - } - std::vector<CreditCard> credit_cards; - credit_cards.reserve(credit_card_set_.size()); - for (it = credit_card_set_.begin(); it != credit_card_set_.end(); ++it) { - credit_cards.push_back(it->credit_card); - } - observer_->OnAutoFillDialogApply(&profiles, &credit_cards); -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::PhoneSubView, public: -AutoFillProfilesView::PhoneSubView::PhoneSubView( - AutoFillProfilesView* autofill_view, - views::Label* label, - views::Textfield* text_phone) - : autofill_view_(autofill_view), - label_(label), - text_phone_(text_phone), - phone_warning_button_(NULL), - last_state_(false) { - DCHECK(label_); - DCHECK(text_phone_); -} - -void AutoFillProfilesView::PhoneSubView::ContentsChanged( - views::Textfield* sender, const string16& new_contents) { - if (sender == text_phone_) { - UpdateButtons(); - } -} - -bool AutoFillProfilesView::PhoneSubView::IsValid() const { - if (text_phone_) { - string16 phone = text_phone_->text(); - if (phone.empty()) - return true; - - // Try to parse it. - string16 number, city, country; - return PhoneNumber::ParsePhoneNumber(phone, &number, &city, &country); - } - return false; -} - -void AutoFillProfilesView::PhoneSubView::UpdateButtons() { - if (phone_warning_button_) { - SkBitmap* image = text_phone_->text().empty() ? NULL : - autofill_view_->GetWarningBitmap(IsValid()); - phone_warning_button_->SetImage(views::CustomButton::BS_NORMAL, image); - if (last_state_ != IsValid()) { - last_state_ = IsValid(); - SchedulePaint(); - } - } -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::PhoneSubView, protected: -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::PhoneSubView, views::View implementations -void AutoFillProfilesView::PhoneSubView::ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child) { - if (is_add && this == child) { - views::GridLayout* layout = new views::GridLayout(this); - SetLayoutManager(layout); - const int two_column_fill_view_set_id = 0; - views::ColumnSet* column_set = - layout->AddColumnSet(two_column_fill_view_set_id); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 1, - views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 0, - views::GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, two_column_fill_view_set_id); - layout->AddView(label_, 3, 1); - layout->StartRow(0, two_column_fill_view_set_id); - text_phone_->set_default_width_in_chars(15); - layout->AddView(text_phone_); - phone_warning_button_ = new views::ImageButton(this); - // Set default size of the image. - SkBitmap* image = autofill_view_->GetWarningBitmap(true); - phone_warning_button_->SetPreferredSize(gfx::Size(image->width(), - image->height())); - phone_warning_button_->SetEnabled(false); - phone_warning_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, - views::ImageButton::ALIGN_MIDDLE); - layout->AddView(phone_warning_button_); - UpdateButtons(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, static data: -AutoFillProfilesView::EditableSetViewContents::TextFieldToAutoFill - AutoFillProfilesView::EditableSetViewContents::address_fields_[] = { - { AutoFillProfilesView::EditableSetViewContents::TEXT_FULL_NAME, - NAME_FULL }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_COMPANY, COMPANY_NAME }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_EMAIL, EMAIL_ADDRESS }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_ADDRESS_LINE_1, - ADDRESS_HOME_LINE1 }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_ADDRESS_LINE_2, - ADDRESS_HOME_LINE2 }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_ADDRESS_CITY, - ADDRESS_HOME_CITY }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_ADDRESS_STATE, - ADDRESS_HOME_STATE }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_ADDRESS_ZIP, - ADDRESS_HOME_ZIP }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_ADDRESS_COUNTRY, - ADDRESS_HOME_COUNTRY }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_PHONE_PHONE, - PHONE_HOME_WHOLE_NUMBER }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_FAX_PHONE, - PHONE_FAX_WHOLE_NUMBER }, -}; - -AutoFillProfilesView::EditableSetViewContents::TextFieldToAutoFill - AutoFillProfilesView::EditableSetViewContents::credit_card_fields_[] = { - { AutoFillProfilesView::EditableSetViewContents::TEXT_CC_NAME, - CREDIT_CARD_NAME }, - { AutoFillProfilesView::EditableSetViewContents::TEXT_CC_NUMBER, - CREDIT_CARD_NUMBER }, -}; - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, public: -AutoFillProfilesView::EditableSetViewContents::EditableSetViewContents( - AutoFillProfilesView* observer, - bool new_item, - const EditableSetInfo& field_set) - : temporary_info_(field_set), - has_credit_card_number_been_edited_(false), - observer_(observer), - new_item_(new_item) { - ZeroMemory(text_fields_, sizeof(text_fields_)); -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, protected: -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, views::View implementations -void AutoFillProfilesView::EditableSetViewContents::Layout() { - View::Layout(); -} - -gfx::Size AutoFillProfilesView::EditableSetViewContents::GetPreferredSize() { - if (temporary_info_.is_address) { - return views::Window::GetLocalizedContentsSize( - IDS_AUTOFILL_DIALOG_EDIT_ADDRESS_WIDTH_CHARS, - IDS_AUTOFILL_DIALOG_EDIT_ADDRESS_HEIGHT_LINES); - } else { - return views::Window::GetLocalizedContentsSize( - IDS_AUTOFILL_DIALOG_EDIT_CCARD_WIDTH_CHARS, - IDS_AUTOFILL_DIALOG_EDIT_CCARD_HEIGHT_LINES); - } -} - -void AutoFillProfilesView::EditableSetViewContents::ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child) { - if (is_add && this == child) { - observer_->ChildWindowOpened(); - views::GridLayout* layout = new views::GridLayout(this); - layout->SetInsets(kSubViewVerticalInsets, kSubViewHorizotalInsets, - kSubViewVerticalInsets, kSubViewHorizotalInsets); - SetLayoutManager(layout); - InitLayoutGrid(layout); - if (temporary_info_.is_address) - InitAddressFields(layout); - else - InitCreditCardFields(layout); - } -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, -// views::DialogDelegate implementations -int AutoFillProfilesView::EditableSetViewContents::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL | - MessageBoxFlags::DIALOGBUTTON_OK; -} - -std::wstring -AutoFillProfilesView::EditableSetViewContents::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString(IDS_AUTOFILL_DIALOG_SAVE); - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return std::wstring(); - default: - break; - } - NOTREACHED(); - return std::wstring(); -} - -bool AutoFillProfilesView::EditableSetViewContents::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: { - // Enable the ok button if at least one non-phone number field has text, - // or the phone numbers are valid. - bool valid = false; - TextFieldToAutoFill* fields; - int field_count; - if (temporary_info_.is_address) { - fields = address_fields_; - field_count = arraysize(address_fields_); - } else { - fields = credit_card_fields_; - field_count = arraysize(credit_card_fields_); - } - for (int i = 0; i < field_count; ++i) { - DCHECK(text_fields_[fields[i].text_field]); - // Phone and fax are handled separately. - if (fields[i].text_field != TEXT_PHONE_PHONE && - fields[i].text_field != TEXT_FAX_PHONE && - !text_fields_[fields[i].text_field]->text().empty()) { - valid = true; - break; - } - } - for (std::vector<PhoneSubView*>::const_iterator i = - phone_sub_views_.begin(); i != phone_sub_views_.end(); ++i) { - if (!(*i)->IsValid()) { - valid = false; - break; - } else if (!valid && !(*i)->text_phone()->text().empty()) { - valid = true; - } - } - return valid; - } - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return true; - default: - break; - } - NOTREACHED(); - return false; -} - -std::wstring -AutoFillProfilesView::EditableSetViewContents::GetWindowTitle() const { - int string_id = 0; - if (temporary_info_.is_address) { - string_id = new_item_ ? IDS_AUTOFILL_ADD_ADDRESS_CAPTION : - IDS_AUTOFILL_EDIT_ADDRESS_CAPTION; - } else { - string_id = new_item_ ? IDS_AUTOFILL_ADD_CREDITCARD_CAPTION : - IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION; - } - return l10n_util::GetString(string_id); -} - -void AutoFillProfilesView::EditableSetViewContents::WindowClosing() { - observer_->ChildWindowClosed(); -} - -views::View* AutoFillProfilesView::EditableSetViewContents::GetContentsView() { - return this; -} - -bool AutoFillProfilesView::EditableSetViewContents::Cancel() { - if (new_item_) { - // Remove added item - it is last in the list. - if (temporary_info_.is_address) { - observer_->profiles_set_.pop_back(); - } else { - observer_->credit_card_set_.pop_back(); - } - } - return true; -} - -bool AutoFillProfilesView::EditableSetViewContents::Accept() { - observer_->EditAccepted(&temporary_info_, new_item_); - return true; -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, -// views::ButtonListener implementations -void AutoFillProfilesView::EditableSetViewContents::ButtonPressed( - views::Button* sender, const views::Event& event) { - NOTREACHED(); -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, -// views::Textfield::Controller implementations -void AutoFillProfilesView::EditableSetViewContents::ContentsChanged( - views::Textfield* sender, const string16& new_contents) { - if (temporary_info_.is_address) { - for (int field = 0; field < arraysize(address_fields_); ++field) { - DCHECK(text_fields_[address_fields_[field].text_field]); - if (text_fields_[address_fields_[field].text_field] == sender) { - if (!UpdateContentsPhoneViews(address_fields_[field].text_field, - sender, new_contents)) { - temporary_info_.address.SetInfo( - AutoFillType(address_fields_[field].type), new_contents); - } - UpdateButtons(); - return; - } - } - } else { - for (int field = 0; field < arraysize(credit_card_fields_); ++field) { - DCHECK(text_fields_[credit_card_fields_[field].text_field]); - if (text_fields_[credit_card_fields_[field].text_field] == sender) { - UpdateContentsPhoneViews(address_fields_[field].text_field, - sender, new_contents); - temporary_info_.credit_card.SetInfo( - AutoFillType(credit_card_fields_[field].type), new_contents); - UpdateButtons(); - return; - } - } - } -} - -bool AutoFillProfilesView::EditableSetViewContents::HandleKeystroke( - views::Textfield* sender, const views::Textfield::Keystroke& keystroke) { - if (sender == text_fields_[TEXT_CC_NUMBER] && - !has_credit_card_number_been_edited_) { - // You cannot edit obfuscated number, you must retype it anew. - sender->SetText(string16()); - has_credit_card_number_been_edited_ = true; - } - return false; -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, -// views::Combobox::Listener implementations: -void AutoFillProfilesView::EditableSetViewContents::ItemChanged( - views::Combobox* combo_box, int prev_index, int new_index) { - if (combo_box == combo_box_month_) { - if (new_index == -1) { - NOTREACHED(); - } else { - temporary_info_.credit_card.SetInfo( - AutoFillType(CREDIT_CARD_EXP_MONTH), - UTF16ToWideHack(combo_box_model_month_->GetItemAt(new_index))); - } - } else if (combo_box == combo_box_year_) { - if (new_index == -1) { - NOTREACHED(); - } else { - temporary_info_.credit_card.SetInfo( - AutoFillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), - UTF16ToWideHack(combo_box_model_year_->GetItemAt(new_index))); - } - } else { - NOTREACHED(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView::EditableSetViewContents, private: -void AutoFillProfilesView::EditableSetViewContents::InitAddressFields( - views::GridLayout* layout) { - DCHECK(temporary_info_.is_address); - - for (int field = 0; field < arraysize(address_fields_); ++field) { - DCHECK(!text_fields_[address_fields_[field].text_field]); - text_fields_[address_fields_[field].text_field] = - new views::Textfield(views::Textfield::STYLE_DEFAULT); - text_fields_[address_fields_[field].text_field]->SetController(this); - text_fields_[address_fields_[field].text_field]->SetText( - temporary_info_.address.GetFieldText( - AutoFillType(address_fields_[field].type))); - } - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_FULL_NAME)); - - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_FULL_NAME]); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_COMPANY_NAME)); - - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_COMPANY]); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_leading_view_set_id_); - layout->AddView(new views::Label(l10n_util::GetString( - IDS_AUTOFILL_DIALOG_ADDRESS_LINE_1))); - - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_ADDRESS_LINE_1]); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_leading_view_set_id_); - layout->AddView(new views::Label(l10n_util::GetString( - IDS_AUTOFILL_DIALOG_ADDRESS_LINE_2))); - - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_ADDRESS_LINE_2]); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, triple_column_fill_view_set_id_); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_CITY)); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_STATE)); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_ZIP_CODE)); - - text_fields_[TEXT_ADDRESS_CITY]->set_default_width_in_chars(16); - text_fields_[TEXT_ADDRESS_STATE]->set_default_width_in_chars(16); - text_fields_[TEXT_ADDRESS_ZIP]->set_default_width_in_chars(5); - - layout->StartRow(0, triple_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_ADDRESS_CITY]); - layout->AddView(text_fields_[TEXT_ADDRESS_STATE]); - layout->AddView(text_fields_[TEXT_ADDRESS_ZIP]); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_COUNTRY)); - - text_fields_[TEXT_ADDRESS_COUNTRY]->set_default_width_in_chars(11); - - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_ADDRESS_COUNTRY]); - - PhoneSubView* phone = new PhoneSubView( - observer_, - CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_PHONE), - text_fields_[TEXT_PHONE_PHONE]); - - phone_sub_views_.push_back(phone); - - PhoneSubView* fax = new PhoneSubView( - observer_, - CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_FAX), - text_fields_[TEXT_FAX_PHONE]); - - phone_sub_views_.push_back(fax); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(phone); - layout->AddView(fax); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_EMAIL)); - - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_EMAIL]); - - UpdateButtons(); -} - -void AutoFillProfilesView::EditableSetViewContents::InitCreditCardFields( - views::GridLayout* layout) { - DCHECK(!temporary_info_.is_address); - - // Create combo box models. - combo_box_model_month_.reset(new StringVectorComboboxModel); - std::vector<std::wstring> model_strings; - model_strings.reserve(12); - for (int month = 1; month <= 12; ++month) - model_strings.push_back(StringPrintf(L"%02i", month)); - combo_box_model_month_->set_cb_strings(&model_strings); - model_strings.clear(); - model_strings.reserve(20); - base::Time::Exploded exploded_time; - base::Time::Now().LocalExplode(&exploded_time); - for (int year = 0; year < 10; ++year) - model_strings.push_back(StringPrintf(L"%04i", year + exploded_time.year)); - combo_box_model_year_.reset(new StringVectorComboboxModel); - combo_box_model_year_->set_cb_strings(&model_strings); - - for (int field = 0; field < arraysize(credit_card_fields_); ++field) { - DCHECK(!text_fields_[credit_card_fields_[field].text_field]); - text_fields_[credit_card_fields_[field].text_field] = - new views::Textfield(views::Textfield::STYLE_DEFAULT); - text_fields_[credit_card_fields_[field].text_field]->SetController(this); - string16 field_text; - if (credit_card_fields_[field].text_field == TEXT_CC_NUMBER) { - field_text = temporary_info_.credit_card.GetFieldText( - AutoFillType(credit_card_fields_[field].type)); - if (!field_text.empty()) - field_text = temporary_info_.credit_card.ObfuscatedNumber(); - } else { - field_text = temporary_info_.credit_card.GetFieldText( - AutoFillType(credit_card_fields_[field].type)); - } - text_fields_[credit_card_fields_[field].text_field]->SetText(field_text); - } - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_NAME_ON_CARD)); - layout->StartRow(0, double_column_fill_view_set_id_); - layout->AddView(text_fields_[TEXT_CC_NAME]); - - // Layout credit card info - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_ccnumber_cvc_); - layout->AddView( - CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_CREDIT_CARD_NUMBER)); - layout->StartRow(0, double_column_ccnumber_cvc_); - // Number (20 chars), month(2 chars), year (4 chars), cvc (4 chars) - text_fields_[TEXT_CC_NUMBER]->set_default_width_in_chars(20); - layout->AddView(text_fields_[TEXT_CC_NUMBER]); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_ccexpiration_); - layout->AddView( - CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_EXPIRATION_DATE), 3, 1); - - combo_box_month_ = new views::Combobox(combo_box_model_month_.get()); - combo_box_month_->set_listener(this); - string16 field_text; - field_text = temporary_info_.credit_card.GetFieldText( - AutoFillType(CREDIT_CARD_EXP_MONTH)); - combo_box_month_->SetSelectedItem( - combo_box_model_month_->GetIndex(field_text)); - - combo_box_year_ = new views::Combobox(combo_box_model_year_.get()); - combo_box_year_->set_listener(this); - field_text = temporary_info_.credit_card.GetFieldText( - AutoFillType(CREDIT_CARD_EXP_4_DIGIT_YEAR)); - combo_box_year_->SetSelectedItem(combo_box_model_year_->GetIndex(field_text)); - - layout->StartRow(0, double_column_ccexpiration_); - layout->AddView(combo_box_month_); - layout->AddView(combo_box_year_); - - UpdateButtons(); -} - -void AutoFillProfilesView::EditableSetViewContents::InitLayoutGrid( - views::GridLayout* layout) { - views::ColumnSet* column_set = - layout->AddColumnSet(double_column_fill_view_set_id_); - int i; - for (i = 0; i < 2; ++i) { - if (i) - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 1, - views::GridLayout::USE_PREF, 0, 0); - } - column_set = layout->AddColumnSet(double_column_leading_view_set_id_); - for (i = 0; i < 2; ++i) { - if (i) - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, - 1, views::GridLayout::USE_PREF, 0, 0); - } - column_set = layout->AddColumnSet(triple_column_fill_view_set_id_); - for (i = 0; i < 3; ++i) { - if (i) - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 1, - views::GridLayout::USE_PREF, 0, 0); - } - column_set = layout->AddColumnSet(triple_column_leading_view_set_id_); - for (i = 0; i < 3; ++i) { - if (i) - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, - 1, views::GridLayout::USE_PREF, 0, 0); - } - // City (33% - 16/48), state(33%), zip (12.7% - 5/42), country (21% - 11/48) - column_set = layout->AddColumnSet(four_column_city_state_zip_set_id_); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 16, views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 16, views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 5, views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 11, views::GridLayout::USE_PREF, 0, 0); - - column_set = layout->AddColumnSet(double_column_ccnumber_cvc_); - // Number and CVC are in ratio 20:4 - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 20, views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 4, views::GridLayout::USE_PREF, 0, 0); - - column_set = layout->AddColumnSet(double_column_ccexpiration_); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - gfx::Font font = - rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); - - // The sizes: 4 characters for drop down icon + 2 for a month or 4 for a year. - column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, - 0, views::GridLayout::FIXED, - font.GetStringWidth(std::wstring(L"000000")), 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, - 0, views::GridLayout::FIXED, - font.GetStringWidth(std::wstring(L"00000000")), 0); - - column_set = layout->AddColumnSet(three_column_header_); - column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, - 0, views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, - 1, views::GridLayout::FIXED, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, - 1, views::GridLayout::FIXED, 0, 0); -} - -views::Label* -AutoFillProfilesView::EditableSetViewContents::CreateLeftAlignedLabel( - int label_id) { - views::Label* label = new views::Label(l10n_util::GetString(label_id)); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - return label; -} - -void AutoFillProfilesView::EditableSetViewContents::UpdateButtons() { - GetDialogClientView()->UpdateDialogButtons(); -} - -bool AutoFillProfilesView::EditableSetViewContents::UpdateContentsPhoneViews( - TextFields field, views::Textfield* sender, const string16& new_contents) { - switch (field) { - case TEXT_PHONE_PHONE: - case TEXT_FAX_PHONE: { - for (std::vector<PhoneSubView*>::iterator it = phone_sub_views_.begin(); - it != phone_sub_views_.end(); ++it) - (*it)->ContentsChanged(sender, new_contents); - DCHECK(temporary_info_.is_address); // Only addresses have phone numbers. - string16 number, city, country; - PhoneNumber::ParsePhoneNumber(new_contents, &number, &city, &country); - temporary_info_.address.SetInfo( - AutoFillType(field == TEXT_PHONE_PHONE ? PHONE_HOME_COUNTRY_CODE : - PHONE_FAX_COUNTRY_CODE), country); - temporary_info_.address.SetInfo( - AutoFillType(field == TEXT_PHONE_PHONE ? PHONE_HOME_CITY_CODE : - PHONE_FAX_CITY_CODE), city); - temporary_info_.address.SetInfo( - AutoFillType(field == TEXT_PHONE_PHONE ? PHONE_HOME_NUMBER : - PHONE_FAX_NUMBER), number); - return true; - } - } - return false; -} - -void AutoFillProfilesView::StringVectorComboboxModel::set_cb_strings( - std::vector<std::wstring> *source) { - cb_strings_.swap(*source); -} - -int AutoFillProfilesView::StringVectorComboboxModel::GetItemCount() { - return cb_strings_.size(); -} - -string16 AutoFillProfilesView::StringVectorComboboxModel::GetItemAt(int index) { - DCHECK_GT(static_cast<int>(cb_strings_.size()), index); - return WideToUTF16Hack(cb_strings_[index]); -} - -int AutoFillProfilesView::StringVectorComboboxModel::GetIndex( - const std::wstring& value) { - for (size_t index = 0; index < cb_strings_.size(); ++index) { - if (cb_strings_[index] == value) - return index; - } - return -1; -} - -AutoFillProfilesView::ContentListTableModel::ContentListTableModel( - std::vector<EditableSetInfo>* profiles, - std::vector<EditableSetInfo>* credit_cards) - : profiles_(profiles), - credit_cards_(credit_cards) { -} - -void AutoFillProfilesView::ContentListTableModel::Refresh() { - if (observer_) - observer_->OnModelChanged(); -} - -void AutoFillProfilesView::ContentListTableModel::AddItem(int index) { - if (observer_) - observer_->OnItemsAdded(index, 1); -} - -void AutoFillProfilesView::ContentListTableModel::RemoveItem(int index) { - DCHECK(index < static_cast<int>(profiles_->size() + credit_cards_->size())); - if (index < static_cast<int>(profiles_->size())) - profiles_->erase(profiles_->begin() + index); - else - credit_cards_->erase(credit_cards_->begin() + (index - profiles_->size())); - if (observer_) - observer_->OnItemsRemoved(index, 1); -} - -void AutoFillProfilesView::ContentListTableModel::UpdateItem(int index) { - if (observer_) - observer_->OnItemsChanged(index, 1); -} - -int AutoFillProfilesView::ContentListTableModel::RowCount() { - return profiles_->size() + credit_cards_->size(); -} - -std::wstring AutoFillProfilesView::ContentListTableModel::GetText( - int row, int column_id) { - DCHECK(row < static_cast<int>(profiles_->size() + credit_cards_->size())); - if (row < static_cast<int>(profiles_->size())) { - return profiles_->at(row).address.Label(); - } else { - row -= profiles_->size(); - return credit_cards_->at(row).credit_card.PreviewSummary(); - } -} - -TableModel::Groups AutoFillProfilesView::ContentListTableModel::GetGroups() { - TableModel::Groups groups; - - TableModel::Group profile_group; - profile_group.title = l10n_util::GetString(IDS_AUTOFILL_ADDRESSES_GROUP_NAME); - profile_group.id = kAddressGroup; - groups.push_back(profile_group); - - Group cc_group; - cc_group.title = l10n_util::GetString(IDS_AUTOFILL_CREDITCARDS_GROUP_NAME); - cc_group.id = kCreditCardGroup; - groups.push_back(cc_group); - - return groups; -} - -int AutoFillProfilesView::ContentListTableModel::GetGroupID(int row) { - DCHECK(row < static_cast<int>(profiles_->size() + credit_cards_->size())); - return (row < static_cast<int>(profiles_->size())) ? kAddressGroup : - kCreditCardGroup; -} - -void AutoFillProfilesView::ContentListTableModel::SetObserver( - TableModelObserver* observer) { - observer_ = observer; -} - - -// Declared in "chrome/browser/autofill/autofill_dialog.h" -void ShowAutoFillDialog(gfx::NativeView parent, - AutoFillDialogObserver* observer, - Profile* profile) { - DCHECK(profile); - - PersonalDataManager* personal_data_manager = - profile->GetPersonalDataManager(); - DCHECK(personal_data_manager); - AutoFillProfilesView::Show(parent, observer, personal_data_manager, profile, - profile->GetPrefs(), NULL, NULL); -} diff --git a/chrome/browser/views/autofill_profiles_view_win.h b/chrome/browser/views/autofill_profiles_view_win.h index efeaf59..5768e9f 100644 --- a/chrome/browser/views/autofill_profiles_view_win.h +++ b/chrome/browser/views/autofill_profiles_view_win.h @@ -6,435 +6,8 @@ #define CHROME_BROWSER_VIEWS_AUTOFILL_PROFILES_VIEW_WIN_H_ #pragma once -#include <list> -#include <map> -#include <vector> - -#include "app/combobox_model.h" -#include "app/table_model.h" -#include "base/string16.h" -#include "chrome/browser/autofill/autofill_dialog.h" -#include "chrome/browser/autofill/autofill_profile.h" -#include "chrome/browser/autofill/personal_data_manager.h" -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/common/notification_observer.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/link.h" -#include "views/controls/table/table_view_observer.h" -#include "views/controls/textfield/textfield.h" -#include "views/focus/focus_manager.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Checkbox; -class GridLayout; -class ImageButton; -class Label; -class RadioButton; -class TableView; -class TextButton; -} // namespace views - -class PrefService; -class SkBitmap; - -/////////////////////////////////////////////////////////////////////////////// -// AutoFillProfilesView -// -// The contents of the "AutoFill profiles" dialog window. -// -// Overview: has following sub-views: -// EditableSetViewContents - set of displayed fields for address or credit card, -// has iterator to std::vector<EditableSetInfo> vector so data could be -// updated or notifications passes to the dialog view. -// PhoneSubView - support view for the phone fields sets. used in -// ScrollViewContents. -// And there is a support data structure EditableSetInfo which encapsulates -// editable set (address or credit card) and allows for quick addition and -// deletion. -class AutoFillProfilesView : public views::View, - public views::DialogDelegate, - public views::ButtonListener, - public views::LinkController, - public views::FocusChangeListener, - public views::TableViewObserver, - public PersonalDataManager::Observer, - public NotificationObserver { - public: - virtual ~AutoFillProfilesView(); - - static int Show(gfx::NativeWindow parent, - AutoFillDialogObserver* observer, - PersonalDataManager* personal_data_manager, - Profile* profile, - PrefService* preferences, - AutoFillProfile* imported_profile, - CreditCard* imported_credit_card); - - protected: - // Forward declaration. This struct defined further down. - struct EditableSetInfo; - // Called when 'Add Address' (|group_type| is - // ContentListTableModel::kAddressGroup) or 'Add Credit Card' (|group_type| is - // ContentListTableModel::kCreditCardGroup) is clicked. - void AddClicked(int group_type); - // Called when 'Edit...' is clicked. - void EditClicked(); - // Called when 'Remove' is clicked. - void DeleteClicked(); - // Called when 'Edit' dialog is accepted. - void EditAccepted(EditableSetInfo* data, bool new_item); - - // Updates state of the buttons. - void UpdateWidgetState(); - - // Following two functions are called from opened child dialog to - // disable/enable buttons. - void ChildWindowOpened(); - void ChildWindowClosed(); - - // Returns warning bitmap to set on warning indicator. If |good| is true it - // returns the bitmap idicating validity, if false - indicating error. - // Caller owns the bitmap after the call. - SkBitmap* GetWarningBitmap(bool good); - - // views::View methods: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - // views::DialogDelegate methods: - virtual int GetDialogButtons() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual View* GetExtraView(); - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool CanResize() const { return true; } - virtual bool CanMaximize() const { return false; } - virtual bool IsAlwaysOnTop() const { return false; } - virtual bool HasAlwaysOnTopMenu() const { return false; } - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual views::View* GetContentsView(); - virtual bool Cancel(); - virtual bool Accept(); - - // views::ButtonListener methods: - virtual void ButtonPressed(views::Button* sender, - const views::Event& event); - - // views::LinkController methods: - virtual void LinkActivated(views::Link* source, int event_flags); - - // views::FocusChangeListener methods: - virtual void FocusWillChange(views::View* focused_before, - views::View* focused_now); - - // views::TableViewObserver methods: - virtual void OnSelectionChanged(); - virtual void OnDoubleClick(); - - // PersonalDataManager::Observer methods: - virtual void OnPersonalDataLoaded(); - virtual void OnPersonalDataChanged(); - - // NotificationObserver methods: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Helper structure to keep info on one address or credit card. - // Keeps info on one item in EditableSetViewContents. - // Also keeps info on opened status. Allows to quickly add and delete items, - // and then rebuild EditableSetViewContents. - struct EditableSetInfo { - bool is_address; - // If |is_address| is true |address| has some data and |credit_card| - // is empty, and vice versa - AutoFillProfile address; - CreditCard credit_card; - - explicit EditableSetInfo(const AutoFillProfile* input_address) - : address(*input_address), - is_address(true) { - } - explicit EditableSetInfo(const CreditCard* input_credit_card) - : credit_card(*input_credit_card), - is_address(false) { - } - - std::string guid() const { - if (is_address) - return address.guid(); - else - return credit_card.guid(); - } - }; - - private: - // Indicates that there was no item focused. After re-building of the lists - // first item will be focused. - static const int kNoItemFocused = -1; - - struct FocusedItem { - int group; - int item; - FocusedItem() : group(kNoItemFocused), item(kNoItemFocused) {} - FocusedItem(int g, int i) : group(g), item(i) {} - }; - - AutoFillProfilesView(AutoFillDialogObserver* observer, - PersonalDataManager* personal_data_manager, - Profile* profile, - PrefService* preferences, - AutoFillProfile* imported_profile, - CreditCard* imported_credit_card); - void Init(); - - void GetData(); - bool IsDataReady() const; - void SaveData(); - - // Rebuilds the view by deleting and re-creating sub-views - void RebuildView(const FocusedItem& new_focus_index); - - // PhoneSubView encapsulates three phone fields (country, area, and phone) - // and label above them, so they could be used together in one grid cell. - class PhoneSubView : public views::View, - public views::ButtonListener { - public: - PhoneSubView(AutoFillProfilesView* autofill_view, - views::Label* label, - views::Textfield* text_phone); - virtual ~PhoneSubView() {} - - virtual void ContentsChanged(views::Textfield* sender, - const string16& new_contents); - - bool IsValid() const; - - views::Textfield* text_phone() { return text_phone_; } - - protected: - // views::View methods: - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - // public views::ButtonListener method: - virtual void ButtonPressed(views::Button* sender, - const views::Event& event) { - // Only stub is needed, it is never called. - NOTREACHED(); - } - - private: - void UpdateButtons(); - AutoFillProfilesView* autofill_view_; - views::Label* label_; - views::Textfield* text_phone_; - views::ImageButton* phone_warning_button_; - bool last_state_; - - DISALLOW_COPY_AND_ASSIGN(PhoneSubView); - }; - - // Forward declaration. - class StringVectorComboboxModel; - - // Sub-view for editing/adding a credit card or address. - class EditableSetViewContents : public views::View, - public views::DialogDelegate, - public views::ButtonListener, - public views::Textfield::Controller, - public views::Combobox::Listener { - public: - EditableSetViewContents(AutoFillProfilesView* observer, - bool new_item, - const EditableSetInfo& field_set); - virtual ~EditableSetViewContents() {} - - protected: - // views::View methods: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - // views::DialogDelegate methods: - virtual int GetDialogButtons() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool CanResize() const { return false; } - virtual bool CanMaximize() const { return false; } - virtual bool IsModal() const { return true; } - virtual bool HasAlwaysOnTopMenu() const { return false; } - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual views::View* GetContentsView(); - virtual bool Cancel(); - virtual bool Accept(); - - // views::ButtonListener methods: - virtual void ButtonPressed(views::Button* sender, - const views::Event& event); - - // views::Textfield::Controller methods: - virtual void ContentsChanged(views::Textfield* sender, - const string16& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& keystroke); - - // views::Combobox::Listener methods: - virtual void ItemChanged(views::Combobox* combo_box, - int prev_index, - int new_index); - private: - enum TextFields { - TEXT_FULL_NAME, - TEXT_COMPANY, - TEXT_EMAIL, - TEXT_ADDRESS_LINE_1, - TEXT_ADDRESS_LINE_2, - TEXT_ADDRESS_CITY, - TEXT_ADDRESS_STATE, - TEXT_ADDRESS_ZIP, - TEXT_ADDRESS_COUNTRY, - TEXT_PHONE_PHONE, - TEXT_FAX_PHONE, - TEXT_CC_NAME, - TEXT_CC_NUMBER, - // Must be last. - MAX_TEXT_FIELD - }; - - void InitAddressFields(views::GridLayout* layout); - void InitCreditCardFields(views::GridLayout* layout); - void InitLayoutGrid(views::GridLayout* layout); - views::Label* CreateLeftAlignedLabel(int label_id); - - void UpdateButtons(); - - // If |field| is a phone or fax ContentsChanged is passed to the - // PhoneSubView, the appropriate fields in |temporary_info_| are updated and - // true is returned. Otherwise false is returned. - bool UpdateContentsPhoneViews(TextFields field, - views::Textfield* sender, - const string16& new_contents); - - views::Textfield* text_fields_[MAX_TEXT_FIELD]; - EditableSetInfo temporary_info_; - bool has_credit_card_number_been_edited_; - AutoFillProfilesView* observer_; - scoped_ptr<StringVectorComboboxModel> combo_box_model_month_; - views::Combobox* combo_box_month_; - scoped_ptr<StringVectorComboboxModel> combo_box_model_year_; - views::Combobox* combo_box_year_; - bool new_item_; - std::vector<PhoneSubView*> phone_sub_views_; - - struct TextFieldToAutoFill { - TextFields text_field; - AutoFillFieldType type; - }; - - static TextFieldToAutoFill address_fields_[]; - static TextFieldToAutoFill credit_card_fields_[]; - - static const int double_column_fill_view_set_id_ = 0; - static const int double_column_leading_view_set_id_ = 1; - static const int triple_column_fill_view_set_id_ = 2; - static const int triple_column_leading_view_set_id_ = 3; - static const int four_column_city_state_zip_set_id_ = 4; - static const int double_column_ccnumber_cvc_ = 5; - static const int three_column_header_ = 6; - static const int double_column_ccexpiration_ = 7; - - DISALLOW_COPY_AND_ASSIGN(EditableSetViewContents); - }; - - class StringVectorComboboxModel : public ComboboxModel { - public: - StringVectorComboboxModel() {} - virtual ~StringVectorComboboxModel() {} - - // Sets the vector of the strings for the combobox. Swaps content with - // |source|. - void set_cb_strings(std::vector<std::wstring> *source); - - // Overridden from ComboboxModel: - virtual int GetItemCount(); - virtual string16 GetItemAt(int index); - - // Find an index of the item in the model, -1 if not present. - int GetIndex(const std::wstring& value); - - private: - std::vector<std::wstring> cb_strings_; - - DISALLOW_COPY_AND_ASSIGN(StringVectorComboboxModel); - }; - - // Model for scrolling credit cards and addresses. - class ContentListTableModel : public TableModel { - public: - ContentListTableModel(std::vector<EditableSetInfo>* profiles, - std::vector<EditableSetInfo>* credit_cards); - virtual ~ContentListTableModel() {} - - // Two constants defined for indexes of groups. The first one is index - // of Add Address button, the second one is the index of Add Credit Card - // button. - static const int kAddressGroup = 1; - static const int kCreditCardGroup = 2; - - void Refresh(); - void AddItem(int index); - void RemoveItem(int index); - void UpdateItem(int index); - - // TableModel members: - virtual int RowCount(); - virtual std::wstring GetText(int row, int column_id); - virtual bool HasGroups() { return true; } - virtual TableModel::Groups GetGroups(); - virtual int GetGroupID(int row); - virtual void SetObserver(TableModelObserver* observer); - - private: - std::vector<EditableSetInfo>* profiles_; - std::vector<EditableSetInfo>* credit_cards_; - TableModelObserver* observer_; - - DISALLOW_COPY_AND_ASSIGN(ContentListTableModel); - }; - - AutoFillDialogObserver* observer_; - PersonalDataManager* personal_data_manager_; - Profile* profile_; - PrefService* preferences_; - std::vector<EditableSetInfo> profiles_set_; - std::vector<EditableSetInfo> credit_card_set_; - - BooleanPrefMember enable_auto_fill_; - - views::Checkbox* enable_auto_fill_button_; - views::Button* add_address_button_; - views::Button* add_credit_card_button_; - views::Button* edit_button_; - views::Button* remove_button_; - views::TableView* scroll_view_; - scoped_ptr<ContentListTableModel> table_model_; - views::FocusManager* focus_manager_; - bool child_dialog_opened_; - - static AutoFillProfilesView* instance_; - - DISALLOW_COPY_AND_ASSIGN(AutoFillProfilesView); -}; +#include "chrome/browser/ui/views/autofill_profiles_view_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_AUTOFILL_PROFILES_VIEW_WIN_H_ + diff --git a/chrome/browser/views/bookmark_bar_instructions_view.cc b/chrome/browser/views/bookmark_bar_instructions_view.cc deleted file mode 100644 index a89eb2d..0000000 --- a/chrome/browser/views/bookmark_bar_instructions_view.cc +++ /dev/null @@ -1,108 +0,0 @@ -// 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/bookmark_bar_instructions_view.h" - -#include "app/l10n_util.h" -#include "chrome/browser/defaults.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "grit/generated_resources.h" -#include "views/controls/label.h" - -using views::View; - -// Horizontal padding, in pixels, between the link and label. -static const int kViewPadding = 6; - -BookmarkBarInstructionsView::BookmarkBarInstructionsView(Delegate* delegate) - : delegate_(delegate), - instructions_(NULL), - import_link_(NULL), - baseline_(-1), - updated_colors_(false) { - instructions_ = new views::Label( - l10n_util::GetString(IDS_BOOKMARKS_NO_ITEMS)); - AddChildView(instructions_); - - if (browser_defaults::kShowImportOnBookmarkBar) { - import_link_ = new views::Link( - l10n_util::GetString(IDS_BOOKMARK_BAR_IMPORT_LINK)); - // We don't want the link to alter tab navigation. - import_link_->SetFocusable(false); - import_link_->SetController(this); - AddChildView(import_link_); - } -} - -gfx::Size BookmarkBarInstructionsView::GetPreferredSize() { - int ascent = 0, descent = 0, height = 0, width = 0; - for (int i = 0; i < GetChildViewCount(); ++i) { - View* view = GetChildViewAt(i); - gfx::Size pref = view->GetPreferredSize(); - int baseline = view->GetBaseline(); - if (baseline != -1) { - ascent = std::max(ascent, baseline); - descent = std::max(descent, pref.height() - baseline); - } else { - height = std::max(pref.height(), height); - } - width += pref.width(); - } - width += (GetChildViewCount() - 1) * kViewPadding; - if (ascent != 0) - height = std::max(ascent + descent, height); - return gfx::Size(width, height); -} - -void BookmarkBarInstructionsView::Layout() { - int remaining_width = width(); - int x = 0; - for (int i = 0; i < GetChildViewCount(); ++i) { - View* view = GetChildViewAt(i); - gfx::Size pref = view->GetPreferredSize(); - int baseline = view->GetBaseline(); - int y; - if (baseline != -1 && baseline_ != -1) - y = baseline_ - baseline; - else - y = (height() - pref.height()) / 2; - int view_width = std::min(remaining_width, pref.width()); - view->SetBounds(x, y, view_width, pref.height()); - x += view_width + kViewPadding; - remaining_width = std::max(0, width() - x); - } -} - -void BookmarkBarInstructionsView::OnThemeChanged() { - UpdateColors(); -} - -void BookmarkBarInstructionsView::ViewHierarchyChanged(bool is_add, - View* parent, - View* child) { - if (!updated_colors_ && is_add && GetWidget()) - UpdateColors(); -} - -AccessibilityTypes::Role BookmarkBarInstructionsView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -void BookmarkBarInstructionsView::LinkActivated(views::Link* source, - int event_flags) { - delegate_->ShowImportDialog(); -} - -void BookmarkBarInstructionsView::UpdateColors() { - // We don't always have a theme provider (ui tests, for example). - const ThemeProvider* theme_provider = GetThemeProvider(); - if (!theme_provider) - return; - updated_colors_ = true; - SkColor text_color = - theme_provider->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT); - instructions_->SetColor(text_color); - if (import_link_) - import_link_->SetColor(text_color); -} diff --git a/chrome/browser/views/bookmark_bar_instructions_view.h b/chrome/browser/views/bookmark_bar_instructions_view.h index 2156bf8..599ad78 100644 --- a/chrome/browser/views/bookmark_bar_instructions_view.h +++ b/chrome/browser/views/bookmark_bar_instructions_view.h @@ -6,63 +6,8 @@ #define CHROME_BROWSER_VIEWS_BOOKMARK_BAR_INSTRUCTIONS_VIEW_H_ #pragma once -#include "views/view.h" -#include "views/controls/link.h" - -namespace views { -class Label; -class Link; -} - -// BookmarkBarInstructionsView is a child of the bookmark bar that is visible -// when the user has no bookmarks on the bookmark bar. -// BookmarkBarInstructionsView shows a description of the bookmarks bar along -// with a link to import bookmarks. Clicking the link results in notifying the -// delegate. -class BookmarkBarInstructionsView : public views::View, - public views::LinkController { - public: - // The delegate is notified once the user clicks on the link to import - // bookmarks. - class Delegate { - public: - virtual void ShowImportDialog() = 0; - - protected: - virtual ~Delegate() {} - }; - - explicit BookmarkBarInstructionsView(Delegate* delegate); - - // View overrides. - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual void OnThemeChanged(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // LinkController. - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - void UpdateColors(); - - Delegate* delegate_; - - views::Label* instructions_; - views::Link* import_link_; - - // The baseline of the child views. This is -1 if none of the views support a - // baseline. - int baseline_; - - // Have the colors of the child views been updated? This is initially false - // and set to true once we have a valid ThemeProvider. - bool updated_colors_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkBarInstructionsView); -}; +#include "chrome/browser/ui/views/bookmark_bar_instructions_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BOOKMARK_BAR_INSTRUCTIONS_VIEW_H_ + diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc deleted file mode 100644 index 9188aa5..0000000 --- a/chrome/browser/views/bookmark_bar_view.cc +++ /dev/null @@ -1,1734 +0,0 @@ -// 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/bookmark_bar_view.h" - -#include <algorithm> -#include <limits> -#include <set> -#include <vector> - -#include "app/l10n_util.h" -#include "app/os_exchange_data.h" -#include "app/resource_bundle.h" -#include "app/text_elider.h" -#include "base/i18n/rtl.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_shutdown.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/importer/importer_data_types.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/sync/sync_ui_util.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/bookmark_context_menu.h" -#include "chrome/browser/views/event_utils.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/page_transition_types.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas_skia.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/label.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/drag_utils.h" -#include "views/view_constants.h" -#include "views/widget/tooltip_manager.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "chrome/browser/views/importer_view.h" -#endif - -using views::CustomButton; -using views::DropTargetEvent; -using views::MenuButton; -using views::MenuItemView; -using views::View; - -// How much we want the bookmark bar to overlap the toolbar when in its -// 'always shown' mode. -static const int kToolbarOverlap = 3; - -// Margins around the content. -static const int kDetachedTopMargin = 1; // When attached, we use 0 and let the - // toolbar above serve as the margin. -static const int kBottomMargin = 2; -static const int kLeftMargin = 1; -static const int kRightMargin = 1; - -// Preferred height of the bookmarks bar. -static const int kBarHeight = 28; - -// Preferred height of the bookmarks bar when only shown on the new tab page. -const int BookmarkBarView::kNewtabBarHeight = 57; - -// Padding between buttons. -static const int kButtonPadding = 0; - -// Command ids used in the menu allowing the user to choose when we're visible. -static const int kAlwaysShowCommandID = 1; - -// Icon to display when one isn't found for the page. -static SkBitmap* kDefaultFavIcon = NULL; - -// Icon used for folders. -static SkBitmap* kFolderIcon = NULL; - -// Offset for where the menu is shown relative to the bottom of the -// BookmarkBarView. -static const int kMenuOffset = 3; - -// Delay during drag and drop before the menu pops up. This is only used if -// we can't get the value from the OS. -static const int kShowFolderDropMenuDelay = 400; - -// Color of the drop indicator. -static const SkColor kDropIndicatorColor = SK_ColorBLACK; - -// Width of the drop indicator. -static const int kDropIndicatorWidth = 2; - -// Distance between the bottom of the bar and the separator. -static const int kSeparatorMargin = 1; - -// Width of the separator between the recently bookmarked button and the -// overflow indicator. -static const int kSeparatorWidth = 4; - -// Starting x-coordinate of the separator line within a separator. -static const int kSeparatorStartX = 2; - -// Left-padding for the instructional text. -static const int kInstructionsPadding = 6; - -// Tag for the 'Other bookmarks' button. -static const int kOtherFolderButtonTag = 1; - -// Tag for the sync error button. -static const int kSyncErrorButtonTag = 2; - -namespace { - -// Returns the tooltip text for the specified url and title. The returned -// text is clipped to fit within the bounds of the monitor. -// -// Note that we adjust the direction of both the URL and the title based on the -// locale so that pure LTR strings are displayed properly in RTL locales. -static std::wstring CreateToolTipForURLAndTitle(const gfx::Point& screen_loc, - const GURL& url, - const std::wstring& title, - const std::wstring& languages) { - int max_width = views::TooltipManager::GetMaxWidth(screen_loc.x(), - screen_loc.y()); - gfx::Font tt_font = views::TooltipManager::GetDefaultFont(); - std::wstring result; - - // First the title. - if (!title.empty()) { - std::wstring localized_title; - if (!base::i18n::AdjustStringForLocaleDirection(title, &localized_title)) - localized_title = title; - result.append(UTF16ToWideHack(gfx::ElideText(WideToUTF16Hack( - localized_title), tt_font, max_width, false))); - } - - // Only show the URL if the url and title differ. - if (title != UTF8ToWide(url.spec())) { - if (!result.empty()) - result.append(views::TooltipManager::GetLineSeparator()); - - // We need to explicitly specify the directionality of the URL's text to - // make sure it is treated as an LTR string when the context is RTL. For - // example, the URL "http://www.yahoo.com/" appears as - // "/http://www.yahoo.com" when rendered, as is, in an RTL context since - // the Unicode BiDi algorithm puts certain characters on the left by - // default. - string16 elided_url(gfx::ElideUrl(url, tt_font, max_width, languages)); - elided_url = base::i18n::GetDisplayStringInLTRDirectionality(elided_url); - result.append(UTF16ToWideHack(elided_url)); - } - return result; -} - -// BookmarkButton ------------------------------------------------------------- - -// Buttons used for the bookmarks on the bookmark bar. - -class BookmarkButton : public views::TextButton { - public: - BookmarkButton(views::ButtonListener* listener, - const GURL& url, - const std::wstring& title, - Profile* profile) - : TextButton(listener, title), - url_(url), - profile_(profile) { - show_animation_.reset(new SlideAnimation(this)); - if (BookmarkBarView::testing_) { - // For some reason during testing the events generated by animating - // throw off the test. So, don't animate while testing. - show_animation_->Reset(1); - } else { - show_animation_->Show(); - } - } - - bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { - gfx::Point location(p); - ConvertPointToScreen(this, &location); - *tooltip = CreateToolTipForURLAndTitle(location, url_, text(), - UTF8ToWide(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages))); - return !tooltip->empty(); - } - - virtual bool IsTriggerableEvent(const views::MouseEvent& e) { - return event_utils::IsPossibleDispositionEvent(e); - } - - private: - const GURL& url_; - Profile* profile_; - scoped_ptr<SlideAnimation> show_animation_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkButton); -}; - -// BookmarkFolderButton ------------------------------------------------------- - -// Buttons used for folders on the bookmark bar, including the 'other folders' -// button. -class BookmarkFolderButton : public views::MenuButton { - public: - BookmarkFolderButton(views::ButtonListener* listener, - const std::wstring& title, - views::ViewMenuDelegate* menu_delegate, - bool show_menu_marker) - : MenuButton(listener, title, menu_delegate, show_menu_marker) { - show_animation_.reset(new SlideAnimation(this)); - if (BookmarkBarView::testing_) { - // For some reason during testing the events generated by animating - // throw off the test. So, don't animate while testing. - show_animation_->Reset(1); - } else { - show_animation_->Show(); - } - } - - virtual bool IsTriggerableEvent(const views::MouseEvent& e) { - // Left clicks should show the menu contents and right clicks should show - // the context menu. They should not trigger the opening of underlying urls. - if (e.GetFlags() == views::MouseEvent::EF_LEFT_BUTTON_DOWN || - e.GetFlags() == views::MouseEvent::EF_RIGHT_BUTTON_DOWN) - return false; - - WindowOpenDisposition disposition( - event_utils::DispositionFromEventFlags(e.GetFlags())); - return disposition != CURRENT_TAB; - } - - virtual void Paint(gfx::Canvas* canvas) { - views::MenuButton::Paint(canvas, false); - } - - private: - scoped_ptr<SlideAnimation> show_animation_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkFolderButton); -}; - -// OverFlowButton (chevron) -------------------------------------------------- - -class OverFlowButton : public views::MenuButton { - public: - explicit OverFlowButton(BookmarkBarView* owner) - : MenuButton(NULL, std::wstring(), owner, false), - owner_(owner) {} - - virtual bool OnMousePressed(const views::MouseEvent& e) { - owner_->StopThrobbing(true); - return views::MenuButton::OnMousePressed(e); - } - - private: - BookmarkBarView* owner_; - - DISALLOW_COPY_AND_ASSIGN(OverFlowButton); -}; - -} // namespace - -// DropInfo ------------------------------------------------------------------- - -// Tracks drops on the BookmarkBarView. - -struct BookmarkBarView::DropInfo { - DropInfo() - : valid(false), - drop_index(-1), - is_menu_showing(false), - drop_on(false), - is_over_overflow(false), - is_over_other(false), - x(0), - y(0), - drag_operation(0) { - } - - // Whether the data is valid. - bool valid; - - // Index into the model the drop is over. This is relative to the root node. - int drop_index; - - // If true, the menu is being shown. - bool is_menu_showing; - - // If true, the user is dropping on a node. This is only used for group - // nodes. - bool drop_on; - - // If true, the user is over the overflow button. - bool is_over_overflow; - - // If true, the user is over the other button. - bool is_over_other; - - // Coordinates of the drag (in terms of the BookmarkBarView). - int x; - int y; - - // The current drag operation. - int drag_operation; - - // DropData for the drop. - BookmarkDragData data; -}; - -// ButtonSeparatorView -------------------------------------------------------- - -class BookmarkBarView::ButtonSeparatorView : public views::View { - public: - ButtonSeparatorView() {} - virtual ~ButtonSeparatorView() {} - - virtual void Paint(gfx::Canvas* canvas) { - DetachableToolbarView::PaintVerticalDivider( - canvas, kSeparatorStartX, height(), 1, - DetachableToolbarView::kEdgeDividerColor, - DetachableToolbarView::kMiddleDividerColor, - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); - } - - virtual gfx::Size GetPreferredSize() { - // We get the full height of the bookmark bar, so that the height returned - // here doesn't matter. - return gfx::Size(kSeparatorWidth, 1); - } - - virtual AccessibilityTypes::Role GetAccessibleRole() { - return AccessibilityTypes::ROLE_SEPARATOR; - } - - private: - DISALLOW_COPY_AND_ASSIGN(ButtonSeparatorView); -}; - -// BookmarkBarView ------------------------------------------------------------ - -// static -const int BookmarkBarView::kMaxButtonWidth = 150; -const int BookmarkBarView::kNewtabHorizontalPadding = 8; -const int BookmarkBarView::kNewtabVerticalPadding = 12; - -// static -bool BookmarkBarView::testing_ = false; - -// Returns the bitmap to use for starred groups. -static const SkBitmap& GetGroupIcon() { - if (!kFolderIcon) { - kFolderIcon = ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_BOOKMARK_BAR_FOLDER); - } - return *kFolderIcon; -} - -BookmarkBarView::BookmarkBarView(Profile* profile, Browser* browser) - : profile_(NULL), - page_navigator_(NULL), - model_(NULL), - bookmark_menu_(NULL), - bookmark_drop_menu_(NULL), - other_bookmarked_button_(NULL), - model_changed_listener_(NULL), - show_folder_drop_menu_task_(NULL), - sync_error_button_(NULL), - sync_service_(NULL), - overflow_button_(NULL), - instructions_(NULL), - bookmarks_separator_view_(NULL), - browser_(browser), - infobar_visible_(false), - throbbing_view_(NULL) { - if (profile->GetProfileSyncService()) { - // Obtain a pointer to the profile sync service and add our instance as an - // observer. - sync_service_ = profile->GetProfileSyncService(); - sync_service_->AddObserver(this); - } - - SetID(VIEW_ID_BOOKMARK_BAR); - Init(); - SetProfile(profile); - - size_animation_->Reset(IsAlwaysShown() ? 1 : 0); -} - -BookmarkBarView::~BookmarkBarView() { - NotifyModelChanged(); - if (model_) - model_->RemoveObserver(this); - - // It's possible for the menu to outlive us, reset the observer to make sure - // it doesn't have a reference to us. - if (bookmark_menu_) - bookmark_menu_->set_observer(NULL); - - StopShowFolderDropMenuTimer(); - - if (sync_service_) - sync_service_->RemoveObserver(this); -} - -void BookmarkBarView::SetProfile(Profile* profile) { - DCHECK(profile); - if (profile_ == profile) - return; - - StopThrobbing(true); - - // Cancels the current cancelable. - NotifyModelChanged(); - registrar_.RemoveAll(); - - profile_ = profile; - - if (model_) - model_->RemoveObserver(this); - - // Disable the other bookmarked button, we'll re-enable when the model is - // loaded. - other_bookmarked_button_->SetEnabled(false); - - Source<Profile> ns_source(profile_->GetOriginalProfile()); - registrar_.Add(this, NotificationType::BOOKMARK_BUBBLE_SHOWN, ns_source); - registrar_.Add(this, NotificationType::BOOKMARK_BUBBLE_HIDDEN, ns_source); - registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, - NotificationService::AllSources()); - - // Remove any existing bookmark buttons. - while (GetBookmarkButtonCount()) - delete GetChildViewAt(0); - - model_ = profile_->GetBookmarkModel(); - if (model_) { - model_->AddObserver(this); - if (model_->IsLoaded()) - Loaded(model_); - // else case: we'll receive notification back from the BookmarkModel when - // done loading, then we'll populate the bar. - } -} - -void BookmarkBarView::SetPageNavigator(PageNavigator* navigator) { - page_navigator_ = navigator; -} - -gfx::Size BookmarkBarView::GetPreferredSize() { - return LayoutItems(true); -} - -gfx::Size BookmarkBarView::GetMinimumSize() { - // The minimum width of the bookmark bar should at least contain the overflow - // button, by which one can access all the Bookmark Bar items, and the "Other - // Bookmarks" folder, along with appropriate margins and button padding. - int width = kLeftMargin; - - if (OnNewTabPage()) { - double current_state = 1 - size_animation_->GetCurrentValue(); - width += 2 * static_cast<int>(static_cast<double> - (kNewtabHorizontalPadding) * current_state); - } - - int sync_error_total_width = 0; - gfx::Size sync_error_button_pref = sync_error_button_->GetPreferredSize(); - if (sync_ui_util::ShouldShowSyncErrorButton(sync_service_)) - sync_error_total_width += kButtonPadding + sync_error_button_pref.width(); - - gfx::Size other_bookmarked_pref = - other_bookmarked_button_->GetPreferredSize(); - gfx::Size overflow_pref = overflow_button_->GetPreferredSize(); - gfx::Size bookmarks_separator_pref = - bookmarks_separator_view_->GetPreferredSize(); - - width += (other_bookmarked_pref.width() + kButtonPadding + - overflow_pref.width() + kButtonPadding + - bookmarks_separator_pref.width() + sync_error_total_width); - - return gfx::Size(width, kBarHeight); -} - -void BookmarkBarView::Layout() { - LayoutItems(false); -} - -void BookmarkBarView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - Layout(); -} - -void BookmarkBarView::ViewHierarchyChanged(bool is_add, - View* parent, - View* child) { - if (is_add && child == this) { - // We may get inserted into a hierarchy with a profile - this typically - // occurs when the bar's contents get populated fast enough that the - // buttons are created before the bar is attached to a frame. - UpdateColors(); - - if (height() > 0) { - // We only layout while parented. When we become parented, if our bounds - // haven't changed, DidChangeBounds won't get invoked and we won't layout. - // Therefore we always force a layout when added. - Layout(); - } - } -} - -void BookmarkBarView::PaintChildren(gfx::Canvas* canvas) { - View::PaintChildren(canvas); - - if (drop_info_.get() && drop_info_->valid && - drop_info_->drag_operation != 0 && drop_info_->drop_index != -1 && - !drop_info_->is_over_overflow && !drop_info_->drop_on) { - int index = drop_info_->drop_index; - DCHECK(index <= GetBookmarkButtonCount()); - int x = 0; - int y = 0; - int h = height(); - if (index == GetBookmarkButtonCount()) { - if (index == 0) { - x = kLeftMargin; - } else { - x = GetBookmarkButton(index - 1)->x() + - GetBookmarkButton(index - 1)->width(); - } - } else { - x = GetBookmarkButton(index)->x(); - } - if (GetBookmarkButtonCount() > 0 && GetBookmarkButton(0)->IsVisible()) { - y = GetBookmarkButton(0)->y(); - h = GetBookmarkButton(0)->height(); - } - - // Since the drop indicator is painted directly onto the canvas, we must - // make sure it is painted in the right location if the locale is RTL. - gfx::Rect indicator_bounds(x - kDropIndicatorWidth / 2, - y, - kDropIndicatorWidth, - h); - indicator_bounds.set_x(MirroredLeftPointForRect(indicator_bounds)); - - // TODO(sky/glen): make me pretty! - canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(), - indicator_bounds.y(), indicator_bounds.width(), - indicator_bounds.height()); - } -} - -bool BookmarkBarView::GetDropFormats( - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats) { - if (!model_ || !model_->IsLoaded()) - return false; - *formats = OSExchangeData::URL; - custom_formats->insert(BookmarkDragData::GetBookmarkCustomFormat()); - return true; -} - -bool BookmarkBarView::AreDropTypesRequired() { - return true; -} - -bool BookmarkBarView::CanDrop(const OSExchangeData& data) { - if (!model_ || !model_->IsLoaded()) - return false; - - if (!drop_info_.get()) - drop_info_.reset(new DropInfo()); - - // Only accept drops of 1 node, which is the case for all data dragged from - // bookmark bar and menus. - return drop_info_->data.Read(data) && drop_info_->data.size() == 1; -} - -void BookmarkBarView::OnDragEntered(const DropTargetEvent& event) { -} - -int BookmarkBarView::OnDragUpdated(const DropTargetEvent& event) { - if (!drop_info_.get()) - return 0; - - if (drop_info_->valid && - (drop_info_->x == event.x() && drop_info_->y == event.y())) { - // The location of the mouse didn't change, return the last operation. - return drop_info_->drag_operation; - } - - drop_info_->x = event.x(); - drop_info_->y = event.y(); - - int drop_index; - bool drop_on; - bool is_over_overflow; - bool is_over_other; - - drop_info_->drag_operation = CalculateDropOperation( - event, drop_info_->data, &drop_index, &drop_on, &is_over_overflow, - &is_over_other); - - if (drop_info_->valid && drop_info_->drop_index == drop_index && - drop_info_->drop_on == drop_on && - drop_info_->is_over_overflow == is_over_overflow && - drop_info_->is_over_other == is_over_other) { - // The position we're going to drop didn't change, return the last drag - // operation we calculated. - return drop_info_->drag_operation; - } - - drop_info_->valid = true; - - StopShowFolderDropMenuTimer(); - - // TODO(sky): Optimize paint region. - SchedulePaint(); - drop_info_->drop_index = drop_index; - drop_info_->drop_on = drop_on; - drop_info_->is_over_overflow = is_over_overflow; - drop_info_->is_over_other = is_over_other; - - if (drop_info_->is_menu_showing) { - if (bookmark_drop_menu_) - bookmark_drop_menu_->Cancel(); - drop_info_->is_menu_showing = false; - } - - if (drop_on || is_over_overflow || is_over_other) { - const BookmarkNode* node; - if (is_over_other) - node = model_->other_node(); - else if (is_over_overflow) - node = model_->GetBookmarkBarNode(); - else - node = model_->GetBookmarkBarNode()->GetChild(drop_index); - StartShowFolderDropMenuTimer(node); - } - - return drop_info_->drag_operation; -} - -void BookmarkBarView::OnDragExited() { - StopShowFolderDropMenuTimer(); - - // NOTE: we don't hide the menu on exit as it's possible the user moved the - // mouse over the menu, which triggers an exit on us. - - drop_info_->valid = false; - - if (drop_info_->drop_index != -1) { - // TODO(sky): optimize the paint region. - SchedulePaint(); - } - drop_info_.reset(); -} - -int BookmarkBarView::OnPerformDrop(const DropTargetEvent& event) { - StopShowFolderDropMenuTimer(); - - if (bookmark_drop_menu_) - bookmark_drop_menu_->Cancel(); - - if (!drop_info_.get() || !drop_info_->drag_operation) - return DragDropTypes::DRAG_NONE; - - const BookmarkNode* root = - drop_info_->is_over_other ? model_->other_node() : - model_->GetBookmarkBarNode(); - int index = drop_info_->drop_index; - const bool drop_on = drop_info_->drop_on; - const BookmarkDragData data = drop_info_->data; - const bool is_over_other = drop_info_->is_over_other; - DCHECK(data.is_valid()); - - if (drop_info_->drop_index != -1) { - // TODO(sky): optimize the SchedulePaint region. - SchedulePaint(); - } - drop_info_.reset(); - - const BookmarkNode* parent_node; - if (is_over_other) { - parent_node = root; - index = parent_node->GetChildCount(); - } else if (drop_on) { - parent_node = root->GetChild(index); - index = parent_node->GetChildCount(); - } else { - parent_node = root; - } - return bookmark_utils::PerformBookmarkDrop(profile_, data, parent_node, - index); -} - -void BookmarkBarView::ShowContextMenu(const gfx::Point& p, - bool is_mouse_gesture) { - ShowContextMenu(this, p, is_mouse_gesture); -} - -bool BookmarkBarView::IsAccessibleViewTraversable(views::View* view) { - return view != bookmarks_separator_view_ && view != instructions_; -} - -AccessibilityTypes::Role BookmarkBarView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_TOOLBAR; -} - -void BookmarkBarView::OnStateChanged() { - // When the sync state changes, it is sufficient to invoke View::Layout since - // during layout we query the profile sync service and determine whether the - // new state requires showing the sync error button so that the user can - // re-enter her password. If extension shelf appears along with the bookmark - // shelf, it too needs to be layed out. Since both have the same parent, it is - // enough to let the parent layout both of these children. - // TODO(sky): This should not require Layout() and SchedulePaint(). Needs - // some cleanup. - PreferredSizeChanged(); - Layout(); - SchedulePaint(); -} - -void BookmarkBarView::OnFullscreenToggled(bool fullscreen) { - if (!fullscreen) - size_animation_->Reset(IsAlwaysShown() ? 1 : 0); - else if (IsAlwaysShown()) - size_animation_->Reset(0); -} - -bool BookmarkBarView::IsDetached() const { - return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1); -} - -bool BookmarkBarView::IsOnTop() const { - return true; -} - -bool BookmarkBarView::IsAlwaysShown() const { - return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); -} - -bool BookmarkBarView::OnNewTabPage() const { - return (browser_ && browser_->GetSelectedTabContents() && - browser_->GetSelectedTabContents()->ShouldShowBookmarkBar()); -} - -int BookmarkBarView::GetToolbarOverlap(bool return_max) const { - // When not on the New Tab Page, always overlap by the full amount. - if (return_max || !OnNewTabPage()) - return kToolbarOverlap; - // When on the New Tab Page with an infobar, overlap by 0 whenever the infobar - // is above us (i.e. when we're detached), since drawing over the infobar - // looks weird. - if (IsDetached() && infobar_visible_) - return 0; - // When on the New Tab Page with no infobar, animate the overlap between the - // attached and detached states. - return static_cast<int>(static_cast<double>(kToolbarOverlap) * - size_animation_->GetCurrentValue()); -} - -void BookmarkBarView::AnimationProgressed(const Animation* animation) { - if (browser_) - browser_->ToolbarSizeChanged(true); -} - -void BookmarkBarView::AnimationEnded(const Animation* animation) { - if (browser_) - browser_->ToolbarSizeChanged(false); - - SchedulePaint(); -} - -void BookmarkBarView::BookmarkMenuDeleted(BookmarkMenuController* controller) { - if (controller == bookmark_menu_) - bookmark_menu_ = NULL; - else if (controller == bookmark_drop_menu_) - bookmark_drop_menu_ = NULL; -} - -views::TextButton* BookmarkBarView::GetBookmarkButton(int index) { - DCHECK(index >= 0 && index < GetBookmarkButtonCount()); - return static_cast<views::TextButton*>(GetChildViewAt(index)); -} - -views::MenuItemView* BookmarkBarView::GetMenu() { - return bookmark_menu_ ? bookmark_menu_->menu() : NULL; -} - -views::MenuItemView* BookmarkBarView::GetContextMenu() { - return bookmark_menu_ ? bookmark_menu_->context_menu() : NULL; -} - -views::MenuItemView* BookmarkBarView::GetDropMenu() { - return bookmark_drop_menu_ ? bookmark_drop_menu_->menu() : NULL; -} - -const BookmarkNode* BookmarkBarView::GetNodeForButtonAt(const gfx::Point& loc, - int* start_index) { - *start_index = 0; - - if (loc.x() < 0 || loc.x() >= width() || loc.y() < 0 || loc.y() >= height()) - return NULL; - - gfx::Point adjusted_loc(MirroredXCoordinateInsideView(loc.x()), loc.y()); - - // Check the buttons first. - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - views::View* child = GetChildViewAt(i); - if (!child->IsVisible()) - break; - if (child->bounds().Contains(adjusted_loc)) - return model_->GetBookmarkBarNode()->GetChild(i); - } - - // Then the overflow button. - if (overflow_button_->IsVisible() && - overflow_button_->bounds().Contains(adjusted_loc)) { - *start_index = GetFirstHiddenNodeIndex(); - return model_->GetBookmarkBarNode(); - } - - // And finally the other folder. - if (other_bookmarked_button_->bounds().Contains(adjusted_loc)) - return model_->other_node(); - - return NULL; -} - -views::MenuButton* BookmarkBarView::GetMenuButtonForNode( - const BookmarkNode* node) { - if (node == model_->other_node()) - return other_bookmarked_button_; - if (node == model_->GetBookmarkBarNode()) - return overflow_button_; - int index = model_->GetBookmarkBarNode()->IndexOfChild(node); - if (index == -1 || !node->is_folder()) - return NULL; - return static_cast<views::MenuButton*>(GetChildViewAt(index)); -} - -void BookmarkBarView::GetAnchorPositionAndStartIndexForButton( - views::MenuButton* button, - MenuItemView::AnchorPosition* anchor, - int* start_index) { - if (button == other_bookmarked_button_ || button == overflow_button_) - *anchor = MenuItemView::TOPRIGHT; - else - *anchor = MenuItemView::TOPLEFT; - - // Invert orientation if right to left. - if (base::i18n::IsRTL()) { - if (*anchor == MenuItemView::TOPRIGHT) - *anchor = MenuItemView::TOPLEFT; - else - *anchor = MenuItemView::TOPRIGHT; - } - - if (button == overflow_button_) - *start_index = GetFirstHiddenNodeIndex(); - else - *start_index = 0; -} - -void BookmarkBarView::ShowImportDialog() { -#if defined(OS_WIN) - views::Window::CreateChromeWindow( - GetWindow()->GetNativeWindow(), - gfx::Rect(), - new ImporterView(profile_, importer::FAVORITES))->Show(); -#endif -} - -void BookmarkBarView::Init() { - // Note that at this point we're not in a hierarchy so GetThemeProvider() will - // return NULL. When we're inserted into a hierarchy, we'll call - // UpdateColors(), which will set the appropriate colors for all the objects - // added in this function. - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - if (!kDefaultFavIcon) - kDefaultFavIcon = rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); - - // Child views are traversed in the order they are added. Make sure the order - // they are added matches the visual order. - sync_error_button_ = CreateSyncErrorButton(); - AddChildView(sync_error_button_); - - overflow_button_ = CreateOverflowButton(); - AddChildView(overflow_button_); - - other_bookmarked_button_ = CreateOtherBookmarkedButton(); - AddChildView(other_bookmarked_button_); - - bookmarks_separator_view_ = new ButtonSeparatorView(); - bookmarks_separator_view_->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_SEPARATOR)); - AddChildView(bookmarks_separator_view_); - - instructions_ = new BookmarkBarInstructionsView(this); - AddChildView(instructions_); - - SetContextMenuController(this); - - size_animation_.reset(new SlideAnimation(this)); -} - -MenuButton* BookmarkBarView::CreateOtherBookmarkedButton() { - MenuButton* button = new BookmarkFolderButton( - this, l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_BOOKMARKED), this, - false); - button->SetID(VIEW_ID_OTHER_BOOKMARKS); - button->SetIcon(GetGroupIcon()); - button->SetContextMenuController(this); - button->set_tag(kOtherFolderButtonTag); - button->SetAccessibleName( - l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_BOOKMARKED)); - return button; -} - -MenuButton* BookmarkBarView::CreateOverflowButton() { - MenuButton* button = new OverFlowButton(this); - button->SetIcon(*ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS)); - - // The overflow button's image contains an arrow and therefore it is a - // direction sensitive image and we need to flip it if the UI layout is - // right-to-left. - // - // By default, menu buttons are not flipped because they generally contain - // text and flipping the gfx::Canvas object will break text rendering. Since - // the overflow button does not contain text, we can safely flip it. - button->EnableCanvasFlippingForRTLUI(true); - - // Make visible as necessary. - button->SetVisible(false); - // Set accessibility name. - button->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_BOOKMARKS_CHEVRON)); - return button; -} - -void BookmarkBarView::Loaded(BookmarkModel* model) { - volatile int button_count = GetBookmarkButtonCount(); - DCHECK(button_count == 0); // If non-zero it means Load was invoked more than - // once, or we didn't properly clear things. - // Either of which shouldn't happen - const BookmarkNode* node = model_->GetBookmarkBarNode(); - DCHECK(node && model_->other_node()); - // Create a button for each of the children on the bookmark bar. - for (int i = 0, child_count = node->GetChildCount(); i < child_count; ++i) - AddChildView(i, CreateBookmarkButton(node->GetChild(i))); - UpdateColors(); - other_bookmarked_button_->SetEnabled(true); - - Layout(); - SchedulePaint(); -} - -void BookmarkBarView::BookmarkModelBeingDeleted(BookmarkModel* model) { - // In normal shutdown The bookmark model should never be deleted before us. - // When X exits suddenly though, it can happen, This code exists - // to check for regressions in shutdown code and not crash. - if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers()) - NOTREACHED(); - - // Do minimal cleanup, presumably we'll be deleted shortly. - NotifyModelChanged(); - model_->RemoveObserver(this); - model_ = NULL; -} - -void BookmarkBarView::BookmarkNodeMoved(BookmarkModel* model, - const BookmarkNode* old_parent, - int old_index, - const BookmarkNode* new_parent, - int new_index) { - BookmarkNodeRemovedImpl(model, old_parent, old_index); - BookmarkNodeAddedImpl(model, new_parent, new_index); -} - -void BookmarkBarView::BookmarkNodeAdded(BookmarkModel* model, - const BookmarkNode* parent, - int index) { - BookmarkNodeAddedImpl(model, parent, index); -} - -void BookmarkBarView::BookmarkNodeAddedImpl(BookmarkModel* model, - const BookmarkNode* parent, - int index) { - NotifyModelChanged(); - if (parent != model_->GetBookmarkBarNode()) { - // We only care about nodes on the bookmark bar. - return; - } - DCHECK(index >= 0 && index <= GetBookmarkButtonCount()); - const BookmarkNode* node = parent->GetChild(index); - if (!throbbing_view_ && sync_service_ && sync_service_->SetupInProgress()) { - StartThrobbing(node, true); - } - AddChildView(index, CreateBookmarkButton(node)); - UpdateColors(); - Layout(); - SchedulePaint(); -} - -void BookmarkBarView::BookmarkNodeRemoved(BookmarkModel* model, - const BookmarkNode* parent, - int old_index, - const BookmarkNode* node) { - BookmarkNodeRemovedImpl(model, parent, old_index); -} - -void BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model, - const BookmarkNode* parent, - int index) { - StopThrobbing(true); - // No need to start throbbing again as the bookmark bubble can't be up at - // the same time as the user reorders. - - NotifyModelChanged(); - if (parent != model_->GetBookmarkBarNode()) { - // We only care about nodes on the bookmark bar. - return; - } - DCHECK(index >= 0 && index < GetBookmarkButtonCount()); - views::View* button = GetChildViewAt(index); - RemoveChildView(button); - MessageLoop::current()->DeleteSoon(FROM_HERE, button); - Layout(); - SchedulePaint(); -} - -void BookmarkBarView::BookmarkNodeChanged(BookmarkModel* model, - const BookmarkNode* node) { - NotifyModelChanged(); - BookmarkNodeChangedImpl(model, node); -} - -void BookmarkBarView::BookmarkNodeChangedImpl(BookmarkModel* model, - const BookmarkNode* node) { - if (node->GetParent() != model_->GetBookmarkBarNode()) { - // We only care about nodes on the bookmark bar. - return; - } - int index = model_->GetBookmarkBarNode()->IndexOfChild(node); - DCHECK_NE(-1, index); - views::TextButton* button = GetBookmarkButton(index); - gfx::Size old_pref = button->GetPreferredSize(); - ConfigureButton(node, button); - gfx::Size new_pref = button->GetPreferredSize(); - if (old_pref.width() != new_pref.width()) { - Layout(); - SchedulePaint(); - } else if (button->IsVisible()) { - button->SchedulePaint(); - } -} - -void BookmarkBarView::BookmarkNodeChildrenReordered(BookmarkModel* model, - const BookmarkNode* node) { - NotifyModelChanged(); - if (node != model_->GetBookmarkBarNode()) - return; // We only care about reordering of the bookmark bar node. - - // Remove the existing buttons. - while (GetBookmarkButtonCount()) { - views::View* button = GetChildViewAt(0); - RemoveChildView(button); - MessageLoop::current()->DeleteSoon(FROM_HERE, button); - } - - // Create the new buttons. - for (int i = 0, child_count = node->GetChildCount(); i < child_count; ++i) - AddChildView(i, CreateBookmarkButton(node->GetChild(i))); - UpdateColors(); - - Layout(); - SchedulePaint(); -} - -void BookmarkBarView::BookmarkNodeFavIconLoaded(BookmarkModel* model, - const BookmarkNode* node) { - BookmarkNodeChangedImpl(model, node); -} - -void BookmarkBarView::WriteDragData(View* sender, - const gfx::Point& press_pt, - OSExchangeData* data) { - UserMetrics::RecordAction(UserMetricsAction("BookmarkBar_DragButton"), - profile_); - - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - if (sender == GetBookmarkButton(i)) { - views::TextButton* button = GetBookmarkButton(i); - gfx::CanvasSkia canvas(button->width(), button->height(), false); - button->Paint(&canvas, true); - drag_utils::SetDragImageOnDataObject(canvas, button->size(), - press_pt, data); - WriteDragData(model_->GetBookmarkBarNode()->GetChild(i), data); - return; - } - } - NOTREACHED(); -} - -int BookmarkBarView::GetDragOperations(View* sender, const gfx::Point& p) { - if (size_animation_->is_animating() || - (size_animation_->GetCurrentValue() == 0 && !OnNewTabPage())) { - // Don't let the user drag while animating open or we're closed (and not on - // the new tab page, on the new tab page size_animation_ is always 0). This - // typically is only hit if the user does something to inadvertanty trigger - // dnd, such as pressing the mouse and hitting control-b. - return DragDropTypes::DRAG_NONE; - } - - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - if (sender == GetBookmarkButton(i)) { - return bookmark_utils::BookmarkDragOperation( - model_->GetBookmarkBarNode()->GetChild(i)); - } - } - NOTREACHED(); - return DragDropTypes::DRAG_NONE; -} - -bool BookmarkBarView::CanStartDrag(views::View* sender, - const gfx::Point& press_pt, - const gfx::Point& p) { - // Check if we have not moved enough horizontally but we have moved downward - // vertically - downward drag. - if (!View::ExceededDragThreshold(press_pt.x() - p.x(), 0) && - press_pt.y() < p.y()) { - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - if (sender == GetBookmarkButton(i)) { - const BookmarkNode* node = model_->GetBookmarkBarNode()->GetChild(i); - // If the folder button was dragged, show the menu instead. - if (node && node->is_folder()) { - views::MenuButton* menu_button = - static_cast<views::MenuButton*>(sender); - menu_button->Activate(); - return false; - } - break; - } - } - } - return true; -} - -void BookmarkBarView::WriteDragData(const BookmarkNode* node, - OSExchangeData* data) { - DCHECK(node && data); - BookmarkDragData drag_data(node); - drag_data.Write(profile_, data); -} - -void BookmarkBarView::RunMenu(views::View* view, const gfx::Point& pt) { - const BookmarkNode* node; - - int start_index = 0; - if (view == other_bookmarked_button_) { - node = model_->other_node(); - } else if (view == overflow_button_) { - node = model_->GetBookmarkBarNode(); - start_index = GetFirstHiddenNodeIndex(); - } else { - int button_index = GetChildIndex(view); - DCHECK_NE(-1, button_index); - node = model_->GetBookmarkBarNode()->GetChild(button_index); - } - - bookmark_menu_ = new BookmarkMenuController(browser_, profile_, - page_navigator_, GetWindow()->GetNativeWindow(), node, start_index); - bookmark_menu_->set_observer(this); - bookmark_menu_->RunMenuAt(this, false); -} - -void BookmarkBarView::ButtonPressed(views::Button* sender, - const views::Event& event) { - // Show the login wizard if the user clicked the re-login button. - if (sender->tag() == kSyncErrorButtonTag) { - DCHECK(sender == sync_error_button_); - DCHECK(sync_service_ && !sync_service_->IsManaged()); - sync_service_->ShowLoginDialog(GetWindow()->GetNativeWindow()); - return; - } - - const BookmarkNode* node; - if (sender->tag() == kOtherFolderButtonTag) { - node = model_->other_node(); - } else { - int index = GetChildIndex(sender); - DCHECK_NE(-1, index); - node = model_->GetBookmarkBarNode()->GetChild(index); - } - DCHECK(page_navigator_); - - WindowOpenDisposition disposition_from_event_flags = - event_utils::DispositionFromEventFlags(sender->mouse_event_flags()); - - if (node->is_url()) { - page_navigator_->OpenURL(node->GetURL(), GURL(), - disposition_from_event_flags, PageTransition::AUTO_BOOKMARK); - } else { - bookmark_utils::OpenAll(GetWindow()->GetNativeWindow(), profile_, - GetPageNavigator(), node, disposition_from_event_flags); - } - UserMetrics::RecordAction(UserMetricsAction("ClickedBookmarkBarURLButton"), - profile_); -} - -void BookmarkBarView::ShowContextMenu(View* source, - const gfx::Point& p, - bool is_mouse_gesture) { - if (!model_->IsLoaded()) { - // Don't do anything if the model isn't loaded. - return; - } - - const BookmarkNode* parent = NULL; - std::vector<const BookmarkNode*> nodes; - if (source == other_bookmarked_button_) { - parent = model_->other_node(); - // Do this so the user can open all bookmarks. BookmarkContextMenu makes - // sure the user can edit/delete the node in this case. - nodes.push_back(parent); - } else if (source != this) { - // User clicked on one of the bookmark buttons, find which one they - // clicked on. - int bookmark_button_index = GetChildIndex(source); - DCHECK(bookmark_button_index != -1 && - bookmark_button_index < GetBookmarkButtonCount()); - const BookmarkNode* node = - model_->GetBookmarkBarNode()->GetChild(bookmark_button_index); - nodes.push_back(node); - parent = node->GetParent(); - } else { - parent = model_->GetBookmarkBarNode(); - nodes.push_back(parent); - } - // Browser may be null during testing. - PageNavigator* navigator = - browser() ? browser()->GetSelectedTabContents() : NULL; - BookmarkContextMenu controller(GetWindow()->GetNativeWindow(), GetProfile(), - navigator, parent, nodes); - controller.RunMenuAt(p); -} - -views::View* BookmarkBarView::CreateBookmarkButton(const BookmarkNode* node) { - if (node->is_url()) { - BookmarkButton* button = new BookmarkButton(this, node->GetURL(), - UTF16ToWide(node->GetTitle()), GetProfile()); - ConfigureButton(node, button); - return button; - } else { - views::MenuButton* button = new BookmarkFolderButton(this, - UTF16ToWide(node->GetTitle()), this, false); - button->SetIcon(GetGroupIcon()); - ConfigureButton(node, button); - return button; - } -} - -void BookmarkBarView::ConfigureButton(const BookmarkNode* node, - views::TextButton* button) { - button->SetText(UTF16ToWide(node->GetTitle())); - button->SetAccessibleName(UTF16ToWide(node->GetTitle())); - button->SetID(VIEW_ID_BOOKMARK_BAR_ELEMENT); - // We don't always have a theme provider (ui tests, for example). - if (GetThemeProvider()) { - button->SetEnabledColor(GetThemeProvider()->GetColor( - BrowserThemeProvider::COLOR_BOOKMARK_TEXT)); - } - - button->ClearMaxTextSize(); - button->SetContextMenuController(this); - button->SetDragController(this); - if (node->is_url()) { - if (model_->GetFavIcon(node).width() != 0) - button->SetIcon(model_->GetFavIcon(node)); - else - button->SetIcon(*kDefaultFavIcon); - } - button->set_max_width(kMaxButtonWidth); -} - -bool BookmarkBarView::IsItemChecked(int id) const { - DCHECK(id == kAlwaysShowCommandID); - return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); -} - -void BookmarkBarView::ExecuteCommand(int id) { - bookmark_utils::ToggleWhenVisible(profile_); -} - -void BookmarkBarView::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(profile_); - switch (type.value) { - case NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED: - if (IsAlwaysShown()) { - size_animation_->Show(); - } else { - size_animation_->Hide(); - } - break; - - case NotificationType::BOOKMARK_BUBBLE_SHOWN: { - StopThrobbing(true); - GURL url = *(Details<GURL>(details).ptr()); - const BookmarkNode* node = model_->GetMostRecentlyAddedNodeForURL(url); - if (!node) - return; // Generally shouldn't happen. - StartThrobbing(node, false); - break; - } - case NotificationType::BOOKMARK_BUBBLE_HIDDEN: - StopThrobbing(false); - break; - - default: - NOTREACHED(); - break; - } -} - -void BookmarkBarView::OnThemeChanged() { - UpdateColors(); -} - -void BookmarkBarView::NotifyModelChanged() { - if (model_changed_listener_) - model_changed_listener_->ModelChanged(); -} - -void BookmarkBarView::ShowDropFolderForNode(const BookmarkNode* node) { - if (bookmark_drop_menu_) { - if (bookmark_drop_menu_->node() == node) { - // Already showing for the specified node. - return; - } - bookmark_drop_menu_->Cancel(); - } - - views::MenuButton* menu_button = GetMenuButtonForNode(node); - if (!menu_button) - return; - - int start_index = 0; - if (node == model_->GetBookmarkBarNode()) - start_index = GetFirstHiddenNodeIndex(); - - drop_info_->is_menu_showing = true; - bookmark_drop_menu_ = new BookmarkMenuController(browser_, profile_, - page_navigator_, GetWindow()->GetNativeWindow(), node, start_index); - bookmark_drop_menu_->set_observer(this); - bookmark_drop_menu_->RunMenuAt(this, true); -} - -void BookmarkBarView::StopShowFolderDropMenuTimer() { - if (show_folder_drop_menu_task_) - show_folder_drop_menu_task_->Cancel(); -} - -void BookmarkBarView::StartShowFolderDropMenuTimer(const BookmarkNode* node) { - if (testing_) { - // So that tests can run as fast as possible disable the delay during - // testing. - ShowDropFolderForNode(node); - return; - } - DCHECK(!show_folder_drop_menu_task_); - show_folder_drop_menu_task_ = new ShowFolderDropMenuTask(this, node); - int delay = View::GetMenuShowDelay(); - MessageLoop::current()->PostDelayedTask(FROM_HERE, - show_folder_drop_menu_task_, delay); -} - -int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, - const BookmarkDragData& data, - int* index, - bool* drop_on, - bool* is_over_overflow, - bool* is_over_other) { - DCHECK(model_); - DCHECK(model_->IsLoaded()); - DCHECK(data.is_valid()); - - // The drop event uses the screen coordinates while the child Views are - // always laid out from left to right (even though they are rendered from - // right-to-left on RTL locales). Thus, in order to make sure the drop - // coordinates calculation works, we mirror the event's X coordinate if the - // locale is RTL. - int mirrored_x = MirroredXCoordinateInsideView(event.x()); - - *index = -1; - *drop_on = false; - *is_over_other = *is_over_overflow = false; - - if (event.y() < other_bookmarked_button_->y() || - event.y() >= other_bookmarked_button_->y() + - other_bookmarked_button_->height()) { - // Mouse isn't over a button. - return DragDropTypes::DRAG_NONE; - } - - bool found = false; - const int other_delta_x = mirrored_x - other_bookmarked_button_->x(); - if (other_delta_x >= 0 && - other_delta_x < other_bookmarked_button_->width()) { - // Mouse is over 'other' folder. - *is_over_other = true; - *drop_on = true; - found = true; - } else if (!GetBookmarkButtonCount()) { - // No bookmarks, accept the drop. - *index = 0; - int ops = data.GetFirstNode(profile_) - ? DragDropTypes::DRAG_MOVE - : DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK; - return - bookmark_utils::PreferredDropOperation(event.GetSourceOperations(), - ops); - } - - for (int i = 0; i < GetBookmarkButtonCount() && - GetBookmarkButton(i)->IsVisible() && !found; i++) { - views::TextButton* button = GetBookmarkButton(i); - int button_x = mirrored_x - button->x(); - int button_w = button->width(); - if (button_x < button_w) { - found = true; - const BookmarkNode* node = model_->GetBookmarkBarNode()->GetChild(i); - if (node->is_folder()) { - if (button_x <= views::kDropBetweenPixels) { - *index = i; - } else if (button_x < button_w - views::kDropBetweenPixels) { - *index = i; - *drop_on = true; - } else { - *index = i + 1; - } - } else if (button_x < button_w / 2) { - *index = i; - } else { - *index = i + 1; - } - break; - } - } - - if (!found) { - if (overflow_button_->IsVisible()) { - // Are we over the overflow button? - int overflow_delta_x = mirrored_x - overflow_button_->x(); - if (overflow_delta_x >= 0 && - overflow_delta_x < overflow_button_->width()) { - // Mouse is over overflow button. - *index = GetFirstHiddenNodeIndex(); - *is_over_overflow = true; - } else if (overflow_delta_x < 0) { - // Mouse is after the last visible button but before overflow button; - // use the last visible index. - *index = GetFirstHiddenNodeIndex(); - } else { - return DragDropTypes::DRAG_NONE; - } - } else if (mirrored_x < other_bookmarked_button_->x()) { - // Mouse is after the last visible button but before more recently - // bookmarked; use the last visible index. - *index = GetFirstHiddenNodeIndex(); - } else { - return DragDropTypes::DRAG_NONE; - } - } - - if (*drop_on) { - const BookmarkNode* parent = - *is_over_other ? model_->other_node() : - model_->GetBookmarkBarNode()->GetChild(*index); - int operation = - bookmark_utils::BookmarkDropOperation(profile_, event, data, parent, - parent->GetChildCount()); - if (!operation && !data.has_single_url() && - data.GetFirstNode(profile_) == parent) { - // Don't open a menu if the node being dragged is the the menu to - // open. - *drop_on = false; - } - return operation; - } - return bookmark_utils::BookmarkDropOperation(profile_, event, data, - model_->GetBookmarkBarNode(), - *index); -} - -int BookmarkBarView::GetFirstHiddenNodeIndex() { - const int bb_count = GetBookmarkButtonCount(); - for (int i = 0; i < bb_count; ++i) { - if (!GetBookmarkButton(i)->IsVisible()) - return i; - } - return bb_count; -} - -void BookmarkBarView::StartThrobbing(const BookmarkNode* node, - bool overflow_only) { - DCHECK(!throbbing_view_); - - // Determine which visible button is showing the bookmark (or is an ancestor - // of the bookmark). - const BookmarkNode* bbn = model_->GetBookmarkBarNode(); - const BookmarkNode* parent_on_bb = node; - while (parent_on_bb) { - const BookmarkNode* parent = parent_on_bb->GetParent(); - if (parent == bbn) - break; - parent_on_bb = parent; - } - if (parent_on_bb) { - int index = bbn->IndexOfChild(parent_on_bb); - if (index >= GetFirstHiddenNodeIndex()) { - // Node is hidden, animate the overflow button. - throbbing_view_ = overflow_button_; - } else if (!overflow_only) { - throbbing_view_ = static_cast<CustomButton*>(GetChildViewAt(index)); - } - } else if (!overflow_only) { - throbbing_view_ = other_bookmarked_button_; - } - - // Use a large number so that the button continues to throb. - if (throbbing_view_) - throbbing_view_->StartThrobbing(std::numeric_limits<int>::max()); -} - -int BookmarkBarView::GetBookmarkButtonCount() { - // We contain at least four non-bookmark button views: other bookmarks, - // bookmarks separator, chevrons (for overflow), the instruction label and - // the sync error button. - return GetChildViewCount() - 5; -} - -void BookmarkBarView::StopThrobbing(bool immediate) { - if (!throbbing_view_) - return; - - // If not immediate, cycle through 2 more complete cycles. - throbbing_view_->StartThrobbing(immediate ? 0 : 4); - throbbing_view_ = NULL; -} - -void BookmarkBarView::UpdateColors() { - // We don't always have a theme provider (ui tests, for example). - const ThemeProvider* theme_provider = GetThemeProvider(); - if (!theme_provider) - return; - SkColor text_color = - theme_provider->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT); - for (int i = 0; i < GetBookmarkButtonCount(); ++i) - GetBookmarkButton(i)->SetEnabledColor(text_color); - other_bookmarked_button()->SetEnabledColor(text_color); -} - -gfx::Size BookmarkBarView::LayoutItems(bool compute_bounds_only) { - gfx::Size prefsize; - if (!GetParent() && !compute_bounds_only) - return prefsize; - - int x = kLeftMargin; - int top_margin = IsDetached() ? kDetachedTopMargin : 0; - int y = top_margin; - int width = View::width() - kRightMargin - kLeftMargin; - int height = View::height() - top_margin - kBottomMargin; - int separator_margin = kSeparatorMargin; - - if (OnNewTabPage()) { - double current_state = 1 - size_animation_->GetCurrentValue(); - x += static_cast<int>(static_cast<double> - (kNewtabHorizontalPadding) * current_state); - y += static_cast<int>(static_cast<double> - (kNewtabVerticalPadding) * current_state); - width -= static_cast<int>(static_cast<double> - (kNewtabHorizontalPadding) * current_state); - height -= static_cast<int>(static_cast<double> - (kNewtabVerticalPadding * 2) * current_state); - separator_margin -= static_cast<int>(static_cast<double> - (kSeparatorMargin) * current_state); - } - - gfx::Size other_bookmarked_pref = - other_bookmarked_button_->GetPreferredSize(); - gfx::Size overflow_pref = overflow_button_->GetPreferredSize(); - gfx::Size bookmarks_separator_pref = - bookmarks_separator_view_->GetPreferredSize(); - - int sync_error_total_width = 0; - gfx::Size sync_error_button_pref = sync_error_button_->GetPreferredSize(); - if (sync_ui_util::ShouldShowSyncErrorButton(sync_service_)) { - sync_error_total_width += kButtonPadding + sync_error_button_pref.width(); - } - const int max_x = width - other_bookmarked_pref.width() - kButtonPadding - - overflow_pref.width() - kButtonPadding - - bookmarks_separator_pref.width() - sync_error_total_width; - - // Next, layout out the buttons. Any buttons that are placed beyond the - // visible region and made invisible. - if (GetBookmarkButtonCount() == 0 && model_ && model_->IsLoaded()) { - gfx::Size pref = instructions_->GetPreferredSize(); - if (!compute_bounds_only) { - instructions_->SetBounds( - x + kInstructionsPadding, y, - std::min(static_cast<int>(pref.width()), - max_x - x), - height); - instructions_->SetVisible(true); - } - } else { - if (!compute_bounds_only) - instructions_->SetVisible(false); - - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - views::View* child = GetChildViewAt(i); - gfx::Size pref = child->GetPreferredSize(); - int next_x = x + pref.width() + kButtonPadding; - if (!compute_bounds_only) { - child->SetVisible(next_x < max_x); - child->SetBounds(x, y, pref.width(), height); - } - x = next_x; - } - } - - // Layout the right side of the bar. - const bool all_visible = - (GetBookmarkButtonCount() == 0 || - GetChildViewAt(GetBookmarkButtonCount() - 1)->IsVisible()); - - // Layout the right side buttons. - if (!compute_bounds_only) - x = max_x + kButtonPadding; - else - x += kButtonPadding; - - // The overflow button. - if (!compute_bounds_only) { - overflow_button_->SetBounds(x, y, overflow_pref.width(), height); - overflow_button_->SetVisible(!all_visible); - } - x += overflow_pref.width(); - - // Separator. - if (!compute_bounds_only) { - bookmarks_separator_view_->SetBounds(x, - y - top_margin, - bookmarks_separator_pref.width(), - height + top_margin + kBottomMargin - - separator_margin); - } - - x += bookmarks_separator_pref.width(); - - // The other bookmarks button. - if (!compute_bounds_only) { - other_bookmarked_button_->SetBounds(x, y, other_bookmarked_pref.width(), - height); - } - x += other_bookmarked_pref.width() + kButtonPadding; - - // Set the real bounds of the sync error button only if it needs to appear on - // the bookmarks bar. - if (sync_ui_util::ShouldShowSyncErrorButton(sync_service_)) { - x += kButtonPadding; - if (!compute_bounds_only) { - sync_error_button_->SetBounds( - x, y, sync_error_button_pref.width(), height); - sync_error_button_->SetVisible(true); - } - x += sync_error_button_pref.width(); - } else if (!compute_bounds_only) { - sync_error_button_->SetBounds(x, y, 0, height); - sync_error_button_->SetVisible(false); - } - - // Set the preferred size computed so far. - if (compute_bounds_only) { - x += kRightMargin; - prefsize.set_width(x); - if (OnNewTabPage()) { - x += static_cast<int>(static_cast<double>(kNewtabHorizontalPadding) * - (1 - size_animation_->GetCurrentValue())); - prefsize.set_height(kBarHeight + static_cast<int>(static_cast<double> - (kNewtabBarHeight - kBarHeight) * - (1 - size_animation_->GetCurrentValue()))); - } else { - prefsize.set_height(static_cast<int>(static_cast<double>(kBarHeight) * - size_animation_->GetCurrentValue())); - } - } - return prefsize; -} - -views::TextButton* BookmarkBarView::CreateSyncErrorButton() { - views::TextButton* sync_error_button = - new views::TextButton(this, - l10n_util::GetString(IDS_SYNC_BOOKMARK_BAR_ERROR)); - sync_error_button->set_tag(kSyncErrorButtonTag); - - // The tooltip is the only way we have to display text explaining the error - // to the user. - sync_error_button->SetTooltipText( - l10n_util::GetString(IDS_SYNC_BOOKMARK_BAR_ERROR_DESC)); - sync_error_button->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_SYNC_ERROR_BUTTON)); - sync_error_button->SetIcon( - *ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING)); - return sync_error_button; -} diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h index 37b606f..7dea837 100644 --- a/chrome/browser/views/bookmark_bar_view.h +++ b/chrome/browser/views/bookmark_bar_view.h @@ -6,503 +6,8 @@ #define CHROME_BROWSER_VIEWS_BOOKMARK_BAR_VIEW_H_ #pragma once -#include <set> - -#include "app/slide_animation.h" -#include "chrome/browser/bookmarks/bookmark_drag_data.h" -#include "chrome/browser/bookmarks/bookmark_model_observer.h" -#include "chrome/browser/sync/profile_sync_service.h" -#include "chrome/browser/views/bookmark_bar_instructions_view.h" -#include "chrome/browser/views/bookmark_menu_controller_views.h" -#include "chrome/browser/views/detachable_toolbar_view.h" -#include "chrome/common/notification_registrar.h" -#include "views/controls/button/button.h" -#include "views/controls/menu/view_menu_delegate.h" - -class Browser; -class PageNavigator; -class PrefService; - -namespace views { -class CustomButton; -class MenuButton; -class MenuItemView; -class TextButton; -} - -// BookmarkBarView renders the BookmarkModel. Each starred entry on the -// BookmarkBar is rendered as a MenuButton. An additional MenuButton aligned to -// the right allows the user to quickly see recently starred entries. -// -// BookmarkBarView shows the bookmarks from a specific Profile. BookmarkBarView -// waits until the HistoryService for the profile has been loaded before -// creating the BookmarkModel. -class BookmarkBarView : public DetachableToolbarView, - public ProfileSyncServiceObserver, - public BookmarkModelObserver, - public views::ViewMenuDelegate, - public views::ButtonListener, - public NotificationObserver, - public views::ContextMenuController, - public views::DragController, - public AnimationDelegate, - public BookmarkMenuController::Observer, - public BookmarkBarInstructionsView::Delegate { - friend class ShowFolderMenuTask; - - public: - // Constants used in Browser View, as well as here. - // How inset the bookmarks bar is when displayed on the new tab page. - static const int kNewtabHorizontalPadding; - static const int kNewtabVerticalPadding; - - // Maximum size of buttons on the bookmark bar. - static const int kMaxButtonWidth; - - // Interface implemented by controllers/views that need to be notified any - // time the model changes, typically to cancel an operation that is showing - // data from the model such as a menu. This isn't intended as a general - // way to be notified of changes, rather for cases where a controller/view is - // showing data from the model in a modal like setting and needs to cleanly - // exit the modal loop if the model changes out from under it. - // - // A controller/view that needs this notification should install itself as the - // ModelChangeListener via the SetModelChangedListener method when shown and - // reset the ModelChangeListener of the BookmarkBarView when it closes by way - // of either the SetModelChangedListener method or the - // ClearModelChangedListenerIfEquals method. - class ModelChangedListener { - public: - virtual ~ModelChangedListener() {} - - // Invoked when the model changes. Should cancel the edit and close any - // dialogs. - virtual void ModelChanged() = 0; - }; - - static const int kNewtabBarHeight; - - BookmarkBarView(Profile* profile, Browser* browser); - virtual ~BookmarkBarView(); - - // Resets the profile. This removes any buttons for the current profile and - // recreates the models. - void SetProfile(Profile* profile); - - // Returns the current profile. - Profile* GetProfile() { return profile_; } - - // Returns the current browser. - Browser* browser() const { return browser_; } - - // Sets the PageNavigator that is used when the user selects an entry on - // the bookmark bar. - void SetPageNavigator(PageNavigator* navigator); - - // Sets whether the containing browser is showing an infobar. This affects - // layout during animation. - void set_infobar_visible(bool infobar_visible) { - infobar_visible_ = infobar_visible; - } - - // DetachableToolbarView methods: - virtual bool IsDetached() const; - virtual bool IsOnTop() const; - virtual double GetAnimationValue() const { - return size_animation_->GetCurrentValue(); - } - virtual int GetToolbarOverlap() const { - return GetToolbarOverlap(false); - } - - // View methods: - virtual gfx::Size GetPreferredSize(); - virtual gfx::Size GetMinimumSize(); - virtual void Layout(); - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - virtual void PaintChildren(gfx::Canvas* canvas); - virtual bool GetDropFormats( - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats); - virtual bool AreDropTypesRequired(); - virtual bool CanDrop(const OSExchangeData& data); - virtual void OnDragEntered(const views::DropTargetEvent& event); - virtual int OnDragUpdated(const views::DropTargetEvent& event); - virtual void OnDragExited(); - virtual int OnPerformDrop(const views::DropTargetEvent& event); - virtual void ShowContextMenu(const gfx::Point& p, bool is_mouse_gesture); - - // AccessiblePaneView methods: - virtual bool IsAccessibleViewTraversable(views::View* view); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // ProfileSyncServiceObserver method. - virtual void OnStateChanged(); - - // Called when fullscreen mode toggles on or off; this affects our layout. - void OnFullscreenToggled(bool fullscreen); - - // Sets the model change listener to listener. - void SetModelChangedListener(ModelChangedListener* listener) { - model_changed_listener_ = listener; - } - - // If the ModelChangedListener is listener, ModelChangeListener is set to - // NULL. - void ClearModelChangedListenerIfEquals(ModelChangedListener* listener) { - if (model_changed_listener_ == listener) - model_changed_listener_ = NULL; - } - - // Returns the model change listener. - ModelChangedListener* GetModelChangedListener() { - return model_changed_listener_; - } - - // Returns the page navigator. - PageNavigator* GetPageNavigator() { return page_navigator_; } - - // Returns the model. - BookmarkModel* GetModel() { return model_; } - - // Returns true if the bookmarks bar preference is set to 'always show'. - bool IsAlwaysShown() const; - - // True if we're on a page where the bookmarks bar is always visible. - bool OnNewTabPage() const; - - // How much we want the bookmark bar to overlap the toolbar. If |return_max| - // is true, we return the maximum overlap rather than the current overlap. - int GetToolbarOverlap(bool return_max) const; - - // Whether or not we are animating. - bool is_animating() { return size_animation_->is_animating(); } - - // SlideAnimationDelegate implementation. - void AnimationProgressed(const Animation* animation); - void AnimationEnded(const Animation* animation); - - // BookmarkMenuController::Observer - virtual void BookmarkMenuDeleted(BookmarkMenuController* controller); - - // Returns the button at the specified index. - views::TextButton* GetBookmarkButton(int index); - - // Returns the button responsible for showing bookmarks in the other bookmark - // folder. - views::MenuButton* other_bookmarked_button() const { - return other_bookmarked_button_; - } - - // Returns the active MenuItemView, or NULL if a menu isn't showing. - views::MenuItemView* GetMenu(); - - // Returns the drop MenuItemView, or NULL if a menu isn't showing. - views::MenuItemView* GetDropMenu(); - - // Returns the context menu, or null if one isn't showing. - views::MenuItemView* GetContextMenu(); - - // Returns the button used when not all the items on the bookmark bar fit. - views::MenuButton* overflow_button() const { return overflow_button_; } - - // If |loc| is over a bookmark button the node is returned corresponding - // to the button and |start_index| is set to 0. If a overflow button is - // showing and |loc| is over the overflow button, the bookmark bar node is - // returned and |start_index| is set to the index of the first node - // contained in the overflow menu. - const BookmarkNode* GetNodeForButtonAt(const gfx::Point& loc, - int* start_index); - - // Returns the MenuButton for node. - views::MenuButton* GetMenuButtonForNode(const BookmarkNode* node); - - // Returns the position to anchor the menu for |button| at, the index of the - // first child of the node to build the menu from. - void GetAnchorPositionAndStartIndexForButton( - views::MenuButton* button, - views::MenuItemView::AnchorPosition* anchor, - int* start_index); - - // BookmarkBarInstructionsView::Delegate. - virtual void ShowImportDialog(); - - // If a button is currently throbbing, it is stopped. If immediate is true - // the throb stops immediately, otherwise it stops after a couple more - // throbs. - void StopThrobbing(bool immediate); - - // Returns the number of buttons corresponding to starred urls/groups. This - // is equivalent to the number of children the bookmark bar node from the - // bookmark bar model has. - int GetBookmarkButtonCount(); - - // If true we're running tests. This short circuits a couple of animations. - static bool testing_; - - private: - class ButtonSeparatorView; - struct DropInfo; - - // Task that invokes ShowDropFolderForNode when run. ShowFolderDropMenuTask - // deletes itself once run. - class ShowFolderDropMenuTask : public Task { - public: - ShowFolderDropMenuTask(BookmarkBarView* view, const BookmarkNode* node) - : view_(view), - node_(node) { - } - - void Cancel() { - view_->show_folder_drop_menu_task_ = NULL; - view_ = NULL; - } - - virtual void Run() { - if (view_) { - view_->show_folder_drop_menu_task_ = NULL; - view_->ShowDropFolderForNode(node_); - } - // MessageLoop deletes us. - } - - private: - BookmarkBarView* view_; - const BookmarkNode* node_; - - DISALLOW_COPY_AND_ASSIGN(ShowFolderDropMenuTask); - }; - - // Creates recent bookmark button and when visible button as well as - // calculating the preferred height. - void Init(); - - // Creates the button showing the other bookmarked items. - views::MenuButton* CreateOtherBookmarkedButton(); - - // Creates the button used when not all bookmark buttons fit. - views::MenuButton* CreateOverflowButton(); - - // Invoked when the bookmark bar model has finished loading. Creates a button - // for each of the children of the root node from the model. - virtual void Loaded(BookmarkModel* model); - - // Invoked when the model is being deleted. - virtual void BookmarkModelBeingDeleted(BookmarkModel* model); - - // Invokes added followed by removed. - virtual void BookmarkNodeMoved(BookmarkModel* model, - const BookmarkNode* old_parent, - int old_index, - const BookmarkNode* new_parent, - int new_index); - - // Notifies ModelChangeListener of change. - // If the node was added to the root node, a button is created and added to - // this bookmark bar view. - virtual void BookmarkNodeAdded(BookmarkModel* model, - const BookmarkNode* parent, - int index); - - // Implementation for BookmarkNodeAddedImpl. - void BookmarkNodeAddedImpl(BookmarkModel* model, - const BookmarkNode* parent, - int index); - - // Notifies ModelChangeListener of change. - // If the node was a child of the root node, the button corresponding to it - // is removed. - virtual void BookmarkNodeRemoved(BookmarkModel* model, - const BookmarkNode* parent, - int old_index, - const BookmarkNode* node); - - // Implementation for BookmarkNodeRemoved. - void BookmarkNodeRemovedImpl(BookmarkModel* model, - const BookmarkNode* parent, - int index); - - // Notifies ModelChangedListener and invokes BookmarkNodeChangedImpl. - virtual void BookmarkNodeChanged(BookmarkModel* model, - const BookmarkNode* node); - - // If the node is a child of the root node, the button is updated - // appropriately. - void BookmarkNodeChangedImpl(BookmarkModel* model, const BookmarkNode* node); - - virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, - const BookmarkNode* node); - - // Invoked when the favicon is available. If the node is a child of the - // root node, the appropriate button is updated. If a menu is showing, the - // call is forwarded to the menu to allow for it to update the icon. - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, - const BookmarkNode* node); - - // DragController method. Determines the node representing sender and invokes - // WriteDragData to write the actual data. - virtual void WriteDragData(views::View* sender, - const gfx::Point& press_pt, - OSExchangeData* data); - - virtual int GetDragOperations(views::View* sender, const gfx::Point& p); - - virtual bool CanStartDrag(views::View* sender, - const gfx::Point& press_pt, - const gfx::Point& p); - - // Writes a BookmarkDragData for node to data. - void WriteDragData(const BookmarkNode* node, OSExchangeData* data); - - // ViewMenuDelegate method. Ends up creating a BookmarkMenuController to - // show the menu. - virtual void RunMenu(views::View* view, const gfx::Point& pt); - - // Invoked when a star entry corresponding to a URL on the bookmark bar is - // pressed. Forwards to the PageNavigator to open the URL. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Invoked for this View, one of the buttons or the 'other' button. Shows the - // appropriate context menu. - virtual void ShowContextMenu(views::View* source, - const gfx::Point& p, - bool is_mouse_gesture); - - // Creates the button for rendering the specified bookmark node. - views::View* CreateBookmarkButton(const BookmarkNode* node); - - // COnfigures the button from the specified node. This sets the text, - // and icon. - void ConfigureButton(const BookmarkNode* node, views::TextButton* button); - - // Used when showing the menu allowing the user to choose when the bar is - // visible. Return value corresponds to the users preference for when the - // bar is visible. - virtual bool IsItemChecked(int id) const; - - // Used when showing the menu allowing the user to choose when the bar is - // visible. Updates the preferences to match the users choice as appropriate. - virtual void ExecuteCommand(int id); - - // NotificationService method. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Overridden from views::View. - virtual void OnThemeChanged(); - - // If the ModelChangedListener is non-null, ModelChanged is invoked on it. - void NotifyModelChanged(); - - // Shows the menu used during drag and drop for the specified node. - void ShowDropFolderForNode(const BookmarkNode* node); - - // Cancels the timer used to show a drop menu. - void StopShowFolderDropMenuTimer(); - - // Stars the timer used to show a drop menu for node. - void StartShowFolderDropMenuTimer(const BookmarkNode* node); - - // Returns the drop operation and index for the drop based on the event - // and data. Returns DragDropTypes::DRAG_NONE if not a valid location. - int CalculateDropOperation(const views::DropTargetEvent& event, - const BookmarkDragData& data, - int* index, - bool* drop_on, - bool* is_over_overflow, - bool* is_over_other); - - // Returns the index of the first hidden bookmark button. If all buttons are - // visible, this returns GetBookmarkButtonCount(). - int GetFirstHiddenNodeIndex(); - - // This determines which view should throb and starts it - // throbbing (e.g when the bookmark bubble is showing). - // If |overflow_only| is true, start throbbing only if |node| is hidden in - // the overflow menu. - void StartThrobbing(const BookmarkNode* node, bool overflow_only); - - // Updates the colors for all the child objects in the bookmarks bar. - void UpdateColors(); - - // This method computes the bounds for the bookmark bar items. If - // |compute_bounds_only| = TRUE, the bounds for the items are just computed, - // but are not set. This mode is used by GetPreferredSize() to obtain the - // desired bounds. If |compute_bounds_only| = FALSE, the bounds are set. - gfx::Size LayoutItems(bool compute_bounds_only); - - // Creates the sync error button and adds it as a child view. - views::TextButton* CreateSyncErrorButton(); - - NotificationRegistrar registrar_; - - Profile* profile_; - - // Used for opening urls. - PageNavigator* page_navigator_; - - // Model providing details as to the starred entries/groups that should be - // shown. This is owned by the Profile. - BookmarkModel* model_; - - // Used to manage showing a Menu, either for the most recently bookmarked - // entries, or for the a starred group. - BookmarkMenuController* bookmark_menu_; - - // Used when showing a menu for drag and drop. That is, if the user drags - // over a group this becomes non-null and manages the menu showing the - // contents of the node. - BookmarkMenuController* bookmark_drop_menu_; - - // Shows the other bookmark entries. - views::MenuButton* other_bookmarked_button_; - - // ModelChangeListener. - ModelChangedListener* model_changed_listener_; - - // Task used to delay showing of the drop menu. - ShowFolderDropMenuTask* show_folder_drop_menu_task_; - - // Used to track drops on the bookmark bar view. - scoped_ptr<DropInfo> drop_info_; - - // The sync re-login indicator which appears when the user needs to re-enter - // credentials in order to continue syncing. - views::TextButton* sync_error_button_; - - // A pointer to the ProfileSyncService instance if one exists. - ProfileSyncService* sync_service_; - - // Visible if not all the bookmark buttons fit. - views::MenuButton* overflow_button_; - - // BookmarkBarInstructionsView that is visible if there are no bookmarks on - // the bookmark bar. - views::View* instructions_; - - ButtonSeparatorView* bookmarks_separator_view_; - - // Owning browser. This is NULL during testing. - Browser* browser_; - - // True if the owning browser is showing an infobar. - bool infobar_visible_; - - // Animation controlling showing and hiding of the bar. - scoped_ptr<SlideAnimation> size_animation_; - - // If the bookmark bubble is showing, this is the visible ancestor of the URL. - // The visible ancestor is either the other_bookmarked_button_, - // overflow_button_ or a button on the bar. - views::CustomButton* throbbing_view_; - - // Background for extension toolstrips. - SkBitmap toolstrip_background_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkBarView); -}; +#include "chrome/browser/ui/views/bookmark_bar_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BOOKMARK_BAR_VIEW_H_ + diff --git a/chrome/browser/views/bookmark_bar_view_test.cc b/chrome/browser/views/bookmark_bar_view_test.cc deleted file mode 100644 index d30d0e4..0000000 --- a/chrome/browser/views/bookmark_bar_view_test.cc +++ /dev/null @@ -1,1358 +0,0 @@ -// 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 "app/keyboard_codes.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/automation/ui_controls.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/browser/views/bookmark_bar_view.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/testing_profile.h" -#include "chrome/test/interactive_ui/view_event_test_base.h" -#include "chrome/test/ui_test_utils.h" -#include "grit/generated_resources.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/button/text_button.h" -#include "views/controls/menu/menu_controller.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/controls/menu/submenu_view.h" -#include "views/views_delegate.h" -#include "views/window/window.h" - -#if defined(OS_LINUX) -// See http://crbug.com/40040 for details. -#define MAYBE_DND DISABLED_DND -#define MAYBE_DNDToDifferentMenu DISABLED_DNDToDifferentMenu -#define MAYBE_DNDBackToOriginatingMenu DISABLED_DNDBackToOriginatingMenu - -// See http://crbug.com/40039 for details. -#define MAYBE_KeyEvents DISABLED_KeyEvents - -// Two bugs here. http://crbug.com/47089 for general Linux Views, and -// http://crbug.com/47452 for ChromiumOS. -#define MAYBE_CloseWithModalDialog DISABLED_CloseWithModalDialog -// See http://crbug.com/47089 for details. -#define MAYBE_CloseMenuAfterClosingContextMenu \ - DISABLED_CloseMenuAfterClosingContextMenu -#else - -#define MAYBE_DND DND -#define MAYBE_DNDToDifferentMenu DNDToDifferentMenu -#define MAYBE_DNDBackToOriginatingMenu DNDBackToOriginatingMenu -#define MAYBE_DNDBackToOriginatingMenu DNDBackToOriginatingMenu -#define MAYBE_KeyEvents KeyEvents -#define MAYBE_CloseWithModalDialog CloseWithModalDialog -#define MAYBE_CloseMenuAfterClosingContextMenu CloseMenuAfterClosingContextMenu - -#endif - -#if defined(OS_LINUX) -// See bug http://crbug.com/60444 for details. -#define MAYBE_ScrollButtonScrolls DISABLED_ScrollButtonScrolls -#else -#define MAYBE_ScrollButtonScrolls ScrollButtonScrolls -#endif - -namespace { - -class ViewsDelegateImpl : public views::ViewsDelegate { - public: - ViewsDelegateImpl() {} - virtual Clipboard* GetClipboard() const { return NULL; } - virtual void SaveWindowPlacement(const std::wstring& window_name, - const gfx::Rect& bounds, - bool maximized) {} - virtual bool GetSavedWindowBounds(const std::wstring& window_name, - gfx::Rect* bounds) const { - return false; - } - virtual bool GetSavedMaximizedState(const std::wstring& window_name, - bool* maximized) const { - return false; - } - - virtual void NotifyAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type) {} - -#if defined(OS_WIN) - virtual HICON GetDefaultWindowIcon() const { return 0; } -#endif - - virtual void AddRef() { - } - - virtual void ReleaseRef() { - MessageLoopForUI::current()->Quit(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ViewsDelegateImpl); -}; - -// PageNavigator implementation that records the URL. -class TestingPageNavigator : public PageNavigator { - public: - virtual void OpenURL(const GURL& url, const GURL& referrer, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - url_ = url; - } - - GURL url_; -}; - -} // namespace - -// Base class for event generating bookmark view tests. These test are intended -// to exercise View's menus, but that's easier done with BookmarkBarView rather -// than View's menu itself. -// -// SetUp creates a bookmark model with the following structure. -// All folders are in upper case, all URLs in lower case. -// F1 -// f1a -// F11 -// f11a -// * -// a -// b -// c -// d -// OTHER -// oa -// OF -// ofa -// ofb -// OF2 -// of2a -// of2b -// -// * if CreateBigMenu returns return true, 100 menu items are created here with -// the names f1-f100. -// -// Subclasses should be sure and invoke super's implementation of SetUp and -// TearDown. -class BookmarkBarViewEventTestBase : public ViewEventTestBase { - public: - BookmarkBarViewEventTestBase() - : ViewEventTestBase(), - model_(NULL), - bb_view_(NULL), - ui_thread_(BrowserThread::UI, MessageLoop::current()), - file_thread_(BrowserThread::FILE, MessageLoop::current()) { - } - - virtual void SetUp() { - BookmarkBarView::testing_ = true; - - profile_.reset(new TestingProfile()); - profile_->set_has_history_service(true); - profile_->CreateBookmarkModel(true); - profile_->BlockUntilBookmarkModelLoaded(); - profile_->GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, true); - - model_ = profile_->GetBookmarkModel(); - model_->ClearStore(); - - bb_view_ = new BookmarkBarView(profile_.get(), NULL); - bb_view_->SetPageNavigator(&navigator_); - - AddTestData(CreateBigMenu()); - - // Calculate the preferred size so that one button doesn't fit, which - // triggers the overflow button to appear. - // - // BookmarkBarView::Layout does nothing if the parent is NULL and - // GetPreferredSize hard codes a width of 1. For that reason we add the - // BookmarkBarView to a dumby view as the parent. - // - // This code looks a bit hacky, but I've written it so that it shouldn't - // be dependant upon any of the layout code in BookmarkBarView. Instead - // we brute force search for a size that triggers the overflow button. - views::View tmp_parent; - - tmp_parent.AddChildView(bb_view_); - - bb_view_pref_ = bb_view_->GetPreferredSize(); - bb_view_pref_.set_width(1000); - views::TextButton* button = bb_view_->GetBookmarkButton(4); - while (button->IsVisible()) { - bb_view_pref_.set_width(bb_view_pref_.width() - 25); - bb_view_->SetBounds(0, 0, bb_view_pref_.width(), bb_view_pref_.height()); - bb_view_->Layout(); - } - - tmp_parent.RemoveChildView(bb_view_); - - ViewEventTestBase::SetUp(); - } - - virtual void TearDown() { - ViewEventTestBase::TearDown(); - BookmarkBarView::testing_ = false; - views::ViewsDelegate::views_delegate = NULL; - } - - protected: - void InstallViewsDelegate() { - views::ViewsDelegate::views_delegate = &views_delegate_; - } - - virtual views::View* CreateContentsView() { - return bb_view_; - } - - virtual gfx::Size GetPreferredSize() { return bb_view_pref_; } - - // See comment above class description for what this does. - virtual bool CreateBigMenu() { return false; } - - BookmarkModel* model_; - BookmarkBarView* bb_view_; - TestingPageNavigator navigator_; - - private: - void AddTestData(bool big_menu) { - std::string test_base = "file:///c:/tmp/"; - - const BookmarkNode* f1 = model_->AddGroup( - model_->GetBookmarkBarNode(), 0, ASCIIToUTF16("F1")); - model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a")); - const BookmarkNode* f11 = model_->AddGroup(f1, 1, ASCIIToUTF16("F11")); - model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a")); - if (big_menu) { - for (int i = 1; i <= 100; ++i) { - model_->AddURL(f1, i + 1, ASCIIToUTF16("f") + base::IntToString16(i), - GURL(test_base + "f" + base::IntToString(i))); - } - } - model_->AddURL(model_->GetBookmarkBarNode(), 1, ASCIIToUTF16("a"), - GURL(test_base + "a")); - model_->AddURL(model_->GetBookmarkBarNode(), 2, ASCIIToUTF16("b"), - GURL(test_base + "b")); - model_->AddURL(model_->GetBookmarkBarNode(), 3, ASCIIToUTF16("c"), - GURL(test_base + "c")); - model_->AddURL(model_->GetBookmarkBarNode(), 4, ASCIIToUTF16("d"), - GURL(test_base + "d")); - model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"), - GURL(test_base + "oa")); - const BookmarkNode* of = model_->AddGroup(model_->other_node(), 1, - ASCIIToUTF16("OF")); - model_->AddURL(of, 0, ASCIIToUTF16("ofa"), GURL(test_base + "ofa")); - model_->AddURL(of, 1, ASCIIToUTF16("ofb"), GURL(test_base + "ofb")); - const BookmarkNode* of2 = model_->AddGroup(model_->other_node(), 2, - ASCIIToUTF16("OF2")); - model_->AddURL(of2, 0, ASCIIToUTF16("of2a"), GURL(test_base + "of2a")); - model_->AddURL(of2, 1, ASCIIToUTF16("of2b"), GURL(test_base + "of2b")); - } - - gfx::Size bb_view_pref_; - scoped_ptr<TestingProfile> profile_; - BrowserThread ui_thread_; - BrowserThread file_thread_; - ViewsDelegateImpl views_delegate_; -}; - -// Clicks on first menu, makes sure button is depressed. Moves mouse to first -// child, clicks it and makes sure a navigation occurs. -class BookmarkBarViewTest1 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest1::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - // Button should be depressed. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ASSERT_TRUE(button->state() == views::CustomButton::BS_PUSHED); - - // Click on the 2nd menu item (A URL). - ASSERT_TRUE(menu->GetSubmenu()); - - views::MenuItemView* menu_to_select = - menu->GetSubmenu()->GetMenuItemAt(0); - ui_controls::MoveMouseToCenterAndPress(menu_to_select, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest1::Step3)); - } - - void Step3() { - // We should have navigated to URL f1a. - ASSERT_TRUE(navigator_.url_ == - model_->GetBookmarkBarNode()->GetChild(0)->GetChild(0)-> - GetURL()); - - // Make sure button is no longer pushed. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ASSERT_TRUE(button->state() == views::CustomButton::BS_NORMAL); - - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu == NULL || !menu->GetSubmenu()->IsShowing()); - - Done(); - } -}; - -// TODO(jcampan): http://crbug.com/26996 temporarily disabled because failing -// since we move to running the process -VIEW_TEST(BookmarkBarViewTest1, DISABLED_Basic) - -// Brings up menu, clicks on empty space and make sure menu hides. -class BookmarkBarViewTest2 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest2::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL && menu->GetSubmenu()->IsShowing()); - - // Click on 0x0, which should trigger closing menu. - // NOTE: this code assume there is a left margin, which is currently - // true. If that changes, this code will need to find another empty space - // to press the mouse on. - gfx::Point mouse_loc; - views::View::ConvertPointToScreen(bb_view_, &mouse_loc); - ui_controls::SendMouseMove(0, 0); - ui_controls::SendMouseEventsNotifyWhenDone( - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest2::Step3)); - } - - void Step3() { - // The menu shouldn't be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu == NULL || !menu->GetSubmenu()->IsShowing()); - - // Make sure button is no longer pushed. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ASSERT_TRUE(button->state() == views::CustomButton::BS_NORMAL); - - window_->Activate(); - - Done(); - } -}; - -// TODO(jcampan): http://crbug.com/26996 temporarily disabled because failing -// since we move to running the process -VIEW_TEST(BookmarkBarViewTest2, DISABLED_HideOnDesktopClick) - -// Brings up menu. Moves over child to make sure submenu appears, moves over -// another child and make sure next menu appears. -class BookmarkBarViewTest3 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::MenuButton* button = bb_view_->other_bookmarked_button(); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest3::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(1); - ASSERT_TRUE(child_menu != NULL); - - // Click on second child, which has a submenu. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest3::Step3)); - } - - void Step3() { - // Make sure sub menu is showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(1); - ASSERT_TRUE(child_menu->GetSubmenu() != NULL); - ASSERT_TRUE(child_menu->GetSubmenu()->IsShowing()); - - // Click on third child, which has a submenu too. - child_menu = menu->GetSubmenu()->GetMenuItemAt(2); - ASSERT_TRUE(child_menu != NULL); - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest3::Step4)); - } - - void Step4() { - // Make sure sub menu we first clicked isn't showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(1); - ASSERT_TRUE(child_menu->GetSubmenu() != NULL); - ASSERT_FALSE(child_menu->GetSubmenu()->IsShowing()); - - // And submenu we last clicked is showing. - child_menu = menu->GetSubmenu()->GetMenuItemAt(2); - ASSERT_TRUE(child_menu != NULL); - ASSERT_TRUE(child_menu->GetSubmenu()->IsShowing()); - - // Nothing should have been selected. - EXPECT_EQ(GURL(), navigator_.url_); - - // Hide menu. - menu->GetMenuController()->CancelAll(); - - Done(); - } -}; - -VIEW_TEST(BookmarkBarViewTest3, Submenus) - -// Observer that posts task upon the context menu creation. -// This is necessary for Linux as the context menu has to check -// the clipboard, which invokes the event loop. -class ContextMenuNotificationObserver : public NotificationObserver { - public: - explicit ContextMenuNotificationObserver(Task* task) : task_(task) { - registrar_.Add(this, - NotificationType::BOOKMARK_CONTEXT_MENU_SHOWN, - NotificationService::AllSources()); - } - - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - MessageLoop::current()->PostTask(FROM_HERE, task_); - } - - private: - NotificationRegistrar registrar_; - Task* task_; - - DISALLOW_COPY_AND_ASSIGN(ContextMenuNotificationObserver); -}; - -// Tests context menus by way of opening a context menu for a bookmark, -// then right clicking to get context menu and selecting the first menu item -// (open). -class BookmarkBarViewTest4 : public BookmarkBarViewEventTestBase { - public: - BookmarkBarViewTest4() - : ALLOW_THIS_IN_INITIALIZER_LIST( - observer_(CreateEventTask(this, &BookmarkBarViewTest4::Step3))) { - } - - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->other_bookmarked_button(); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest4::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - - // Right click on the first child to get its context menu. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT, - ui_controls::DOWN | ui_controls::UP, NULL); - // Step3 will be invoked by ContextMenuNotificationObserver. - } - - void Step3() { - // Make sure the context menu is showing. - views::MenuItemView* menu = bb_view_->GetContextMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - // Select the first menu item (open). - ui_controls::MoveMouseToCenterAndPress(menu->GetSubmenu()->GetMenuItemAt(0), - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest4::Step4)); - } - - void Step4() { - EXPECT_EQ(navigator_.url_, - model_->other_node()->GetChild(0)->GetURL()); - - Done(); - } - - ContextMenuNotificationObserver observer_; -}; - -VIEW_TEST(BookmarkBarViewTest4, ContextMenus) - -// Tests drag and drop within the same menu. -class BookmarkBarViewTest5 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - url_dragging_ = - model_->GetBookmarkBarNode()->GetChild(0)->GetChild(0)->GetURL(); - - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest5::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - - // Move mouse to center of menu and press button. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, - ui_controls::DOWN, - CreateEventTask(this, &BookmarkBarViewTest5::Step3)); - } - - void Step3() { - views::MenuItemView* target_menu = - bb_view_->GetMenu()->GetSubmenu()->GetMenuItemAt(1); - gfx::Point loc(1, target_menu->height() - 1); - views::View::ConvertPointToScreen(target_menu, &loc); - - // Start a drag. - ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(), - CreateEventTask(this, &BookmarkBarViewTest5::Step4)); - - // See comment above this method as to why we do this. - ScheduleMouseMoveInBackground(loc.x(), loc.y()); - } - - void Step4() { - // Drop the item so that it's now the second item. - views::MenuItemView* target_menu = - bb_view_->GetMenu()->GetSubmenu()->GetMenuItemAt(1); - gfx::Point loc(1, target_menu->height() - 1); - views::View::ConvertPointToScreen(target_menu, &loc); - ui_controls::SendMouseMove(loc.x(), loc.y()); - - ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, - ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest5::Step5)); - } - - void Step5() { - GURL url = model_->GetBookmarkBarNode()->GetChild(0)->GetChild(1)->GetURL(); - EXPECT_EQ(url_dragging_, url); - Done(); - } - - GURL url_dragging_; -}; - -VIEW_TEST(BookmarkBarViewTest5, MAYBE_DND) - -// Tests holding mouse down on overflow button, dragging such that menu pops up -// then selecting an item. -class BookmarkBarViewTest6 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - // Press the mouse button on the overflow button. Don't release it though. - views::TextButton* button = bb_view_->overflow_button(); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN, CreateEventTask(this, &BookmarkBarViewTest6::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - - // Move mouse to center of menu and release mouse. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, - ui_controls::UP, CreateEventTask(this, &BookmarkBarViewTest6::Step3)); - } - - void Step3() { - ASSERT_TRUE(navigator_.url_ == - model_->GetBookmarkBarNode()->GetChild(4)->GetURL()); - Done(); - } - - GURL url_dragging_; -}; - -VIEW_TEST(BookmarkBarViewTest6, OpenMenuOnClickAndHold) - -// Tests drag and drop to different menu. -class BookmarkBarViewTest7 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - url_dragging_ = - model_->GetBookmarkBarNode()->GetChild(0)->GetChild(0)->GetURL(); - - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest7::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - - // Move mouse to center of menu and press button. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, - ui_controls::DOWN, - CreateEventTask(this, &BookmarkBarViewTest7::Step3)); - } - - void Step3() { - // Drag over other button. - views::TextButton* other_button = - bb_view_->other_bookmarked_button(); - gfx::Point loc(other_button->width() / 2, other_button->height() / 2); - views::View::ConvertPointToScreen(other_button, &loc); - - // Start a drag. - ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(), - NewRunnableMethod(this, &BookmarkBarViewTest7::Step4)); - - // See comment above this method as to why we do this. - ScheduleMouseMoveInBackground(loc.x(), loc.y()); - } - - void Step4() { - views::MenuItemView* drop_menu = bb_view_->GetDropMenu(); - ASSERT_TRUE(drop_menu != NULL); - ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* target_menu = - drop_menu->GetSubmenu()->GetMenuItemAt(0); - gfx::Point loc(1, 1); - views::View::ConvertPointToScreen(target_menu, &loc); - ui_controls::SendMouseMove(loc.x(), loc.y()); - ui_controls::SendMouseEventsNotifyWhenDone( - ui_controls::LEFT, ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest7::Step5)); - } - - void Step5() { - ASSERT_TRUE(model_->other_node()->GetChild(0)->GetURL() == url_dragging_); - Done(); - } - - GURL url_dragging_; -}; - -VIEW_TEST(BookmarkBarViewTest7, MAYBE_DNDToDifferentMenu) - -// Drags from one menu to next so that original menu closes, then back to -// original menu. -class BookmarkBarViewTest8 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - url_dragging_ = - model_->GetBookmarkBarNode()->GetChild(0)->GetChild(0)->GetURL(); - - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest8::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - - // Move mouse to center of menu and press button. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, - ui_controls::DOWN, - CreateEventTask(this, &BookmarkBarViewTest8::Step3)); - } - - void Step3() { - // Drag over other button. - views::TextButton* other_button = - bb_view_->other_bookmarked_button(); - gfx::Point loc(other_button->width() / 2, other_button->height() / 2); - views::View::ConvertPointToScreen(other_button, &loc); - - // Start a drag. - ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(), - NewRunnableMethod(this, &BookmarkBarViewTest8::Step4)); - - // See comment above this method as to why we do this. - ScheduleMouseMoveInBackground(loc.x(), loc.y()); - } - - void Step4() { - views::MenuItemView* drop_menu = bb_view_->GetDropMenu(); - ASSERT_TRUE(drop_menu != NULL); - ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing()); - - // Now drag back over first menu. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - gfx::Point loc(button->width() / 2, button->height() / 2); - views::View::ConvertPointToScreen(button, &loc); - ui_controls::SendMouseMoveNotifyWhenDone(loc.x(), loc.y(), - NewRunnableMethod(this, &BookmarkBarViewTest8::Step5)); - } - - void Step5() { - // Drop on folder F11. - views::MenuItemView* drop_menu = bb_view_->GetDropMenu(); - ASSERT_TRUE(drop_menu != NULL); - ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* target_menu = - drop_menu->GetSubmenu()->GetMenuItemAt(1); - ui_controls::MoveMouseToCenterAndPress( - target_menu, ui_controls::LEFT, ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest8::Step6)); - } - - void Step6() { - // Make sure drop was processed. - GURL final_url = model_->GetBookmarkBarNode()->GetChild(0)->GetChild(0)-> - GetChild(1)->GetURL(); - ASSERT_TRUE(final_url == url_dragging_); - Done(); - } - - GURL url_dragging_; -}; - -VIEW_TEST(BookmarkBarViewTest8, MAYBE_DNDBackToOriginatingMenu) - -// Moves the mouse over the scroll button and makes sure we get scrolling. -class BookmarkBarViewTest9 : public BookmarkBarViewEventTestBase { - protected: - virtual bool CreateBigMenu() { return true; } - - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest9::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - first_menu_ = menu->GetSubmenu()->GetMenuItemAt(0); - gfx::Point menu_loc; - views::View::ConvertPointToScreen(first_menu_, &menu_loc); - start_y_ = menu_loc.y(); - - // Move the mouse over the scroll button. - views::View* scroll_container = menu->GetSubmenu()->GetParent(); - ASSERT_TRUE(scroll_container != NULL); - scroll_container = scroll_container->GetParent(); - ASSERT_TRUE(scroll_container != NULL); - views::View* scroll_down_button = scroll_container->GetChildViewAt(1); - ASSERT_TRUE(scroll_down_button); - gfx::Point loc(scroll_down_button->width() / 2, - scroll_down_button->height() / 2); - views::View::ConvertPointToScreen(scroll_down_button, &loc); - - // On linux, the sending one location isn't enough. - ui_controls::SendMouseMove(loc.x() - 1 , loc.y() - 1); - ui_controls::SendMouseMoveNotifyWhenDone( - loc.x(), loc.y(), CreateEventTask(this, &BookmarkBarViewTest9::Step3)); - } - - void Step3() { - MessageLoop::current()->PostDelayedTask(FROM_HERE, - NewRunnableMethod(this, &BookmarkBarViewTest9::Step4), 200); - } - - void Step4() { - gfx::Point menu_loc; - views::View::ConvertPointToScreen(first_menu_, &menu_loc); - ASSERT_NE(start_y_, menu_loc.y()); - - // Hide menu. - bb_view_->GetMenu()->GetMenuController()->CancelAll(); - - // On linux, Cancelling menu will call Quit on the message loop, - // which can interfere with Done. We need to run Done in the - // next execution loop. - MessageLoop::current()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ViewEventTestBase::Done)); - } - - int start_y_; - views::MenuItemView* first_menu_; -}; - -VIEW_TEST(BookmarkBarViewTest9, MAYBE_ScrollButtonScrolls) - -// Tests up/down/left/enter key messages. -class BookmarkBarViewTest10 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest10::Step2)); - MessageLoop::current()->RunAllPending(); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - // Send a down event, which should select the first item. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_DOWN, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest10::Step3)); - } - - void Step3() { - // Make sure menu is showing and item is selected. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected()); - - // Send a key down event, which should select the next item. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_DOWN, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest10::Step4)); - } - - void Step4() { - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - ASSERT_FALSE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected()); - ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(1)->IsSelected()); - - // Send a right arrow to force the menu to open. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_RIGHT, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest10::Step5)); - } - - void Step5() { - // Make sure the submenu is showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - views::MenuItemView* submenu = menu->GetSubmenu()->GetMenuItemAt(1); - ASSERT_TRUE(submenu->IsSelected()); - ASSERT_TRUE(submenu->GetSubmenu()); - ASSERT_TRUE(submenu->GetSubmenu()->IsShowing()); - - // Send a left arrow to close the submenu. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_LEFT, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest10::Step6)); - } - - void Step6() { - // Make sure the submenu is showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - views::MenuItemView* submenu = menu->GetSubmenu()->GetMenuItemAt(1); - ASSERT_TRUE(submenu->IsSelected()); - ASSERT_TRUE(!submenu->GetSubmenu() || !submenu->GetSubmenu()->IsShowing()); - - // Send a down arrow to wrap back to f1a - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_DOWN, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest10::Step7)); - } - - void Step7() { - // Make sure menu is showing and item is selected. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected()); - - // Send enter, which should select the item. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_RETURN, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest10::Step8)); - } - - void Step8() { - ASSERT_TRUE( - model_->GetBookmarkBarNode()->GetChild(0)->GetChild(0)->GetURL() == - navigator_.url_); - Done(); - } -}; - -VIEW_TEST(BookmarkBarViewTest10, MAYBE_KeyEvents) - -// Make sure the menu closes with the following sequence: show menu, show -// context menu, close context menu (via escape), then click else where. This -// effectively verifies we maintain mouse capture after the context menu is -// hidden. -class BookmarkBarViewTest11 : public BookmarkBarViewEventTestBase { - public: - BookmarkBarViewTest11() - : ALLOW_THIS_IN_INITIALIZER_LIST( - observer_(CreateEventTask(this, &BookmarkBarViewTest11::Step3))) { - } - - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->other_bookmarked_button(); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest11::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - - // Right click on the first child to get its context menu. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT, - ui_controls::DOWN | ui_controls::UP, NULL); - // Step3 will be invoked by ContextMenuNotificationObserver. - } - - void Step3() { - // Send escape so that the context menu hides. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_ESCAPE, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest11::Step4)); - } - - void Step4() { - // Make sure the context menu is no longer showing. - views::MenuItemView* menu = bb_view_->GetContextMenu(); - ASSERT_TRUE(!menu || !menu->GetSubmenu() || - !menu->GetSubmenu()->IsShowing()); - - // But the menu should be showing. - menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing()); - - // Now click on empty space. - gfx::Point mouse_loc; - views::View::ConvertPointToScreen(bb_view_, &mouse_loc); - ui_controls::SendMouseMove(mouse_loc.x(), mouse_loc.y()); - ui_controls::SendMouseEventsNotifyWhenDone( - ui_controls::LEFT, ui_controls::UP | ui_controls::DOWN, - CreateEventTask(this, &BookmarkBarViewTest11::Step5)); - } - - void Step5() { - // Make sure the menu is not showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(!menu || !menu->GetSubmenu() || - !menu->GetSubmenu()->IsShowing()); - Done(); - } - - ContextMenuNotificationObserver observer_; -}; - -VIEW_TEST(BookmarkBarViewTest11, MAYBE_CloseMenuAfterClosingContextMenu) - -// Tests showing a modal dialog from a context menu. -class BookmarkBarViewTest12 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - // Open up the other folder. - views::TextButton* button = bb_view_->other_bookmarked_button(); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest12::Step2)); - bookmark_utils::num_urls_before_prompting = 1; - } - - ~BookmarkBarViewTest12() { - bookmark_utils::num_urls_before_prompting = 15; - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(1); - ASSERT_TRUE(child_menu != NULL); - - // Right click on the second child (a folder) to get its context menu. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest12::Step3)); - } - - void Step3() { - // Make sure the context menu is showing. - views::MenuItemView* menu = bb_view_->GetContextMenu(); - ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing()); - - // Select the first item in the context menu (open all). - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, NULL); - - // Delay until we send tab, otherwise the message box doesn't appear - // correctly. - MessageLoop::current()->PostDelayedTask(FROM_HERE, - CreateEventTask(this, &BookmarkBarViewTest12::Step4), 1000); - } - - void Step4() { - // Press tab to give focus to the cancel button. - ui_controls::SendKeyPress(NULL, app::VKEY_TAB, false, false, false, false); - - // For some reason return isn't processed correctly unless we delay. - MessageLoop::current()->PostDelayedTask(FROM_HERE, - CreateEventTask(this, &BookmarkBarViewTest12::Step5), 1000); - } - - void Step5() { - // And press enter so that the cancel button is selected. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_RETURN, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest12::Step6)); - } - - void Step6() { - // Do a delayed task to give the dialog time to exit. - MessageLoop::current()->PostTask( - FROM_HERE, CreateEventTask(this, &BookmarkBarViewTest12::Step7)); - } - - void Step7() { - Done(); - } -}; - -VIEW_TEST(BookmarkBarViewTest12, MAYBE_CloseWithModalDialog) - -// Tests clicking on the separator of a context menu (this is for coverage of -// bug 17862). -class BookmarkBarViewTest13 : public BookmarkBarViewEventTestBase { - public: - BookmarkBarViewTest13() - : ALLOW_THIS_IN_INITIALIZER_LIST( - observer_(CreateEventTask(this, &BookmarkBarViewTest13::Step3))) { - } - - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->other_bookmarked_button(); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest13::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(0); - ASSERT_TRUE(child_menu != NULL); - - // Right click on the first child to get its context menu. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT, - ui_controls::DOWN | ui_controls::UP, NULL); - // Step3 will be invoked by ContextMenuNotificationObserver. - } - - void Step3() { - // Make sure the context menu is showing. - views::MenuItemView* menu = bb_view_->GetContextMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - // Find the first separator. - views::SubmenuView* submenu = menu->GetSubmenu(); - views::View* separator_view = NULL; - for (int i = 0; i < submenu->GetChildViewCount(); ++i) { - if (submenu->GetChildViewAt(i)->GetID() != - views::MenuItemView::kMenuItemViewID) { - separator_view = submenu->GetChildViewAt(i); - break; - } - } - ASSERT_TRUE(separator_view); - - // Click on the separator. Clicking on the separator shouldn't visually - // change anything. - ui_controls::MoveMouseToCenterAndPress(separator_view, - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest13::Step4)); - } - - void Step4() { - // The context menu should still be showing. - views::MenuItemView* menu = bb_view_->GetContextMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - // Select the first context menu item. - ui_controls::MoveMouseToCenterAndPress(menu->GetSubmenu()->GetMenuItemAt(0), - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest13::Step5)); - } - - void Step5() { - Done(); - } - - ContextMenuNotificationObserver observer_; -}; - -VIEW_TEST(BookmarkBarViewTest13, ClickOnContextMenuSeparator) - -// Makes sure right cliking on a folder on the bookmark bar doesn't result in -// both a context menu and showing the menu. -class BookmarkBarViewTest14 : public BookmarkBarViewEventTestBase { - public: - BookmarkBarViewTest14() - : ALLOW_THIS_IN_INITIALIZER_LIST( - observer_(CreateEventTask(this, &BookmarkBarViewTest14::Step2))) { - } - - protected: - virtual void DoTestOnMessageLoop() { - // Move the mouse to the first folder on the bookmark bar and press the - // right mouse button. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::RIGHT, - ui_controls::DOWN | ui_controls::UP, NULL); - // Step2 will be invoked by ContextMenuNotificationObserver. - } - - private: - - void Step2() { - // Menu should NOT be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu == NULL); - - // Send escape so that the context menu hides. - ui_controls::SendKeyPressNotifyWhenDone( - NULL, app::VKEY_ESCAPE, false, false, false, false, - CreateEventTask(this, &BookmarkBarViewTest14::Step3)); - } - - void Step3() { - Done(); - } - - ContextMenuNotificationObserver observer_; -}; - -VIEW_TEST(BookmarkBarViewTest14, ContextMenus2) - -// Makes sure deleting from the context menu keeps the bookmark menu showing. -class BookmarkBarViewTest15 : public BookmarkBarViewEventTestBase { - public: - BookmarkBarViewTest15() - : deleted_menu_id_(0), - ALLOW_THIS_IN_INITIALIZER_LIST( - observer_(CreateEventTask(this, &BookmarkBarViewTest15::Step3))) { - } - - protected: - virtual void DoTestOnMessageLoop() { - // Show the other bookmarks. - views::TextButton* button = bb_view_->other_bookmarked_button(); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest15::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* child_menu = - menu->GetSubmenu()->GetMenuItemAt(1); - ASSERT_TRUE(child_menu != NULL); - - deleted_menu_id_ = child_menu->GetCommand(); - - // Right click on the second child to get its context menu. - ui_controls::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT, - ui_controls::DOWN | ui_controls::UP, NULL); - // Step3 will be invoked by ContextMenuNotificationObserver. - } - - void Step3() { - // Make sure the context menu is showing. - views::MenuItemView* menu = bb_view_->GetContextMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - views::MenuItemView* delete_menu = - menu->GetMenuItemByID(IDS_BOOKMARK_BAR_REMOVE); - ASSERT_TRUE(delete_menu); - - // Click on the delete button. - ui_controls::MoveMouseToCenterAndPress(delete_menu, - ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest15::Step4)); - } - - void Step4() { - // The context menu should not be showing. - views::MenuItemView* context_menu = bb_view_->GetContextMenu(); - ASSERT_TRUE(context_menu == NULL); - - // But the menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - // And the deleted_menu_id_ should have been removed. - ASSERT_TRUE(menu->GetMenuItemByID(deleted_menu_id_) == NULL); - - bb_view_->GetMenu()->GetMenuController()->CancelAll(); - - Done(); - } - - int deleted_menu_id_; - ContextMenuNotificationObserver observer_; -}; - -VIEW_TEST(BookmarkBarViewTest15, MenuStaysVisibleAfterDelete) - -// Tests that we don't crash or get stuck if the parent of a menu is closed. -class BookmarkBarViewTest16 : public BookmarkBarViewEventTestBase { - protected: - virtual void DoTestOnMessageLoop() { - InstallViewsDelegate(); - - // Move the mouse to the first folder on the bookmark bar and press the - // mouse. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - CreateEventTask(this, &BookmarkBarViewTest16::Step2)); - } - - private: - void Step2() { - // Menu should be showing. - views::MenuItemView* menu = bb_view_->GetMenu(); - ASSERT_TRUE(menu != NULL); - ASSERT_TRUE(menu->GetSubmenu()->IsShowing()); - - // Button should be depressed. - views::TextButton* button = bb_view_->GetBookmarkButton(0); - ASSERT_TRUE(button->state() == views::CustomButton::BS_PUSHED); - - // Close the window. - window_->Close(); - window_ = NULL; - } -}; - -VIEW_TEST(BookmarkBarViewTest16, DeleteMenu) diff --git a/chrome/browser/views/bookmark_bar_view_unittest.cc b/chrome/browser/views/bookmark_bar_view_unittest.cc deleted file mode 100644 index 3f66795..0000000 --- a/chrome/browser/views/bookmark_bar_view_unittest.cc +++ /dev/null @@ -1,47 +0,0 @@ -// 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 "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/views/bookmark_bar_view.h" -#include "chrome/test/browser_with_test_window_test.h" -#include "chrome/test/testing_profile.h" - -class BookmarkBarViewTest : public BrowserWithTestWindowTest { - public: - BookmarkBarViewTest() - : file_thread_(BrowserThread::FILE, message_loop()) {} - - private: - BrowserThread file_thread_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkBarViewTest); -}; - -TEST_F(BookmarkBarViewTest, SwitchProfile) { - profile()->CreateBookmarkModel(true); - profile()->BlockUntilBookmarkModelLoaded(); - - profile()->GetBookmarkModel()->AddURL( - profile()->GetBookmarkModel()->GetBookmarkBarNode(), - 0, - ASCIIToUTF16("blah"), - GURL("http://www.google.com")); - - BookmarkBarView bookmark_bar(profile(), browser()); - - EXPECT_EQ(1, bookmark_bar.GetBookmarkButtonCount()); - - TestingProfile profile2; - profile2.CreateBookmarkModel(true); - profile2.BlockUntilBookmarkModelLoaded(); - - bookmark_bar.SetProfile(&profile2); - - EXPECT_EQ(0, bookmark_bar.GetBookmarkButtonCount()); - - bookmark_bar.SetProfile(profile()); - EXPECT_EQ(1, bookmark_bar.GetBookmarkButtonCount()); -} diff --git a/chrome/browser/views/bookmark_bubble_view.cc b/chrome/browser/views/bookmark_bubble_view.cc deleted file mode 100644 index a1f651b..0000000 --- a/chrome/browser/views/bookmark_bubble_view.cc +++ /dev/null @@ -1,413 +0,0 @@ -// 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/bookmark_bubble_view.h" - -#include "app/keyboard_codes.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/string16.h" -#include "base/string_util.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/bookmarks/bookmark_editor.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/info_bubble.h" -#include "chrome/common/notification_service.h" -#include "gfx/canvas.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/event.h" -#include "views/standard_layout.h" -#include "views/controls/button/native_button.h" -#include "views/controls/textfield/textfield.h" -#include "views/focus/focus_manager.h" -#include "views/window/client_view.h" -#include "views/window/window.h" - -using views::Combobox; -using views::ColumnSet; -using views::GridLayout; -using views::Label; -using views::Link; -using views::NativeButton; -using views::View; - -// Padding between "Title:" and the actual title. -static const int kTitlePadding = 4; - -// Minimum width for the fields - they will push out the size of the bubble if -// necessary. This should be big enough so that the field pushes the right side -// of the bubble far enough so that the edit button's left edge is to the right -// of the field's left edge. -static const int kMinimumFieldSize = 180; - -// Bubble close image. -static SkBitmap* kCloseImage = NULL; - -// Declared in browser_dialogs.h so callers don't have to depend on our header. - -namespace browser { - -void ShowBookmarkBubbleView(views::Window* parent, - const gfx::Rect& bounds, - InfoBubbleDelegate* delegate, - Profile* profile, - const GURL& url, - bool newly_bookmarked) { - BookmarkBubbleView::Show(parent, bounds, delegate, profile, url, - newly_bookmarked); -} - -void HideBookmarkBubbleView() { - BookmarkBubbleView::Hide(); -} - -bool IsBookmarkBubbleViewShowing() { - return BookmarkBubbleView::IsShowing(); -} - -} // namespace browser - -// BookmarkBubbleView --------------------------------------------------------- - -BookmarkBubbleView* BookmarkBubbleView::bubble_ = NULL; - -// static -void BookmarkBubbleView::Show(views::Window* parent, - const gfx::Rect& bounds, - InfoBubbleDelegate* delegate, - Profile* profile, - const GURL& url, - bool newly_bookmarked) { - if (IsShowing()) - return; - - bubble_ = new BookmarkBubbleView(delegate, profile, url, newly_bookmarked); - InfoBubble* info_bubble = InfoBubble::Show( - parent->GetClientView()->GetWidget(), bounds, BubbleBorder::TOP_RIGHT, - bubble_, bubble_); - bubble_->set_info_bubble(info_bubble); - GURL url_ptr(url); - NotificationService::current()->Notify( - NotificationType::BOOKMARK_BUBBLE_SHOWN, - Source<Profile>(profile->GetOriginalProfile()), - Details<GURL>(&url_ptr)); - bubble_->BubbleShown(); -} - -// static -bool BookmarkBubbleView::IsShowing() { - return bubble_ != NULL; -} - -void BookmarkBubbleView::Hide() { - if (IsShowing()) - bubble_->Close(); -} - -BookmarkBubbleView::~BookmarkBubbleView() { - if (apply_edits_) { - ApplyEdits(); - } else if (remove_bookmark_) { - BookmarkModel* model = profile_->GetBookmarkModel(); - const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url_); - if (node) - model->Remove(node->GetParent(), node->GetParent()->IndexOfChild(node)); - } -} - -void BookmarkBubbleView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - Layout(); -} - -void BookmarkBubbleView::BubbleShown() { - DCHECK(GetWidget()); - GetFocusManager()->RegisterAccelerator( - views::Accelerator(app::VKEY_RETURN, false, false, false), this); - - title_tf_->RequestFocus(); - title_tf_->SelectAll(); -} - -bool BookmarkBubbleView::AcceleratorPressed( - const views::Accelerator& accelerator) { - if (accelerator.GetKeyCode() != app::VKEY_RETURN) - return false; - - if (edit_button_->HasFocus()) - HandleButtonPressed(edit_button_); - else - HandleButtonPressed(close_button_); - return true; -} - -void BookmarkBubbleView::ViewHierarchyChanged(bool is_add, View* parent, - View* child) { - if (is_add && child == this) - Init(); -} - -BookmarkBubbleView::BookmarkBubbleView(InfoBubbleDelegate* delegate, - Profile* profile, - const GURL& url, - bool newly_bookmarked) - : delegate_(delegate), - profile_(profile), - url_(url), - newly_bookmarked_(newly_bookmarked), - parent_model_( - profile_->GetBookmarkModel(), - profile_->GetBookmarkModel()->GetMostRecentlyAddedNodeForURL(url)), - remove_bookmark_(false), - apply_edits_(true) { -} - -void BookmarkBubbleView::Init() { - static SkColor kTitleColor; - static bool initialized = false; - if (!initialized) { - kTitleColor = color_utils::GetReadableColor(SkColorSetRGB(6, 45, 117), - InfoBubble::kBackgroundColor); - kCloseImage = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_INFO_BUBBLE_CLOSE); - - initialized = true; - } - - remove_link_ = new Link(l10n_util::GetString( - IDS_BOOMARK_BUBBLE_REMOVE_BOOKMARK)); - remove_link_->SetController(this); - - edit_button_ = new NativeButton( - this, l10n_util::GetString(IDS_BOOMARK_BUBBLE_OPTIONS)); - - close_button_ = new NativeButton(this, l10n_util::GetString(IDS_DONE)); - close_button_->SetIsDefault(true); - - Label* combobox_label = new Label( - l10n_util::GetString(IDS_BOOMARK_BUBBLE_FOLDER_TEXT)); - - parent_combobox_ = new Combobox(&parent_model_); - parent_combobox_->SetSelectedItem(parent_model_.node_parent_index()); - parent_combobox_->set_listener(this); - parent_combobox_->SetAccessibleName(combobox_label->GetText()); - - Label* title_label = new Label(l10n_util::GetString( - newly_bookmarked_ ? IDS_BOOMARK_BUBBLE_PAGE_BOOKMARKED : - IDS_BOOMARK_BUBBLE_PAGE_BOOKMARK)); - title_label->SetFont( - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); - title_label->SetColor(kTitleColor); - - GridLayout* layout = new GridLayout(this); - SetLayoutManager(layout); - - ColumnSet* cs = layout->AddColumnSet(0); - - // Top (title) row. - cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF, - 0, 0); - cs->AddPaddingColumn(1, kUnrelatedControlHorizontalSpacing); - cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF, - 0, 0); - - // Middle (input field) rows. - cs = layout->AddColumnSet(2); - cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - cs->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, kMinimumFieldSize); - - // Bottom (buttons) row. - cs = layout->AddColumnSet(3); - cs->AddPaddingColumn(1, kRelatedControlHorizontalSpacing); - cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, - GridLayout::USE_PREF, 0, 0); - // We subtract 2 to account for the natural button padding, and - // to bring the separation visually in line with the row separation - // height. - cs->AddPaddingColumn(0, kRelatedButtonHSpacing - 2); - cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, 0); - layout->AddView(title_label); - layout->AddView(remove_link_); - - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, 2); - layout->AddView( - new Label(l10n_util::GetString(IDS_BOOMARK_BUBBLE_TITLE_TEXT))); - title_tf_ = new views::Textfield(); - title_tf_->SetText(GetTitle()); - layout->AddView(title_tf_); - - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - - layout->StartRow(0, 2); - layout->AddView(combobox_label); - layout->AddView(parent_combobox_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - - layout->StartRow(0, 3); - layout->AddView(edit_button_); - layout->AddView(close_button_); -} - -string16 BookmarkBubbleView::GetTitle() { - BookmarkModel* bookmark_model= profile_->GetBookmarkModel(); - const BookmarkNode* node = - bookmark_model->GetMostRecentlyAddedNodeForURL(url_); - if (node) - return node->GetTitle(); - else - NOTREACHED(); - return string16(); -} - -void BookmarkBubbleView::ButtonPressed( - views::Button* sender, const views::Event& event) { - HandleButtonPressed(sender); -} - -void BookmarkBubbleView::LinkActivated(Link* source, int event_flags) { - DCHECK(source == remove_link_); - UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Unstar"), - profile_); - - // Set this so we remove the bookmark after the window closes. - remove_bookmark_ = true; - apply_edits_ = false; - - info_bubble_->set_fade_away_on_close(true); - Close(); -} - -void BookmarkBubbleView::ItemChanged(Combobox* combobox, - int prev_index, - int new_index) { - if (new_index + 1 == parent_model_.GetItemCount()) { - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBubble_EditFromCombobox"), profile_); - - ShowEditor(); - return; - } -} - -void BookmarkBubbleView::InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape) { - if (closed_by_escape) { - remove_bookmark_ = newly_bookmarked_; - apply_edits_ = false; - } - - // We have to reset |bubble_| here, not in our destructor, because we'll be - // destroyed asynchronously and the shown state will be checked before then. - DCHECK(bubble_ == this); - bubble_ = NULL; - - if (delegate_) - delegate_->InfoBubbleClosing(info_bubble, closed_by_escape); - NotificationService::current()->Notify( - NotificationType::BOOKMARK_BUBBLE_HIDDEN, - Source<Profile>(profile_->GetOriginalProfile()), - NotificationService::NoDetails()); -} - -bool BookmarkBubbleView::CloseOnEscape() { - return delegate_ ? delegate_->CloseOnEscape() : true; -} - -std::wstring BookmarkBubbleView::accessible_name() { - return l10n_util::GetString(IDS_BOOMARK_BUBBLE_ADD_BOOKMARK); -} - -void BookmarkBubbleView::Close() { - static_cast<InfoBubble*>(GetWidget())->Close(); -} - -void BookmarkBubbleView::HandleButtonPressed(views::Button* sender) { - if (sender == edit_button_) { - UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Edit"), - profile_); - info_bubble_->set_fade_away_on_close(true); - ShowEditor(); - } else { - DCHECK(sender == close_button_); - info_bubble_->set_fade_away_on_close(true); - Close(); - } - // WARNING: we've most likely been deleted when CloseWindow returns. -} - -void BookmarkBubbleView::ShowEditor() { - const BookmarkNode* node = - profile_->GetBookmarkModel()->GetMostRecentlyAddedNodeForURL(url_); - - // Commit any edits now. - ApplyEdits(); - -#if defined(OS_WIN) - // Parent the editor to our root ancestor (not the root we're in, as that - // is the info bubble and will close shortly). - HWND parent = GetAncestor(GetWidget()->GetNativeView(), GA_ROOTOWNER); - - // We're about to show the bookmark editor. When the bookmark editor closes - // we want the browser to become active. WidgetWin::Hide() does a hide in - // a such way that activation isn't changed, which means when we close - // Windows gets confused as to who it should give active status to. We - // explicitly hide the bookmark bubble window in such a way that activation - // status changes. That way, when the editor closes, activation is properly - // restored to the browser. - ShowWindow(GetWidget()->GetNativeView(), SW_HIDE); -#else - gfx::NativeWindow parent = GTK_WINDOW( - static_cast<views::WidgetGtk*>(GetWidget())->GetTransientParent()); -#endif - - // Even though we just hid the window, we need to invoke Close to schedule - // the delete and all that. - Close(); - - if (node) { - BookmarkEditor::Show(parent, profile_, NULL, - BookmarkEditor::EditDetails(node), - BookmarkEditor::SHOW_TREE); - } -} - -void BookmarkBubbleView::ApplyEdits() { - // Set this to make sure we don't attempt to apply edits again. - apply_edits_ = false; - - BookmarkModel* model = profile_->GetBookmarkModel(); - const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url_); - if (node) { - const string16 new_title = title_tf_->text(); - if (new_title != node->GetTitle()) { - model->SetTitle(node, new_title); - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBubble_ChangeTitleInBubble"), - profile_); - } - // Last index means 'Choose another folder...' - if (parent_combobox_->selected_item() < - parent_model_.GetItemCount() - 1) { - const BookmarkNode* new_parent = - parent_model_.GetNodeAt(parent_combobox_->selected_item()); - if (new_parent != node->GetParent()) { - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBubble_ChangeParent"), profile_); - model->Move(node, new_parent, new_parent->GetChildCount()); - } - } - } -} diff --git a/chrome/browser/views/bookmark_bubble_view.h b/chrome/browser/views/bookmark_bubble_view.h index 32a928f..cd35459 100644 --- a/chrome/browser/views/bookmark_bubble_view.h +++ b/chrome/browser/views/bookmark_bubble_view.h @@ -6,157 +6,8 @@ #define CHROME_BROWSER_VIEWS_BOOKMARK_BUBBLE_VIEW_H_ #pragma once -#include "base/string16.h" -#include "chrome/browser/bookmarks/recently_used_folders_combo_model.h" -#include "chrome/browser/views/info_bubble.h" -#include "gfx/rect.h" -#include "googleurl/src/gurl.h" -#include "views/controls/button/button.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/link.h" -#include "views/view.h" - -class Profile; - -class BookmarkModel; -class BookmarkNode; - -namespace views { -class NativeButton; -class Textfield; -} - -// BookmarkBubbleView is a view intended to be used as the content of an -// InfoBubble. BookmarkBubbleView provides views for unstarring and editting -// the bookmark it is created with. Don't create a BookmarkBubbleView directly, -// instead use the static Show method. -class BookmarkBubbleView : public views::View, - public views::LinkController, - public views::ButtonListener, - public views::Combobox::Listener, - public InfoBubbleDelegate { - public: - static void Show(views::Window* window, - const gfx::Rect& bounds, - InfoBubbleDelegate* delegate, - Profile* profile, - const GURL& url, - bool newly_bookmarked); - - static bool IsShowing(); - - static void Hide(); - - virtual ~BookmarkBubbleView(); - - void set_info_bubble(InfoBubble* info_bubble) { info_bubble_ = info_bubble; } - - // Overridden to force a layout. - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - - // Invoked after the bubble has been shown. - virtual void BubbleShown(); - - // Override to close on return. - virtual bool AcceleratorPressed(const views::Accelerator& accelerator); - - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - - private: - // Creates a BookmarkBubbleView. - // |title| is the title of the page. If newly_bookmarked is false, title is - // ignored and the title of the bookmark is fetched from the database. - BookmarkBubbleView(InfoBubbleDelegate* delegate, - Profile* profile, - const GURL& url, - bool newly_bookmarked); - // Creates the child views. - void Init(); - - // Returns the title to display. - string16 GetTitle(); - - // LinkController method, either unstars the item or shows the bookmark - // editor (depending upon which link was clicked). - virtual void LinkActivated(views::Link* source, int event_flags); - - // ButtonListener method, closes the bubble or opens the edit dialog. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Combobox::Listener method. Changes the parent of the bookmark. - virtual void ItemChanged(views::Combobox* combobox, - int prev_index, - int new_index); - - // InfoBubbleDelegate methods. These forward to the InfoBubbleDelegate - // supplied in the constructor as well as sending out the necessary - // notification. - virtual void InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape); - virtual bool CloseOnEscape(); - virtual bool FadeInOnShow() { return false; } - virtual std::wstring accessible_name(); - - // Closes the bubble. - void Close(); - - // Handle the message when the user presses a button. - void HandleButtonPressed(views::Button* sender); - - // Shows the BookmarkEditor. - void ShowEditor(); - - // Sets the title and parent of the node. - void ApplyEdits(); - - // The bookmark bubble, if we're showing one. - static BookmarkBubbleView* bubble_; - - // The InfoBubble showing us. - InfoBubble* info_bubble_; - - // Delegate for the bubble, may be null. - InfoBubbleDelegate* delegate_; - - // The profile. - Profile* profile_; - - // The bookmark URL. - const GURL url_; - - // Title of the bookmark. This is initially the title supplied to the - // constructor, which is typically the title of the page. - std::wstring title_; - - // If true, the page was just bookmarked. - const bool newly_bookmarked_; - - RecentlyUsedFoldersComboModel parent_model_; - - // Link for removing/unstarring the bookmark. - views::Link* remove_link_; - - // Button to bring up the editor. - views::NativeButton* edit_button_; - - // Button to close the window. - views::NativeButton* close_button_; - - // Textfield showing the title of the bookmark. - views::Textfield* title_tf_; - - // Combobox showing a handful of folders the user can choose from, including - // the current parent. - views::Combobox* parent_combobox_; - - // When the destructor is invoked should the bookmark be removed? - bool remove_bookmark_; - - // When the destructor is invoked should edits be applied? - bool apply_edits_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkBubbleView); -}; +#include "chrome/browser/ui/views/bookmark_bubble_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BOOKMARK_BUBBLE_VIEW_H_ + diff --git a/chrome/browser/views/bookmark_context_menu.cc b/chrome/browser/views/bookmark_context_menu.cc deleted file mode 100644 index cdd778a..0000000 --- a/chrome/browser/views/bookmark_context_menu.cc +++ /dev/null @@ -1,100 +0,0 @@ -// 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/bookmark_context_menu.h" - -#include "app/l10n_util.h" -#include "base/i18n/rtl.h" -#include "chrome/browser/profile.h" -#include "chrome/common/notification_service.h" -#include "grit/generated_resources.h" -#include "views/controls/menu/menu_item_view.h" - -//////////////////////////////////////////////////////////////////////////////// -// BookmarkContextMenu, public: - -BookmarkContextMenu::BookmarkContextMenu( - gfx::NativeWindow parent_window, - Profile* profile, - PageNavigator* page_navigator, - const BookmarkNode* parent, - const std::vector<const BookmarkNode*>& selection) - : ALLOW_THIS_IN_INITIALIZER_LIST( - controller_(new BookmarkContextMenuControllerViews(parent_window, - this, profile, page_navigator, parent, selection))), - parent_window_(parent_window), - ALLOW_THIS_IN_INITIALIZER_LIST(menu_(new views::MenuItemView(this))), - observer_(NULL) { - controller_->BuildMenu(); -} - -BookmarkContextMenu::~BookmarkContextMenu() { -} - -void BookmarkContextMenu::RunMenuAt(const gfx::Point& point) { - NotificationService::current()->Notify( - NotificationType::BOOKMARK_CONTEXT_MENU_SHOWN, - Source<BookmarkContextMenu>(this), - NotificationService::NoDetails()); - // width/height don't matter here. - views::MenuItemView::AnchorPosition anchor = base::i18n::IsRTL() ? - views::MenuItemView::TOPRIGHT : views::MenuItemView::TOPLEFT; - menu_->RunMenuAt(parent_window_, NULL, gfx::Rect(point.x(), point.y(), 0, 0), - anchor, true); -} - -//////////////////////////////////////////////////////////////////////////////// -// BookmarkContextMenu, views::MenuDelegate implementation: - -void BookmarkContextMenu::ExecuteCommand(int command_id) { - controller_->ExecuteCommand(command_id); -} - -bool BookmarkContextMenu::IsItemChecked(int command_id) const { - return controller_->IsItemChecked(command_id); -} - -bool BookmarkContextMenu::IsCommandEnabled(int command_id) const { - return controller_->IsCommandEnabled(command_id); -} - -bool BookmarkContextMenu::ShouldCloseAllMenusOnExecute(int id) { - return id != IDS_BOOKMARK_BAR_REMOVE; -} - -//////////////////////////////////////////////////////////////////////////////// -// BookmarkContextMenu, BookmarkContextMenuControllerViewsDelegate -// implementation: - -void BookmarkContextMenu::CloseMenu() { - menu_->Cancel(); -} - -void BookmarkContextMenu::AddItem(int command_id) { - menu_->AppendMenuItemWithLabel(command_id, l10n_util::GetString(command_id)); -} - -void BookmarkContextMenu::AddItemWithStringId(int command_id, int string_id) { - menu_->AppendMenuItemWithLabel(command_id, l10n_util::GetString(string_id)); -} - -void BookmarkContextMenu::AddSeparator() { - menu_->AppendSeparator(); -} - -void BookmarkContextMenu::AddCheckboxItem(int command_id) { - menu_->AppendMenuItem(command_id, l10n_util::GetString(command_id), - views::MenuItemView::CHECKBOX); -} - -void BookmarkContextMenu::WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks) { - if (observer_) - observer_->WillRemoveBookmarks(bookmarks); -} - -void BookmarkContextMenu::DidRemoveBookmarks() { - if (observer_) - observer_->DidRemoveBookmarks(); -} diff --git a/chrome/browser/views/bookmark_context_menu.h b/chrome/browser/views/bookmark_context_menu.h index 2a50195..1f6f2f2 100644 --- a/chrome/browser/views/bookmark_context_menu.h +++ b/chrome/browser/views/bookmark_context_menu.h @@ -6,71 +6,8 @@ #define CHROME_BROWSER_VIEWS_BOOKMARK_CONTEXT_MENU_H_ #pragma once -#include "chrome/browser/views/bookmark_context_menu_controller_views.h" -#include "views/controls/menu/menu_delegate.h" - -// Observer for the BookmarkContextMenu. -class BookmarkContextMenuObserver { - public: - // Invoked before the specified items are removed from the bookmark model. - virtual void WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks) = 0; - - // Invoked after the items have been removed from the model. - virtual void DidRemoveBookmarks() = 0; - - protected: - virtual ~BookmarkContextMenuObserver() {} -}; - -class BookmarkContextMenu : public BookmarkContextMenuControllerViewsDelegate, - public views::MenuDelegate { - public: - BookmarkContextMenu( - gfx::NativeWindow parent_window, - Profile* profile, - PageNavigator* page_navigator, - const BookmarkNode* parent, - const std::vector<const BookmarkNode*>& selection); - virtual ~BookmarkContextMenu(); - - // Shows the context menu at the specified point. - void RunMenuAt(const gfx::Point& point); - - views::MenuItemView* menu() const { return menu_.get(); } - - void set_observer(BookmarkContextMenuObserver* observer) { - observer_ = observer; - } - - // Overridden from views::MenuDelegate: - virtual void ExecuteCommand(int command_id); - virtual bool IsItemChecked(int command_id) const; - virtual bool IsCommandEnabled(int command_id) const; - virtual bool ShouldCloseAllMenusOnExecute(int id); - - // Overridden from BookmarkContextMenuControllerViewsDelegate: - virtual void CloseMenu(); - virtual void AddItem(int command_id); - virtual void AddItemWithStringId(int command_id, int string_id); - virtual void AddSeparator(); - virtual void AddCheckboxItem(int command_id); - virtual void WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks); - virtual void DidRemoveBookmarks(); - - private: - scoped_ptr<BookmarkContextMenuControllerViews> controller_; - - // The parent of dialog boxes opened from the context menu. - gfx::NativeWindow parent_window_; - - // The menu itself. - scoped_ptr<views::MenuItemView> menu_; - - BookmarkContextMenuObserver* observer_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenu); -}; +#include "chrome/browser/ui/views/bookmark_context_menu.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BOOKMARK_CONTEXT_MENU_H_ + diff --git a/chrome/browser/views/bookmark_context_menu_controller_views.cc b/chrome/browser/views/bookmark_context_menu_controller_views.cc deleted file mode 100644 index b2dcde9..0000000 --- a/chrome/browser/views/bookmark_context_menu_controller_views.cc +++ /dev/null @@ -1,292 +0,0 @@ -// 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/bookmark_context_menu_controller_views.h" - -#include "base/compiler_specific.h" -#include "chrome/browser/bookmarks/bookmark_editor.h" -#include "chrome/browser/bookmarks/bookmark_folder_editor_controller.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/common/pref_names.h" -#include "grit/generated_resources.h" - -namespace { - -// Returns true if the specified node is of type URL, or has a descendant -// of type URL. -bool NodeHasURLs(const BookmarkNode* node) { - if (node->is_url()) - return true; - - for (int i = 0; i < node->GetChildCount(); ++i) { - if (NodeHasURLs(node->GetChild(i))) - return true; - } - return false; -} - -} // namespace - -BookmarkContextMenuControllerViews::BookmarkContextMenuControllerViews( - gfx::NativeWindow parent_window, - BookmarkContextMenuControllerViewsDelegate* delegate, - Profile* profile, - PageNavigator* navigator, - const BookmarkNode* parent, - const std::vector<const BookmarkNode*>& selection) - : parent_window_(parent_window), - delegate_(delegate), - profile_(profile), - navigator_(navigator), - parent_(parent), - selection_(selection), - model_(profile->GetBookmarkModel()) { - DCHECK(profile_); - DCHECK(model_->IsLoaded()); - model_->AddObserver(this); -} - -BookmarkContextMenuControllerViews::~BookmarkContextMenuControllerViews() { - if (model_) - model_->RemoveObserver(this); -} - -void BookmarkContextMenuControllerViews::BuildMenu() { - if (selection_.size() == 1 && selection_[0]->is_url()) { - delegate_->AddItemWithStringId(IDS_BOOMARK_BAR_OPEN_ALL, - IDS_BOOMARK_BAR_OPEN_IN_NEW_TAB); - delegate_->AddItemWithStringId(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW, - IDS_BOOMARK_BAR_OPEN_IN_NEW_WINDOW); - delegate_->AddItemWithStringId(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO, - IDS_BOOMARK_BAR_OPEN_INCOGNITO); - } else { - delegate_->AddItem(IDS_BOOMARK_BAR_OPEN_ALL); - delegate_->AddItem(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW); - delegate_->AddItem(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO); - } - - delegate_->AddSeparator(); - if (selection_.size() == 1 && selection_[0]->is_folder()) { - delegate_->AddItem(IDS_BOOKMARK_BAR_RENAME_FOLDER); - } else { - delegate_->AddItem(IDS_BOOKMARK_BAR_EDIT); - } - - delegate_->AddSeparator(); - delegate_->AddItem(IDS_CUT); - delegate_->AddItem(IDS_COPY); - delegate_->AddItem(IDS_PASTE); - - delegate_->AddSeparator(); - delegate_->AddItem(IDS_BOOKMARK_BAR_REMOVE); - - delegate_->AddSeparator(); - delegate_->AddItem(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK); - delegate_->AddItem(IDS_BOOMARK_BAR_NEW_FOLDER); - - delegate_->AddSeparator(); - delegate_->AddItem(IDS_BOOKMARK_MANAGER); - delegate_->AddCheckboxItem(IDS_BOOMARK_BAR_ALWAYS_SHOW); -} - -void BookmarkContextMenuControllerViews::ExecuteCommand(int id) { - BookmarkModel* model = RemoveModelObserver(); - - switch (id) { - case IDS_BOOMARK_BAR_OPEN_ALL: - case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: - case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: { - WindowOpenDisposition initial_disposition; - if (id == IDS_BOOMARK_BAR_OPEN_ALL) { - initial_disposition = NEW_FOREGROUND_TAB; - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBar_ContextMenu_OpenAll"), - profile_); - } else if (id == IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW) { - initial_disposition = NEW_WINDOW; - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBar_ContextMenu_OpenAllInNewWindow"), - profile_); - } else { - initial_disposition = OFF_THE_RECORD; - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBar_ContextMenu_OpenAllIncognito"), - profile_); - } - bookmark_utils::OpenAll(parent_window_, profile_, navigator_, selection_, - initial_disposition); - break; - } - - case IDS_BOOKMARK_BAR_RENAME_FOLDER: - case IDS_BOOKMARK_BAR_EDIT: - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBar_ContextMenu_Edit"), profile_); - - if (selection_.size() != 1) { - NOTREACHED(); - return; - } - - if (selection_[0]->is_url()) { - BookmarkEditor::Show(parent_window_, profile_, parent_, - BookmarkEditor::EditDetails(selection_[0]), - BookmarkEditor::SHOW_TREE); - } else { - BookmarkFolderEditorController::Show(profile_, parent_window_, - selection_[0], -1, - BookmarkFolderEditorController::EXISTING_BOOKMARK); - } - break; - - case IDS_BOOKMARK_BAR_REMOVE: { - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBar_ContextMenu_Remove"), profile_); - - delegate_->WillRemoveBookmarks(selection_); - for (size_t i = 0; i < selection_.size(); ++i) { - model->Remove(selection_[i]->GetParent(), - selection_[i]->GetParent()->IndexOfChild(selection_[i])); - } - delegate_->DidRemoveBookmarks(); - selection_.clear(); - break; - } - - case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: { - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBar_ContextMenu_Add"), profile_); - - // TODO: this should honor the index from GetParentForNewNodes. - BookmarkEditor::Show( - parent_window_, profile_, - bookmark_utils::GetParentForNewNodes(parent_, selection_, NULL), - BookmarkEditor::EditDetails(), BookmarkEditor::SHOW_TREE); - break; - } - - case IDS_BOOMARK_BAR_NEW_FOLDER: { - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBar_ContextMenu_NewFolder"), - profile_); - int index; - const BookmarkNode* parent = - bookmark_utils::GetParentForNewNodes(parent_, selection_, &index); - BookmarkFolderEditorController::Show(profile_, parent_window_, parent, - index, BookmarkFolderEditorController::NEW_BOOKMARK); - break; - } - - case IDS_BOOMARK_BAR_ALWAYS_SHOW: - bookmark_utils::ToggleWhenVisible(profile_); - break; - - case IDS_BOOKMARK_MANAGER: - UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"), - profile_); - { - Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); - if (browser) - browser->OpenBookmarkManager(); - else - NOTREACHED(); - } - break; - - case IDS_CUT: - delegate_->WillRemoveBookmarks(selection_); - bookmark_utils::CopyToClipboard(model, selection_, true); - delegate_->DidRemoveBookmarks(); - break; - - case IDS_COPY: - bookmark_utils::CopyToClipboard(model, selection_, false); - break; - - case IDS_PASTE: { - int index; - const BookmarkNode* paste_target = - bookmark_utils::GetParentForNewNodes(parent_, selection_, &index); - if (!paste_target) - return; - - bookmark_utils::PasteFromClipboard(model, paste_target, index); - break; - } - - default: - NOTREACHED(); - } -} - -bool BookmarkContextMenuControllerViews::IsItemChecked(int id) const { - DCHECK(id == IDS_BOOMARK_BAR_ALWAYS_SHOW); - return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); -} - -bool BookmarkContextMenuControllerViews::IsCommandEnabled(int id) const { - bool is_root_node = - (selection_.size() == 1 && - selection_[0]->GetParent() == model_->root_node()); - switch (id) { - case IDS_BOOMARK_BAR_OPEN_INCOGNITO: - return !profile_->IsOffTheRecord(); - - case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: - return HasURLs() && !profile_->IsOffTheRecord(); - - case IDS_BOOMARK_BAR_OPEN_ALL: - case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: - return HasURLs(); - - case IDS_BOOKMARK_BAR_RENAME_FOLDER: - case IDS_BOOKMARK_BAR_EDIT: - return selection_.size() == 1 && !is_root_node; - - case IDS_BOOKMARK_BAR_REMOVE: - return !selection_.empty() && !is_root_node; - - case IDS_BOOMARK_BAR_NEW_FOLDER: - case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: - return bookmark_utils::GetParentForNewNodes( - parent_, selection_, NULL) != NULL; - - case IDS_COPY: - case IDS_CUT: - return selection_.size() > 0 && !is_root_node; - - case IDS_PASTE: - // Paste to selection from the Bookmark Bar, to parent_ everywhere else - return (!selection_.empty() && - bookmark_utils::CanPasteFromClipboard(selection_[0])) || - bookmark_utils::CanPasteFromClipboard(parent_); - } - return true; -} - -void BookmarkContextMenuControllerViews::BookmarkModelChanged() { - delegate_->CloseMenu(); -} - -BookmarkModel* BookmarkContextMenuControllerViews::RemoveModelObserver() { - BookmarkModel* model = model_; - model_->RemoveObserver(this); - model_ = NULL; - return model; -} - -bool BookmarkContextMenuControllerViews::HasURLs() const { - for (size_t i = 0; i < selection_.size(); ++i) { - if (NodeHasURLs(selection_[i])) - return true; - } - return false; -} diff --git a/chrome/browser/views/bookmark_context_menu_controller_views.h b/chrome/browser/views/bookmark_context_menu_controller_views.h index 16b3dd2..73b54e6 100644 --- a/chrome/browser/views/bookmark_context_menu_controller_views.h +++ b/chrome/browser/views/bookmark_context_menu_controller_views.h @@ -6,88 +6,8 @@ #define CHROME_BROWSER_VIEWS_BOOKMARK_CONTEXT_MENU_CONTROLLER_VIEWS_H_ #pragma once -#include <vector> - -#include "base/basictypes.h" -#include "chrome/browser/bookmarks/base_bookmark_model_observer.h" -#include "gfx/native_widget_types.h" - -class Browser; -class PageNavigator; -class Profile; - -// An interface implemented by an object that performs actions on the actual -// menu for the controller. -class BookmarkContextMenuControllerViewsDelegate { - public: - virtual ~BookmarkContextMenuControllerViewsDelegate() {} - - // Closes the bookmark context menu. - virtual void CloseMenu() = 0; - - // Methods that add items to the underlying menu. - virtual void AddItem(int command_id) = 0; - virtual void AddItemWithStringId(int command_id, int string_id) = 0; - virtual void AddSeparator() = 0; - virtual void AddCheckboxItem(int command_id) = 0; - - // Sent before bookmarks are removed. - virtual void WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks) {} - - // Sent after bookmarks have been removed. - virtual void DidRemoveBookmarks() {} -}; - -// BookmarkContextMenuControllerViews creates and manages state for the context -// menu shown for any bookmark item. -class BookmarkContextMenuControllerViews : public BaseBookmarkModelObserver { - public: - // Creates the bookmark context menu. - // |profile| is used for opening urls as well as enabling 'open incognito'. - // |browser| is used to determine the PageNavigator and may be null. - // |navigator| is used if |browser| is null, and is provided for testing. - // |parent| is the parent for newly created nodes if |selection| is empty. - // |selection| is the nodes the context menu operates on and may be empty. - BookmarkContextMenuControllerViews( - gfx::NativeWindow parent_window, - BookmarkContextMenuControllerViewsDelegate* delegate, - Profile* profile, - PageNavigator* navigator, - const BookmarkNode* parent, - const std::vector<const BookmarkNode*>& selection); - virtual ~BookmarkContextMenuControllerViews(); - - void BuildMenu(); - - void ExecuteCommand(int id); - bool IsItemChecked(int id) const; - bool IsCommandEnabled(int id) const; - - // Accessors: - Profile* profile() const { return profile_; } - PageNavigator* navigator() const { return navigator_; } - - private: - // Overridden from BaseBookmarkModelObserver: - // Any change to the model results in closing the menu. - virtual void BookmarkModelChanged(); - - // Removes the observer from the model and NULLs out model_. - BookmarkModel* RemoveModelObserver(); - - // Returns true if selection_ has at least one bookmark of type url. - bool HasURLs() const; - - gfx::NativeWindow parent_window_; - BookmarkContextMenuControllerViewsDelegate* delegate_; - Profile* profile_; - PageNavigator* navigator_; - const BookmarkNode* parent_; - std::vector<const BookmarkNode*> selection_; - BookmarkModel* model_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenuControllerViews); -}; +#include "chrome/browser/ui/views/bookmark_context_menu_controller_views.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BOOKMARK_CONTEXT_MENU_CONTROLLER_VIEWS_H_ + diff --git a/chrome/browser/views/bookmark_context_menu_test.cc b/chrome/browser/views/bookmark_context_menu_test.cc deleted file mode 100644 index 8d3f89c..0000000 --- a/chrome/browser/views/bookmark_context_menu_test.cc +++ /dev/null @@ -1,311 +0,0 @@ -// 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 "base/scoped_ptr.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/browser/views/bookmark_context_menu.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/testing_profile.h" -#include "grit/generated_resources.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(OS_WIN) -#include "chrome/browser/views/bookmark_bar_view.h" -#endif - -namespace { - -// PageNavigator implementation that records the URL. -class TestingPageNavigator : public PageNavigator { - public: - virtual void OpenURL(const GURL& url, - const GURL& referrer, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - urls_.push_back(url); - } - - std::vector<GURL> urls_; -}; - -} // namespace - -class BookmarkContextMenuTest : public testing::Test { - public: - BookmarkContextMenuTest() - : ui_thread_(BrowserThread::UI, &message_loop_), - file_thread_(BrowserThread::FILE, &message_loop_), - model_(NULL) { - } - - virtual void SetUp() { -#if defined(OS_WIN) - BookmarkBarView::testing_ = true; -#endif - - profile_.reset(new TestingProfile()); - profile_->set_has_history_service(true); - profile_->CreateBookmarkModel(true); - profile_->BlockUntilBookmarkModelLoaded(); - - model_ = profile_->GetBookmarkModel(); - - AddTestData(); - } - - virtual void TearDown() { -#if defined(OS_WIN) - BookmarkBarView::testing_ = false; -#endif - - // Flush the message loop to make Purify happy. - message_loop_.RunAllPending(); - } - - protected: - MessageLoopForUI message_loop_; - BrowserThread ui_thread_; - BrowserThread file_thread_; - scoped_ptr<TestingProfile> profile_; - BookmarkModel* model_; - TestingPageNavigator navigator_; - - private: - // Creates the following structure: - // a - // F1 - // f1a - // F11 - // f11a - // F2 - // F3 - // F4 - // f4a - void AddTestData() { - std::string test_base = "file:///c:/tmp/"; - - model_->AddURL(model_->GetBookmarkBarNode(), 0, ASCIIToUTF16("a"), - GURL(test_base + "a")); - const BookmarkNode* f1 = - model_->AddGroup(model_->GetBookmarkBarNode(), 1, ASCIIToUTF16("F1")); - model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a")); - const BookmarkNode* f11 = model_->AddGroup(f1, 1, ASCIIToUTF16("F11")); - model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a")); - model_->AddGroup(model_->GetBookmarkBarNode(), 2, ASCIIToUTF16("F2")); - model_->AddGroup(model_->GetBookmarkBarNode(), 3, ASCIIToUTF16("F3")); - const BookmarkNode* f4 = - model_->AddGroup(model_->GetBookmarkBarNode(), 4, ASCIIToUTF16("F4")); - model_->AddURL(f4, 0, ASCIIToUTF16("f4a"), GURL(test_base + "f4a")); - } -}; - -// Tests Deleting from the menu. -TEST_F(BookmarkContextMenuTest, DeleteURL) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes); - GURL url = model_->GetBookmarkBarNode()->GetChild(0)->GetURL(); - ASSERT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - // Delete the URL. - controller.ExecuteCommand(IDS_BOOKMARK_BAR_REMOVE); - // Model shouldn't have URL anymore. - ASSERT_FALSE(model_->IsBookmarked(url)); -} - -// Tests open all on a folder with a couple of bookmarks. -TEST_F(BookmarkContextMenuTest, OpenAll) { - const BookmarkNode* folder = model_->GetBookmarkBarNode()->GetChild(1); - bookmark_utils::OpenAll( - NULL, profile_.get(), &navigator_, folder, NEW_FOREGROUND_TAB); - - // Should have navigated to F1's children. - ASSERT_EQ(static_cast<size_t>(2), navigator_.urls_.size()); - ASSERT_TRUE(folder->GetChild(0)->GetURL() == navigator_.urls_[0]); - ASSERT_TRUE(folder->GetChild(1)->GetChild(0)->GetURL() == - navigator_.urls_[1]); -} - -// Tests the enabled state of the menus when supplied an empty vector. -TEST_F(BookmarkContextMenuTest, EmptyNodes) { - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, model_->other_node(), - std::vector<const BookmarkNode*>()); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with a single -// url. -TEST_F(BookmarkContextMenuTest, SingleURL) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with multiple -// urls. -TEST_F(BookmarkContextMenuTest, MultipleURLs) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(1)->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied an vector with a single -// folder. -TEST_F(BookmarkContextMenuTest, SingleFolder) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with multiple -// folders, all of which are empty. -TEST_F(BookmarkContextMenuTest, MultipleEmptyFolders) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with multiple -// folders, some of which contain URLs. -TEST_F(BookmarkContextMenuTest, MultipleFoldersWithURLs) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(4)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of open incognito. -TEST_F(BookmarkContextMenuTest, DisableIncognito) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes); - profile_->set_off_the_record(true); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_INCOGNITO)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); -} - -// Tests that you can't remove/edit when showing the other node. -TEST_F(BookmarkContextMenuTest, DisabledItemsWithOtherNode) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->other_node()); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, nodes[0], nodes); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_EDIT)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); -} - -// Tests the enabled state of the menus when supplied an empty vector and null -// parent. -TEST_F(BookmarkContextMenuTest, EmptyNodesNullParent) { - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, std::vector<const BookmarkNode*>()); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -TEST_F(BookmarkContextMenuTest, CutCopyPasteNode) { - std::vector<const BookmarkNode*> nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - scoped_ptr<BookmarkContextMenu> controller(new BookmarkContextMenu( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes)); - EXPECT_TRUE(controller->IsCommandEnabled(IDS_COPY)); - EXPECT_TRUE(controller->IsCommandEnabled(IDS_CUT)); - - // Copy the URL. - controller->ExecuteCommand(IDS_COPY); - - controller.reset(new BookmarkContextMenu( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes)); - int old_count = model_->GetBookmarkBarNode()->GetChildCount(); - controller->ExecuteCommand(IDS_PASTE); - - ASSERT_TRUE(model_->GetBookmarkBarNode()->GetChild(1)->is_url()); - ASSERT_EQ(old_count + 1, model_->GetBookmarkBarNode()->GetChildCount()); - ASSERT_EQ(model_->GetBookmarkBarNode()->GetChild(0)->GetURL(), - model_->GetBookmarkBarNode()->GetChild(1)->GetURL()); - - controller.reset(new BookmarkContextMenu( - NULL, profile_.get(), NULL, nodes[0]->GetParent(), nodes)); - // Cut the URL. - controller->ExecuteCommand(IDS_CUT); - ASSERT_TRUE(model_->GetBookmarkBarNode()->GetChild(0)->is_url()); - ASSERT_TRUE(model_->GetBookmarkBarNode()->GetChild(1)->is_folder()); - ASSERT_EQ(old_count, model_->GetBookmarkBarNode()->GetChildCount()); -} - diff --git a/chrome/browser/views/bookmark_editor_view.cc b/chrome/browser/views/bookmark_editor_view.cc deleted file mode 100644 index 6f892a3..0000000 --- a/chrome/browser/views/bookmark_editor_view.cc +++ /dev/null @@ -1,581 +0,0 @@ -// 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/bookmark_editor_view.h" - -#include "app/l10n_util.h" -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/history/history.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/common/pref_names.h" -#include "googleurl/src/gurl.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/base/net_util.h" -#include "views/background.h" -#include "views/focus/focus_manager.h" -#include "views/grid_layout.h" -#include "views/controls/button/native_button.h" -#include "views/controls/label.h" -#include "views/controls/menu/menu_2.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -using views::Button; -using views::ColumnSet; -using views::GridLayout; -using views::Label; -using views::NativeButton; -using views::Textfield; - -// Background color of text field when URL is invalid. -static const SkColor kErrorColor = SkColorSetRGB(0xFF, 0xBC, 0xBC); - -// Preferred width of the tree. -static const int kTreeWidth = 300; - -// ID for various children. -static const int kNewGroupButtonID = 1002; - -// static -void BookmarkEditor::Show(HWND parent_hwnd, - Profile* profile, - const BookmarkNode* parent, - const EditDetails& details, - Configuration configuration) { - DCHECK(profile); - BookmarkEditorView* editor = - new BookmarkEditorView(profile, parent, details, configuration); - editor->Show(parent_hwnd); -} - -BookmarkEditorView::BookmarkEditorView( - Profile* profile, - const BookmarkNode* parent, - const EditDetails& details, - BookmarkEditor::Configuration configuration) - : profile_(profile), - tree_view_(NULL), - new_group_button_(NULL), - url_label_(NULL), - title_label_(NULL), - parent_(parent), - details_(details), - running_menu_for_root_(false), - show_tree_(configuration == SHOW_TREE) { - DCHECK(profile); - Init(); -} - -BookmarkEditorView::~BookmarkEditorView() { - // The tree model is deleted before the view. Reset the model otherwise the - // tree will reference a deleted model. - if (tree_view_) - tree_view_->SetModel(NULL); - bb_model_->RemoveObserver(this); -} - -bool BookmarkEditorView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - if (details_.type == EditDetails::NEW_FOLDER) - return !title_tf_.text().empty(); - - const GURL url(GetInputURL()); - return bb_model_->IsLoaded() && url.is_valid(); - } - return true; -} - -bool BookmarkEditorView::IsModal() const { - return true; -} - -std::wstring BookmarkEditorView::GetWindowTitle() const { - return l10n_util::GetString(IDS_BOOMARK_EDITOR_TITLE); -} - -bool BookmarkEditorView::Accept() { - if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) { - // The url is invalid, focus the url field. - url_tf_.SelectAll(); - url_tf_.RequestFocus(); - return false; - } - // Otherwise save changes and close the dialog box. - ApplyEdits(); - return true; -} - -bool BookmarkEditorView::AreAcceleratorsEnabled( - MessageBoxFlags::DialogButton button) { - return !show_tree_ || !tree_view_->GetEditingNode(); -} - -views::View* BookmarkEditorView::GetContentsView() { - return this; -} - -void BookmarkEditorView::Layout() { - // Let the grid layout manager lay out most of the dialog... - GetLayoutManager()->Layout(this); - - if (!show_tree_) - return; - - // Manually lay out the New Folder button in the same row as the OK/Cancel - // buttons... - gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false); - gfx::Size prefsize = new_group_button_->GetPreferredSize(); - int button_y = - parent_bounds.bottom() - prefsize.height() - kButtonVEdgeMargin; - new_group_button_->SetBounds(kPanelHorizMargin, button_y, prefsize.width(), - prefsize.height()); -} - -gfx::Size BookmarkEditorView::GetPreferredSize() { - if (!show_tree_) - return views::View::GetPreferredSize(); - - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_EDITBOOKMARK_DIALOG_WIDTH_CHARS, - IDS_EDITBOOKMARK_DIALOG_HEIGHT_LINES)); -} - -void BookmarkEditorView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (show_tree_ && child == this) { - // Add and remove the New Folder button from the ClientView's hierarchy. - if (is_add) { - parent->AddChildView(new_group_button_.get()); - } else { - parent->RemoveChildView(new_group_button_.get()); - } - } -} - -void BookmarkEditorView::OnTreeViewSelectionChanged( - views::TreeView* tree_view) { -} - -bool BookmarkEditorView::CanEdit(views::TreeView* tree_view, - TreeModelNode* node) { - // Only allow editting of children of the bookmark bar node and other node. - EditorNode* bb_node = tree_model_->AsNode(node); - return (bb_node->GetParent() && bb_node->GetParent()->GetParent()); -} - -void BookmarkEditorView::ContentsChanged(Textfield* sender, - const std::wstring& new_contents) { - UserInputChanged(); -} - -void BookmarkEditorView::ButtonPressed( - Button* sender, const views::Event& event) { - DCHECK(sender); - switch (sender->GetID()) { - case kNewGroupButtonID: - NewGroup(); - break; - - default: - NOTREACHED(); - } -} - -bool BookmarkEditorView::IsCommandIdChecked(int command_id) const { - return false; -} - -bool BookmarkEditorView::IsCommandIdEnabled(int command_id) const { - return (command_id != IDS_EDIT || !running_menu_for_root_); -} - -bool BookmarkEditorView::GetAcceleratorForCommandId( - int command_id, - menus::Accelerator* accelerator) { - return GetWidget()->GetAccelerator(command_id, accelerator); -} - -void BookmarkEditorView::ExecuteCommand(int command_id) { - DCHECK(tree_view_->GetSelectedNode()); - if (command_id == IDS_EDIT) { - tree_view_->StartEditing(tree_view_->GetSelectedNode()); - } else { - DCHECK(command_id == IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM); - NewGroup(); - } -} - -void BookmarkEditorView::Show(HWND parent_hwnd) { - views::Window::CreateChromeWindow(parent_hwnd, gfx::Rect(), this); - UserInputChanged(); - if (show_tree_ && bb_model_->IsLoaded()) - ExpandAndSelect(); - window()->Show(); - // Select all the text in the name Textfield. - title_tf_.SelectAll(); - // Give focus to the name Textfield. - title_tf_.RequestFocus(); -} - -void BookmarkEditorView::Close() { - DCHECK(window()); - window()->Close(); -} - -void BookmarkEditorView::ShowContextMenu(View* source, - const gfx::Point& p, - bool is_mouse_gesture) { - DCHECK(source == tree_view_); - if (!tree_view_->GetSelectedNode()) - return; - running_menu_for_root_ = - (tree_model_->GetParent(tree_view_->GetSelectedNode()) == - tree_model_->GetRoot()); - if (!context_menu_contents_.get()) { - context_menu_contents_.reset(new menus::SimpleMenuModel(this)); - context_menu_contents_->AddItemWithStringId(IDS_EDIT, IDS_EDIT); - context_menu_contents_->AddItemWithStringId( - IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM, - IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM); - context_menu_.reset(new views::Menu2(context_menu_contents_.get())); - } - context_menu_->RunContextMenuAt(p); -} - -void BookmarkEditorView::Init() { - bb_model_ = profile_->GetBookmarkModel(); - DCHECK(bb_model_); - bb_model_->AddObserver(this); - - url_tf_.set_parent_owned(false); - title_tf_.set_parent_owned(false); - - std::wstring title; - if (details_.type == EditDetails::EXISTING_NODE) - title = details_.existing_node->GetTitle(); - else if (details_.type == EditDetails::NEW_FOLDER) - title = l10n_util::GetString(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME); - title_tf_.SetText(title); - title_tf_.SetController(this); - - title_label_ = new views::Label( - l10n_util::GetString(IDS_BOOMARK_EDITOR_NAME_LABEL)); - title_tf_.SetAccessibleName(title_label_->GetText()); - - string16 url_text; - if (details_.type == EditDetails::EXISTING_NODE) { - std::string languages = profile_ - ? profile_->GetPrefs()->GetString(prefs::kAcceptLanguages) - : std::string(); - // Because this gets parsed by FixupURL(), it's safe to omit the scheme or - // trailing slash, and unescape most characters, but we need to not drop any - // username/password, or unescape anything that changes the meaning. - url_text = net::FormatUrl(details_.existing_node->GetURL(), languages, - net::kFormatUrlOmitAll & ~net::kFormatUrlOmitUsernamePassword, - UnescapeRule::SPACES, NULL, NULL, NULL); - } - url_tf_.SetText(UTF16ToWide(url_text)); - url_tf_.SetController(this); - - url_label_ = new views::Label( - l10n_util::GetString(IDS_BOOMARK_EDITOR_URL_LABEL)); - url_tf_.SetAccessibleName(url_label_->GetText()); - - if (show_tree_) { - tree_view_ = new views::TreeView(); - new_group_button_.reset(new views::NativeButton( - this, l10n_util::GetString(IDS_BOOMARK_EDITOR_NEW_FOLDER_BUTTON))); - new_group_button_->set_parent_owned(false); - tree_view_->SetContextMenuController(this); - - tree_view_->SetRootShown(false); - new_group_button_->SetEnabled(false); - new_group_button_->SetID(kNewGroupButtonID); - } - - // Yummy layout code. - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int labels_column_set_id = 0; - const int single_column_view_set_id = 1; - const int buttons_column_set_id = 2; - - ColumnSet* column_set = layout->AddColumnSet(labels_column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::FIXED, kTreeWidth, 0); - - column_set = layout->AddColumnSet(buttons_column_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(1, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0, - GridLayout::USE_PREF, 0, 0); - column_set->LinkColumnSizes(0, 2, 4, -1); - - layout->StartRow(0, labels_column_set_id); - - layout->AddView(title_label_); - layout->AddView(&title_tf_); - - if (details_.type != EditDetails::NEW_FOLDER) { - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, labels_column_set_id); - layout->AddView(url_label_); - layout->AddView(&url_tf_); - } - - if (show_tree_) { - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(1, single_column_view_set_id); - layout->AddView(tree_view_); - } - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - if (!show_tree_ || bb_model_->IsLoaded()) - Reset(); -} - -void BookmarkEditorView::BookmarkNodeMoved(BookmarkModel* model, - const BookmarkNode* old_parent, - int old_index, - const BookmarkNode* new_parent, - int new_index) { - Reset(); -} - -void BookmarkEditorView::BookmarkNodeAdded(BookmarkModel* model, - const BookmarkNode* parent, - int index) { - Reset(); -} - -void BookmarkEditorView::BookmarkNodeRemoved(BookmarkModel* model, - const BookmarkNode* parent, - int index, - const BookmarkNode* node) { - if ((details_.type == EditDetails::EXISTING_NODE && - details_.existing_node->HasAncestor(node)) || - (parent_ && parent_->HasAncestor(node))) { - // The node, or its parent was removed. Close the dialog. - window()->Close(); - } else { - Reset(); - } -} - -void BookmarkEditorView::BookmarkNodeChildrenReordered( - BookmarkModel* model, const BookmarkNode* node) { - Reset(); -} - -void BookmarkEditorView::Reset() { - if (!show_tree_) { - if (GetParent()) - UserInputChanged(); - return; - } - - new_group_button_->SetEnabled(true); - - // Do this first, otherwise when we invoke SetModel with the real one - // tree_view will try to invoke something on the model we just deleted. - tree_view_->SetModel(NULL); - - EditorNode* root_node = CreateRootNode(); - tree_model_.reset(new EditorTreeModel(root_node)); - - tree_view_->SetModel(tree_model_.get()); - tree_view_->SetController(this); - - context_menu_.reset(); - - if (GetParent()) - ExpandAndSelect(); -} -GURL BookmarkEditorView::GetInputURL() const { - return URLFixerUpper::FixupURL(UTF16ToUTF8(url_tf_.text()), std::string()); -} - -std::wstring BookmarkEditorView::GetInputTitle() const { - return title_tf_.text(); -} - -void BookmarkEditorView::UserInputChanged() { - const GURL url(GetInputURL()); - if (!url.is_valid()) - url_tf_.SetBackgroundColor(kErrorColor); - else - url_tf_.UseDefaultBackgroundColor(); - GetDialogClientView()->UpdateDialogButtons(); -} - -void BookmarkEditorView::NewGroup() { - // Create a new entry parented to the selected item, or the bookmark - // bar if nothing is selected. - EditorNode* parent = tree_model_->AsNode(tree_view_->GetSelectedNode()); - if (!parent) { - NOTREACHED(); - return; - } - - tree_view_->StartEditing(AddNewGroup(parent)); -} - -BookmarkEditorView::EditorNode* BookmarkEditorView::AddNewGroup( - EditorNode* parent) { - EditorNode* new_node = new EditorNode(); - new_node->SetTitle( - l10n_util::GetStringUTF16(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME)); - new_node->value = 0; - // new_node is now owned by parent. - tree_model_->Add(parent, parent->GetChildCount(), new_node); - return new_node; -} - -void BookmarkEditorView::ExpandAndSelect() { - tree_view_->ExpandAll(); - - const BookmarkNode* to_select = parent_; - if (details_.type == EditDetails::EXISTING_NODE) - to_select = details_.existing_node->GetParent(); - int64 group_id_to_select = to_select->id(); - EditorNode* b_node = - FindNodeWithID(tree_model_->GetRoot(), group_id_to_select); - if (!b_node) - b_node = tree_model_->GetRoot()->GetChild(0); // Bookmark bar node. - - tree_view_->SetSelectedNode(b_node); -} - -BookmarkEditorView::EditorNode* BookmarkEditorView::CreateRootNode() { - EditorNode* root_node = new EditorNode(std::wstring(), 0); - const BookmarkNode* bb_root_node = bb_model_->root_node(); - CreateNodes(bb_root_node, root_node); - DCHECK(root_node->GetChildCount() == 2); - DCHECK(bb_root_node->GetChild(0)->type() == BookmarkNode::BOOKMARK_BAR); - DCHECK(bb_root_node->GetChild(1)->type() == BookmarkNode::OTHER_NODE); - return root_node; -} - -void BookmarkEditorView::CreateNodes(const BookmarkNode* bb_node, - BookmarkEditorView::EditorNode* b_node) { - for (int i = 0; i < bb_node->GetChildCount(); ++i) { - const BookmarkNode* child_bb_node = bb_node->GetChild(i); - if (child_bb_node->is_folder()) { - EditorNode* new_b_node = - new EditorNode(WideToUTF16(child_bb_node->GetTitle()), - child_bb_node->id()); - b_node->Add(b_node->GetChildCount(), new_b_node); - CreateNodes(child_bb_node, new_b_node); - } - } -} - -BookmarkEditorView::EditorNode* BookmarkEditorView::FindNodeWithID( - BookmarkEditorView::EditorNode* node, - int64 id) { - if (node->value == id) - return node; - for (int i = 0; i < node->GetChildCount(); ++i) { - EditorNode* result = FindNodeWithID(node->GetChild(i), id); - if (result) - return result; - } - return NULL; -} - -void BookmarkEditorView::ApplyEdits() { - DCHECK(bb_model_->IsLoaded()); - - EditorNode* parent = show_tree_ ? - tree_model_->AsNode(tree_view_->GetSelectedNode()) : NULL; - if (show_tree_ && !parent) { - NOTREACHED(); - return; - } - ApplyEdits(parent); -} - -void BookmarkEditorView::ApplyEdits(EditorNode* parent) { - DCHECK(!show_tree_ || parent); - - // We're going to apply edits to the bookmark bar model, which will call us - // back. Normally when a structural edit occurs we reset the tree model. - // We don't want to do that here, so we remove ourselves as an observer. - bb_model_->RemoveObserver(this); - - GURL new_url(GetInputURL()); - string16 new_title(WideToUTF16Hack(GetInputTitle())); - - if (!show_tree_) { - bookmark_utils::ApplyEditsWithNoGroupChange( - bb_model_, parent_, details_, new_title, new_url); - return; - } - - // Create the new groups and update the titles. - const BookmarkNode* new_parent = NULL; - ApplyNameChangesAndCreateNewGroups( - bb_model_->root_node(), tree_model_->GetRoot(), parent, &new_parent); - - bookmark_utils::ApplyEditsWithPossibleGroupChange( - bb_model_, new_parent, details_, new_title, new_url); -} - -void BookmarkEditorView::ApplyNameChangesAndCreateNewGroups( - const BookmarkNode* bb_node, - BookmarkEditorView::EditorNode* b_node, - BookmarkEditorView::EditorNode* parent_b_node, - const BookmarkNode** parent_bb_node) { - if (parent_b_node == b_node) - *parent_bb_node = bb_node; - for (int i = 0; i < b_node->GetChildCount(); ++i) { - EditorNode* child_b_node = b_node->GetChild(i); - const BookmarkNode* child_bb_node = NULL; - if (child_b_node->value == 0) { - // New group. - child_bb_node = bb_model_->AddGroup(bb_node, - bb_node->GetChildCount(), child_b_node->GetTitle()); - } else { - // Existing node, reset the title (BBModel ignores changes if the title - // is the same). - for (int j = 0; j < bb_node->GetChildCount(); ++j) { - const BookmarkNode* node = bb_node->GetChild(j); - if (node->is_folder() && node->id() == child_b_node->value) { - child_bb_node = node; - break; - } - } - DCHECK(child_bb_node); - bb_model_->SetTitle(child_bb_node, child_b_node->GetTitle()); - } - ApplyNameChangesAndCreateNewGroups(child_bb_node, child_b_node, - parent_b_node, parent_bb_node); - } -} diff --git a/chrome/browser/views/bookmark_editor_view.h b/chrome/browser/views/bookmark_editor_view.h index 6b11439..fca0aab 100644 --- a/chrome/browser/views/bookmark_editor_view.h +++ b/chrome/browser/views/bookmark_editor_view.h @@ -6,260 +6,8 @@ #define CHROME_BROWSER_VIEWS_BOOKMARK_EDITOR_VIEW_H_ #pragma once -#include "app/menus/simple_menu_model.h" -#include "app/tree_node_model.h" -#include "base/string16.h" -#include "chrome/browser/bookmarks/bookmark_editor.h" -#include "chrome/browser/bookmarks/bookmark_model_observer.h" -#include "views/controls/button/button.h" -#include "views/controls/textfield/textfield.h" -#include "views/controls/tree/tree_view.h" -#include "views/window/dialog_delegate.h" -#include "testing/gtest/include/gtest/gtest_prod.h" - -namespace views { -class Label; -class Menu2; -class NativeButton; -class Window; -} - -class BookmarkEditorViewTest; -class GURL; -class Menu; -class Profile; - -// View that allows the user to edit a bookmark/starred URL. The user can -// change the URL, title and where the bookmark appears as well as adding -// new groups and changing the name of other groups. The editor is used for -// both editing a url bookmark, as well as editing a folder bookmark when -// created from 'Bookmark all tabs'. -// -// Edits are applied to the BookmarkModel when the user presses 'OK'. -// -// To use BookmarkEditorView invoke the static show method. - -class BookmarkEditorView : public BookmarkEditor, - public views::View, - public views::ButtonListener, - public views::TreeViewController, - public views::DialogDelegate, - public views::Textfield::Controller, - public views::ContextMenuController, - public menus::SimpleMenuModel::Delegate, - public BookmarkModelObserver { - public: - // Type of node in the tree. Public purely for testing. - typedef TreeNodeWithValue<int64> EditorNode; - - // Model for the TreeView. Trivial subclass that doesn't allow titles with - // empty strings. Public purely for testing. - class EditorTreeModel : public TreeNodeModel<EditorNode> { - public: - explicit EditorTreeModel(EditorNode* root) - : TreeNodeModel<EditorNode>(root) {} - - virtual void SetTitle(TreeModelNode* node, - const string16& title) { - if (!title.empty()) - TreeNodeModel::SetTitle(node, title); - } - - private: - DISALLOW_COPY_AND_ASSIGN(EditorTreeModel); - }; - - BookmarkEditorView(Profile* profile, - const BookmarkNode* parent, - const EditDetails& details, - BookmarkEditor::Configuration configuration); - - virtual ~BookmarkEditorView(); - - // DialogDelegate methods: - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool Accept(); - virtual bool AreAcceleratorsEnabled(MessageBoxFlags::DialogButton button); - virtual views::View* GetContentsView(); - - // View methods. - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - // TreeViewObserver methods. - virtual void OnTreeViewSelectionChanged(views::TreeView* tree_view); - virtual bool CanEdit(views::TreeView* tree_view, TreeModelNode* node); - - // Textfield::Controller methods. - virtual void ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke&) { - return false; - } - - // NativeButton. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // menus::SimpleMenuModel::Delegate. - virtual bool IsCommandIdChecked(int command_id) const; - virtual bool IsCommandIdEnabled(int command_id) const; - virtual bool GetAcceleratorForCommandId(int command_id, - menus::Accelerator* accelerator); - virtual void ExecuteCommand(int command_id); - - // Creates a Window and adds the BookmarkEditorView to it. When the window is - // closed the BookmarkEditorView is deleted. - void Show(HWND parent_hwnd); - - // Closes the dialog. - void Close(); - - // Shows the context menu. - virtual void ShowContextMenu(View* source, - const gfx::Point& p, - bool is_mouse_gesture); - - private: - friend class BookmarkEditorViewTest; - - // Creates the necessary sub-views, configures them, adds them to the layout, - // and requests the entries to display from the database. - void Init(); - - // BookmarkModel observer methods. Any structural change results in - // resetting the tree model. - virtual void Loaded(BookmarkModel* model) { } - virtual void BookmarkNodeMoved(BookmarkModel* model, - const BookmarkNode* old_parent, - int old_index, - const BookmarkNode* new_parent, - int new_index); - virtual void BookmarkNodeAdded(BookmarkModel* model, - const BookmarkNode* parent, - int index); - virtual void BookmarkNodeRemoved(BookmarkModel* model, - const BookmarkNode* parent, - int index, - const BookmarkNode* node); - virtual void BookmarkNodeChanged(BookmarkModel* model, - const BookmarkNode* node) {} - virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, - const BookmarkNode* node); - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, - const BookmarkNode* node) {} - - // Resets the model of the tree and updates the various buttons appropriately. - void Reset(); - - // Expands all the nodes in the tree and selects the parent node of the - // url we're editing or the most recent parent if the url being editted isn't - // starred. - void ExpandAndSelect(); - - // Creates a returns the new root node. This invokes CreateNodes to do - // the real work. - EditorNode* CreateRootNode(); - - // Adds and creates a child node in b_node for all children of bb_node that - // are groups. - void CreateNodes(const BookmarkNode* bb_node, EditorNode* b_node); - - // Returns the node with the specified id, or NULL if one can't be found. - EditorNode* FindNodeWithID(BookmarkEditorView::EditorNode* node, int64 id); - - // Invokes ApplyEdits with the selected node. - void ApplyEdits(); - - // Applies the edits done by the user. |parent| gives the parent of the URL - // being edited. - void ApplyEdits(EditorNode* parent); - - // Recursively adds newly created groups and sets the title of nodes to - // match the user edited title. - // - // bb_node gives the BookmarkNode the edits are to be applied to, with b_node - // the source of the edits. - // - // If b_node == parent_b_node, parent_bb_node is set to bb_node. This is - // used to determine the new BookmarkNode parent based on the EditorNode - // parent. - void ApplyNameChangesAndCreateNewGroups( - const BookmarkNode* bb_node, - BookmarkEditorView::EditorNode* b_node, - BookmarkEditorView::EditorNode* parent_b_node, - const BookmarkNode** parent_bb_node); - - // Returns the current url the user has input. - GURL GetInputURL() const; - - // Returns the title the user has input. - std::wstring GetInputTitle() const; - - // Invoked when the url or title has possibly changed. Updates the background - // of Textfields and ok button appropriately. - void UserInputChanged(); - - // Creates a new group as a child of the selected node. If no node is - // selected, the new group is added as a child of the bookmark node. Starts - // editing on the new gorup as well. - void NewGroup(); - - // Creates a new EditorNode as the last child of parent. The new node is - // added to the model and returned. This does NOT start editing. This is used - // internally by NewGroup and broken into a separate method for testing. - EditorNode* AddNewGroup(EditorNode* parent); - - // Profile the entry is from. - Profile* profile_; - - // Model driving the TreeView. - scoped_ptr<EditorTreeModel> tree_model_; - - // Displays star groups. - views::TreeView* tree_view_; - - // Used to create a new group. - scoped_ptr<views::NativeButton> new_group_button_; - - // The label for the url text field. - views::Label* url_label_; - - // Used for editing the URL. - views::Textfield url_tf_; - - // The label for the title text field. - views::Label* title_label_; - - // Used for editing the title. - views::Textfield title_tf_; - - // Initial parent to select. Is only used if |details_.existing_node| is - // NULL. - const BookmarkNode* parent_; - - const EditDetails details_; - - // The context menu. - scoped_ptr<menus::SimpleMenuModel> context_menu_contents_; - scoped_ptr<views::Menu2> context_menu_; - - // Mode used to create nodes from. - BookmarkModel* bb_model_; - - // If true, we're running the menu for the bookmark bar or other bookmarks - // nodes. - bool running_menu_for_root_; - - // Is the tree shown? - bool show_tree_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkEditorView); -}; +#include "chrome/browser/ui/views/bookmark_editor_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BOOKMARK_EDITOR_VIEW_H_ + diff --git a/chrome/browser/views/bookmark_editor_view_unittest.cc b/chrome/browser/views/bookmark_editor_view_unittest.cc deleted file mode 100644 index afeeb4e..0000000 --- a/chrome/browser/views/bookmark_editor_view_unittest.cc +++ /dev/null @@ -1,366 +0,0 @@ -// 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 "base/message_loop.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/bookmark_editor_view.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/testing_profile.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::Time; -using base::TimeDelta; - -// Base class for bookmark editor tests. Creates a BookmarkModel and populates -// it with test data. -class BookmarkEditorViewTest : public testing::Test { - public: - BookmarkEditorViewTest() - : model_(NULL), - ui_thread_(BrowserThread::UI, &message_loop_), - file_thread_(BrowserThread::FILE, &message_loop_) { - } - - virtual void SetUp() { - profile_.reset(new TestingProfile()); - profile_->set_has_history_service(true); - profile_->CreateBookmarkModel(true); - - model_ = profile_->GetBookmarkModel(); - profile_->BlockUntilBookmarkModelLoaded(); - - AddTestData(); - } - - virtual void TearDown() { - } - - protected: - MessageLoopForUI message_loop_; - BookmarkModel* model_; - scoped_ptr<TestingProfile> profile_; - - std::string base_path() const { return "file:///c:/tmp/"; } - - const BookmarkNode* GetNode(const std::string& name) { - return model_->GetMostRecentlyAddedNodeForURL(GURL(base_path() + name)); - } - - BookmarkNode* GetMutableNode(const std::string& name) { - return const_cast<BookmarkNode*>(GetNode(name)); - } - - BookmarkEditorView::EditorTreeModel* editor_tree_model() { - return editor_->tree_model_.get(); - } - - void CreateEditor(Profile* profile, - const BookmarkNode* parent, - const BookmarkEditor::EditDetails& details, - BookmarkEditor::Configuration configuration) { - editor_.reset(new BookmarkEditorView(profile, parent, details, - configuration)); - } - - void SetTitleText(const std::wstring& title) { - editor_->title_tf_.SetText(title); - } - - void SetURLText(const std::wstring& text) { - editor_->url_tf_.SetText(text); - } - - void ApplyEdits(BookmarkEditorView::EditorNode* node) { - editor_->ApplyEdits(node); - } - - BookmarkEditorView::EditorNode* AddNewGroup( - BookmarkEditorView::EditorNode* parent) { - return editor_->AddNewGroup(parent); - } - - bool URLTFHasParent() { - return editor_->url_tf_.GetParent(); - } - - private: - // Creates the following structure: - // bookmark bar node - // a - // F1 - // f1a - // F11 - // f11a - // F2 - // other node - // oa - // OF1 - // of1a - void AddTestData() { - std::string test_base = base_path(); - - model_->AddURL(model_->GetBookmarkBarNode(), 0, ASCIIToUTF16("a"), - GURL(test_base + "a")); - const BookmarkNode* f1 = - model_->AddGroup(model_->GetBookmarkBarNode(), 1, ASCIIToUTF16("F1")); - model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a")); - const BookmarkNode* f11 = model_->AddGroup(f1, 1, ASCIIToUTF16("F11")); - model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a")); - model_->AddGroup(model_->GetBookmarkBarNode(), 2, ASCIIToUTF16("F2")); - - // Children of the other node. - model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"), - GURL(test_base + "oa")); - const BookmarkNode* of1 = - model_->AddGroup(model_->other_node(), 1, ASCIIToUTF16("OF1")); - model_->AddURL(of1, 0, ASCIIToUTF16("of1a"), GURL(test_base + "of1a")); - } - - scoped_ptr<BookmarkEditorView> editor_; - BrowserThread ui_thread_; - BrowserThread file_thread_; -}; - -// Makes sure the tree model matches that of the bookmark bar model. -TEST_F(BookmarkEditorViewTest, ModelsMatch) { - CreateEditor(profile_.get(), NULL, BookmarkEditor::EditDetails(), - BookmarkEditorView::SHOW_TREE); - BookmarkEditorView::EditorNode* editor_root = editor_tree_model()->GetRoot(); - // The root should have two children, one for the bookmark bar node, - // the other for the 'other bookmarks' folder. - ASSERT_EQ(2, editor_root->GetChildCount()); - - BookmarkEditorView::EditorNode* bb_node = editor_root->GetChild(0); - // The root should have 2 nodes: folder F1 and F2. - ASSERT_EQ(2, bb_node->GetChildCount()); - ASSERT_EQ(ASCIIToUTF16("F1"), bb_node->GetChild(0)->GetTitle()); - ASSERT_EQ(ASCIIToUTF16("F2"), bb_node->GetChild(1)->GetTitle()); - - // F1 should have one child, F11 - ASSERT_EQ(1, bb_node->GetChild(0)->GetChildCount()); - ASSERT_EQ(ASCIIToUTF16("F11"), bb_node->GetChild(0)->GetChild(0)->GetTitle()); - - BookmarkEditorView::EditorNode* other_node = editor_root->GetChild(1); - // Other node should have one child (OF1). - ASSERT_EQ(1, other_node->GetChildCount()); - ASSERT_EQ(ASCIIToUTF16("OF1"), other_node->GetChild(0)->GetTitle()); -} - -// Changes the title and makes sure parent/visual order doesn't change. -TEST_F(BookmarkEditorViewTest, EditTitleKeepsPosition) { - CreateEditor(profile_.get(), NULL, BookmarkEditor::EditDetails(GetNode("a")), - BookmarkEditorView::SHOW_TREE); - SetTitleText(L"new_a"); - - ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0)); - - const BookmarkNode* bb_node = - profile_->GetBookmarkModel()->GetBookmarkBarNode(); - ASSERT_EQ(ASCIIToUTF16("new_a"), bb_node->GetChild(0)->GetTitle()); - // The URL shouldn't have changed. - ASSERT_TRUE(GURL(base_path() + "a") == bb_node->GetChild(0)->GetURL()); -} - -// Changes the url and makes sure parent/visual order doesn't change. -TEST_F(BookmarkEditorViewTest, EditURLKeepsPosition) { - Time node_time = Time::Now() + TimeDelta::FromDays(2); - GetMutableNode("a")->set_date_added(node_time); - CreateEditor(profile_.get(), NULL, BookmarkEditor::EditDetails(GetNode("a")), - BookmarkEditorView::SHOW_TREE); - - SetURLText(UTF8ToWide(GURL(base_path() + "new_a").spec())); - - ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0)); - - const BookmarkNode* bb_node = - profile_->GetBookmarkModel()->GetBookmarkBarNode(); - ASSERT_EQ(ASCIIToUTF16("a"), bb_node->GetChild(0)->GetTitle()); - // The URL should have changed. - ASSERT_TRUE(GURL(base_path() + "new_a") == bb_node->GetChild(0)->GetURL()); - ASSERT_TRUE(node_time == bb_node->GetChild(0)->date_added()); -} - -// Moves 'a' to be a child of the other node. -TEST_F(BookmarkEditorViewTest, ChangeParent) { - CreateEditor(profile_.get(), NULL, BookmarkEditor::EditDetails(GetNode("a")), - BookmarkEditorView::SHOW_TREE); - - ApplyEdits(editor_tree_model()->GetRoot()->GetChild(1)); - - const BookmarkNode* other_node = profile_->GetBookmarkModel()->other_node(); - ASSERT_EQ(ASCIIToUTF16("a"), other_node->GetChild(2)->GetTitle()); - ASSERT_TRUE(GURL(base_path() + "a") == other_node->GetChild(2)->GetURL()); -} - -// Moves 'a' to be a child of the other node and changes its url to new_a. -TEST_F(BookmarkEditorViewTest, ChangeParentAndURL) { - Time node_time = Time::Now() + TimeDelta::FromDays(2); - GetMutableNode("a")->set_date_added(node_time); - CreateEditor(profile_.get(), NULL, BookmarkEditor::EditDetails(GetNode("a")), - BookmarkEditorView::SHOW_TREE); - - SetURLText(UTF8ToWide(GURL(base_path() + "new_a").spec())); - - ApplyEdits(editor_tree_model()->GetRoot()->GetChild(1)); - - const BookmarkNode* other_node = profile_->GetBookmarkModel()->other_node(); - ASSERT_EQ(ASCIIToUTF16("a"), other_node->GetChild(2)->GetTitle()); - ASSERT_TRUE(GURL(base_path() + "new_a") == other_node->GetChild(2)->GetURL()); - ASSERT_TRUE(node_time == other_node->GetChild(2)->date_added()); -} - -// Creates a new folder and moves a node to it. -TEST_F(BookmarkEditorViewTest, MoveToNewParent) { - CreateEditor(profile_.get(), NULL, BookmarkEditor::EditDetails(GetNode("a")), - BookmarkEditorView::SHOW_TREE); - - // Create two nodes: "F21" as a child of "F2" and "F211" as a child of "F21". - BookmarkEditorView::EditorNode* f2 = - editor_tree_model()->GetRoot()->GetChild(0)->GetChild(1); - BookmarkEditorView::EditorNode* f21 = AddNewGroup(f2); - f21->SetTitle(ASCIIToUTF16("F21")); - BookmarkEditorView::EditorNode* f211 = AddNewGroup(f21); - f211->SetTitle(ASCIIToUTF16("F211")); - - // Parent the node to "F21". - ApplyEdits(f2); - - const BookmarkNode* bb_node = - profile_->GetBookmarkModel()->GetBookmarkBarNode(); - const BookmarkNode* mf2 = bb_node->GetChild(1); - - // F2 in the model should have two children now: F21 and the node edited. - ASSERT_EQ(2, mf2->GetChildCount()); - // F21 should be first. - ASSERT_EQ(ASCIIToUTF16("F21"), mf2->GetChild(0)->GetTitle()); - // Then a. - ASSERT_EQ(ASCIIToUTF16("a"), mf2->GetChild(1)->GetTitle()); - - // F21 should have one child, F211. - const BookmarkNode* mf21 = mf2->GetChild(0); - ASSERT_EQ(1, mf21->GetChildCount()); - ASSERT_EQ(ASCIIToUTF16("F211"), mf21->GetChild(0)->GetTitle()); -} - -// Brings up the editor, creating a new URL on the bookmark bar. -TEST_F(BookmarkEditorViewTest, NewURL) { - CreateEditor(profile_.get(), NULL, BookmarkEditor::EditDetails(), - BookmarkEditorView::SHOW_TREE); - - SetURLText(UTF8ToWide(GURL(base_path() + "a").spec())); - SetTitleText(L"new_a"); - - ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0)); - - const BookmarkNode* bb_node = - profile_->GetBookmarkModel()->GetBookmarkBarNode(); - ASSERT_EQ(4, bb_node->GetChildCount()); - - const BookmarkNode* new_node = bb_node->GetChild(3); - - EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle()); - EXPECT_TRUE(GURL(base_path() + "a") == new_node->GetURL()); -} - -// Brings up the editor with no tree and modifies the url. -TEST_F(BookmarkEditorViewTest, ChangeURLNoTree) { - CreateEditor(profile_.get(), NULL, - BookmarkEditor::EditDetails(model_->other_node()->GetChild(0)), - BookmarkEditorView::NO_TREE); - - SetURLText(UTF8ToWide(GURL(base_path() + "a").spec())); - SetTitleText(L"new_a"); - - ApplyEdits(NULL); - - const BookmarkNode* other_node = profile_->GetBookmarkModel()->other_node(); - ASSERT_EQ(2, other_node->GetChildCount()); - - const BookmarkNode* new_node = other_node->GetChild(0); - - EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle()); - EXPECT_TRUE(GURL(base_path() + "a") == new_node->GetURL()); -} - -// Brings up the editor with no tree and modifies only the title. -TEST_F(BookmarkEditorViewTest, ChangeTitleNoTree) { - CreateEditor(profile_.get(), NULL, - BookmarkEditor::EditDetails(model_->other_node()->GetChild(0)), - BookmarkEditorView::NO_TREE); - - SetTitleText(L"new_a"); - - ApplyEdits(NULL); - - const BookmarkNode* other_node = profile_->GetBookmarkModel()->other_node(); - ASSERT_EQ(2, other_node->GetChildCount()); - - const BookmarkNode* new_node = other_node->GetChild(0); - - EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle()); -} - -// Creates a new folder. -TEST_F(BookmarkEditorViewTest, NewFolder) { - BookmarkEditor::EditDetails details; - details.urls.push_back(std::make_pair(GURL(base_path() + "x"), - ASCIIToUTF16("z"))); - details.type = BookmarkEditor::EditDetails::NEW_FOLDER; - CreateEditor(profile_.get(), model_->GetBookmarkBarNode(), - details, BookmarkEditorView::SHOW_TREE); - - // The url field shouldn't be visible. - EXPECT_FALSE(URLTFHasParent()); - SetTitleText(L"new_F"); - - ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0)); - - // Make sure the folder was created. - ASSERT_EQ(4, model_->GetBookmarkBarNode()->GetChildCount()); - const BookmarkNode* new_node = - model_->GetBookmarkBarNode()->GetChild(3); - EXPECT_EQ(BookmarkNode::FOLDER, new_node->type()); - EXPECT_EQ(ASCIIToUTF16("new_F"), new_node->GetTitle()); - // The node should have one child. - ASSERT_EQ(1, new_node->GetChildCount()); - const BookmarkNode* new_child = new_node->GetChild(0); - // Make sure the child url/title match. - EXPECT_EQ(BookmarkNode::URL, new_child->type()); - EXPECT_EQ(WideToUTF16Hack(details.urls[0].second), new_child->GetTitle()); - EXPECT_EQ(details.urls[0].first, new_child->GetURL()); -} - -// Creates a new folder and selects a different folder for the folder to appear -// in then the editor is initially created showing. -TEST_F(BookmarkEditorViewTest, MoveFolder) { - BookmarkEditor::EditDetails details; - details.urls.push_back(std::make_pair(GURL(base_path() + "x"), - ASCIIToUTF16("z"))); - details.type = BookmarkEditor::EditDetails::NEW_FOLDER; - CreateEditor(profile_.get(), model_->GetBookmarkBarNode(), - details, BookmarkEditorView::SHOW_TREE); - - SetTitleText(L"new_F"); - - // Create the folder in the 'other' folder. - ApplyEdits(editor_tree_model()->GetRoot()->GetChild(1)); - - // Make sure the folder we edited is still there. - ASSERT_EQ(3, model_->other_node()->GetChildCount()); - const BookmarkNode* new_node = model_->other_node()->GetChild(2); - EXPECT_EQ(BookmarkNode::FOLDER, new_node->type()); - EXPECT_EQ(ASCIIToUTF16("new_F"), new_node->GetTitle()); - // The node should have one child. - ASSERT_EQ(1, new_node->GetChildCount()); - const BookmarkNode* new_child = new_node->GetChild(0); - // Make sure the child url/title match. - EXPECT_EQ(BookmarkNode::URL, new_child->type()); - EXPECT_EQ(WideToUTF16Hack(details.urls[0].second), new_child->GetTitle()); - EXPECT_EQ(details.urls[0].first, new_child->GetURL()); -} diff --git a/chrome/browser/views/bookmark_editor_viw.h b/chrome/browser/views/bookmark_editor_viw.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/chrome/browser/views/bookmark_editor_viw.h diff --git a/chrome/browser/views/bookmark_menu_controller_views.cc b/chrome/browser/views/bookmark_menu_controller_views.cc deleted file mode 100644 index c86432e..0000000 --- a/chrome/browser/views/bookmark_menu_controller_views.cc +++ /dev/null @@ -1,415 +0,0 @@ -// 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/bookmark_menu_controller_views.h" - -#include "app/os_exchange_data.h" -#include "app/resource_bundle.h" -#include "base/stl_util-inl.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_drag_data.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/browser/views/bookmark_bar_view.h" -#include "chrome/browser/views/event_utils.h" -#include "chrome/common/page_transition_types.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/menu_button.h" - -using views::MenuItemView; - -// Max width of a menu. There does not appear to be an OS value for this, yet -// both IE and FF restrict the max width of a menu. -static const int kMaxMenuWidth = 400; - -BookmarkMenuController::BookmarkMenuController(Browser* browser, - Profile* profile, - PageNavigator* navigator, - gfx::NativeWindow parent, - const BookmarkNode* node, - int start_child_index) - : browser_(browser), - profile_(profile), - page_navigator_(navigator), - parent_(parent), - node_(node), - menu_(NULL), - observer_(NULL), - for_drop_(false), - bookmark_bar_(NULL), - next_menu_id_(1) { - menu_ = CreateMenu(node, start_child_index); -} - -void BookmarkMenuController::RunMenuAt(BookmarkBarView* bookmark_bar, - bool for_drop) { - bookmark_bar_ = bookmark_bar; - views::MenuButton* menu_button = bookmark_bar_->GetMenuButtonForNode(node_); - DCHECK(menu_button); - MenuItemView::AnchorPosition anchor; - int start_index; - bookmark_bar_->GetAnchorPositionAndStartIndexForButton( - menu_button, &anchor, &start_index); - RunMenuAt(menu_button, anchor, for_drop); -} - -void BookmarkMenuController::RunMenuAt( - views::MenuButton* button, - MenuItemView::AnchorPosition position, - bool for_drop) { - gfx::Point screen_loc; - views::View::ConvertPointToScreen(button, &screen_loc); - // Subtract 1 from the height to make the popup flush with the button border. - gfx::Rect bounds(screen_loc.x(), screen_loc.y(), button->width(), - button->height() - 1); - for_drop_ = for_drop; - profile_->GetBookmarkModel()->AddObserver(this); - // The constructor creates the initial menu and that is all we should have - // at this point. - DCHECK(node_to_menu_map_.size() == 1); - if (for_drop) { - menu_->RunMenuForDropAt(parent_, bounds, position); - } else { - menu_->RunMenuAt(parent_, button, bounds, position, false); - delete this; - } -} - -void BookmarkMenuController::Cancel() { - menu_->Cancel(); -} - -bool BookmarkMenuController::IsTriggerableEvent(const views::MouseEvent& e) { - return event_utils::IsPossibleDispositionEvent(e); -} - -void BookmarkMenuController::ExecuteCommand(int id, int mouse_event_flags) { - DCHECK(page_navigator_); - DCHECK(menu_id_to_node_map_.find(id) != menu_id_to_node_map_.end()); - - const BookmarkNode* node = menu_id_to_node_map_[id]; - std::vector<const BookmarkNode*> selection; - selection.push_back(node); - - WindowOpenDisposition initial_disposition = - event_utils::DispositionFromEventFlags(mouse_event_flags); - - bookmark_utils::OpenAll(parent_, profile_, page_navigator_, selection, - initial_disposition); -} - -bool BookmarkMenuController::GetDropFormats( - MenuItemView* menu, - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats) { - *formats = OSExchangeData::URL; - custom_formats->insert(BookmarkDragData::GetBookmarkCustomFormat()); - return true; -} - -bool BookmarkMenuController::AreDropTypesRequired(MenuItemView* menu) { - return true; -} - -bool BookmarkMenuController::CanDrop(MenuItemView* menu, - const OSExchangeData& data) { - // Only accept drops of 1 node, which is the case for all data dragged from - // bookmark bar and menus. - - if (!drop_data_.Read(data) || drop_data_.elements.size() != 1) - return false; - - if (drop_data_.has_single_url()) - return true; - - const BookmarkNode* drag_node = drop_data_.GetFirstNode(profile_); - if (!drag_node) { - // Dragging a group from another profile, always accept. - return true; - } - - // Drag originated from same profile and is not a URL. Only accept it if - // the dragged node is not a parent of the node menu represents. - const BookmarkNode* drop_node = menu_id_to_node_map_[menu->GetCommand()]; - DCHECK(drop_node); - while (drop_node && drop_node != drag_node) - drop_node = drop_node->GetParent(); - return (drop_node == NULL); -} - -int BookmarkMenuController::GetDropOperation( - MenuItemView* item, - const views::DropTargetEvent& event, - DropPosition* position) { - // Should only get here if we have drop data. - DCHECK(drop_data_.is_valid()); - - const BookmarkNode* node = menu_id_to_node_map_[item->GetCommand()]; - const BookmarkNode* drop_parent = node->GetParent(); - int index_to_drop_at = drop_parent->IndexOfChild(node); - if (*position == DROP_AFTER) { - index_to_drop_at++; - } else if (*position == DROP_ON) { - drop_parent = node; - index_to_drop_at = node->GetChildCount(); - } - DCHECK(drop_parent); - return bookmark_utils::BookmarkDropOperation( - profile_, event, drop_data_, drop_parent, index_to_drop_at); -} - -int BookmarkMenuController::OnPerformDrop(MenuItemView* menu, - DropPosition position, - const views::DropTargetEvent& event) { - const BookmarkNode* drop_node = menu_id_to_node_map_[menu->GetCommand()]; - DCHECK(drop_node); - BookmarkModel* model = profile_->GetBookmarkModel(); - DCHECK(model); - const BookmarkNode* drop_parent = drop_node->GetParent(); - DCHECK(drop_parent); - int index_to_drop_at = drop_parent->IndexOfChild(drop_node); - if (position == DROP_AFTER) { - index_to_drop_at++; - } else if (position == DROP_ON) { - DCHECK(drop_node->is_folder()); - drop_parent = drop_node; - index_to_drop_at = drop_node->GetChildCount(); - } - - int result = bookmark_utils::PerformBookmarkDrop( - profile_, drop_data_, drop_parent, index_to_drop_at); - if (for_drop_) - delete this; - return result; -} - -bool BookmarkMenuController::ShowContextMenu(MenuItemView* source, - int id, - const gfx::Point& p, - bool is_mouse_gesture) { - DCHECK(menu_id_to_node_map_.find(id) != menu_id_to_node_map_.end()); - std::vector<const BookmarkNode*> nodes; - nodes.push_back(menu_id_to_node_map_[id]); - context_menu_.reset( - new BookmarkContextMenu( - parent_, - profile_, - page_navigator_, - nodes[0]->GetParent(), - nodes)); - context_menu_->set_observer(this); - context_menu_->RunMenuAt(p); - context_menu_.reset(NULL); - return true; -} - -void BookmarkMenuController::DropMenuClosed(MenuItemView* menu) { - delete this; -} - -bool BookmarkMenuController::CanDrag(MenuItemView* menu) { - return true; -} - -void BookmarkMenuController::WriteDragData(MenuItemView* sender, - OSExchangeData* data) { - DCHECK(sender && data); - - UserMetrics::RecordAction(UserMetricsAction("BookmarkBar_DragFromFolder"), - profile_); - - BookmarkDragData drag_data(menu_id_to_node_map_[sender->GetCommand()]); - drag_data.Write(profile_, data); -} - -int BookmarkMenuController::GetDragOperations(MenuItemView* sender) { - return bookmark_utils::BookmarkDragOperation( - menu_id_to_node_map_[sender->GetCommand()]); -} - -views::MenuItemView* BookmarkMenuController::GetSiblingMenu( - views::MenuItemView* menu, - const gfx::Point& screen_point, - views::MenuItemView::AnchorPosition* anchor, - bool* has_mnemonics, - views::MenuButton** button) { - if (!bookmark_bar_ || for_drop_) - return NULL; - gfx::Point bookmark_bar_loc(screen_point); - views::View::ConvertPointToView(NULL, bookmark_bar_, &bookmark_bar_loc); - int start_index; - const BookmarkNode* node = - bookmark_bar_->GetNodeForButtonAt(bookmark_bar_loc, &start_index); - if (!node || !node->is_folder()) - return NULL; - - MenuItemView* alt_menu = node_to_menu_map_[node]; - if (!alt_menu) - alt_menu = CreateMenu(node, start_index); - - menu_ = alt_menu; - - *button = bookmark_bar_->GetMenuButtonForNode(node); - bookmark_bar_->GetAnchorPositionAndStartIndexForButton( - *button, anchor, &start_index); - *has_mnemonics = false; - return alt_menu; -} - -int BookmarkMenuController::GetMaxWidthForMenu() { - return kMaxMenuWidth; -} - -void BookmarkMenuController::BookmarkModelChanged() { - menu_->Cancel(); -} - -void BookmarkMenuController::BookmarkNodeFavIconLoaded( - BookmarkModel* model, const BookmarkNode* node) { - NodeToMenuIDMap::iterator menu_pair = node_to_menu_id_map_.find(node); - if (menu_pair == node_to_menu_id_map_.end()) - return; // We're not showing a menu item for the node. - - // Iterate through the menus looking for the menu containing node. - for (NodeToMenuMap::iterator i = node_to_menu_map_.begin(); - i != node_to_menu_map_.end(); ++i) { - MenuItemView* menu_item = i->second->GetMenuItemByID(menu_pair->second); - if (menu_item) { - menu_item->SetIcon(model->GetFavIcon(node)); - return; - } - } -} - -void BookmarkMenuController::WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks) { - std::set<MenuItemView*> removed_menus; - - WillRemoveBookmarksImpl(bookmarks, &removed_menus); - - STLDeleteElements(&removed_menus); -} - -void BookmarkMenuController::DidRemoveBookmarks() { - profile_->GetBookmarkModel()->AddObserver(this); -} - -MenuItemView* BookmarkMenuController::CreateMenu(const BookmarkNode* parent, - int start_child_index) { - MenuItemView* menu = new MenuItemView(this); - menu->SetCommand(next_menu_id_++); - menu_id_to_node_map_[menu->GetCommand()] = parent; - menu->set_has_icons(true); - BuildMenu(parent, start_child_index, menu, &next_menu_id_); - node_to_menu_map_[parent] = menu; - return menu; -} - -void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, - int start_child_index, - MenuItemView* menu, - int* next_menu_id) { - DCHECK(!parent->GetChildCount() || - start_child_index < parent->GetChildCount()); - for (int i = start_child_index; i < parent->GetChildCount(); ++i) { - const BookmarkNode* node = parent->GetChild(i); - int id = *next_menu_id; - - (*next_menu_id)++; - if (node->is_url()) { - SkBitmap icon = profile_->GetBookmarkModel()->GetFavIcon(node); - if (icon.width() == 0) { - icon = *ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_DEFAULT_FAVICON); - } - menu->AppendMenuItemWithIcon(id, UTF16ToWide(node->GetTitle()), icon); - node_to_menu_id_map_[node] = id; - } else if (node->is_folder()) { - SkBitmap* folder_icon = ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_BOOKMARK_BAR_FOLDER); - MenuItemView* submenu = menu->AppendSubMenuWithIcon(id, - UTF16ToWide(node->GetTitle()), *folder_icon); - node_to_menu_id_map_[node] = id; - BuildMenu(node, 0, submenu, next_menu_id); - } else { - NOTREACHED(); - } - menu_id_to_node_map_[id] = node; - } -} - -BookmarkMenuController::~BookmarkMenuController() { - profile_->GetBookmarkModel()->RemoveObserver(this); - if (observer_) - observer_->BookmarkMenuDeleted(this); - STLDeleteValues(&node_to_menu_map_); -} - -MenuItemView* BookmarkMenuController::GetMenuByID(int id) { - for (NodeToMenuMap::const_iterator i = node_to_menu_map_.begin(); - i != node_to_menu_map_.end(); ++i) { - MenuItemView* menu = i->second->GetMenuItemByID(id); - if (menu) - return menu; - } - return NULL; -} - -void BookmarkMenuController::WillRemoveBookmarksImpl( - const std::vector<const BookmarkNode*>& bookmarks, - std::set<views::MenuItemView*>* removed_menus) { - // Remove the observer so that when the remove happens we don't prematurely - // cancel the menu. - profile_->GetBookmarkModel()->RemoveObserver(this); - - // Remove the menu items. - std::set<MenuItemView*> changed_parent_menus; - for (std::vector<const BookmarkNode*>::const_iterator i = bookmarks.begin(); - i != bookmarks.end(); ++i) { - NodeToMenuIDMap::iterator node_to_menu = node_to_menu_id_map_.find(*i); - if (node_to_menu != node_to_menu_id_map_.end()) { - MenuItemView* menu = GetMenuByID(node_to_menu->second); - DCHECK(menu); // If there an entry in node_to_menu_id_map_, there should - // be a menu. - removed_menus->insert(menu); - changed_parent_menus.insert(menu->GetParentMenuItem()); - menu->GetParent()->RemoveChildView(menu); - node_to_menu_id_map_.erase(node_to_menu); - } - } - - // All the bookmarks in |bookmarks| should have the same parent. It's possible - // to support different parents, but this would need to prune any nodes whose - // parent has been removed. As all nodes currently have the same parent, there - // is the DCHECK. - DCHECK(changed_parent_menus.size() <= 1); - - for (std::set<MenuItemView*>::const_iterator i = changed_parent_menus.begin(); - i != changed_parent_menus.end(); ++i) { - (*i)->ChildrenChanged(); - } - - // Remove any descendants of the removed nodes in node_to_menu_id_map_. - for (NodeToMenuIDMap::iterator i = node_to_menu_id_map_.begin(); - i != node_to_menu_id_map_.end(); ) { - bool ancestor_removed = false; - for (std::vector<const BookmarkNode*>::const_iterator j = bookmarks.begin(); - j != bookmarks.end(); ++j) { - if (i->first->HasAncestor(*j)) { - ancestor_removed = true; - break; - } - } - if (ancestor_removed) { - node_to_menu_id_map_.erase(i++); - } else { - ++i; - } - } -} diff --git a/chrome/browser/views/bookmark_menu_controller_views.h b/chrome/browser/views/bookmark_menu_controller_views.h index f71196b..2fcca0c 100644 --- a/chrome/browser/views/bookmark_menu_controller_views.h +++ b/chrome/browser/views/bookmark_menu_controller_views.h @@ -6,195 +6,8 @@ #define CHROME_BROWSER_VIEWS_BOOKMARK_MENU_CONTROLLER_VIEWS_H_ #pragma once -#include <map> -#include <set> - -#include "chrome/browser/bookmarks/base_bookmark_model_observer.h" -#include "chrome/browser/bookmarks/bookmark_drag_data.h" -#include "chrome/browser/views/bookmark_context_menu.h" -#include "gfx/native_widget_types.h" -#include "views/controls/menu/menu_delegate.h" -#include "views/controls/menu/menu_item_view.h" - -namespace gfx { -class Rect; -} // namespace gfx - -namespace views { -class MenuButton; -} // namespace views - -class BookmarkBarView; -class BookmarkContextMenu; -class BookmarkNode; -class Browser; -class OSExchangeData; -class PageNavigator; -class Profile; - -// BookmarkMenuController is responsible for showing a menu of bookmarks, -// each item in the menu represents a bookmark. -// BookmarkMenuController deletes itself as necessary, although the menu can -// be explicitly hidden by way of the Cancel method. -class BookmarkMenuController : public BaseBookmarkModelObserver, - public views::MenuDelegate, - public BookmarkContextMenuObserver { - public: - // The observer is notified prior to the menu being deleted. - class Observer { - public: - virtual void BookmarkMenuDeleted(BookmarkMenuController* controller) = 0; - - protected: - virtual ~Observer() {} - }; - - // Creates a BookmarkMenuController showing the children of |node| starting - // at index |start_child_index|. - BookmarkMenuController(Browser* browser, - Profile* profile, - PageNavigator* page_navigator, - gfx::NativeWindow parent, - const BookmarkNode* node, - int start_child_index); - - void RunMenuAt(BookmarkBarView* bookmark_bar, bool for_drop); - - // Shows the menu. - void RunMenuAt(views::MenuButton* button, - views::MenuItemView::AnchorPosition position, - bool for_drop); - - // Hides the menu. - void Cancel(); - - // Returns the node the menu is showing for. - const BookmarkNode* node() const { return node_; } - - // Returns the menu. - views::MenuItemView* menu() const { return menu_; } - - // Returns the context menu, or NULL if the context menu isn't showing. - views::MenuItemView* context_menu() const { - return context_menu_.get() ? context_menu_->menu() : NULL; - } - - void set_observer(Observer* observer) { observer_ = observer; } - - // MenuDelegate methods. - virtual bool IsTriggerableEvent(const views::MouseEvent& e); - virtual void ExecuteCommand(int id, int mouse_event_flags); - virtual bool GetDropFormats( - views::MenuItemView* menu, - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats); - virtual bool AreDropTypesRequired(views::MenuItemView* menu); - virtual bool CanDrop(views::MenuItemView* menu, const OSExchangeData& data); - virtual int GetDropOperation(views::MenuItemView* item, - const views::DropTargetEvent& event, - DropPosition* position); - virtual int OnPerformDrop(views::MenuItemView* menu, - DropPosition position, - const views::DropTargetEvent& event); - virtual bool ShowContextMenu(views::MenuItemView* source, - int id, - const gfx::Point& p, - bool is_mouse_gesture); - virtual void DropMenuClosed(views::MenuItemView* menu); - virtual bool CanDrag(views::MenuItemView* menu); - virtual void WriteDragData(views::MenuItemView* sender, OSExchangeData* data); - virtual int GetDragOperations(views::MenuItemView* sender); - virtual views::MenuItemView* GetSiblingMenu( - views::MenuItemView* menu, - const gfx::Point& screen_point, - views::MenuItemView::AnchorPosition* anchor, - bool* has_mnemonics, - views::MenuButton** button); - virtual int GetMaxWidthForMenu(); - - // BookmarkModelObserver methods. - virtual void BookmarkModelChanged(); - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, - const BookmarkNode* node); - - // BookmarkContextMenu::Observer methods. - virtual void WillRemoveBookmarks( - const std::vector<const BookmarkNode*>& bookmarks); - virtual void DidRemoveBookmarks(); - - private: - typedef std::map<const BookmarkNode*, int> NodeToMenuIDMap; - - // BookmarkMenuController deletes itself as necessary. - virtual ~BookmarkMenuController(); - - // Creates a menu and adds it to node_to_menu_id_map_. This uses - // BuildMenu to recursively populate the menu. - views::MenuItemView* CreateMenu(const BookmarkNode* parent, - int start_child_index); - - // Creates an entry in menu for each child node of |parent| starting at - // |start_child_index|. - void BuildMenu(const BookmarkNode* parent, - int start_child_index, - views::MenuItemView* menu, - int* next_menu_id); - - // Returns the menu whose id is |id|. - views::MenuItemView* GetMenuByID(int id); - - // Does the work of processing WillRemoveBookmarks. On exit the set of removed - // menus is added to |removed_menus|. It's up to the caller to delete the - // the menus added to |removed_menus|. - void WillRemoveBookmarksImpl( - const std::vector<const BookmarkNode*>& bookmarks, - std::set<views::MenuItemView*>* removed_menus); - - Browser* browser_; - - Profile* profile_; - - PageNavigator* page_navigator_; - - // Parent of menus. - gfx::NativeWindow parent_; - - // The node we're showing the contents of. - const BookmarkNode* node_; - - // Maps from menu id to BookmarkNode. - std::map<int, const BookmarkNode*> menu_id_to_node_map_; - - // Mapping from node to menu id. This only contains entries for nodes of type - // URL. - NodeToMenuIDMap node_to_menu_id_map_; - - // Current menu. - views::MenuItemView* menu_; - - // Data for the drop. - BookmarkDragData drop_data_; - - // Used when a context menu is shown. - scoped_ptr<BookmarkContextMenu> context_menu_; - - // The observer, may be null. - Observer* observer_; - - // Is the menu being shown for a drop? - bool for_drop_; - - // The bookmark bar. This is only non-null if we're showing a menu item - // for a folder on the bookmark bar and not for drop. - BookmarkBarView* bookmark_bar_; - - typedef std::map<const BookmarkNode*, views::MenuItemView*> NodeToMenuMap; - NodeToMenuMap node_to_menu_map_; - - // ID of the next menu item. - int next_menu_id_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController); -}; +#include "chrome/browser/ui/views/bookmark_menu_controller_views.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BOOKMARK_MENU_CONTROLLER_VIEWS_H_ + diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc deleted file mode 100644 index b630806..0000000 --- a/chrome/browser/views/browser_actions_container.cc +++ /dev/null @@ -1,1100 +0,0 @@ -// 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/browser_actions_container.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/slide_animation.h" -#include "base/stl_util-inl.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/extensions/extension_browser_event_router.h" -#include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/extensions/extension_tabs_module.h" -#include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/detachable_toolbar_view.h" -#include "chrome/browser/views/extensions/browser_action_drag_data.h" -#include "chrome/browser/views/extensions/extension_popup.h" -#include "chrome/browser/views/toolbar_view.h" -#include "chrome/common/extensions/extension_action.h" -#include "chrome/common/extensions/extension_resource.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas.h" -#include "gfx/canvas_skia.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkTypeface.h" -#include "third_party/skia/include/effects/SkGradientShader.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/button/text_button.h" -#include "views/controls/menu/menu_2.h" -#include "views/drag_utils.h" -#include "views/window/window.h" - -#include "grit/theme_resources.h" - -// Horizontal spacing between most items in the container, as well as after the -// last item or chevron (if visible). -static const int kItemSpacing = ToolbarView::kStandardSpacing; -// Horizontal spacing before the chevron (if visible). -static const int kChevronSpacing = kItemSpacing - 2; - -// static -bool BrowserActionsContainer::disable_animations_during_testing_ = false; - -//////////////////////////////////////////////////////////////////////////////// -// BrowserActionButton - -BrowserActionButton::BrowserActionButton(const Extension* extension, - BrowserActionsContainer* panel) - : ALLOW_THIS_IN_INITIALIZER_LIST( - MenuButton(this, std::wstring(), NULL, false)), - browser_action_(extension->browser_action()), - extension_(extension), - ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)), - showing_context_menu_(false), - panel_(panel) { - set_border(NULL); - set_alignment(TextButton::ALIGN_CENTER); - - // No UpdateState() here because View hierarchy not setup yet. Our parent - // should call UpdateState() after creation. - - registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED, - Source<ExtensionAction>(browser_action_)); -} - -void BrowserActionButton::Destroy() { - if (showing_context_menu_) { - context_menu_menu_->CancelMenu(); - MessageLoop::current()->DeleteSoon(FROM_HERE, this); - } else { - delete this; - } -} - -void BrowserActionButton::ViewHierarchyChanged( - bool is_add, View* parent, View* child) { - if (is_add && child == this) { - // The Browser Action API does not allow the default icon path to be - // changed at runtime, so we can load this now and cache it. - std::string relative_path = browser_action_->default_icon_path(); - if (relative_path.empty()) - return; - - // LoadImage is not guaranteed to be synchronous, so we might see the - // callback OnImageLoaded execute immediately. It (through UpdateState) - // expects GetParent() to return the owner for this button, so this - // function is as early as we can start this request. - tracker_.LoadImage(extension_, extension_->GetResource(relative_path), - gfx::Size(Extension::kBrowserActionIconMaxSize, - Extension::kBrowserActionIconMaxSize), - ImageLoadingTracker::DONT_CACHE); - } - - MenuButton::ViewHierarchyChanged(is_add, parent, child); -} - -void BrowserActionButton::ButtonPressed(views::Button* sender, - const views::Event& event) { - panel_->OnBrowserActionExecuted(this, false); -} - -void BrowserActionButton::OnImageLoaded(SkBitmap* image, - ExtensionResource resource, - int index) { - if (image) - default_icon_ = *image; - - // Call back to UpdateState() because a more specific icon might have been set - // while the load was outstanding. - UpdateState(); -} - -void BrowserActionButton::UpdateState() { - int tab_id = panel_->GetCurrentTabId(); - if (tab_id < 0) - return; - - SkBitmap icon(browser_action()->GetIcon(tab_id)); - if (icon.isNull()) - icon = default_icon_; - if (!icon.isNull()) { - SkPaint paint; - paint.setXfermode(SkXfermode::Create(SkXfermode::kSrcOver_Mode)); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - SkBitmap bg; - rb.GetBitmapNamed(IDR_BROWSER_ACTION)->copyTo(&bg, - SkBitmap::kARGB_8888_Config); - SkCanvas bg_canvas(bg); - bg_canvas.drawBitmap(icon, SkIntToScalar((bg.width() - icon.width()) / 2), - SkIntToScalar((bg.height() - icon.height()) / 2), &paint); - SetIcon(bg); - - SkBitmap bg_h; - rb.GetBitmapNamed(IDR_BROWSER_ACTION_H)->copyTo(&bg_h, - SkBitmap::kARGB_8888_Config); - SkCanvas bg_h_canvas(bg_h); - bg_h_canvas.drawBitmap(icon, - SkIntToScalar((bg_h.width() - icon.width()) / 2), - SkIntToScalar((bg_h.height() - icon.height()) / 2), &paint); - SetHoverIcon(bg_h); - - SkBitmap bg_p; - rb.GetBitmapNamed(IDR_BROWSER_ACTION_P)->copyTo(&bg_p, - SkBitmap::kARGB_8888_Config); - SkCanvas bg_p_canvas(bg_p); - bg_p_canvas.drawBitmap(icon, - SkIntToScalar((bg_p.width() - icon.width()) / 2), - SkIntToScalar((bg_p.height() - icon.height()) / 2), &paint); - SetPushedIcon(bg_p); - } - - // If the browser action name is empty, show the extension name instead. - std::wstring name = UTF8ToWide(browser_action()->GetTitle(tab_id)); - if (name.empty()) - name = UTF8ToWide(extension()->name()); - SetTooltipText(name); - SetAccessibleName(name); - GetParent()->SchedulePaint(); -} - -void BrowserActionButton::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED); - UpdateState(); - // The browser action may have become visible/hidden so we need to make - // sure the state gets updated. - panel_->OnBrowserActionVisibilityChanged(); -} - -bool BrowserActionButton::IsPopup() { - int tab_id = panel_->GetCurrentTabId(); - return (tab_id < 0) ? false : browser_action_->HasPopup(tab_id); -} - -GURL BrowserActionButton::GetPopupUrl() { - int tab_id = panel_->GetCurrentTabId(); - return (tab_id < 0) ? GURL() : browser_action_->GetPopupUrl(tab_id); -} - -bool BrowserActionButton::Activate() { - if (!IsPopup()) - return true; - - panel_->OnBrowserActionExecuted(this, false); - - // TODO(erikkay): Run a nested modal loop while the mouse is down to - // enable menu-like drag-select behavior. - - // The return value of this method is returned via OnMousePressed. - // We need to return false here since we're handing off focus to another - // widget/view, and true will grab it right back and try to send events - // to us. - return false; -} - -bool BrowserActionButton::OnMousePressed(const views::MouseEvent& e) { - if (!e.IsRightMouseButton()) { - return IsPopup() ? - MenuButton::OnMousePressed(e) : TextButton::OnMousePressed(e); - } - - // Get the top left point of this button in screen coordinates. - gfx::Point point = gfx::Point(0, 0); - ConvertPointToScreen(this, &point); - - // Make the menu appear below the button. - point.Offset(0, height()); - - ShowContextMenu(point, true); - return false; -} - -void BrowserActionButton::OnMouseReleased(const views::MouseEvent& e, - bool canceled) { - if (IsPopup() || showing_context_menu_) { - // TODO(erikkay) this never actually gets called (probably because of the - // loss of focus). - MenuButton::OnMouseReleased(e, canceled); - } else { - TextButton::OnMouseReleased(e, canceled); - } -} - -bool BrowserActionButton::OnKeyReleased(const views::KeyEvent& e) { - return IsPopup() ? - MenuButton::OnKeyReleased(e) : TextButton::OnKeyReleased(e); -} - -void BrowserActionButton::OnMouseExited(const views::MouseEvent& e) { - if (IsPopup() || showing_context_menu_) - MenuButton::OnMouseExited(e); - else - TextButton::OnMouseExited(e); -} - -void BrowserActionButton::ShowContextMenu(const gfx::Point& p, - bool is_mouse_gesture) { - showing_context_menu_ = true; - SetButtonPushed(); - - // Reconstructs the menu every time because the menu's contents are dynamic. - context_menu_contents_ = - new ExtensionContextMenuModel(extension(), panel_->browser(), panel_); - context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get())); - context_menu_menu_->RunContextMenuAt(p); - - SetButtonNotPushed(); - showing_context_menu_ = false; -} - -void BrowserActionButton::SetButtonPushed() { - SetState(views::CustomButton::BS_PUSHED); - menu_visible_ = true; -} - -void BrowserActionButton::SetButtonNotPushed() { - SetState(views::CustomButton::BS_NORMAL); - menu_visible_ = false; -} - -BrowserActionButton::~BrowserActionButton() { -} - - -//////////////////////////////////////////////////////////////////////////////// -// BrowserActionView - -BrowserActionView::BrowserActionView(const Extension* extension, - BrowserActionsContainer* panel) - : panel_(panel) { - button_ = new BrowserActionButton(extension, panel); - button_->SetDragController(panel_); - AddChildView(button_); - button_->UpdateState(); - SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_EXTENSIONS_BROWSER_ACTION)); -} - -BrowserActionView::~BrowserActionView() { - RemoveChildView(button_); - button_->Destroy(); -} - -gfx::Canvas* BrowserActionView::GetIconWithBadge() { - int tab_id = panel_->GetCurrentTabId(); - - SkBitmap icon = button_->extension()->browser_action()->GetIcon(tab_id); - if (icon.isNull()) - icon = button_->default_icon(); - - gfx::Canvas* canvas = new gfx::CanvasSkia(icon.width(), icon.height(), false); - canvas->DrawBitmapInt(icon, 0, 0); - - if (tab_id >= 0) { - gfx::Rect bounds(icon.width(), icon.height() + ToolbarView::kVertSpacing); - button_->extension()->browser_action()->PaintBadge(canvas, bounds, tab_id); - } - - return canvas; -} - -AccessibilityTypes::Role BrowserActionView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -void BrowserActionView::Layout() { - // We can't rely on button_->GetPreferredSize() here because that's not set - // correctly until the first call to - // BrowserActionsContainer::RefreshBrowserActionViews(), whereas this can be - // called before that when the initial bounds are set (and then not after, - // since the bounds don't change). So instead of setting the height from the - // button's preferred size, we use IconHeight(), since that's how big the - // button should be regardless of what it's displaying. - button_->SetBounds(0, ToolbarView::kVertSpacing, width(), - BrowserActionsContainer::IconHeight()); -} - -void BrowserActionView::PaintChildren(gfx::Canvas* canvas) { - View::PaintChildren(canvas); - ExtensionAction* action = button()->browser_action(); - int tab_id = panel_->GetCurrentTabId(); - if (tab_id >= 0) - action->PaintBadge(canvas, gfx::Rect(width(), height()), tab_id); -} - -//////////////////////////////////////////////////////////////////////////////// -// BrowserActionsContainer - -BrowserActionsContainer::BrowserActionsContainer(Browser* browser, - View* owner_view) - : profile_(browser->profile()), - browser_(browser), - owner_view_(owner_view), - popup_(NULL), - popup_button_(NULL), - model_(NULL), - container_width_(0), - chevron_(NULL), - overflow_menu_(NULL), - suppress_chevron_(false), - resize_amount_(0), - animation_target_size_(0), - drop_indicator_position_(-1), - ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), - ALLOW_THIS_IN_INITIALIZER_LIST(show_menu_task_factory_(this)) { - SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR); - - if (profile_->GetExtensionsService()) { - model_ = profile_->GetExtensionsService()->toolbar_model(); - model_->AddObserver(this); - } - - resize_animation_.reset(new SlideAnimation(this)); - resize_area_ = new views::ResizeArea(this); - resize_area_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SEPARATOR)); - AddChildView(resize_area_); - - chevron_ = new views::MenuButton(NULL, std::wstring(), this, false); - chevron_->set_border(NULL); - chevron_->EnableCanvasFlippingForRTLUI(true); - chevron_->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_EXTENSIONS_CHEVRON)); - chevron_->SetVisible(false); - AddChildView(chevron_); - - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_EXTENSIONS)); -} - -BrowserActionsContainer::~BrowserActionsContainer() { - if (model_) - model_->RemoveObserver(this); - StopShowFolderDropMenuTimer(); - HidePopup(); - DeleteBrowserActionViews(); -} - -// Static. -void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) { - prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0); -} - -void BrowserActionsContainer::Init() { - LoadImages(); - - // We wait to set the container width until now so that the chevron images - // will be loaded. The width calculation needs to know the chevron size. - if (model_ && - !profile_->GetPrefs()->HasPrefPath(prefs::kExtensionToolbarSize)) { - // Migration code to the new VisibleIconCount pref. - // TODO(mpcomplete): remove this after users are upgraded to 5.0. - int predefined_width = - profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth); - if (predefined_width != 0) - model_->SetVisibleIconCount(WidthToIconCount(predefined_width)); - } - if (model_ && model_->extensions_initialized()) - SetContainerWidth(); -} - -int BrowserActionsContainer::GetCurrentTabId() const { - TabContents* tab_contents = browser_->GetSelectedTabContents(); - return tab_contents ? tab_contents->controller().session_id().id() : -1; -} - -BrowserActionView* BrowserActionsContainer::GetBrowserActionView( - ExtensionAction* action) { - for (BrowserActionViews::iterator iter = browser_action_views_.begin(); - iter != browser_action_views_.end(); ++iter) { - if ((*iter)->button()->browser_action() == action) - return *iter; - } - return NULL; -} - -void BrowserActionsContainer::RefreshBrowserActionViews() { - for (size_t i = 0; i < browser_action_views_.size(); ++i) - browser_action_views_[i]->button()->UpdateState(); -} - -void BrowserActionsContainer::CreateBrowserActionViews() { - DCHECK(browser_action_views_.empty()); - if (!model_) - return; - - for (ExtensionList::iterator iter = model_->begin(); iter != model_->end(); - ++iter) { - if (!ShouldDisplayBrowserAction(*iter)) - continue; - - BrowserActionView* view = new BrowserActionView(*iter, this); - browser_action_views_.push_back(view); - AddChildView(view); - } -} - -void BrowserActionsContainer::DeleteBrowserActionViews() { - if (!browser_action_views_.empty()) { - for (size_t i = 0; i < browser_action_views_.size(); ++i) - RemoveChildView(browser_action_views_[i]); - STLDeleteContainerPointers(browser_action_views_.begin(), - browser_action_views_.end()); - browser_action_views_.clear(); - } -} - -void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { - SetVisible(!browser_action_views_.empty()); - owner_view_->Layout(); - owner_view_->SchedulePaint(); -} - -size_t BrowserActionsContainer::VisibleBrowserActions() const { - size_t visible_actions = 0; - for (size_t i = 0; i < browser_action_views_.size(); ++i) { - if (browser_action_views_[i]->IsVisible()) - ++visible_actions; - } - return visible_actions; -} - -void BrowserActionsContainer::OnBrowserActionExecuted( - BrowserActionButton* button, - bool inspect_with_devtools) { - ExtensionAction* browser_action = button->browser_action(); - - // Popups just display. No notification to the extension. - // TODO(erikkay): should there be? - if (!button->IsPopup()) { - ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted( - profile_, browser_action->extension_id(), browser_); - return; - } - - // If we're showing the same popup, just hide it and return. - bool same_showing = popup_ && button == popup_button_; - - // Always hide the current popup, even if it's not the same. - // Only one popup should be visible at a time. - HidePopup(); - - if (same_showing) - return; - - // We can get the execute event for browser actions that are not visible, - // since buttons can be activated from the overflow menu (chevron). In that - // case we show the popup as originating from the chevron. - View* reference_view = button->GetParent()->IsVisible() ? button : chevron_; - gfx::Point origin; - View::ConvertPointToScreen(reference_view, &origin); - gfx::Rect rect = reference_view->bounds(); - rect.set_origin(origin); - - gfx::NativeWindow frame_window = browser_->window()->GetNativeHandle(); - BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ? - BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT; - - popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_, - browser_->profile(), frame_window, rect, arrow_location, true, - inspect_with_devtools, ExtensionPopup::BUBBLE_CHROME, this); - popup_button_ = button; - popup_button_->SetButtonPushed(); -} - -gfx::Size BrowserActionsContainer::GetPreferredSize() { - if (browser_action_views_.empty()) - return gfx::Size(ToolbarView::kStandardSpacing, 0); - - // We calculate the size of the view by taking the current width and - // subtracting resize_amount_ (the latter represents how far the user is - // resizing the view or, if animating the snapping, how far to animate it). - // But we also clamp it to a minimum size and the maximum size, so that the - // container can never shrink too far or take up more space than it needs. In - // other words: ContainerMinSize() < width() - resize < ClampTo(MAX). - int clamped_width = std::min( - std::max(ContainerMinSize(), container_width_ - resize_amount_), - IconCountToWidth(-1, false)); - return gfx::Size(clamped_width, 0); -} - -void BrowserActionsContainer::Layout() { - if (browser_action_views_.empty()) { - SetVisible(false); - return; - } - - SetVisible(true); - resize_area_->SetBounds(0, ToolbarView::kVertSpacing, kItemSpacing, - IconHeight()); - - // If the icons don't all fit, show the chevron (unless suppressed). - int max_x = GetPreferredSize().width(); - if ((IconCountToWidth(-1, false) > max_x) && !suppress_chevron_) { - chevron_->SetVisible(true); - gfx::Size chevron_size(chevron_->GetPreferredSize()); - max_x -= - ToolbarView::kStandardSpacing + chevron_size.width() + kChevronSpacing; - chevron_->SetBounds( - width() - ToolbarView::kStandardSpacing - chevron_size.width(), - ToolbarView::kVertSpacing, chevron_size.width(), chevron_size.height()); - } else { - chevron_->SetVisible(false); - } - - // Now draw the icons for the browser actions in the available space. - int icon_width = IconWidth(false); - for (size_t i = 0; i < browser_action_views_.size(); ++i) { - BrowserActionView* view = browser_action_views_[i]; - int x = ToolbarView::kStandardSpacing + (i * IconWidth(true)); - if (x + icon_width <= max_x) { - view->SetBounds(x, 0, icon_width, height()); - view->SetVisible(true); - } else { - view->SetVisible(false); - } - } -} - -void BrowserActionsContainer::Paint(gfx::Canvas* canvas) { - // TODO(sky/glen): Instead of using a drop indicator, animate the icons while - // dragging (like we do for tab dragging). - if (drop_indicator_position_ > -1) { - // The two-pixel width drop indicator. - static const int kDropIndicatorWidth = 2; - gfx::Rect indicator_bounds( - drop_indicator_position_ - (kDropIndicatorWidth / 2), - ToolbarView::kVertSpacing, kDropIndicatorWidth, IconHeight()); - - // Color of the drop indicator. - static const SkColor kDropIndicatorColor = SK_ColorBLACK; - canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(), - indicator_bounds.y(), indicator_bounds.width(), - indicator_bounds.height()); - } -} - -void BrowserActionsContainer::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - // No extensions (e.g., incognito). - if (!model_) - return; - - if (is_add && child == this) { - // Initial toolbar button creation and placement in the widget hierarchy. - // We do this here instead of in the constructor because AddBrowserAction - // calls Layout on the Toolbar, which needs this object to be constructed - // before its Layout function is called. - CreateBrowserActionViews(); - } -} - -bool BrowserActionsContainer::GetDropFormats( - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats) { - custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat()); - - return true; -} - -bool BrowserActionsContainer::AreDropTypesRequired() { - return true; -} - -bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { - BrowserActionDragData drop_data; - return drop_data.Read(data) ? drop_data.IsFromProfile(profile_) : false; -} - -void BrowserActionsContainer::OnDragEntered( - const views::DropTargetEvent& event) { -} - -int BrowserActionsContainer::OnDragUpdated( - const views::DropTargetEvent& event) { - // First check if we are above the chevron (overflow) menu. - if (GetViewForPoint(event.location()) == chevron_) { - if (show_menu_task_factory_.empty() && !overflow_menu_) - StartShowFolderDropMenuTimer(); - return DragDropTypes::DRAG_MOVE; - } - StopShowFolderDropMenuTimer(); - - // Figure out where to display the indicator. This is a complex calculation: - - // First, we figure out how much space is to the left of the icon area, so we - // can calculate the true offset into the icon area. - int width_before_icons = ToolbarView::kStandardSpacing + - (base::i18n::IsRTL() ? - (chevron_->GetPreferredSize().width() + kChevronSpacing) : 0); - int offset_into_icon_area = event.x() - width_before_icons; - - // Next, we determine which icon to place the indicator in front of. We want - // to place the indicator in front of icon n when the cursor is between the - // midpoints of icons (n - 1) and n. To do this we take the offset into the - // icon area and transform it as follows: - // - // Real icon area: - // 0 a * b c - // | | | | - // |[IC|ON] [IC|ON] [IC|ON] - // We want to be before icon 0 for 0 < x <= a, icon 1 for a < x <= b, etc. - // Here the "*" represents the offset into the icon area, and since it's - // between a and b, we want to return "1". - // - // Transformed "icon area": - // 0 a * b c - // | | | | - // |[ICON] |[ICON] |[ICON] | - // If we shift both our offset and our divider points later by half an icon - // plus one spacing unit, then it becomes very easy to calculate how many - // divider points we've passed, because they're the multiples of "one icon - // plus padding". - int before_icon_unclamped = (offset_into_icon_area + (IconWidth(false) / 2) + - kItemSpacing) / IconWidth(true); - - // Because the user can drag outside the container bounds, we need to clamp to - // the valid range. Note that the maximum allowable value is (num icons), not - // (num icons - 1), because we represent the indicator being past the last - // icon as being "before the (last + 1) icon". - int before_icon = std::min(std::max(before_icon_unclamped, 0), - static_cast<int>(VisibleBrowserActions())); - - // Now we convert back to a pixel offset into the container. We want to place - // the center of the drop indicator at the midpoint of the space before our - // chosen icon. - SetDropIndicator(width_before_icons + (before_icon * IconWidth(true)) - - (kItemSpacing / 2)); - - return DragDropTypes::DRAG_MOVE; -} - -void BrowserActionsContainer::OnDragExited() { - StopShowFolderDropMenuTimer(); - drop_indicator_position_ = -1; - SchedulePaint(); -} - -int BrowserActionsContainer::OnPerformDrop( - const views::DropTargetEvent& event) { - BrowserActionDragData data; - if (!data.Read(event.GetData())) - return DragDropTypes::DRAG_NONE; - - // Make sure we have the same view as we started with. - DCHECK_EQ(browser_action_views_[data.index()]->button()->extension()->id(), - data.id()); - DCHECK(model_); - - size_t i = 0; - for (; i < browser_action_views_.size(); ++i) { - int view_x = - browser_action_views_[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).x(); - if (!browser_action_views_[i]->IsVisible() || - (base::i18n::IsRTL() ? (view_x < drop_indicator_position_) : - (view_x >= drop_indicator_position_))) { - // We have reached the end of the visible icons or found one that has a - // higher x position than the drop point. - break; - } - } - - // |i| now points to the item to the right of the drop indicator*, which is - // correct when dragging an icon to the left. When dragging to the right, - // however, we want the icon being dragged to get the index of the item to - // the left of the drop indicator, so we subtract one. - // * Well, it can also point to the end, but not when dragging to the left. :) - if (i > data.index()) - --i; - - if (profile_->IsOffTheRecord()) - i = model_->IncognitoIndexToOriginal(i); - - model_->MoveBrowserAction( - browser_action_views_[data.index()]->button()->extension(), i); - - OnDragExited(); // Perform clean up after dragging. - return DragDropTypes::DRAG_MOVE; -} - -void BrowserActionsContainer::OnThemeChanged() { - LoadImages(); -} - -AccessibilityTypes::Role BrowserActionsContainer::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) { - if (source == chevron_) { - overflow_menu_ = new BrowserActionOverflowMenuController( - this, chevron_, browser_action_views_, VisibleBrowserActions()); - overflow_menu_->set_observer(this); - overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), false); - } -} - -void BrowserActionsContainer::WriteDragData(View* sender, - const gfx::Point& press_pt, - OSExchangeData* data) { - DCHECK(data); - - for (size_t i = 0; i < browser_action_views_.size(); ++i) { - BrowserActionButton* button = browser_action_views_[i]->button(); - if (button == sender) { - // Set the dragging image for the icon. - scoped_ptr<gfx::Canvas> canvas( - browser_action_views_[i]->GetIconWithBadge()); - drag_utils::SetDragImageOnDataObject(*canvas, button->size(), press_pt, - data); - - // Fill in the remaining info. - BrowserActionDragData drag_data( - browser_action_views_[i]->button()->extension()->id(), i); - drag_data.Write(profile_, data); - break; - } - } -} - -int BrowserActionsContainer::GetDragOperations(View* sender, - const gfx::Point& p) { - return DragDropTypes::DRAG_MOVE; -} - -bool BrowserActionsContainer::CanStartDrag(View* sender, - const gfx::Point& press_pt, - const gfx::Point& p) { - return true; -} - -void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) { - if (!done_resizing) { - resize_amount_ = resize_amount; - OnBrowserActionVisibilityChanged(); - return; - } - - // Up until now we've only been modifying the resize_amount, but now it is - // time to set the container size to the size we have resized to, and then - // animate to the nearest icon count size if necessary (which may be 0). - int max_width = IconCountToWidth(-1, false); - container_width_ = - std::min(std::max(0, container_width_ - resize_amount), max_width); - SaveDesiredSizeAndAnimate(Tween::EASE_OUT, - WidthToIconCount(container_width_)); -} - -void BrowserActionsContainer::AnimationProgressed(const Animation* animation) { - DCHECK_EQ(resize_animation_.get(), animation); - resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() * - (container_width_ - animation_target_size_)); - OnBrowserActionVisibilityChanged(); -} - -void BrowserActionsContainer::AnimationEnded(const Animation* animation) { - container_width_ = animation_target_size_; - animation_target_size_ = 0; - resize_amount_ = 0; - OnBrowserActionVisibilityChanged(); - suppress_chevron_ = false; -} - -void BrowserActionsContainer::NotifyMenuDeleted( - BrowserActionOverflowMenuController* controller) { - DCHECK(controller == overflow_menu_); - overflow_menu_ = NULL; -} - -void BrowserActionsContainer::InspectPopup(ExtensionAction* action) { - OnBrowserActionExecuted(GetBrowserActionView(action)->button(), true); -} - -void BrowserActionsContainer::ExtensionPopupIsClosing(ExtensionPopup* popup) { - // ExtensionPopup is ref-counted, so we don't need to delete it. - DCHECK_EQ(popup_, popup); - popup_ = NULL; - popup_button_->SetButtonNotPushed(); - popup_button_ = NULL; -} - -void BrowserActionsContainer::MoveBrowserAction(const std::string& extension_id, - size_t new_index) { - ExtensionsService* service = profile_->GetExtensionsService(); - if (service) { - const Extension* extension = service->GetExtensionById(extension_id, false); - model_->MoveBrowserAction(extension, new_index); - SchedulePaint(); - } -} - -void BrowserActionsContainer::HidePopup() { - if (popup_) - popup_->Close(); -} - -void BrowserActionsContainer::TestExecuteBrowserAction(int index) { - BrowserActionButton* button = browser_action_views_[index]->button(); - OnBrowserActionExecuted(button, false); -} - -void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) { - model_->SetVisibleIconCount(icons); - chevron_->SetVisible(icons < browser_action_views_.size()); - container_width_ = IconCountToWidth(icons, chevron_->IsVisible()); - Layout(); - SchedulePaint(); -} - -// static -int BrowserActionsContainer::IconWidth(bool include_padding) { - static bool initialized = false; - static int icon_width = 0; - if (!initialized) { - initialized = true; - icon_width = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_BROWSER_ACTION)->width(); - } - return icon_width + (include_padding ? kItemSpacing : 0); -} - -// static -int BrowserActionsContainer::IconHeight() { - static bool initialized = false; - static int icon_height = 0; - if (!initialized) { - initialized = true; - icon_height = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_BROWSER_ACTION)->height(); - } - return icon_height; -} - -void BrowserActionsContainer::BrowserActionAdded(const Extension* extension, - int index) { -#if defined(DEBUG) - for (size_t i = 0; i < browser_action_views_.size(); ++i) { - DCHECK(browser_action_views_[i]->button()->extension() != extension) << - "Asked to add a browser action view for an extension that already " - "exists."; - } -#endif - CloseOverflowMenu(); - - if (!ShouldDisplayBrowserAction(extension)) - return; - - size_t visible_actions = VisibleBrowserActions(); - - // Add the new browser action to the vector and the view hierarchy. - if (profile_->IsOffTheRecord()) - index = model_->OriginalIndexToIncognito(index); - BrowserActionView* view = new BrowserActionView(extension, this); - browser_action_views_.insert(browser_action_views_.begin() + index, view); - AddChildView(index, view); - - // If we are still initializing the container, don't bother animating. - if (!model_->extensions_initialized()) - return; - - // Enlarge the container if it was already at maximum size and we're not in - // the middle of upgrading. - if ((model_->GetVisibleIconCount() < 0) && - !profile_->GetExtensionsService()->IsBeingUpgraded(extension)) { - suppress_chevron_ = true; - SaveDesiredSizeAndAnimate(Tween::LINEAR, visible_actions + 1); - } else { - // Just redraw the (possibly modified) visible icon set. - OnBrowserActionVisibilityChanged(); - } -} - -void BrowserActionsContainer::BrowserActionRemoved(const Extension* extension) { - CloseOverflowMenu(); - - if (popup_ && popup_->host()->extension() == extension) - HidePopup(); - - size_t visible_actions = VisibleBrowserActions(); - for (BrowserActionViews::iterator iter = browser_action_views_.begin(); - iter != browser_action_views_.end(); ++iter) { - if ((*iter)->button()->extension() == extension) { - RemoveChildView(*iter); - delete *iter; - browser_action_views_.erase(iter); - - // If the extension is being upgraded we don't want the bar to shrink - // because the icon is just going to get re-added to the same location. - if (profile_->GetExtensionsService()->IsBeingUpgraded(extension)) - return; - - if (browser_action_views_.size() > visible_actions) { - // If we have more icons than we can show, then we must not be changing - // the container size (since we either removed an icon from the main - // area and one from the overflow list will have shifted in, or we - // removed an entry directly from the overflow list). - OnBrowserActionVisibilityChanged(); - } else { - // Either we went from overflow to no-overflow, or we shrunk the no- - // overflow container by 1. Either way the size changed, so animate. - chevron_->SetVisible(false); - SaveDesiredSizeAndAnimate(Tween::EASE_OUT, - browser_action_views_.size()); - } - return; - } - } -} - -void BrowserActionsContainer::BrowserActionMoved(const Extension* extension, - int index) { - if (!ShouldDisplayBrowserAction(extension)) - return; - - if (profile_->IsOffTheRecord()) - index = model_->OriginalIndexToIncognito(index); - - DCHECK(index >= 0 && index < static_cast<int>(browser_action_views_.size())); - - DeleteBrowserActionViews(); - CreateBrowserActionViews(); - Layout(); - SchedulePaint(); -} - -void BrowserActionsContainer::ModelLoaded() { - SetContainerWidth(); -} - -void BrowserActionsContainer::LoadImages() { - ThemeProvider* tp = GetThemeProvider(); - chevron_->SetIcon(*tp->GetBitmapNamed(IDR_BROWSER_ACTIONS_OVERFLOW)); - chevron_->SetHoverIcon(*tp->GetBitmapNamed(IDR_BROWSER_ACTIONS_OVERFLOW_H)); - chevron_->SetPushedIcon(*tp->GetBitmapNamed(IDR_BROWSER_ACTIONS_OVERFLOW_P)); -} - -void BrowserActionsContainer::SetContainerWidth() { - int visible_actions = model_->GetVisibleIconCount(); - if (visible_actions < 0) // All icons should be visible. - visible_actions = model_->size(); - chevron_->SetVisible(static_cast<size_t>(visible_actions) < model_->size()); - container_width_ = IconCountToWidth(visible_actions, chevron_->IsVisible()); -} - -void BrowserActionsContainer::CloseOverflowMenu() { - if (overflow_menu_) - overflow_menu_->CancelMenu(); -} - -void BrowserActionsContainer::StopShowFolderDropMenuTimer() { - show_menu_task_factory_.RevokeAll(); -} - -void BrowserActionsContainer::StartShowFolderDropMenuTimer() { - int delay = View::GetMenuShowDelay(); - MessageLoop::current()->PostDelayedTask(FROM_HERE, - show_menu_task_factory_.NewRunnableMethod( - &BrowserActionsContainer::ShowDropFolder), - delay); -} - -void BrowserActionsContainer::ShowDropFolder() { - DCHECK(!overflow_menu_); - SetDropIndicator(-1); - overflow_menu_ = new BrowserActionOverflowMenuController( - this, chevron_, browser_action_views_, VisibleBrowserActions()); - overflow_menu_->set_observer(this); - overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), true); -} - -void BrowserActionsContainer::SetDropIndicator(int x_pos) { - if (drop_indicator_position_ != x_pos) { - drop_indicator_position_ = x_pos; - SchedulePaint(); - } -} - -int BrowserActionsContainer::IconCountToWidth(int icons, - bool display_chevron) const { - if (icons < 0) - icons = browser_action_views_.size(); - if ((icons == 0) && !display_chevron) - return ToolbarView::kStandardSpacing; - int icons_size = - (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); - int chevron_size = display_chevron ? - (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; - return ToolbarView::kStandardSpacing + icons_size + chevron_size + - ToolbarView::kStandardSpacing; -} - -size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { - // Check for widths large enough to show the entire icon set. - if (pixels >= IconCountToWidth(-1, false)) - return browser_action_views_.size(); - - // We need to reserve space for the resize area, chevron, and the spacing on - // either side of the chevron. - int available_space = pixels - ToolbarView::kStandardSpacing - - chevron_->GetPreferredSize().width() - kChevronSpacing - - ToolbarView::kStandardSpacing; - // Now we add an extra between-item padding value so the space can be divided - // evenly by (size of icon with padding). - return static_cast<size_t>( - std::max(0, available_space + kItemSpacing) / IconWidth(true)); -} - -int BrowserActionsContainer::ContainerMinSize() const { - return ToolbarView::kStandardSpacing + kChevronSpacing + - chevron_->GetPreferredSize().width() + ToolbarView::kStandardSpacing; -} - -void BrowserActionsContainer::SaveDesiredSizeAndAnimate( - Tween::Type tween_type, - size_t num_visible_icons) { - // Save off the desired number of visible icons. We do this now instead of at - // the end of the animation so that even if the browser is shut down while - // animating, the right value will be restored on next run. - // NOTE: Don't save the icon count in incognito because there may be fewer - // icons in that mode. The result is that the container in a normal window is - // always at least as wide as in an incognito window. - if (!profile_->IsOffTheRecord()) - model_->SetVisibleIconCount(num_visible_icons); - - int target_size = IconCountToWidth(num_visible_icons, - num_visible_icons < browser_action_views_.size()); - if (!disable_animations_during_testing_) { - // Animate! We have to set the animation_target_size_ after calling Reset(), - // because that could end up calling AnimationEnded which clears the value. - resize_animation_->Reset(); - resize_animation_->SetTweenType(tween_type); - animation_target_size_ = target_size; - resize_animation_->Show(); - } else { - animation_target_size_ = target_size; - AnimationEnded(resize_animation_.get()); - } -} - -bool BrowserActionsContainer::ShouldDisplayBrowserAction( - const Extension* extension) { - // Only display incognito-enabled extensions while in incognito mode. - return (!profile_->IsOffTheRecord() || - profile_->GetExtensionsService()->IsIncognitoEnabled(extension)); -} diff --git a/chrome/browser/views/browser_actions_container.h b/chrome/browser/views/browser_actions_container.h index 0bc5fdd..0b6b094 100644 --- a/chrome/browser/views/browser_actions_container.h +++ b/chrome/browser/views/browser_actions_container.h @@ -6,504 +6,8 @@ #define CHROME_BROWSER_VIEWS_BROWSER_ACTIONS_CONTAINER_H_ #pragma once -#include <set> -#include <string> -#include <vector> - -#include "app/slide_animation.h" -#include "base/task.h" -#include "chrome/browser/extensions/extension_context_menu_model.h" -#include "chrome/browser/extensions/extension_toolbar_model.h" -#include "chrome/browser/extensions/image_loading_tracker.h" -#include "chrome/browser/views/browser_bubble.h" -#include "chrome/browser/views/extensions/browser_action_overflow_menu_controller.h" -#include "chrome/browser/views/extensions/extension_popup.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/menu/view_menu_delegate.h" -#include "views/controls/resize_area.h" -#include "views/view.h" - -class Browser; -class BrowserActionsContainer; -class BrowserActionOverflowMenuController; -class BrowserActionsContainer; -class Extension; -class ExtensionAction; -class ExtensionPopup; -class PrefService; -class Profile; - -namespace gfx { -class CanvasSkia; -} - -namespace views { -class Menu2; -} - -//////////////////////////////////////////////////////////////////////////////// -// BrowserActionButton - -// The BrowserActionButton is a specialization of the MenuButton class. -// It acts on a ExtensionAction, in this case a BrowserAction and handles -// loading the image for the button asynchronously on the file thread. -class BrowserActionButton : public views::MenuButton, - public views::ButtonListener, - public ImageLoadingTracker::Observer, - public NotificationObserver { - public: - BrowserActionButton(const Extension* extension, - BrowserActionsContainer* panel); - - // Call this instead of delete. - void Destroy(); - - ExtensionAction* browser_action() const { return browser_action_; } - const Extension* extension() { return extension_; } - - // Called to update the display to match the browser action's state. - void UpdateState(); - - // Returns the default icon, if any. - const SkBitmap& default_icon() const { return default_icon_; } - - // Overridden from views::View: - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from ImageLoadingTracker. - virtual void OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index); - - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // MenuButton behavior overrides. These methods all default to TextButton - // behavior unless this button is a popup. In that case, it uses MenuButton - // behavior. MenuButton has the notion of a child popup being shown where the - // button will stay in the pushed state until the "menu" (a popup in this - // case) is dismissed. - virtual bool Activate(); - virtual bool OnMousePressed(const views::MouseEvent& e); - virtual void OnMouseReleased(const views::MouseEvent& e, bool canceled); - virtual bool OnKeyReleased(const views::KeyEvent& e); - virtual void OnMouseExited(const views::MouseEvent& event); - virtual void ShowContextMenu(const gfx::Point& p, bool is_mouse_gesture); - - // Does this button's action have a popup? - virtual bool IsPopup(); - virtual GURL GetPopupUrl(); - - // Notifications when to set button state to pushed/not pushed (for when the - // popup/context menu is hidden or shown by the container). - void SetButtonPushed(); - void SetButtonNotPushed(); - - private: - virtual ~BrowserActionButton(); - - // The browser action this view represents. The ExtensionAction is not owned - // by this class. - ExtensionAction* browser_action_; - - // The extension associated with the browser action we're displaying. - const Extension* extension_; - - // The object that is waiting for the image loading to complete - // asynchronously. - ImageLoadingTracker tracker_; - - // Whether we are currently showing/just finished showing a context menu. - bool showing_context_menu_; - - // The default icon for our browser action. This might be non-empty if the - // browser action had a value for default_icon in the manifest. - SkBitmap default_icon_; - - // The browser action shelf. - BrowserActionsContainer* panel_; - - scoped_refptr<ExtensionContextMenuModel> context_menu_contents_; - scoped_ptr<views::Menu2> context_menu_menu_; - - NotificationRegistrar registrar_; - - friend class DeleteTask<BrowserActionButton>; - - DISALLOW_COPY_AND_ASSIGN(BrowserActionButton); -}; - - -//////////////////////////////////////////////////////////////////////////////// -// BrowserActionView -// A single section in the browser action container. This contains the actual -// BrowserActionButton, as well as the logic to paint the badge. - -class BrowserActionView : public views::View { - public: - BrowserActionView(const Extension* extension, BrowserActionsContainer* panel); - virtual ~BrowserActionView(); - - BrowserActionButton* button() { return button_; } - - // Allocates a canvas object on the heap and draws into it the icon for the - // view as well as the badge (if any). Caller is responsible for deleting the - // returned object. - gfx::Canvas* GetIconWithBadge(); - - // Accessibility accessors, overridden from View. - virtual AccessibilityTypes::Role GetAccessibleRole(); - - private: - virtual void Layout(); - - // Override PaintChildren so that we can paint the badge on top of children. - virtual void PaintChildren(gfx::Canvas* canvas); - - // The container for this view. - BrowserActionsContainer* panel_; - - // The button this view contains. - BrowserActionButton* button_; - - DISALLOW_COPY_AND_ASSIGN(BrowserActionView); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// The BrowserActionsContainer is a container view, responsible for drawing the -// browser action icons (extensions that add icons to the toolbar). -// -// The container is placed flush against the omnibox and wrench menu, and its -// layout looks like: -// rI_I_IcCs -// Where the letters are as follows: -// r: An invisible resize area. This is ToolbarView::kStandardSpacing pixels -// wide and directly adjacent to the omnibox. -// I: An icon. This is as wide as the IDR_BROWSER_ACTION image. -// _: kItemSpacing pixels of empty space. -// c: kChevronSpacing pixels of empty space. Only present if C is present. -// C: An optional chevron, visible for overflow. As wide as the -// IDR_BROWSER_ACTIONS_OVERFLOW image. -// s: ToolbarView::kStandardSpacing pixels of empty space (before the wrench -// menu). -// The reason the container contains the trailing space "s", rather than having -// it be handled by the parent view, is so that when the chevron is invisible -// and the user starts dragging an icon around, we have the space to draw the -// ultimate drop indicator. (Otherwise, we'd be trying to draw it into the -// padding beyond our right edge, and it wouldn't appear.) -// -// The BrowserActionsContainer follows a few rules, in terms of user experience: -// -// 1) The container can never grow beyond the space needed to show all icons -// (hereby referred to as the max width). -// 2) The container can never shrink below the space needed to show just the -// initial padding and the chevron (ignoring the case where there are no icons -// to show, in which case the container won't be visible anyway). -// 3) The container snaps into place (to the pixel count that fits the visible -// icons) to make sure there is no wasted space at the edges of the container. -// 4) If the user adds or removes icons (read: installs/uninstalls browser -// actions) we grow and shrink the container as needed - but ONLY if the -// container was at max width to begin with. -// 5) If the container is NOT at max width (has an overflow menu), we respect -// that size when adding and removing icons and DON'T grow/shrink the container. -// This means that new icons (which always appear at the far right) will show up -// in the overflow menu. The install bubble for extensions points to the chevron -// menu in this case. -// -// Resizing the BrowserActionsContainer: -// -// The ResizeArea view sends OnResize messages to the BrowserActionsContainer -// class as the user drags it. This modifies the value for |resize_amount_|. -// That indicates to the container that a resize is in progress and is used to -// calculate the size in GetPreferredSize(), though that function never exceeds -// the defined minimum and maximum size of the container. -// -// When the user releases the mouse (ends the resize), we calculate a target -// size for the container (animation_target_size_), clamp that value to the -// containers min and max and then animate from the *current* position (that the -// user has dragged the view to) to the target size. -// -// Animating the BrowserActionsContainer: -// -// Animations are used when snapping the container to a value that fits all -// visible icons. This can be triggered when the user finishes resizing the -// container or when Browser Actions are added/removed. -// -// We always animate from the current width (container_width_) to the target -// size (animation_target_size_), using |resize_amount| to keep track of the -// animation progress. -// -// NOTE: When adding Browser Actions to a maximum width container (no overflow) -// we make sure to suppress the chevron menu if it wasn't visible. This is -// because we won't have enough space to show the new Browser Action until the -// animation ends and we don't want the chevron to flash into view while we are -// growing the container. -// -//////////////////////////////////////////////////////////////////////////////// -class BrowserActionsContainer - : public views::View, - public views::ViewMenuDelegate, - public views::DragController, - public views::ResizeArea::ResizeAreaDelegate, - public AnimationDelegate, - public ExtensionToolbarModel::Observer, - public BrowserActionOverflowMenuController::Observer, - public ExtensionContextMenuModel::PopupDelegate, - public ExtensionPopup::Observer { - public: - BrowserActionsContainer(Browser* browser, views::View* owner_view); - virtual ~BrowserActionsContainer(); - - static void RegisterUserPrefs(PrefService* prefs); - - void Init(); - - // Get the number of browser actions being displayed. - int num_browser_actions() const { return browser_action_views_.size(); } - - // Whether we are performing resize animation on the container. - bool animating() const { return animation_target_size_ > 0; } - - // Returns the chevron, if any. - const views::View* chevron() const { return chevron_; } - - // Returns the profile this container is associated with. - Profile* profile() const { return profile_; } - - // Returns the browser this container is associated with. - Browser* browser() const { return browser_; } - - // Returns the current tab's ID, or -1 if there is no current tab. - int GetCurrentTabId() const; - - // Get a particular browser action view. - BrowserActionView* GetBrowserActionViewAt(int index) { - return browser_action_views_[index]; - } - - // Retrieve the BrowserActionView for |extension|. - BrowserActionView* GetBrowserActionView(ExtensionAction* action); - - // Update the views to reflect the state of the browser action icons. - void RefreshBrowserActionViews(); - - // Sets up the browser action view vector. - void CreateBrowserActionViews(); - - // Delete all browser action views. - void DeleteBrowserActionViews(); - - // Called when a browser action becomes visible/hidden. - void OnBrowserActionVisibilityChanged(); - - // Returns how many browser actions are visible. - size_t VisibleBrowserActions() const; - - // Called when the user clicks on the browser action icon. - void OnBrowserActionExecuted(BrowserActionButton* button, - bool inspect_with_devtools); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - virtual bool GetDropFormats( - int* formats, std::set<OSExchangeData::CustomFormat>* custom_formats); - virtual bool AreDropTypesRequired(); - virtual bool CanDrop(const OSExchangeData& data); - virtual void OnDragEntered(const views::DropTargetEvent& event); - virtual int OnDragUpdated(const views::DropTargetEvent& event); - virtual void OnDragExited(); - virtual int OnPerformDrop(const views::DropTargetEvent& event); - virtual void OnThemeChanged(); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // Overridden from views::ViewMenuDelegate: - virtual void RunMenu(View* source, const gfx::Point& pt); - - // Overridden from views::DragController: - virtual void WriteDragData(View* sender, - const gfx::Point& press_pt, - OSExchangeData* data); - virtual int GetDragOperations(View* sender, const gfx::Point& p); - virtual bool CanStartDrag(View* sender, - const gfx::Point& press_pt, - const gfx::Point& p); - - // Overridden from ResizeArea::ResizeAreaDelegate: - virtual void OnResize(int resize_amount, bool done_resizing); - - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation); - virtual void AnimationEnded(const Animation* animation); - - // Overridden from BrowserActionOverflowMenuController::Observer: - virtual void NotifyMenuDeleted( - BrowserActionOverflowMenuController* controller); - - // Overridden from ExtensionContextMenuModel::PopupDelegate - virtual void InspectPopup(ExtensionAction* action); - - // Overriden from ExtensionPopup::Delegate - virtual void ExtensionPopupIsClosing(ExtensionPopup* popup); - - // Moves a browser action with |id| to |new_index|. - void MoveBrowserAction(const std::string& extension_id, size_t new_index); - - // Hide the current popup. - void HidePopup(); - - // Simulate a click on a browser action button. This should only be - // used by unit tests. - void TestExecuteBrowserAction(int index); - - // Retrieve the current popup. This should only be used by unit tests. - ExtensionPopup* TestGetPopup() { return popup_; } - - // Set how many icons the container should show. This should only be used by - // unit tests. - void TestSetIconVisibilityCount(size_t icons); - - // During testing we can disable animations by setting this flag to true, - // so that the bar resizes instantly, instead of having to poll it while it - // animates to open/closed status. - static bool disable_animations_during_testing_; - - private: - friend class BrowserActionView; // So it can access IconHeight(). - friend class ShowFolderMenuTask; - - typedef std::vector<BrowserActionView*> BrowserActionViews; - - // Returns the width of an icon, optionally with its padding. - static int IconWidth(bool include_padding); - - // Returns the height of an icon. - static int IconHeight(); - - // ExtensionToolbarModel::Observer implementation. - virtual void BrowserActionAdded(const Extension* extension, int index); - virtual void BrowserActionRemoved(const Extension* extension); - virtual void BrowserActionMoved(const Extension* extension, int index); - virtual void ModelLoaded(); - - void LoadImages(); - - // Sets the initial container width. - void SetContainerWidth(); - - // Closes the overflow menu if open. - void CloseOverflowMenu(); - - // Cancels the timer for showing the drop down menu. - void StopShowFolderDropMenuTimer(); - - // Show the drop down folder after a slight delay. - void StartShowFolderDropMenuTimer(); - - // Show the overflow menu. - void ShowDropFolder(); - - // Sets the drop indicator position (and schedules paint if the position has - // changed). - void SetDropIndicator(int x_pos); - - // Given a number of |icons| and whether to |display_chevron|, returns the - // amount of pixels needed to draw the entire container. For convenience, - // callers can set |icons| to -1 to mean "all icons". - int IconCountToWidth(int icons, bool display_chevron) const; - - // Given a pixel width, returns the number of icons that fit. (This - // automatically determines whether a chevron will be needed and includes it - // in the calculation.) - size_t WidthToIconCount(int pixels) const; - - // Returns the absolute minimum size you can shrink the container down to and - // still show it. This assumes a visible chevron because the only way we - // would not have a chevron when shrinking down this far is if there were no - // icons, in which case the container wouldn't be shown at all. - int ContainerMinSize() const; - - // Animate to the target size (unless testing, in which case we go straight to - // the target size). This also saves the target number of visible icons in - // the pref if we're not off the record. - void SaveDesiredSizeAndAnimate(Tween::Type type, size_t num_visible_icons); - - // Returns true if this extension should be shown in this toolbar. This can - // return false if we are in an incognito window and the extension is disabled - // for incognito. - bool ShouldDisplayBrowserAction(const Extension* extension); - - // The vector of browser actions (icons/image buttons for each action). Note - // that not every BrowserAction in the ToolbarModel will necessarily be in - // this collection. Some extensions may be disabled in incognito windows. - BrowserActionViews browser_action_views_; - - Profile* profile_; - - // The Browser object the container is associated with. - Browser* browser_; - - // The view that owns us. - views::View* owner_view_; - - // The current popup and the button it came from. NULL if no popup. - ExtensionPopup* popup_; - - // The button that triggered the current popup (just a reference to a button - // from browser_action_views_). - BrowserActionButton* popup_button_; - - // The model that tracks the order of the toolbar icons. - ExtensionToolbarModel* model_; - - // The current width of the container. - int container_width_; - - // The resize area for the container. - views::ResizeArea* resize_area_; - - // The chevron for accessing the overflow items. - views::MenuButton* chevron_; - - // The menu to show for the overflow button (chevron). This class manages its - // own lifetime so that it can stay alive during drag and drop operations. - BrowserActionOverflowMenuController* overflow_menu_; - - // The animation that happens when the container snaps to place. - scoped_ptr<SlideAnimation> resize_animation_; - - // Don't show the chevron while animating. - bool suppress_chevron_; - - // This is used while the user is resizing (and when the animations are in - // progress) to know how wide the delta is between the current state and what - // we should draw. - int resize_amount_; - - // Keeps track of the absolute pixel width the container should have when we - // are done animating. - int animation_target_size_; - - // The x position for where to draw the drop indicator. -1 if no indicator. - int drop_indicator_position_; - - ScopedRunnableMethodFactory<BrowserActionsContainer> task_factory_; - - // Handles delayed showing of the overflow menu when hovering. - ScopedRunnableMethodFactory<BrowserActionsContainer> show_menu_task_factory_; - - DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainer); -}; +#include "chrome/browser/ui/views/browser_actions_container.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BROWSER_ACTIONS_CONTAINER_H_ + diff --git a/chrome/browser/views/browser_actions_container_browsertest.cc b/chrome/browser/views/browser_actions_container_browsertest.cc deleted file mode 100644 index ee30ddb..0000000 --- a/chrome/browser/views/browser_actions_container_browsertest.cc +++ /dev/null @@ -1,200 +0,0 @@ -// 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/browser.h" -#include "chrome/browser/extensions/browser_action_test_util.h" -#include "chrome/browser/extensions/extension_browsertest.h" -#include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/browser_actions_container.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/extension_action.h" -#include "chrome/common/extensions/extension_resource.h" - -class BrowserActionsContainerTest : public ExtensionBrowserTest { - public: - BrowserActionsContainerTest() { - } - virtual ~BrowserActionsContainerTest() {} - - virtual Browser* CreateBrowser(Profile* profile) { - Browser* b = InProcessBrowserTest::CreateBrowser(profile); - browser_actions_bar_.reset(new BrowserActionTestUtil(b)); - return b; - } - - BrowserActionTestUtil* browser_actions_bar() { - return browser_actions_bar_.get(); - } - - // Make sure extension with index |extension_index| has an icon. - void EnsureExtensionHasIcon(int extension_index) { - if (!browser_actions_bar_->HasIcon(extension_index)) { - // The icon is loaded asynchronously and a notification is then sent to - // observers. So we wait on it. - browser_actions_bar_->WaitForBrowserActionUpdated(extension_index); - } - EXPECT_TRUE(browser_actions_bar()->HasIcon(extension_index)); - } - - private: - scoped_ptr<BrowserActionTestUtil> browser_actions_bar_; -}; - -// Test the basic functionality. -IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, Basic) { - BrowserActionsContainer::disable_animations_during_testing_ = true; - - // Load an extension with no browser action. - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") - .AppendASCII("browser_action") - .AppendASCII("none"))); - // This extension should not be in the model (has no browser action). - EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions()); - - // Load an extension with a browser action. - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") - .AppendASCII("browser_action") - .AppendASCII("basics"))); - EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions()); - EnsureExtensionHasIcon(0); - - // Unload the extension. - std::string id = browser_actions_bar()->GetExtensionId(0); - UnloadExtension(id); - EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions()); -} - -// TODO(mpcomplete): http://code.google.com/p/chromium/issues/detail?id=38992 -// Disabled, http://crbug.com/38992. -IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, DISABLED_Visibility) { - BrowserActionsContainer::disable_animations_during_testing_ = true; - - // Load extension A (contains browser action). - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") - .AppendASCII("browser_action") - .AppendASCII("basics"))); - EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions()); - EnsureExtensionHasIcon(0); - EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); - std::string idA = browser_actions_bar()->GetExtensionId(0); - - // Load extension B (contains browser action). - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") - .AppendASCII("browser_action") - .AppendASCII("add_popup"))); - EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); - EnsureExtensionHasIcon(0); - EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions()); - std::string idB = browser_actions_bar()->GetExtensionId(1); - - EXPECT_NE(idA, idB); - - // Load extension C (contains browser action). - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") - .AppendASCII("browser_action") - .AppendASCII("remove_popup"))); - EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); - EnsureExtensionHasIcon(2); - EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); - std::string idC = browser_actions_bar()->GetExtensionId(2); - - // Change container to show only one action, rest in overflow: A, [B, C]. - browser_actions_bar()->SetIconVisibilityCount(1); - EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); - - // Disable extension A (should disappear). State becomes: B [C]. - DisableExtension(idA); - EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0)); - - // Enable A again. A should get its spot in the same location and the bar - // should not grow (chevron is showing). For details: http://crbug.com/35349. - // State becomes: A, [B, C]. - EnableExtension(idA); - EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0)); - - // Disable C (in overflow). State becomes: A, [B]. - DisableExtension(idC); - EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0)); - - // Enable C again. State becomes: A, [B, C]. - EnableExtension(idC); - EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0)); - - // Now we have 3 extensions. Make sure they are all visible. State: A, B, C. - browser_actions_bar()->SetIconVisibilityCount(3); - EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); - - // Disable extension A (should disappear). State becomes: B, C. - DisableExtension(idA); - EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0)); - - // Disable extension B (should disappear). State becomes: C. - DisableExtension(idB); - EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idC, browser_actions_bar()->GetExtensionId(0)); - - // Enable B (makes B and C showing now). State becomes: B, C. - EnableExtension(idB); - EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0)); - - // Enable A (makes A, B and C showing now). State becomes: B, C, A. - EnableExtension(idA); - EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); - EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); - EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(2)); -} - -IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, TestCrash57536) { - std::cout << "Test starting\n" << std::flush; - - ExtensionsService* service = browser()->profile()->GetExtensionsService(); - const size_t size_before = service->extensions()->size(); - - std::cout << "Loading extension\n" << std::flush; - - // Load extension A (contains browser action). - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") - .AppendASCII("browser_action") - .AppendASCII("crash_57536"))); - - const Extension* extension = service->extensions()->at(size_before); - - std::cout << "Creating bitmap\n" << std::flush; - - // Create and cache and empty bitmap. - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, - Extension::kBrowserActionIconMaxSize, - Extension::kBrowserActionIconMaxSize); - bitmap.allocPixels(); - - std::cout << "Set as cached image\n" << std::flush; - - gfx::Size size(Extension::kBrowserActionIconMaxSize, - Extension::kBrowserActionIconMaxSize); - extension->SetCachedImage( - extension->GetResource(extension->browser_action()->default_icon_path()), - bitmap, - size); - - std::cout << "Disabling extension\n" << std::flush; - DisableExtension(extension->id()); - std::cout << "Enabling extension\n" << std::flush; - EnableExtension(extension->id()); - std::cout << "Test ending\n" << std::flush; -} diff --git a/chrome/browser/views/browser_bubble.cc b/chrome/browser/views/browser_bubble.cc deleted file mode 100644 index a118852..0000000 --- a/chrome/browser/views/browser_bubble.cc +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2009 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/browser_bubble.h" - -#include "chrome/browser/views/frame/browser_view.h" -#if defined(OS_WIN) -#include "chrome/browser/external_tab_container_win.h" -#endif -#include "views/widget/root_view.h" -#include "views/window/window.h" - -namespace { - -BrowserBubbleHost* GetBubbleHostFromFrame(views::Widget* frame) { - if (!frame) - return NULL; - - BrowserBubbleHost* bubble_host = NULL; - views::Window* window = frame->GetWindow(); - if (window) { - bubble_host = BrowserView::GetBrowserViewForNativeWindow( - window->GetNativeWindow()); - DCHECK(bubble_host); - } -#if defined(OS_WIN) - // The frame may also be an ExternalTabContainer, which is also capable of - // hosting BrowserBubbles. - gfx::NativeView native_view = frame->GetNativeView(); - if (!bubble_host) { - bubble_host = - ExternalTabContainer::GetExternalContainerFromNativeWindow(native_view); - } -#endif - return bubble_host; -} - -} // namespace - -BrowserBubble::BrowserBubble(views::View* view, views::Widget* frame, - const gfx::Point& origin, bool drop_shadow) - : frame_(frame), - view_(view), - visible_(false), - delegate_(NULL), - attached_(false), - drop_shadow_enabled_(drop_shadow), - bubble_host_(GetBubbleHostFromFrame(frame)) { - gfx::Size size = view->GetPreferredSize(); - bounds_.SetRect(origin.x(), origin.y(), size.width(), size.height()); - InitPopup(); -} - -BrowserBubble::~BrowserBubble() { - DCHECK(!attached_); - popup_->Close(); - - // Don't call DetachFromBrowser from here. It needs to talk to the - // BrowserView to deregister itself, and if BrowserBubble is owned - // by a child of BrowserView, then it's possible that this stack frame - // is a descendant of BrowserView's destructor, which leads to problems. - // In that case, Detach doesn't need to get called anyway since BrowserView - // will do the necessary cleanup. -} - -void BrowserBubble::DetachFromBrowser() { - DCHECK(attached_); - if (!attached_) - return; - attached_ = false; - - if (bubble_host_) - bubble_host_->DetachBrowserBubble(this); -} - -void BrowserBubble::AttachToBrowser() { - DCHECK(!attached_); - if (attached_) - return; - - if (bubble_host_) - bubble_host_->AttachBrowserBubble(this); - - attached_ = true; -} - -void BrowserBubble::BrowserWindowMoved() { - if (delegate_) - delegate_->BubbleBrowserWindowMoved(this); - else - Hide(); - if (visible_) - Reposition(); -} - -void BrowserBubble::BrowserWindowClosing() { - if (delegate_) - delegate_->BubbleBrowserWindowClosing(this); - else - Hide(); -} - -void BrowserBubble::SetBounds(int x, int y, int w, int h) { - // If the UI layout is RTL, we don't need to mirror coordinates, since - // View logic will do that for us. - bounds_.SetRect(x, y, w, h); - Reposition(); -} - -void BrowserBubble::MoveTo(int x, int y) { - SetBounds(x, y, bounds_.width(), bounds_.height()); -} - -void BrowserBubble::Reposition() { - gfx::Point top_left; - views::View::ConvertPointToScreen(frame_->GetRootView(), &top_left); - MovePopup(top_left.x() + bounds_.x(), - top_left.y() + bounds_.y(), - bounds_.width(), - bounds_.height()); -} - -void BrowserBubble::ResizeToView() { - SetBounds(bounds_.x(), bounds_.y(), view_->width(), view_->height()); -} diff --git a/chrome/browser/views/browser_bubble.h b/chrome/browser/views/browser_bubble.h index 790c677..cc4352c 100644 --- a/chrome/browser/views/browser_bubble.h +++ b/chrome/browser/views/browser_bubble.h @@ -6,126 +6,8 @@ #define CHROME_BROWSER_VIEWS_BROWSER_BUBBLE_H_ #pragma once -#include "views/view.h" -#include "views/widget/widget.h" - -class BrowserBubbleHost; - -// A class for creating a floating window that is "attached" to a particular -// Browser. If you don't install a delegate, the bubble will hide -// automatically when the browser moves. The bubble is only shown manually. -// Users are expected to delete the bubble when finished with it. -// Class assumes that RTL related mirroring is done by the view. -class BrowserBubble { - public: - // Delegate to browser bubble events. - class Delegate { - public: - // Called when the Browser Window that this bubble is attached to moves. - virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble) {} - - // Called with the Browser Window that this bubble is attached to is - // about to close. - virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble) {} - - // Called when the bubble became active / got focus. - virtual void BubbleGotFocus(BrowserBubble* bubble) {} - - // Called when the bubble became inactive / lost focus. - // |lost_focus_to_child| is true when a child window became active. - virtual void BubbleLostFocus(BrowserBubble* bubble, - bool lost_focus_to_child) {} - }; - - // Note that the bubble will size itself to the preferred size of |view|. - // |view| is the embedded view, |frame| is widget that the bubble is being - // positioned relative to, |origin| is the location that the bubble will - // be positioned relative to |frame|. Pass true through |drop_shadow| to - // surround the bubble widget with a drop-shadow. - BrowserBubble(views::View* view, views::Widget* frame, - const gfx::Point& origin, bool drop_shadow); - virtual ~BrowserBubble(); - - // Call manually if you need to detach the bubble from tracking the browser's - // position. Note that you must call this manually before deleting this - // object since it can't be safely called from the destructor. - void DetachFromBrowser(); - - // Normally called automatically during construction, but if DetachFromBrowser - // has been called manually, then this call will reattach. - void AttachToBrowser(); - bool attached() const { return attached_; } - - // Get/Set the delegate. - Delegate* delegate() const { return delegate_; } - void set_delegate(Delegate* del) { delegate_ = del; } - - // Notifications from BrowserBubbleHost. - // With no delegate, both of these default to Hiding the bubble. - virtual void BrowserWindowMoved(); - virtual void BrowserWindowClosing(); - - // Show or hide the bubble. - virtual void Show(bool activate); - virtual void Hide(); - bool visible() const { return visible_; } - - // The contained view. - views::View* view() const { return view_; } - - // Set the bounds of the bubble relative to the browser window. - void SetBounds(int x, int y, int w, int h); - void MoveTo(int x, int y); - int width() { return bounds_.width(); } - int height() { return bounds_.height(); } - const gfx::Rect& bounds() const { return bounds_; } - - // Reposition the bubble - as we are using a WS_POPUP for the bubble, - // we have to manually position it when the browser window moves. - void Reposition(); - - // Resize the bubble to fit the view. - void ResizeToView(); - - // Returns the NativeView containing that popup. - gfx::NativeView native_view() const { return popup_->GetNativeView(); } - - protected: - // Create the popup widget. - virtual void InitPopup(); - - // Move the popup to an absolute position. - void MovePopup(int x, int y, int w, int h); - - // The widget that this bubble is in. - views::Widget* popup_; - - // The frame that this bubble is attached to. - views::Widget* frame_; - - private: - // The view that is displayed in this bubble. - views::View* view_; - - // The bounds relative to the frame. - gfx::Rect bounds_; - - // Current visibility. - bool visible_; - - // The delegate isn't owned by the bubble. - Delegate* delegate_; - - // Is the bubble attached to a Browser window. - bool attached_; - - // Does the bubble have a drop-shadow. - bool drop_shadow_enabled_; - - // Non-owning pointer to the host of this bubble. - BrowserBubbleHost* bubble_host_; - - DISALLOW_COPY_AND_ASSIGN(BrowserBubble); -}; +#include "chrome/browser/ui/views/browser_bubble.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BROWSER_BUBBLE_H_ + diff --git a/chrome/browser/views/browser_bubble_gtk.cc b/chrome/browser/views/browser_bubble_gtk.cc deleted file mode 100644 index 7f18070..0000000 --- a/chrome/browser/views/browser_bubble_gtk.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2009 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/browser_bubble.h" - -#include "chrome/browser/views/frame/browser_view.h" -#include "views/widget/widget_gtk.h" -#include "views/window/window.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/wm_ipc.h" -#include "cros/chromeos_wm_ipc_enums.h" -#endif - -namespace { - -class BubbleWidget : public views::WidgetGtk { - public: - explicit BubbleWidget(BrowserBubble* bubble) - : views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW), - bubble_(bubble) { - } - - void Show(bool activate) { - // TODO: honor activate. - views::WidgetGtk::Show(); - } - - virtual void Close() { - if (!bubble_) - return; // We have already been closed. - if (IsActive()) { - BrowserBubble::Delegate* delegate = bubble_->delegate(); - if (delegate) - delegate->BubbleLostFocus(bubble_, false); - } - views::WidgetGtk::Close(); - bubble_ = NULL; - } - - virtual void Hide() { - if (IsActive()&& bubble_) { - BrowserBubble::Delegate* delegate = bubble_->delegate(); - if (delegate) - delegate->BubbleLostFocus(bubble_, false); - } - views::WidgetGtk::Hide(); - } - - virtual void IsActiveChanged() { - if (IsActive() || !bubble_) - return; - BrowserBubble::Delegate* delegate = bubble_->delegate(); - if (!delegate) { - bubble_->DetachFromBrowser(); - delete bubble_; - return; - } - - // TODO(jcampan): http://crbugs.com/29131 Check if the window we are losing - // focus to is a child window and pass that to the call - // below. - delegate->BubbleLostFocus(bubble_, false); - } - - virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event) { - if (bubble_ && bubble_->delegate()) - bubble_->delegate()->BubbleGotFocus(bubble_); - return views::WidgetGtk::OnFocusIn(widget, event); - } - - private: - BrowserBubble* bubble_; - - DISALLOW_COPY_AND_ASSIGN(BubbleWidget); -}; - -} // namespace - -void BrowserBubble::InitPopup() { - // TODO(port) - DCHECK(!drop_shadow_enabled_) << - "Drop shadows not supported on GTK browser bubbles."; - - views::WidgetGtk* pop = new BubbleWidget(this); - pop->SetOpacity(0xFF); - pop->make_transient_to_parent(); - pop->Init(frame_->GetNativeView(), bounds_); -#if defined(OS_CHROMEOS) - chromeos::WmIpc::instance()->SetWindowType( - pop->GetNativeView(), - chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE, - NULL); -#endif - pop->SetContentsView(view_); - popup_ = pop; - Reposition(); - AttachToBrowser(); -} - -void BrowserBubble::MovePopup(int x, int y, int w, int h) { - views::WidgetGtk* pop = static_cast<views::WidgetGtk*>(popup_); - pop->SetBounds(gfx::Rect(x, y, w, h)); -} - -void BrowserBubble::Show(bool activate) { - if (visible_) - return; - static_cast<BubbleWidget*>(popup_)->Show(activate); - visible_ = true; -} - -void BrowserBubble::Hide() { - if (!visible_) - return; - views::WidgetGtk* pop = static_cast<views::WidgetGtk*>(popup_); - pop->Hide(); - visible_ = false; -} diff --git a/chrome/browser/views/browser_bubble_win.cc b/chrome/browser/views/browser_bubble_win.cc deleted file mode 100644 index 84985fd..0000000 --- a/chrome/browser/views/browser_bubble_win.cc +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2009 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/browser_bubble.h" - -#include "chrome/browser/views/frame/browser_view.h" -#include "views/widget/root_view.h" -#include "views/widget/widget_win.h" -#include "views/window/window.h" - -class BubbleWidget : public views::WidgetWin { - public: - explicit BubbleWidget(BrowserBubble* bubble) - : bubble_(bubble) { - set_window_style(WS_POPUP | WS_CLIPCHILDREN); - set_window_ex_style(WS_EX_TOOLWINDOW); - } - - void Show(bool activate) { - if (activate) - ShowWindow(SW_SHOW); - else - views::WidgetWin::Show(); - } - - void Close() { - if (!bubble_) - return; // We have already been closed. - if (IsActive()) { - BrowserBubble::Delegate* delegate = bubble_->delegate(); - if (delegate) - delegate->BubbleLostFocus(bubble_, NULL); - } - views::WidgetWin::Close(); - bubble_ = NULL; - } - - void Hide() { - if (IsActive() && bubble_) { - BrowserBubble::Delegate* delegate = bubble_->delegate(); - if (delegate) - delegate->BubbleLostFocus(bubble_, NULL); - } - views::WidgetWin::Hide(); - } - - void OnActivate(UINT action, BOOL minimized, HWND window) { - WidgetWin::OnActivate(action, minimized, window); - if (!bubble_) - return; - - BrowserBubble::Delegate* delegate = bubble_->delegate(); - if (!delegate) { - if (action == WA_INACTIVE) { - bubble_->DetachFromBrowser(); - delete bubble_; - } - return; - } - - if (action == WA_INACTIVE) { - bool lost_focus_to_child = false; - - // Are we a parent of this window? - gfx::NativeView parent = window; - while (parent = ::GetParent(parent)) { - if (window == GetNativeView()) { - lost_focus_to_child = true; - break; - } - } - - // Do we own this window? - if (!lost_focus_to_child && - ::GetWindow(window, GW_OWNER) == GetNativeView()) { - lost_focus_to_child = true; - } - - delegate->BubbleLostFocus(bubble_, lost_focus_to_child); - } - } - - virtual void OnSetFocus(HWND focused_window) { - WidgetWin::OnSetFocus(focused_window); - if (bubble_ && bubble_->delegate()) - bubble_->delegate()->BubbleGotFocus(bubble_); - } - - private: - BrowserBubble* bubble_; - - DISALLOW_COPY_AND_ASSIGN(BubbleWidget); -}; - -void BrowserBubble::InitPopup() { - // popup_ is a Widget, but we need to do some WidgetWin stuff first, then - // we'll assign it into popup_. - views::WidgetWin* pop = new BubbleWidget(this); - - // Enable the drop-shadow through the native windows drop-shadow support. - if (drop_shadow_enabled_) - pop->set_initial_class_style(CS_DROPSHADOW | pop->initial_class_style()); - - pop->Init(frame_->GetNativeView(), bounds_); - pop->SetContentsView(view_); - - popup_ = pop; - Reposition(); - AttachToBrowser(); -} - -void BrowserBubble::MovePopup(int x, int y, int w, int h) { - views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_); - pop->SetBounds(gfx::Rect(x, y, w, h)); -} - -void BrowserBubble::Show(bool activate) { - if (visible_) - return; - BubbleWidget* pop = static_cast<BubbleWidget*>(popup_); - pop->Show(activate); - visible_ = true; -} - -void BrowserBubble::Hide() { - if (!visible_) - return; - views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_); - pop->Hide(); - visible_ = false; -} diff --git a/chrome/browser/views/browser_dialogs.h b/chrome/browser/views/browser_dialogs.h index 8affac9..ebff745 100644 --- a/chrome/browser/views/browser_dialogs.h +++ b/chrome/browser/views/browser_dialogs.h @@ -6,125 +6,8 @@ #define CHROME_BROWSER_VIEWS_BROWSER_DIALOGS_H_ #pragma once -#include <string> - -#include "chrome/common/content_settings_types.h" -#include "gfx/native_widget_types.h" - -// This file contains functions for running a variety of browser dialogs and -// popups. The dialogs here are the ones that the caller does not need to -// access the class of the popup. It allows us to break dependencies by -// allowing the callers to not depend on the classes implementing the dialogs. - -class Browser; -class BrowserView; -class EditSearchEngineControllerDelegate; -class FilePath; -class FindBar; -class GURL; -class HtmlDialogUIDelegate; -class InfoBubbleDelegate; -class Profile; -class TabContents; -class TemplateURL; - -namespace gfx { -class Rect; -class Size; -} // namespace gfx - -namespace views { -class Widget; -class Window; -} // namespace views - -namespace browser { - -// Shows the "Report a problem with this page" dialog box. See BugReportView. -void ShowBugReportView(views::Window* parent, - Profile* profile, - TabContents* tab); - -// Shows the "Report a problem with this page" page in a new tab -void ShowHtmlBugReportView(views::Window* parent, Browser* browser); - -// Shows the "Clear browsing data" dialog box. See ClearBrowsingDataView. -void ShowClearBrowsingDataView(gfx::NativeWindow parent, - Profile* profile); - -// Shows the "Importer" dialog. See ImporterView. -void ShowImporterView(views::Widget* parent, - Profile* profile); - -// Shows or hides the global bookmark bubble for the star button. -void ShowBookmarkBubbleView(views::Window* parent, - const gfx::Rect& bounds, - InfoBubbleDelegate* delegate, - Profile* profile, - const GURL& url, - bool newly_bookmarked); -void HideBookmarkBubbleView(); -bool IsBookmarkBubbleViewShowing(); - -// Shows the bookmark manager. -void ShowBookmarkManagerView(Profile* profile); - -// Shows the about dialog. See AboutChromeView. -views::Window* ShowAboutChromeView(gfx::NativeWindow parent, - Profile* profile); - -// Shows an HTML dialog. See HtmlDialogView. -void ShowHtmlDialogView(gfx::NativeWindow parent, Profile* profile, - HtmlDialogUIDelegate* delegate); - -// Creates and returns a find bar for the given browser window. See FindBarWin. -FindBar* CreateFindBar(BrowserView* browser_view); - -// Shows the "Save passwords and exceptions" dialog. -// See PasswordsExceptionsWindowView. -void ShowPasswordsExceptionsWindowView(Profile* profile); - -// Shows the keyword editor. See KeywordEditorView. -void ShowKeywordEditorView(Profile* profile); - -// Shows the "new profile" dialog box. See NewProfileDialog. -void ShowNewProfileDialog(); - -// Shows the Task Manager. -void ShowTaskManager(); - -#if defined(OS_CHROMEOS) -// Shows the Login Wizard. -void ShowLoginWizard(const std::string& start_screen, const gfx::Size& size); -#endif - -// Shows a dialog box that allows a search engine to be edited. |template_url| -// is the search engine being edited. If it is NULL, then the dialog will add a -// new search engine with the data the user supplies. |delegate| is an object -// to be notified when the user is done editing, or NULL. If NULL, the dialog -// will update the model with the user's edits directly. -void EditSearchEngine(gfx::NativeWindow parent, - const TemplateURL* template_url, - EditSearchEngineControllerDelegate* delegate, - Profile* profile); - -// Shows the repost form confirmation dialog box. -void ShowRepostFormWarningDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents); - -// Shows the content settings dialog box. -void ShowContentSettingsWindow(gfx::NativeWindow parent_window, - ContentSettingsType content_type, - Profile* profile); - -// Shows the collected cookies dialog box. -void ShowCollectedCookiesDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents); - -// Shows the create web app shortcut dialog box. -void ShowCreateShortcutsDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents); - -} // namespace browser +#include "chrome/browser/ui/views/browser_dialogs.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BROWSER_DIALOGS_H_ + diff --git a/chrome/browser/views/browser_keyboard_accessibility_test_win.cc b/chrome/browser/views/browser_keyboard_accessibility_test_win.cc deleted file mode 100644 index 1218367..0000000 --- a/chrome/browser/views/browser_keyboard_accessibility_test_win.cc +++ /dev/null @@ -1,210 +0,0 @@ -// 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 "app/keyboard_codes.h" -#include "chrome/browser/automation/ui_controls.h" -#include "chrome/browser/views/chrome_views_delegate.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/test/in_process_browser_test.h" -#include "chrome/test/ui_test_utils.h" -#include "views/view.h" -#include "views/accessibility/view_accessibility.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -namespace { - -class BrowserKeyboardAccessibility : public InProcessBrowserTest, - public ChromeViewsDelegate { - public: - BrowserKeyboardAccessibility() - : is_waiting_(false), - current_view_(NULL), - current_event_type_(AccessibilityTypes::EVENT_FOCUS) { - // Set ourselves as the currently active ViewsDelegate. - ViewsDelegate::views_delegate = this; - } - - ~BrowserKeyboardAccessibility() {} - - // Overridden from ChromeViewsDelegate. - // Save the last notification sent by views::View::NotifyAccessibilityEvent. - virtual void NotifyAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type) { - current_view_ = view; - current_event_type_ = event_type; - - // Are we within a message loop waiting for a particular event? - // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663. - LOG(ERROR) << "Got notification; is_waiting_ is " - << (is_waiting_ ? "true" : "false"); - if (is_waiting_) { - is_waiting_ = false; - MessageLoop::current()->Quit(); - } - } - - // Helper that performs tabbing until it cycles back to the original focus. - void TabCyclerForwardAndBack(gfx::NativeWindow hwnd); - void TabCycler(gfx::NativeWindow hwnd, bool forward_tab); - - views::View* current_view() const { return current_view_; } - - gfx::NativeWindow current_view_native_window() const { - return current_view()->GetWidget()->GetNativeView(); - } - - AccessibilityTypes::Event current_event() const { - return current_event_type_; - } - - void set_waiting(bool value) { is_waiting_ = value; } - - private: - // Are we waiting for an event? - bool is_waiting_; - - // View of interest (i.e. for testing or one we are waiting to gain focus). - views::View* current_view_; - - // Event type of interest. - AccessibilityTypes::Event current_event_type_; -}; - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInAboutChromeDialog) { - views::Window* about_chrome_window = - BrowserView::GetBrowserViewForNativeWindow( - browser()->window()->GetNativeHandle())->ShowAboutChromeDialog(); - - TabCyclerForwardAndBack(about_chrome_window->GetNativeWindow()); -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInClearBrowsingDataDialog) { - browser()->OpenClearBrowsingDataDialog(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInImportSettingsDialog) { - browser()->OpenImportSettingsDialog(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInKeywordEditor) { - browser()->OpenKeywordEditor(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInOptionsDialog) { - browser()->OpenOptionsDialog(); - - // Tab through each of the three tabs. - for (int i = 0; i < 3; ++i) { - // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663. - LOG(ERROR) << "Iteration no. " << i; - - TabCyclerForwardAndBack(current_view_native_window()); - - - // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663. - LOG(ERROR) << "Sending TAB key event..."; - ui_controls::SendKeyPressNotifyWhenDone(current_view_native_window(), - app::VKEY_TAB, - true, false, false, false, - new MessageLoop::QuitTask()); - set_waiting(true); - ui_test_utils::RunMessageLoop(); - } -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInPasswordManager) { - browser()->OpenPasswordManager(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -// TODO(dtseng): http://www.crbug.com/50402 -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - FAILS_TabInSyncMyBookmarksDialog) { - browser()->OpenSyncMyBookmarksDialog(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInTaskManager) { - browser()->OpenTaskManager(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInToolbar) { - gfx::NativeWindow native_window = browser()->window()->GetNativeHandle(); - ui_controls::SendKeyPressNotifyWhenDone(native_window, - app::VKEY_T, - false, true, true, false, - new MessageLoop::QuitTask()); - set_waiting(true); - ui_test_utils::RunMessageLoop(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -// This test is disabled, see bug 50864. -IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility, - DISABLED_TabInUpdateChromeDialog) { - browser()->OpenUpdateChromeDialog(); - TabCyclerForwardAndBack(current_view_native_window()); -} - -void BrowserKeyboardAccessibility::TabCyclerForwardAndBack( - gfx::NativeWindow hwnd) { - TabCycler(hwnd, true); - TabCycler(hwnd, false); -} - -void BrowserKeyboardAccessibility::TabCycler(gfx::NativeWindow hwnd, - bool forward_tab) { - // Wait for a focus event on the provided native window. - while (current_event() != AccessibilityTypes::EVENT_FOCUS || - current_view_native_window() != hwnd) { - // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663. - LOG(ERROR) << "Runnig message loop..."; - set_waiting(true); - ui_test_utils::RunMessageLoop(); - } - // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663. - LOG(ERROR) << "After the loop."; - - views::View* first_focused_item = current_view(); - - ASSERT_TRUE(first_focused_item != NULL); - - views::View* next_focused_item = first_focused_item; - - // Keep tabbing until we reach the originally focused view. - do { - // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663. - LOG(ERROR) << "Sending TAB key event."; - ui_controls::SendKeyPressNotifyWhenDone(hwnd, app::VKEY_TAB, - false, !forward_tab, false, false, new MessageLoop::QuitTask()); - set_waiting(true); - ui_test_utils::RunMessageLoop(); - next_focused_item = current_view(); - } while (first_focused_item != next_focused_item); - // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663. - LOG(ERROR) << "After second loop."; -} - -} // namespace diff --git a/chrome/browser/views/bubble_border.cc b/chrome/browser/views/bubble_border.cc deleted file mode 100644 index e37f5fe..0000000 --- a/chrome/browser/views/bubble_border.cc +++ /dev/null @@ -1,443 +0,0 @@ -// 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/bubble_border.h" - -#include "app/resource_bundle.h" -#include "base/logging.h" -#include "gfx/canvas_skia.h" -#include "gfx/path.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkBitmap.h" - -// static -SkBitmap* BubbleBorder::left_ = NULL; -SkBitmap* BubbleBorder::top_left_ = NULL; -SkBitmap* BubbleBorder::top_ = NULL; -SkBitmap* BubbleBorder::top_right_ = NULL; -SkBitmap* BubbleBorder::right_ = NULL; -SkBitmap* BubbleBorder::bottom_right_ = NULL; -SkBitmap* BubbleBorder::bottom_ = NULL; -SkBitmap* BubbleBorder::bottom_left_ = NULL; -SkBitmap* BubbleBorder::top_arrow_ = NULL; -SkBitmap* BubbleBorder::bottom_arrow_ = NULL; -SkBitmap* BubbleBorder::left_arrow_ = NULL; -SkBitmap* BubbleBorder::right_arrow_ = NULL; - -// static -int BubbleBorder::arrow_offset_; - -// The height inside the arrow image, in pixels. -static const int kArrowInteriorHeight = 7; - -gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, - const gfx::Size& contents_size) const { - // Desired size is size of contents enlarged by the size of the border images. - gfx::Size border_size(contents_size); - gfx::Insets insets; - GetInsets(&insets); - border_size.Enlarge(insets.left() + insets.right(), - insets.top() + insets.bottom()); - - // Screen position depends on the arrow location. - // The arrow should overlap the target by some amount since there is space - // for shadow between arrow tip and bitmap bounds. - const int kArrowOverlap = 3; - int x = position_relative_to.x(); - int y = position_relative_to.y(); - int w = position_relative_to.width(); - int h = position_relative_to.height(); - int arrow_offset = override_arrow_offset_ ? override_arrow_offset_ : - arrow_offset_; - - // Calculate bubble x coordinate. - switch (arrow_location_) { - case TOP_LEFT: - case BOTTOM_LEFT: - x += w / 2 - arrow_offset; - break; - - case TOP_RIGHT: - case BOTTOM_RIGHT: - x += w / 2 + arrow_offset - border_size.width() + 1; - break; - - case LEFT_TOP: - case LEFT_BOTTOM: - x += w - kArrowOverlap; - break; - - case RIGHT_TOP: - case RIGHT_BOTTOM: - x += kArrowOverlap - border_size.width(); - break; - - case NONE: - case FLOAT: - x += w / 2 - border_size.width() / 2; - break; - } - - // Calculate bubble y coordinate. - switch (arrow_location_) { - case TOP_LEFT: - case TOP_RIGHT: - y += h - kArrowOverlap; - break; - - case BOTTOM_LEFT: - case BOTTOM_RIGHT: - y += kArrowOverlap - border_size.height(); - break; - - case LEFT_TOP: - case RIGHT_TOP: - y += h / 2 - arrow_offset; - break; - - case LEFT_BOTTOM: - case RIGHT_BOTTOM: - y += h / 2 + arrow_offset - border_size.height() + 1; - break; - - case NONE: - y += h; - break; - - case FLOAT: - y += h / 2 - border_size.height() / 2; - break; - } - - return gfx::Rect(x, y, border_size.width(), border_size.height()); -} - -void BubbleBorder::GetInsets(gfx::Insets* insets) const { - int top = top_->height(); - int bottom = bottom_->height(); - int left = left_->width(); - int right = right_->width(); - switch (arrow_location_) { - case TOP_LEFT: - case TOP_RIGHT: - top = std::max(top, top_arrow_->height()); - break; - - case BOTTOM_LEFT: - case BOTTOM_RIGHT: - bottom = std::max(bottom, bottom_arrow_->height()); - break; - - case LEFT_TOP: - case LEFT_BOTTOM: - left = std::max(left, left_arrow_->width()); - break; - - case RIGHT_TOP: - case RIGHT_BOTTOM: - right = std::max(right, right_arrow_->width()); - break; - - case NONE: - case FLOAT: - // Nothing to do. - break; - } - insets->Set(top, left, bottom, right); -} - -int BubbleBorder::SetArrowOffset(int offset, const gfx::Size& contents_size) { - gfx::Size border_size(contents_size); - gfx::Insets insets; - GetInsets(&insets); - border_size.Enlarge(insets.left() + insets.right(), - insets.top() + insets.bottom()); - offset = std::max(arrow_offset_, - std::min(offset, (is_arrow_on_horizontal(arrow_location_) ? - border_size.width() : border_size.height()) - arrow_offset_)); - override_arrow_offset_ = offset; - return override_arrow_offset_; -} - -// static -void BubbleBorder::InitClass() { - static bool initialized = false; - if (!initialized) { - // Load images. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - left_ = rb.GetBitmapNamed(IDR_BUBBLE_L); - top_left_ = rb.GetBitmapNamed(IDR_BUBBLE_TL); - top_ = rb.GetBitmapNamed(IDR_BUBBLE_T); - top_right_ = rb.GetBitmapNamed(IDR_BUBBLE_TR); - right_ = rb.GetBitmapNamed(IDR_BUBBLE_R); - bottom_right_ = rb.GetBitmapNamed(IDR_BUBBLE_BR); - bottom_ = rb.GetBitmapNamed(IDR_BUBBLE_B); - bottom_left_ = rb.GetBitmapNamed(IDR_BUBBLE_BL); - left_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_L_ARROW); - top_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_T_ARROW); - right_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_R_ARROW); - bottom_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_B_ARROW); - - // Calculate horizontal and vertical insets for arrow by ensuring that - // the widest arrow and corner images will have enough room to avoid overlap - int offset_x = - (std::max(top_arrow_->width(), bottom_arrow_->width()) / 2) + - std::max(std::max(top_left_->width(), top_right_->width()), - std::max(bottom_left_->width(), bottom_right_->width())); - int offset_y = - (std::max(left_arrow_->height(), right_arrow_->height()) / 2) + - std::max(std::max(top_left_->height(), top_right_->height()), - std::max(bottom_left_->height(), bottom_right_->height())); - arrow_offset_ = std::max(offset_x, offset_y); - - initialized = true; - } -} - -void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { - // Convenience shorthand variables. - const int tl_width = top_left_->width(); - const int tl_height = top_left_->height(); - const int t_height = top_->height(); - const int tr_width = top_right_->width(); - const int tr_height = top_right_->height(); - const int l_width = left_->width(); - const int r_width = right_->width(); - const int br_width = bottom_right_->width(); - const int br_height = bottom_right_->height(); - const int b_height = bottom_->height(); - const int bl_width = bottom_left_->width(); - const int bl_height = bottom_left_->height(); - - gfx::Insets insets; - GetInsets(&insets); - const int top = insets.top() - t_height; - const int bottom = view.height() - insets.bottom() + b_height; - const int left = insets.left() - l_width; - const int right = view.width() - insets.right() + r_width; - const int height = bottom - top; - const int width = right - left; - - // |arrow_offset| is offset of arrow from the begining of the edge. - int arrow_offset = arrow_offset_; - if (override_arrow_offset_) - arrow_offset = override_arrow_offset_; - else if (is_arrow_on_horizontal(arrow_location_) && - !is_arrow_on_left(arrow_location_)) { - arrow_offset = view.width() - arrow_offset - 1; - } else if (!is_arrow_on_horizontal(arrow_location_) && - !is_arrow_on_top(arrow_location_)) { - arrow_offset = view.height() - arrow_offset - 1; - } - - // Left edge. - if (arrow_location_ == LEFT_TOP || arrow_location_ == LEFT_BOTTOM) { - int start_y = top + tl_height; - int before_arrow = arrow_offset - start_y - left_arrow_->height() / 2; - int after_arrow = - height - tl_height - bl_height - left_arrow_->height() - before_arrow; - DrawArrowInterior(canvas, - false, - left_arrow_->width() - kArrowInteriorHeight, - start_y + before_arrow + left_arrow_->height() / 2, - kArrowInteriorHeight, - left_arrow_->height() / 2 - 1); - DrawEdgeWithArrow(canvas, - false, - left_, - left_arrow_, - left, - start_y, - before_arrow, - after_arrow, - left_->width() - left_arrow_->width()); - } else { - canvas->TileImageInt(*left_, left, top + tl_height, l_width, - height - tl_height - bl_height); - } - - // Top left corner. - canvas->DrawBitmapInt(*top_left_, left, top); - - // Top edge. - if (arrow_location_ == TOP_LEFT || arrow_location_ == TOP_RIGHT) { - int start_x = left + tl_width; - int before_arrow = arrow_offset - start_x - top_arrow_->width() / 2; - int after_arrow = - width - tl_width - tr_width - top_arrow_->width() - before_arrow; - DrawArrowInterior(canvas, - true, - start_x + before_arrow + top_arrow_->width() / 2, - top_arrow_->height() - kArrowInteriorHeight, - 1 - top_arrow_->width() / 2, - kArrowInteriorHeight); - DrawEdgeWithArrow(canvas, - true, - top_, - top_arrow_, - start_x, - top, - before_arrow, - after_arrow, - top_->height() - top_arrow_->height()); - } else { - canvas->TileImageInt(*top_, left + tl_width, top, - width - tl_width - tr_width, t_height); - } - - // Top right corner. - canvas->DrawBitmapInt(*top_right_, right - tr_width, top); - - // Right edge. - if (arrow_location_ == RIGHT_TOP || arrow_location_ == RIGHT_BOTTOM) { - int start_y = top + tr_height; - int before_arrow = arrow_offset - start_y - right_arrow_->height() / 2; - int after_arrow = height - tl_height - bl_height - - right_arrow_->height() - before_arrow; - DrawArrowInterior(canvas, - false, - right - r_width + kArrowInteriorHeight, - start_y + before_arrow + right_arrow_->height() / 2, - -kArrowInteriorHeight, - right_arrow_->height() / 2 - 1); - DrawEdgeWithArrow(canvas, - false, - right_, - right_arrow_, - right - r_width, - start_y, - before_arrow, - after_arrow, - 0); - } else { - canvas->TileImageInt(*right_, right - r_width, top + tr_height, r_width, - height - tr_height - br_height); - } - - // Bottom right corner. - canvas->DrawBitmapInt(*bottom_right_, right - br_width, bottom - br_height); - - // Bottom edge. - if (arrow_location_ == BOTTOM_LEFT || arrow_location_ == BOTTOM_RIGHT) { - int start_x = left + bl_width; - int before_arrow = arrow_offset - start_x - bottom_arrow_->width() / 2; - int after_arrow = - width - bl_width - br_width - bottom_arrow_->width() - before_arrow; - DrawArrowInterior(canvas, - true, - start_x + before_arrow + bottom_arrow_->width() / 2, - bottom - b_height + kArrowInteriorHeight, - 1 - bottom_arrow_->width() / 2, - -kArrowInteriorHeight); - DrawEdgeWithArrow(canvas, - true, - bottom_, - bottom_arrow_, - start_x, - bottom - b_height, - before_arrow, - after_arrow, - 0); - } else { - canvas->TileImageInt(*bottom_, left + bl_width, bottom - b_height, - width - bl_width - br_width, b_height); - } - - // Bottom left corner. - canvas->DrawBitmapInt(*bottom_left_, left, bottom - bl_height); -} - -void BubbleBorder::DrawEdgeWithArrow(gfx::Canvas* canvas, - bool is_horizontal, - SkBitmap* edge, - SkBitmap* arrow, - int start_x, - int start_y, - int before_arrow, - int after_arrow, - int offset) const { - /* Here's what the parameters mean: - * start_x - * . - * . ┌───┐ ┬ offset - * start_y..........┌────┬────────┤ ▲ ├────────┬────┐ - * │ / │--------│∙ ∙│--------│ \ │ - * │ / ├────────┴───┴────────┤ \ │ - * ├───┬┘ └┬───┤ - * └───┬────┘ └───┬────┘ - * before_arrow ─┘ └─ after_arrow - */ - if (before_arrow) { - canvas->TileImageInt(*edge, start_x, start_y, - is_horizontal ? before_arrow : edge->width(), - is_horizontal ? edge->height() : before_arrow); - } - - canvas->DrawBitmapInt(*arrow, - start_x + (is_horizontal ? before_arrow : offset), - start_y + (is_horizontal ? offset : before_arrow)); - - if (after_arrow) { - start_x += (is_horizontal ? before_arrow + arrow->width() : 0); - start_y += (is_horizontal ? 0 : before_arrow + arrow->height()); - canvas->TileImageInt(*edge, start_x, start_y, - is_horizontal ? after_arrow : edge->width(), - is_horizontal ? edge->height() : after_arrow); - } -} - -void BubbleBorder::DrawArrowInterior(gfx::Canvas* canvas, - bool is_horizontal, - int tip_x, - int tip_y, - int shift_x, - int shift_y) const { - /* This function fills the interior of the arrow with background color. - * It draws isosceles triangle under semitransparent arrow tip. - * - * Here's what the parameters mean: - * - * ┌──────── |tip_x| - * ┌─────┐ - * │ ▲ │ ──── |tip y| - * │∙∙∙∙∙│ ┐ - * └─────┘ └─── |shift_x| (offset from tip to vertexes of isosceles triangle) - * └────────── |shift_y| - */ - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(background_color_); - gfx::Path path; - path.incReserve(4); - path.moveTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); - path.lineTo(SkIntToScalar(tip_x + shift_x), - SkIntToScalar(tip_y + shift_y)); - if (is_horizontal) - path.lineTo(SkIntToScalar(tip_x - shift_x), SkIntToScalar(tip_y + shift_y)); - else - path.lineTo(SkIntToScalar(tip_x + shift_x), SkIntToScalar(tip_y - shift_y)); - path.close(); - canvas->AsCanvasSkia()->drawPath(path, paint); -} - -///////////////////////// - -void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const { - // The border of this view creates an anti-aliased round-rect region for the - // contents, which we need to fill with the background color. - // NOTE: This doesn't handle an arrow location of "NONE", which has square top - // corners. - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(border_->background_color()); - gfx::Path path; - gfx::Rect bounds(view->GetLocalBounds(false)); - SkRect rect; - rect.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()), - SkIntToScalar(bounds.right()), SkIntToScalar(bounds.bottom())); - SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); - path.addRoundRect(rect, radius, radius); - canvas->AsCanvasSkia()->drawPath(path, paint); -} diff --git a/chrome/browser/views/bubble_border.h b/chrome/browser/views/bubble_border.h index 6d5191a..2d88c30 100644 --- a/chrome/browser/views/bubble_border.h +++ b/chrome/browser/views/bubble_border.h @@ -6,167 +6,8 @@ #define CHROME_BROWSER_VIEWS_BUBBLE_BORDER_H_ #pragma once -#include "third_party/skia/include/core/SkColor.h" -#include "views/background.h" -#include "views/border.h" - -class SkBitmap; - -// Renders a border, with optional arrow, and a custom dropshadow. -// This can be used to produce floating "bubble" objects with rounded corners. -class BubbleBorder : public views::Border { - public: - // Possible locations for the (optional) arrow. - // 0 bit specifies left or right. - // 1 bit specifies top or bottom. - // 2 bit specifies horizontal or vertical. - enum ArrowLocation { - TOP_LEFT = 0, - TOP_RIGHT = 1, - BOTTOM_LEFT = 2, - BOTTOM_RIGHT = 3, - LEFT_TOP = 4, - RIGHT_TOP = 5, - LEFT_BOTTOM = 6, - RIGHT_BOTTOM = 7, - NONE = 8, // No arrow. Positioned under the supplied rect. - FLOAT = 9 // No arrow. Centered over the supplied rect. - }; - - explicit BubbleBorder(ArrowLocation arrow_location) - : override_arrow_offset_(0), - arrow_location_(arrow_location), - background_color_(SK_ColorWHITE) { - InitClass(); - } - - // Returns the radius of the corner of the border. - static int GetCornerRadius() { - // We can't safely calculate a border radius by comparing the sizes of the - // side and corner images, because either may have been extended in various - // directions in order to do more subtle dropshadow fading or other effects. - // So we hardcode the most accurate value. - return 4; - } - - // Sets the location for the arrow. - void set_arrow_location(ArrowLocation arrow_location) { - arrow_location_ = arrow_location; - } - ArrowLocation arrow_location() const { return arrow_location_; } - - static ArrowLocation horizontal_mirror(ArrowLocation loc) { - return loc >= NONE ? loc : static_cast<ArrowLocation>(loc ^ 1); - } - - static ArrowLocation vertical_mirror(ArrowLocation loc) { - return loc >= NONE ? loc : static_cast<ArrowLocation>(loc ^ 2); - } - - static bool has_arrow(ArrowLocation loc) { - return loc >= NONE ? false : true; - } - - static bool is_arrow_on_left(ArrowLocation loc) { - return loc >= NONE ? false : !(loc & 1); - } - - static bool is_arrow_on_top(ArrowLocation loc) { - return loc >= NONE ? false : !(loc & 2); - } - - static bool is_arrow_on_horizontal(ArrowLocation loc) { - return loc >= NONE ? false : !(loc & 4); - } - - // Sets the background color for the arrow body. This is irrelevant if you do - // not also set the arrow location to something other than NONE. - void set_background_color(SkColor background_color) { - background_color_ = background_color; - } - SkColor background_color() const { return background_color_; } - - // For borders with an arrow, gives the desired bounds (in screen coordinates) - // given the rect to point to and the size of the contained contents. This - // depends on the arrow location, so if you change that, you should call this - // again to find out the new coordinates. - gfx::Rect GetBounds(const gfx::Rect& position_relative_to, - const gfx::Size& contents_size) const; - - // Sets a fixed offset for the arrow from the beginning of corresponding edge. - // The arrow will still point to the same location but the bubble will shift - // location to make that happen. Returns actuall arrow offset, in case of - // overflow it differ from desired. - int SetArrowOffset(int offset, const gfx::Size& contents_size); - - // Overridden from views::Border: - virtual void GetInsets(gfx::Insets* insets) const; - - private: - // Loads images if necessary. - static void InitClass(); - - virtual ~BubbleBorder() { } - - // Overridden from views::Border: - virtual void Paint(const views::View& view, gfx::Canvas* canvas) const; - - void DrawEdgeWithArrow(gfx::Canvas* canvas, - bool is_horizontal, - SkBitmap* edge, - SkBitmap* arrow, - int start_x, - int start_y, - int before_arrow, - int after_arrow, - int offset) const; - - void DrawArrowInterior(gfx::Canvas* canvas, - bool is_horizontal, - int tip_x, - int tip_y, - int shift_x, - int shift_y) const; - - // Border graphics. - static SkBitmap* left_; - static SkBitmap* top_left_; - static SkBitmap* top_; - static SkBitmap* top_right_; - static SkBitmap* right_; - static SkBitmap* bottom_right_; - static SkBitmap* bottom_; - static SkBitmap* bottom_left_; - static SkBitmap* left_arrow_; - static SkBitmap* top_arrow_; - static SkBitmap* right_arrow_; - static SkBitmap* bottom_arrow_; - - // Minimal offset of the arrow from the closet edge of bounding rect. - static int arrow_offset_; - - // If specified, overrides the pre-calculated |arrow_offset_| of the arrow. - int override_arrow_offset_; - - ArrowLocation arrow_location_; - SkColor background_color_; - - DISALLOW_COPY_AND_ASSIGN(BubbleBorder); -}; - -// A Background that clips itself to the specified BubbleBorder and uses -// the background color of the BubbleBorder. -class BubbleBackground : public views::Background { - public: - explicit BubbleBackground(BubbleBorder* border) : border_(border) {} - - // Background overrides. - virtual void Paint(gfx::Canvas* canvas, views::View* view) const; - - private: - BubbleBorder* border_; - - DISALLOW_COPY_AND_ASSIGN(BubbleBackground); -}; +#include "chrome/browser/ui/views/bubble_border.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_BUBBLE_BORDER_H_ + diff --git a/chrome/browser/views/certificate_viewer_win.cc b/chrome/browser/views/certificate_viewer_win.cc deleted file mode 100644 index ba54267..0000000 --- a/chrome/browser/views/certificate_viewer_win.cc +++ /dev/null @@ -1,32 +0,0 @@ -// 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/certificate_viewer.h" - -#include <windows.h> -#include <cryptuiapi.h> -#pragma comment(lib, "cryptui.lib") - -#include "net/base/x509_certificate.h" - -void ShowCertificateViewer(gfx::NativeWindow parent, - net::X509Certificate* cert) { - CRYPTUI_VIEWCERTIFICATE_STRUCT view_info = { 0 }; - view_info.dwSize = sizeof(view_info); - // We set our parent to the tab window. This makes the cert dialog created - // in CryptUIDlgViewCertificate modal to the browser. - view_info.hwndParent = parent; - view_info.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | - CRYPTUI_DISABLE_ADDTOSTORE; - view_info.pCertContext = cert->os_cert_handle(); - // Search the cert store that 'cert' is in when building the cert chain. - HCERTSTORE cert_store = view_info.pCertContext->hCertStore; - view_info.cStores = 1; - view_info.rghStores = &cert_store; - BOOL properties_changed; - - // This next call blocks but keeps processing windows messages, making it - // modal to the browser window. - BOOL rv = ::CryptUIDlgViewCertificate(&view_info, &properties_changed); -} diff --git a/chrome/browser/views/chrome_views_delegate.cc b/chrome/browser/views/chrome_views_delegate.cc deleted file mode 100644 index d872ace..0000000 --- a/chrome/browser/views/chrome_views_delegate.cc +++ /dev/null @@ -1,102 +0,0 @@ -// 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/chrome_views_delegate.h" - -#include "app/clipboard/clipboard.h" -#include "base/scoped_ptr.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/views/accessibility_event_router_views.h" -#include "chrome/browser/window_sizer.h" -#include "gfx/rect.h" - -#if defined(OS_WIN) -#include "chrome/browser/app_icon_win.h" -#endif - -/////////////////////////////////////////////////////////////////////////////// -// ChromeViewsDelegate, views::ViewsDelegate implementation: - -Clipboard* ChromeViewsDelegate::GetClipboard() const { - return g_browser_process->clipboard(); -} - -void ChromeViewsDelegate::SaveWindowPlacement(const std::wstring& window_name, - const gfx::Rect& bounds, - bool maximized) { - if (!g_browser_process->local_state()) - return; - - DictionaryValue* window_preferences = - g_browser_process->local_state()->GetMutableDictionary( - WideToUTF8(window_name).c_str()); - window_preferences->SetInteger("left", bounds.x()); - window_preferences->SetInteger("top", bounds.y()); - window_preferences->SetInteger("right", bounds.right()); - window_preferences->SetInteger("bottom", bounds.bottom()); - window_preferences->SetBoolean("maximized", maximized); - - scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_info_provider( - WindowSizer::CreateDefaultMonitorInfoProvider()); - gfx::Rect work_area( - monitor_info_provider->GetMonitorWorkAreaMatching(bounds)); - window_preferences->SetInteger("work_area_left", work_area.x()); - window_preferences->SetInteger("work_area_top", work_area.y()); - window_preferences->SetInteger("work_area_right", work_area.right()); - window_preferences->SetInteger("work_area_bottom", work_area.bottom()); -} - -bool ChromeViewsDelegate::GetSavedWindowBounds(const std::wstring& window_name, - gfx::Rect* bounds) const { - if (!g_browser_process->local_state()) - return false; - - const DictionaryValue* dictionary = - g_browser_process->local_state()->GetDictionary( - WideToUTF8(window_name).c_str()); - int left, top, right, bottom; - if (!dictionary || !dictionary->GetInteger("left", &left) || - !dictionary->GetInteger("top", &top) || - !dictionary->GetInteger("right", &right) || - !dictionary->GetInteger("bottom", &bottom)) - return false; - - bounds->SetRect(left, top, right - left, bottom - top); - return true; -} - -bool ChromeViewsDelegate::GetSavedMaximizedState( - const std::wstring& window_name, - bool* maximized) const { - if (!g_browser_process->local_state()) - return false; - - const DictionaryValue* dictionary = - g_browser_process->local_state()->GetDictionary( - WideToUTF8(window_name).c_str()); - return dictionary && dictionary->GetBoolean("maximized", maximized) && - maximized; -} - -void ChromeViewsDelegate::NotifyAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type) { - AccessibilityEventRouterViews::GetInstance()->HandleAccessibilityEvent( - view, event_type); -} - -#if defined(OS_WIN) -HICON ChromeViewsDelegate::GetDefaultWindowIcon() const { - return GetAppIcon(); -} -#endif - -void ChromeViewsDelegate::AddRef() { - g_browser_process->AddRefModule(); -} - -void ChromeViewsDelegate::ReleaseRef() { - g_browser_process->ReleaseModule(); -} diff --git a/chrome/browser/views/chrome_views_delegate.h b/chrome/browser/views/chrome_views_delegate.h index af046d2..01144e5 100644 --- a/chrome/browser/views/chrome_views_delegate.h +++ b/chrome/browser/views/chrome_views_delegate.h @@ -6,34 +6,8 @@ #define CHROME_BROWSER_VIEWS_CHROME_VIEWS_DELEGATE_H_ #pragma once -#include "base/basictypes.h" -#include "build/build_config.h" -#include "views/views_delegate.h" - -class ChromeViewsDelegate : public views::ViewsDelegate { - public: - ChromeViewsDelegate() {} - virtual ~ChromeViewsDelegate() {} - - // Overridden from views::ViewsDelegate: - virtual Clipboard* GetClipboard() const; - virtual void SaveWindowPlacement(const std::wstring& window_name, - const gfx::Rect& bounds, - bool maximized); - virtual bool GetSavedWindowBounds(const std::wstring& window_name, - gfx::Rect* bounds) const; - virtual bool GetSavedMaximizedState(const std::wstring& window_name, - bool* maximized) const; - virtual void NotifyAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type); -#if defined(OS_WIN) - virtual HICON GetDefaultWindowIcon() const; -#endif - virtual void AddRef(); - virtual void ReleaseRef(); - - private: - DISALLOW_COPY_AND_ASSIGN(ChromeViewsDelegate); -}; +#include "chrome/browser/ui/views/chrome_views_delegate.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CHROME_VIEWS_DELEGATE_H_ + diff --git a/chrome/browser/views/clear_browsing_data.cc b/chrome/browser/views/clear_browsing_data.cc deleted file mode 100644 index 3eb4e5c..0000000 --- a/chrome/browser/views/clear_browsing_data.cc +++ /dev/null @@ -1,472 +0,0 @@ -// 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/clear_browsing_data.h" - -#include "app/l10n_util.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#if defined(OS_WIN) -#include "chrome/browser/views/clear_browsing_data_view.h" -#endif -#include "chrome/common/pref_names.h" -#include "gfx/insets.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/url_request/url_request_context.h" -#include "views/background.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/controls/throbber.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/dialog_client_view.h" -#include "views/window/window.h" - -using views::GridLayout; - -// The combo box is vertically aligned to the 'time-period' label, which makes -// the combo box look a little too close to the check box above it when we use -// standard layout to separate them. We therefore add a little extra margin to -// the label, giving it a little breathing space. -static const int kExtraMarginForTimePeriodLabel = 3; - -namespace browser { -// Defined in browser_dialogs.h for creation of the view. -void ShowClearBrowsingDataView(gfx::NativeWindow parent, - Profile* profile) { -#if defined(OS_WIN) - views::Window::CreateChromeWindow(parent, gfx::Rect(), - new ClearDataView(profile))->Show(); -#else - views::Window::CreateChromeWindow(parent, gfx::Rect(), - new ClearBrowsingDataView(profile))->Show(); -#endif -} - -} // namespace browser - - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView, public: - -ClearBrowsingDataView::ClearBrowsingDataView(Profile* profile) - : del_history_checkbox_(NULL), - del_downloads_checkbox_(NULL), - del_cache_checkbox_(NULL), - del_cookies_checkbox_(NULL), - del_passwords_checkbox_(NULL), - del_form_data_checkbox_(NULL), - time_period_label_(NULL), - time_period_combobox_(NULL), - delete_in_progress_(false), - profile_(profile), - remover_(NULL) { - DCHECK(profile); - Init(); -} - -ClearBrowsingDataView::~ClearBrowsingDataView(void) { - if (remover_) { - // We were destroyed while clearing history was in progress. This can only - // occur during automated tests (normally the user can't close the dialog - // while clearing is in progress as the dialog is modal and not closeable). - remover_->RemoveObserver(this); - } -} - -void ClearBrowsingDataView::Init() { - // Views we will add to the *parent* of this dialog, since it will display - // next to the buttons which we don't draw ourselves. - throbber_ = new views::Throbber(50, true); - throbber_->SetVisible(false); - - status_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_DATA_DELETING)); - status_label_->SetVisible(false); - - // Regular view controls we draw by ourself. First, we add the dialog label. - delete_all_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_BROWSING_DATA_LABEL)); - AddChildView(delete_all_label_); - - // Add all the check-boxes. - del_history_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_BROWSING_HISTORY_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteBrowsingHistory)); - - del_downloads_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_DOWNLOAD_HISTORY_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteDownloadHistory)); - - del_cache_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_CACHE_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteCache)); - - del_cookies_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_COOKIES_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteCookies)); - - del_passwords_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_PASSWORDS_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeletePasswords)); - - del_form_data_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_FORM_DATA_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteFormData)); - - // Add a label which appears before the combo box for the time period. - time_period_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_BROWSING_DATA_TIME_LABEL)); - AddChildView(time_period_label_); - - // Add the combo box showing how far back in time we want to delete. - time_period_combobox_ = new views::Combobox(this); - time_period_combobox_->SetSelectedItem(profile_->GetPrefs()->GetInteger( - prefs::kDeleteTimePeriod)); - time_period_combobox_->set_listener(this); - time_period_combobox_->SetAccessibleName(time_period_label_->GetText()); - AddChildView(time_period_combobox_); - - // Create the throbber and related views. The throbber and status link are - // contained in throbber_view_, which is positioned by DialogClientView right - // next to the buttons. - throbber_view_ = new views::View(); - - GridLayout* layout = new GridLayout(throbber_view_); - throbber_view_->SetLayoutManager(layout); - views::ColumnSet* column_set = layout->AddColumnSet(0); - // DialogClientView positions the extra view at kButtonHEdgeMargin, but we - // put all our controls at kPanelHorizMargin. Add a padding column so things - // line up nicely. - if (kPanelHorizMargin - kButtonHEdgeMargin > 0) - column_set->AddPaddingColumn(0, kPanelHorizMargin - kButtonHEdgeMargin); - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(1, 0); - layout->AddView(throbber_); - layout->AddView(status_label_); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView, views::View implementation: - -gfx::Size ClearBrowsingDataView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_CLEARDATA_DIALOG_WIDTH_CHARS, - IDS_CLEARDATA_DIALOG_HEIGHT_LINES)); -} - -void ClearBrowsingDataView::Layout() { - gfx::Size panel_size = GetPreferredSize(); - - // Delete All label goes to the top left corner. - gfx::Size sz = delete_all_label_->GetPreferredSize(); - delete_all_label_->SetBounds(kPanelHorizMargin, kPanelVertMargin, - sz.width(), sz.height()); - - // Check-boxes go beneath it (with a little indentation). - sz = del_history_checkbox_->GetPreferredSize(); - del_history_checkbox_->SetBounds(2 * kPanelHorizMargin, - delete_all_label_->y() + - delete_all_label_->height() + - kRelatedControlVerticalSpacing, - sz.width(), sz.height()); - - sz = del_downloads_checkbox_->GetPreferredSize(); - del_downloads_checkbox_->SetBounds(2 * kPanelHorizMargin, - del_history_checkbox_->y() + - del_history_checkbox_->height() + - kRelatedControlVerticalSpacing, - sz.width(), sz.height()); - - sz = del_cache_checkbox_->GetPreferredSize(); - del_cache_checkbox_->SetBounds(2 * kPanelHorizMargin, - del_downloads_checkbox_->y() + - del_downloads_checkbox_->height() + - kRelatedControlVerticalSpacing, - sz.width(), sz.height()); - - sz = del_cookies_checkbox_->GetPreferredSize(); - del_cookies_checkbox_->SetBounds(2 * kPanelHorizMargin, - del_cache_checkbox_->y() + - del_cache_checkbox_->height() + - kRelatedControlVerticalSpacing, - sz.width(), sz.height()); - - sz = del_passwords_checkbox_->GetPreferredSize(); - del_passwords_checkbox_->SetBounds(2 * kPanelHorizMargin, - del_cookies_checkbox_->y() + - del_cookies_checkbox_->height() + - kRelatedControlVerticalSpacing, - sz.width(), sz.height()); - - sz = del_form_data_checkbox_->GetPreferredSize(); - del_form_data_checkbox_->SetBounds(2 * kPanelHorizMargin, - del_passwords_checkbox_->y() + - del_passwords_checkbox_->height() + - kRelatedControlVerticalSpacing, - sz.width(), sz.height()); - - // Time period label is next below the combo boxes. - sz = time_period_label_->GetPreferredSize(); - time_period_label_->SetBounds(kPanelHorizMargin, - del_form_data_checkbox_->y() + - del_form_data_checkbox_->height() + - kRelatedControlVerticalSpacing + - kExtraMarginForTimePeriodLabel, - sz.width(), sz.height()); - - // Time period combo box goes on the right of the label, and we align it - // vertically to the label as well. - int label_y_size = sz.height(); - sz = time_period_combobox_->GetPreferredSize(); - time_period_combobox_->SetBounds(time_period_label_->x() + - time_period_label_->width() + - kRelatedControlVerticalSpacing, - time_period_label_->y() - - ((sz.height() - label_y_size) / 2), - sz.width(), sz.height()); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView, views::DialogDelegate implementation: - -int ClearBrowsingDataView::GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_NONE; -} - -std::wstring ClearBrowsingDataView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - DCHECK((button == MessageBoxFlags::DIALOGBUTTON_OK) || - (button == MessageBoxFlags::DIALOGBUTTON_CANCEL)); - return l10n_util::GetString((button == MessageBoxFlags::DIALOGBUTTON_OK) ? - IDS_CLEAR_BROWSING_DATA_COMMIT : IDS_CANCEL); -} - -bool ClearBrowsingDataView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (delete_in_progress_) - return false; - - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return del_history_checkbox_->checked() || - del_downloads_checkbox_->checked() || - del_cache_checkbox_->checked() || - del_cookies_checkbox_->checked() || - del_passwords_checkbox_->checked() || - del_form_data_checkbox_->checked(); - } - - return true; -} - -bool ClearBrowsingDataView::CanResize() const { - return false; -} - -bool ClearBrowsingDataView::CanMaximize() const { - return false; -} - -bool ClearBrowsingDataView::IsAlwaysOnTop() const { - return false; -} - -bool ClearBrowsingDataView::HasAlwaysOnTopMenu() const { - return false; -} - -bool ClearBrowsingDataView::IsModal() const { - return true; -} - -std::wstring ClearBrowsingDataView::GetWindowTitle() const { - return l10n_util::GetString(IDS_CLEAR_BROWSING_DATA_TITLE); -} - -bool ClearBrowsingDataView::Accept() { - if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) { - return false; - } - - PrefService* prefs = profile_->GetPrefs(); - prefs->SetBoolean(prefs::kDeleteBrowsingHistory, - del_history_checkbox_->checked()); - prefs->SetBoolean(prefs::kDeleteDownloadHistory, - del_downloads_checkbox_->checked()); - prefs->SetBoolean(prefs::kDeleteCache, - del_cache_checkbox_->checked()); - prefs->SetBoolean(prefs::kDeleteCookies, - del_cookies_checkbox_->checked()); - prefs->SetBoolean(prefs::kDeletePasswords, - del_passwords_checkbox_->checked()); - prefs->SetBoolean(prefs::kDeleteFormData, - del_form_data_checkbox_->checked()); - OnDelete(); - return false; // We close the dialog in OnBrowsingDataRemoverDone(). -} - -views::View* ClearBrowsingDataView::GetContentsView() { - return this; -} - -views::View* ClearBrowsingDataView::GetInitiallyFocusedView() { - return GetDialogClientView()->cancel_button(); -} - -views::ClientView* ClearBrowsingDataView::CreateClientView( - views::Window* window) { - views::Link* flash_link = - new views::Link(l10n_util::GetString(IDS_FLASH_STORAGE_SETTINGS)); - flash_link->SetController(this); - - views::View* settings_view = new views::View(); - GridLayout* layout = new GridLayout(settings_view); - layout->SetInsets(gfx::Insets(0, kPanelHorizMargin, 0, kButtonHEdgeMargin)); - settings_view->SetLayoutManager(layout); - views::ColumnSet* column_set = layout->AddColumnSet(0); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, 0); - layout->AddView(new views::Separator()); - layout->StartRowWithPadding(0, 0, 0, kRelatedControlVerticalSpacing); - layout->AddView(flash_link, 1, 1, GridLayout::LEADING, GridLayout::CENTER); - - views::DialogClientView* client_view = - new views::DialogClientView(window, GetContentsView()); - client_view->SetBottomView(settings_view); - return client_view; -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView, ComboboxModel implementation: - -int ClearBrowsingDataView::GetItemCount() { - return 5; -} - -string16 ClearBrowsingDataView::GetItemAt(int index) { - switch (index) { - case 0: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_HOUR); - case 1: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_DAY); - case 2: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_WEEK); - case 3: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_4WEEKS); - case 4: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_EVERYTHING); - default: NOTREACHED() << "Missing item"; - return ASCIIToUTF16("?"); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView, views::ComboBoxListener implementation: - -void ClearBrowsingDataView::ItemChanged(views::Combobox* sender, - int prev_index, int new_index) { - if (sender == time_period_combobox_ && prev_index != new_index) - profile_->GetPrefs()->SetInteger(prefs::kDeleteTimePeriod, new_index); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView, views::ButtonListener implementation: - -void ClearBrowsingDataView::ButtonPressed(views::Button* sender, - const views::Event& event) { - // When no checkbox is checked we should not have the action button enabled. - // This forces the button to evaluate what state they should be in. - GetDialogClientView()->UpdateDialogButtons(); -} - -void ClearBrowsingDataView::LinkActivated(views::Link* source, - int event_flags) { - Browser* browser = Browser::Create(profile_); - browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), - GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); - browser->window()->Show(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView, private: - -views::Checkbox* ClearBrowsingDataView::AddCheckbox(const std::wstring& text, - bool checked) { - views::Checkbox* checkbox = new views::Checkbox(text); - checkbox->SetChecked(checked); - checkbox->set_listener(this); - AddChildView(checkbox); - return checkbox; -} - -void ClearBrowsingDataView::UpdateControlEnabledState() { - window()->EnableClose(!delete_in_progress_); - - del_history_checkbox_->SetEnabled(!delete_in_progress_); - del_downloads_checkbox_->SetEnabled(!delete_in_progress_); - del_cache_checkbox_->SetEnabled(!delete_in_progress_); - del_cookies_checkbox_->SetEnabled(!delete_in_progress_); - del_passwords_checkbox_->SetEnabled(!delete_in_progress_); - del_form_data_checkbox_->SetEnabled(!delete_in_progress_); - time_period_combobox_->SetEnabled(!delete_in_progress_); - - status_label_->SetVisible(delete_in_progress_); - throbber_->SetVisible(delete_in_progress_); - if (delete_in_progress_) - throbber_->Start(); - else - throbber_->Stop(); - - // Make sure to update the state for OK and Cancel buttons. - GetDialogClientView()->UpdateDialogButtons(); -} - -// Convenience method that returns true if the supplied checkbox is selected -// and enabled. -static bool IsCheckBoxEnabledAndSelected(views::Checkbox* cb) { - return (cb->IsEnabled() && cb->checked()); -} - -void ClearBrowsingDataView::OnDelete() { - int period_selected = time_period_combobox_->selected_item(); - - int remove_mask = 0; - if (IsCheckBoxEnabledAndSelected(del_history_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_HISTORY; - if (IsCheckBoxEnabledAndSelected(del_downloads_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_DOWNLOADS; - if (IsCheckBoxEnabledAndSelected(del_cookies_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_COOKIES; - if (IsCheckBoxEnabledAndSelected(del_passwords_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_PASSWORDS; - if (IsCheckBoxEnabledAndSelected(del_form_data_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_FORM_DATA; - if (IsCheckBoxEnabledAndSelected(del_cache_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_CACHE; - - delete_in_progress_ = true; - UpdateControlEnabledState(); - - // BrowsingDataRemover deletes itself when done. - remover_ = new BrowsingDataRemover(profile_, - static_cast<BrowsingDataRemover::TimePeriod>(period_selected), - base::Time()); - remover_->AddObserver(this); - remover_->Remove(remove_mask); -} - -void ClearBrowsingDataView::OnBrowsingDataRemoverDone() { - // No need to remove ourselves as an observer as BrowsingDataRemover deletes - // itself after we return. - remover_ = NULL; - window()->Close(); -} diff --git a/chrome/browser/views/clear_browsing_data.h b/chrome/browser/views/clear_browsing_data.h index 9a3e61a..e9d8b20 100644 --- a/chrome/browser/views/clear_browsing_data.h +++ b/chrome/browser/views/clear_browsing_data.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,123 +6,8 @@ #define CHROME_BROWSER_VIEWS_CLEAR_BROWSING_DATA_H_ #pragma once -#include "app/combobox_model.h" -#include "chrome/browser/browsing_data_remover.h" -#include "views/controls/button/button.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/label.h" -#include "views/controls/link.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Checkbox; -class Label; -class Throbber; -class Window; -} - -class Profile; -class MessageLoop; - -//////////////////////////////////////////////////////////////////////////////// -// -// The ClearBrowsingData class is responsible for drawing the UI controls of the -// dialog that allows the user to select what to delete (history, downloads, -// etc). -// -//////////////////////////////////////////////////////////////////////////////// -class ClearBrowsingDataView : public views::View, - public views::DialogDelegate, - public views::ButtonListener, - public ComboboxModel, - public views::Combobox::Listener, - public BrowsingDataRemover::Observer, - public views::LinkController { - public: - explicit ClearBrowsingDataView(Profile* profile); - virtual ~ClearBrowsingDataView(void); - - // Initialize the controls on the dialog. - void Init(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - // Overridden from views::DialogDelegate: - virtual int GetDefaultDialogButton() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool CanResize() const; - virtual bool CanMaximize() const; - virtual bool IsAlwaysOnTop() const; - virtual bool HasAlwaysOnTopMenu() const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool Accept(); - virtual views::View* GetContentsView(); - views::ClientView* CreateClientView(views::Window* window); - virtual views::View* GetExtraView() { return throbber_view_; } - virtual bool GetSizeExtraViewHeightToButtons() { return true; } - virtual views::View* GetInitiallyFocusedView(); - - // Overridden from ComboboxModel: - virtual int GetItemCount(); - virtual string16 GetItemAt(int index); - - // Overridden from views::Combobox::Listener: - virtual void ItemChanged(views::Combobox* sender, int prev_index, - int new_index); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overriden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - // Adds a new check-box as a child to the view. - views::Checkbox* AddCheckbox(const std::wstring& text, bool checked); - - // Sets the controls on the UI to be enabled/disabled depending on whether we - // have a delete operation in progress or not. - void UpdateControlEnabledState(); - - // Starts the process of deleting the browsing data depending on what the - // user selected. - void OnDelete(); - - // Callback from BrowsingDataRemover. Closes the dialog. - virtual void OnBrowsingDataRemoverDone(); - - // UI elements we add to the parent view. - views::View* throbber_view_; - views::Throbber* throbber_; - views::Label* status_label_; - // Other UI elements. - views::Label* delete_all_label_; - views::Checkbox* del_history_checkbox_; - views::Checkbox* del_downloads_checkbox_; - views::Checkbox* del_cache_checkbox_; - views::Checkbox* del_cookies_checkbox_; - views::Checkbox* del_passwords_checkbox_; - views::Checkbox* del_form_data_checkbox_; - views::Label* time_period_label_; - views::Combobox* time_period_combobox_; - - // Used to signal enabled/disabled state for controls in the UI. - bool delete_in_progress_; - - Profile* profile_; - - // If non-null it means removal is in progress. BrowsingDataRemover takes care - // of deleting itself when done. - BrowsingDataRemover* remover_; - - DISALLOW_COPY_AND_ASSIGN(ClearBrowsingDataView); -}; +#include "chrome/browser/ui/views/clear_browsing_data.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CLEAR_BROWSING_DATA_H_ + diff --git a/chrome/browser/views/clear_browsing_data_view.cc b/chrome/browser/views/clear_browsing_data_view.cc deleted file mode 100644 index d6f7ab5..0000000 --- a/chrome/browser/views/clear_browsing_data_view.cc +++ /dev/null @@ -1,371 +0,0 @@ -// 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/clear_browsing_data_view.h" - -#include "app/l10n_util.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/common/pref_names.h" -#include "gfx/insets.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/url_request/url_request_context.h" -#include "views/background.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/controls/throbber.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/dialog_client_view.h" -#include "views/window/window.h" - -using views::GridLayout; - -// The combo box is vertically aligned to the 'time-period' label, which makes -// the combo box look a little too close to the check box above it when we use -// standard layout to separate them. We therefore add a little extra margin to -// the label, giving it a little breathing space. -static const int kExtraMarginForTimePeriodLabel = 3; - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView2, public: - -ClearBrowsingDataView2::ClearBrowsingDataView2(Profile* profile, - ClearDataView* clear_data_view) - : clear_data_parent_window_(clear_data_view), - allow_clear_(true), - throbber_view_(NULL), - throbber_(NULL), - status_label_(NULL), - delete_all_label_(NULL), - del_history_checkbox_(NULL), - del_downloads_checkbox_(NULL), - del_cache_checkbox_(NULL), - del_cookies_checkbox_(NULL), - del_passwords_checkbox_(NULL), - del_form_data_checkbox_(NULL), - time_period_label_(NULL), - time_period_combobox_(NULL), - clear_browsing_data_button_(NULL), - delete_in_progress_(false), - profile_(profile), - remover_(NULL) { - DCHECK(profile); - Init(); - InitControlLayout(); -} - -ClearBrowsingDataView2::~ClearBrowsingDataView2(void) { - if (remover_) { - // We were destroyed while clearing history was in progress. This can only - // occur during automated tests (normally the user can't close the dialog - // while clearing is in progress as the dialog is modal and not closeable). - remover_->RemoveObserver(this); - } -} - -void ClearBrowsingDataView2::SetAllowClear(bool allow) { - allow_clear_ = allow; - UpdateControlEnabledState(); -} - -void ClearBrowsingDataView2::Init() { - throbber_ = new views::Throbber(50, true); - throbber_->SetVisible(false); - - status_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_DATA_DELETING)); - status_label_->SetVisible(false); - - // Regular view controls we draw by ourself. First, we add the dialog label. - delete_all_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_BROWSING_DATA_LABEL)); - - // Add all the check-boxes. - del_history_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_BROWSING_HISTORY_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteBrowsingHistory)); - - del_downloads_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_DOWNLOAD_HISTORY_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteDownloadHistory)); - - del_cache_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_CACHE_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteCache)); - - del_cookies_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_COOKIES_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteCookies)); - - del_passwords_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_PASSWORDS_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeletePasswords)); - - del_form_data_checkbox_ = - AddCheckbox(l10n_util::GetString(IDS_DEL_FORM_DATA_CHKBOX), - profile_->GetPrefs()->GetBoolean(prefs::kDeleteFormData)); - - clear_browsing_data_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_CLEAR_BROWSING_DATA_BUTTON)); - - // Add a label which appears before the combo box for the time period. - time_period_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_BROWSING_DATA_TIME_LABEL)); - - // Add the combo box showing how far back in time we want to delete. - time_period_combobox_ = new views::Combobox(this); - time_period_combobox_->SetSelectedItem(profile_->GetPrefs()->GetInteger( - prefs::kDeleteTimePeriod)); - time_period_combobox_->set_listener(this); - time_period_combobox_->SetAccessibleName(time_period_label_->GetText()); - - // Create the throbber and related views. The throbber and status link are - // contained in throbber_view_, which is positioned by DialogClientView right - // next to the buttons. - throbber_view_ = new views::View(); - - GridLayout* layout = new GridLayout(throbber_view_); - throbber_view_->SetLayoutManager(layout); - views::ColumnSet* column_set = layout->AddColumnSet(0); - - // DialogClientView positions the extra view at kButtonHEdgeMargin, but we - // put all our controls at kPanelHorizMargin. Add a padding column so things - // line up nicely. - if (kPanelHorizMargin - kButtonHEdgeMargin > 0) - column_set->AddPaddingColumn(0, kPanelHorizMargin - kButtonHEdgeMargin); - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(1, 0); - layout->AddView(throbber_); - layout->AddView(status_label_); -} - -void ClearBrowsingDataView2::InitControlLayout() { - GridLayout* layout = CreatePanelGridLayout(this); - this->SetLayoutManager(layout); - - int leading_column_set_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(leading_column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - const int indented_column_set_id = 1; - column_set = layout->AddColumnSet(indented_column_set_id); - column_set->AddPaddingColumn(0, views::Checkbox::GetTextIndent()); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - const int two_column_set_id = 2; - column_set = layout->AddColumnSet(two_column_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - const int fill_column_set_id = 3; - column_set = layout->AddColumnSet(fill_column_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - // Delete All label goes to the top left corner. - layout->StartRow(0, leading_column_set_id); - layout->AddView(delete_all_label_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Check-boxes go beneath it (with a little indentation). - layout->StartRow(0, indented_column_set_id); - layout->AddView(del_history_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, indented_column_set_id); - layout->AddView(del_downloads_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, indented_column_set_id); - layout->AddView(del_cache_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, indented_column_set_id); - layout->AddView(del_cookies_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, indented_column_set_id); - layout->AddView(del_passwords_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, indented_column_set_id); - layout->AddView(del_form_data_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Time period label is next below the combo boxes followed by time - // period combo box - layout->StartRow(0, two_column_set_id); - layout->AddView(time_period_label_); - time_period_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->AddView(time_period_combobox_, 1, 1, views::GridLayout::LEADING, - views::GridLayout::CENTER); - - layout->AddPaddingRow(0, kUnrelatedControlLargeVerticalSpacing); - - // Left-align the throbber - layout->StartRow(0, two_column_set_id); - layout->AddView(throbber_view_, 1, 1, - GridLayout::LEADING, GridLayout::CENTER); - - // Right-align the clear button - layout->AddView(clear_browsing_data_button_, 1, 1, - GridLayout::TRAILING, GridLayout::CENTER); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView2, ComboboxModel implementation: - -int ClearBrowsingDataView2::GetItemCount() { - return 5; -} - -string16 ClearBrowsingDataView2::GetItemAt(int index) { - switch (index) { - case 0: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_HOUR); - case 1: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_DAY); - case 2: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_WEEK); - case 3: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_4WEEKS); - case 4: return l10n_util::GetStringUTF16(IDS_CLEAR_DATA_EVERYTHING); - default: NOTREACHED() << "Missing item"; - return ASCIIToUTF16("?"); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView2, views::ComboBoxListener implementation: - -void ClearBrowsingDataView2::ItemChanged(views::Combobox* sender, - int prev_index, int new_index) { - if (sender == time_period_combobox_ && prev_index != new_index) - profile_->GetPrefs()->SetInteger(prefs::kDeleteTimePeriod, new_index); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView2, views::ButtonListener implementation: - -void ClearBrowsingDataView2::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == clear_browsing_data_button_) { - profile_->GetPrefs()->SetBoolean(prefs::kDeleteBrowsingHistory, - del_history_checkbox_->checked() ? true : false); - profile_->GetPrefs()->SetBoolean(prefs::kDeleteDownloadHistory, - del_downloads_checkbox_->checked() ? true : false); - profile_->GetPrefs()->SetBoolean(prefs::kDeleteCache, - del_cache_checkbox_->checked() ? true : false); - profile_->GetPrefs()->SetBoolean(prefs::kDeleteCookies, - del_cookies_checkbox_->checked() ? true : false); - profile_->GetPrefs()->SetBoolean(prefs::kDeletePasswords, - del_passwords_checkbox_->checked() ? true : false); - profile_->GetPrefs()->SetBoolean(prefs::kDeleteFormData, - del_form_data_checkbox_->checked() ? true : false); - clear_data_parent_window_->StartClearingBrowsingData(); - OnDelete(); - } - - // When no checkbox is checked we should not have the action button enabled. - // This forces the button to evaluate what state they should be in. - UpdateControlEnabledState(); -} - -void ClearBrowsingDataView2::LinkActivated(views::Link* source, - int event_flags) { - Browser* browser = Browser::Create(profile_); - browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), - GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); - browser->window()->Show(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearBrowsingDataView2, private: - -views::Checkbox* ClearBrowsingDataView2::AddCheckbox(const std::wstring& text, - bool checked) { - views::Checkbox* checkbox = new views::Checkbox(text); - checkbox->SetChecked(checked); - checkbox->set_listener(this); - return checkbox; -} - -void ClearBrowsingDataView2::UpdateControlEnabledState() { - del_history_checkbox_->SetEnabled(!delete_in_progress_); - del_downloads_checkbox_->SetEnabled(!delete_in_progress_); - del_cache_checkbox_->SetEnabled(!delete_in_progress_); - del_cookies_checkbox_->SetEnabled(!delete_in_progress_); - del_passwords_checkbox_->SetEnabled(!delete_in_progress_); - del_form_data_checkbox_->SetEnabled(!delete_in_progress_); - time_period_combobox_->SetEnabled(!delete_in_progress_); - - status_label_->SetVisible(delete_in_progress_); - throbber_->SetVisible(delete_in_progress_); - if (delete_in_progress_) - throbber_->Start(); - else - throbber_->Stop(); - - clear_browsing_data_button_->SetEnabled( - allow_clear_ && - !delete_in_progress_ && - (del_history_checkbox_->checked() || - del_downloads_checkbox_->checked() || - del_cache_checkbox_->checked() || - del_cookies_checkbox_->checked() || - del_passwords_checkbox_->checked() || - del_form_data_checkbox_->checked())); -} - -// Convenience method that returns true if the supplied checkbox is selected -// and enabled. -static bool IsCheckBoxEnabledAndSelected(views::Checkbox* cb) { - return (cb->IsEnabled() && cb->checked()); -} - -void ClearBrowsingDataView2::OnDelete() { - int period_selected = time_period_combobox_->selected_item(); - - int remove_mask = 0; - if (IsCheckBoxEnabledAndSelected(del_history_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_HISTORY; - if (IsCheckBoxEnabledAndSelected(del_downloads_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_DOWNLOADS; - if (IsCheckBoxEnabledAndSelected(del_cookies_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_COOKIES; - if (IsCheckBoxEnabledAndSelected(del_passwords_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_PASSWORDS; - if (IsCheckBoxEnabledAndSelected(del_form_data_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_FORM_DATA; - if (IsCheckBoxEnabledAndSelected(del_cache_checkbox_)) - remove_mask |= BrowsingDataRemover::REMOVE_CACHE; - - delete_in_progress_ = true; - UpdateControlEnabledState(); - - // BrowsingDataRemover deletes itself when done. - remover_ = new BrowsingDataRemover(profile_, - static_cast<BrowsingDataRemover::TimePeriod>(period_selected), - base::Time()); - remover_->AddObserver(this); - remover_->Remove(remove_mask); -} - -void ClearBrowsingDataView2::OnBrowsingDataRemoverDone() { - clear_data_parent_window_->StopClearingBrowsingData(); -} diff --git a/chrome/browser/views/clear_browsing_data_view.h b/chrome/browser/views/clear_browsing_data_view.h index 92133b3..9911fb1 100644 --- a/chrome/browser/views/clear_browsing_data_view.h +++ b/chrome/browser/views/clear_browsing_data_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,116 +6,8 @@ #define CHROME_BROWSER_VIEWS_CLEAR_BROWSING_DATA_VIEW_H_ #pragma once -#include "app/combobox_model.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/views/clear_data_view.h" -#include "views/controls/button/button.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/label.h" -#include "views/controls/link.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Checkbox; -class Label; -class Throbber; -class Window; -} - -class ClearDataView; -class Profile; -class MessageLoop; - -//////////////////////////////////////////////////////////////////////////////// -// -// The ClearBrowsingData2 class is responsible for drawing the UI controls of -// the dialog that allows the user to select what to delete (history, -// downloads, etc). -// -// TODO(raz) Remove the 2 suffix when the mac/linux/chromeos versions are there -// -//////////////////////////////////////////////////////////////////////////////// -class ClearBrowsingDataView2 : public views::View, - public views::ButtonListener, - public ComboboxModel, - public views::Combobox::Listener, - public BrowsingDataRemover::Observer, - public views::LinkController { - public: - ClearBrowsingDataView2(Profile* profile, ClearDataView* clear_data_view); - - virtual ~ClearBrowsingDataView2(void); - - // Initialize the controls on the dialog. - void Init(); - - // Overridden from ComboboxModel: - virtual int GetItemCount(); - virtual string16 GetItemAt(int index); - - // Overridden from views::Combobox::Listener: - virtual void ItemChanged(views::Combobox* sender, int prev_index, - int new_index); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overriden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - // Enable/disable clearing from this tab - void SetAllowClear(bool allow); - - private: - // Adds a new check-box as a child to the view. - views::Checkbox* AddCheckbox(const std::wstring& text, bool checked); - - // Sets the controls on the UI to be enabled/disabled depending on whether we - // have a delete operation in progress or not. - void UpdateControlEnabledState(); - - // Hand off control layout to layout manger - void InitControlLayout(); - - // Starts the process of deleting the browsing data depending on what the - // user selected. - void OnDelete(); - - // Callback from BrowsingDataRemover. Closes the dialog. - virtual void OnBrowsingDataRemoverDone(); - - // Parent window, used for disabling close - ClearDataView* clear_data_parent_window_; - - // Allows for disabling the clear button from outside this view - bool allow_clear_; - - // UI elements - views::View* throbber_view_; - views::Throbber* throbber_; - views::Label* status_label_; - views::Label* delete_all_label_; - views::Checkbox* del_history_checkbox_; - views::Checkbox* del_downloads_checkbox_; - views::Checkbox* del_cache_checkbox_; - views::Checkbox* del_cookies_checkbox_; - views::Checkbox* del_passwords_checkbox_; - views::Checkbox* del_form_data_checkbox_; - views::Label* time_period_label_; - views::Combobox* time_period_combobox_; - views::NativeButton* clear_browsing_data_button_; - - // Used to signal enabled/disabled state for controls in the UI. - bool delete_in_progress_; - - Profile* profile_; - - // If non-null it means removal is in progress. BrowsingDataRemover takes care - // of deleting itself when done. - BrowsingDataRemover* remover_; - - DISALLOW_COPY_AND_ASSIGN(ClearBrowsingDataView2); -}; +#include "chrome/browser/ui/views/clear_browsing_data_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CLEAR_BROWSING_DATA_VIEW_H_ + diff --git a/chrome/browser/views/clear_data_view.cc b/chrome/browser/views/clear_data_view.cc deleted file mode 100644 index 8f349bd..0000000 --- a/chrome/browser/views/clear_data_view.cc +++ /dev/null @@ -1,174 +0,0 @@ -// 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/clear_data_view.h" - -#include "app/l10n_util.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/views/clear_browsing_data.h" -#include "chrome/browser/views/clear_server_data.h" -#include "chrome/common/pref_names.h" -#include "gfx/insets.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/url_request/url_request_context.h" -#include "views/background.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/controls/throbber.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/dialog_client_view.h" -#include "views/window/window.h" - -using views::GridLayout; - -// The combo box is vertically aligned to the 'time-period' label, which makes -// the combo box look a little too close to the check box above it when we use -// standard layout to separate them. We therefore add a little extra margin to -// the label, giving it a little breathing space. -static const int kExtraMarginForTimePeriodLabel = 3; - -//////////////////////////////////////////////////////////////////////////////// -// ClearDataView, public: - -ClearDataView::ClearDataView(Profile* profile) - : profile_(profile), - clear_server_data_tab_(NULL), - clear_browsing_data_tab_(NULL), - clearing_data_(false) { - DCHECK(profile); - Init(); -} - -void ClearDataView::Init() { - tabs_ = new views::TabbedPane; - - tabs_->SetAccessibleName(l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE, - l10n_util::GetString(IDS_OPTIONS_DIALOG_TITLE))); - AddChildView(tabs_); - - int tab_index = 0; - clear_browsing_data_tab_ = new ClearBrowsingDataView2(profile_, this); - tabs_->AddTabAtIndex(tab_index++, - l10n_util::GetString(IDS_CLEAR_CHROME_DATA_TAB_LABEL), - clear_browsing_data_tab_, false); - clear_server_data_tab_ = new ClearServerDataView(profile_, this); - tabs_->AddTabAtIndex(tab_index++, - l10n_util::GetString(IDS_CLEAR_OTHER_DATA_TAB_LABEL), - clear_server_data_tab_, false); - - tabs_->SelectTabAt(static_cast<int>(0)); -} - -void ClearDataView::StartClearingBrowsingData() { - // Only one clear can happen at a time - clear_server_data_tab_->SetAllowClear(false); - clearing_data_ = true; - window()->EnableClose(false); - GetDialogClientView()->UpdateDialogButtons(); -} - -void ClearDataView::StopClearingBrowsingData() { - window()->Close(); -} - -void ClearDataView::StartClearingServerData() { - // Only one clear can happen at a time - clear_browsing_data_tab_->SetAllowClear(false); - clearing_data_ = true; - window()->EnableClose(false); - GetDialogClientView()->UpdateDialogButtons(); -} - -void ClearDataView::SucceededClearingServerData() { - window()->Close(); -} - -void ClearDataView::FailedClearingServerData() { - clear_browsing_data_tab_->SetAllowClear(true); - clearing_data_ = false; - window()->EnableClose(false); - GetDialogClientView()->UpdateDialogButtons(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearDataView, views::View implementation: - -gfx::Size ClearDataView::GetPreferredSize() { - gfx::Size size(tabs_->GetPreferredSize()); - size.Enlarge(2 * kDialogPadding, 2 * kDialogPadding); - return size; -} - -void ClearDataView::Layout() { - tabs_->SetBounds(kDialogPadding, kDialogPadding, - width() - (2 * kDialogPadding), - height() - (2 * kDialogPadding)); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearDataView, views::DialogDelegate implementation: - -int ClearDataView::GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_NONE; -} - -std::wstring ClearDataView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - DCHECK(button == MessageBoxFlags::DIALOGBUTTON_CANCEL); - return l10n_util::GetString(IDS_CANCEL); -} - -int ClearDataView::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - - -bool ClearDataView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - - return !clearing_data_; -} - -bool ClearDataView::CanResize() const { - return false; -} - -bool ClearDataView::CanMaximize() const { - return false; -} - -bool ClearDataView::IsAlwaysOnTop() const { - return false; -} - -bool ClearDataView::HasAlwaysOnTopMenu() const { - return false; -} - -bool ClearDataView::IsModal() const { - return true; -} - -std::wstring ClearDataView::GetWindowTitle() const { - return l10n_util::GetString(IDS_CLEAR_BROWSING_DATA_TITLE); -} - -views::View* ClearDataView::GetContentsView() { - return this; -} - -views::View* ClearDataView::GetInitiallyFocusedView() { - return GetDialogClientView()->cancel_button(); -} - diff --git a/chrome/browser/views/clear_data_view.h b/chrome/browser/views/clear_data_view.h index 9481ec4..f03a941 100644 --- a/chrome/browser/views/clear_data_view.h +++ b/chrome/browser/views/clear_data_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// 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. @@ -6,94 +6,8 @@ #define CHROME_BROWSER_VIEWS_CLEAR_DATA_VIEW_H_ #pragma once -#include "app/combobox_model.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/views/clear_browsing_data_view.h" -#include "chrome/browser/views/clear_server_data.h" -#include "views/controls/button/button.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/label.h" -#include "views/controls/link.h" -#include "views/controls/tabbed_pane/tabbed_pane.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Checkbox; -class Label; -class Throbber; -class Window; -} - -class ClearBrowsingDataView2; -class ClearServerDataView; -class Profile; -class MessageLoop; - -//////////////////////////////////////////////////////////////////////////////// -// -// The ClearDataView class is responsible for drawing the window that allows -// the user to select what to delete (history, downloads, etc). It has tabs -// separating "local" data from "other" (e.g. server) data -// -//////////////////////////////////////////////////////////////////////////////// -class ClearDataView : public views::View, - public views::DialogDelegate { - public: - explicit ClearDataView(Profile* profile); - virtual ~ClearDataView(void) {} - - // Disallow the window closing while clearing either server or browsing - // data. After clear completes, close the window. - void StartClearingBrowsingData(); - void StopClearingBrowsingData(); - - void StartClearingServerData(); - void SucceededClearingServerData(); - void FailedClearingServerData(); - - // Initialize the controls on the dialog. - void Init(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - // Overridden from views::DialogDelegate: - virtual int GetDefaultDialogButton() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual int GetDialogButtons() const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool CanResize() const; - virtual bool CanMaximize() const; - virtual bool IsAlwaysOnTop() const; - virtual bool HasAlwaysOnTopMenu() const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual views::View* GetContentsView(); - virtual bool GetSizeExtraViewHeightToButtons() { return true; } - virtual views::View* GetInitiallyFocusedView(); - - private: - // Sets the controls on the UI to be enabled/disabled depending on whether we - // have a delete operation in progress or not. - void UpdateControlEnabledState(); - - // Currently clearing - bool clearing_data_; - - views::TabbedPane* tabs_; - ClearServerDataView* clear_server_data_tab_; - ClearBrowsingDataView2* clear_browsing_data_tab_; - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(ClearDataView); -}; - -static const int kDialogPadding = 7; +#include "chrome/browser/ui/views/clear_data_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CLEAR_DATA_VIEW_H_ diff --git a/chrome/browser/views/clear_server_data.cc b/chrome/browser/views/clear_server_data.cc deleted file mode 100644 index 2cd3be7..0000000 --- a/chrome/browser/views/clear_server_data.cc +++ /dev/null @@ -1,344 +0,0 @@ -// 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/clear_server_data.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/command_line.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/sync/profile_sync_service.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "gfx/insets.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/url_request/url_request_context.h" -#include "views/background.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/controls/throbber.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/dialog_client_view.h" -#include "views/window/window.h" - -using views::GridLayout; -using views::ColumnSet; - -// The combo box is vertically aligned to the 'time-period' label, which makes -// the combo box look a little too close to the check box above it when we use -// standard layout to separate them. We therefore add a little extra margin to -// the label, giving it a little breathing space. -static const int kExtraMarginForTimePeriodLabel = 3; - -//////////////////////////////////////////////////////////////////////////////// -// ClearServerDataView, public: - -ClearServerDataView::ClearServerDataView(Profile* profile, - ClearDataView* clear_data_view) - : profile_(profile), - clear_data_parent_window_(clear_data_view), - allow_clear_(true) { - DCHECK(profile); - DCHECK(clear_data_view); - - // Always show preferences for the original profile. Most state when off - // the record comes from the original profile, but we explicitly use - // the original profile to avoid potential problems. - profile_ = profile->GetOriginalProfile(); - sync_service_ = profile_->GetProfileSyncService(); - - if (NULL != sync_service_) { - sync_service_->ResetClearServerDataState(); - sync_service_->AddObserver(this); - } - - Init(); - InitControlLayout(); - InitControlVisibility(); -} - -ClearServerDataView::~ClearServerDataView(void) { - if (NULL != sync_service_) { - sync_service_->RemoveObserver(this); - } -} - -void ClearServerDataView::Init() { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - gfx::Font title_font = - rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); - - flash_title_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_DATA_ADOBE_FLASH_TITLE)); - flash_title_label_->SetFont(title_font); - - flash_description_label_= new views::Label( - l10n_util::GetString(IDS_CLEAR_DATA_ADOBE_FLASH_DESCRIPTION)); - flash_link_ = - new views::Link(l10n_util::GetString(IDS_FLASH_STORAGE_SETTINGS)); - flash_link_->SetController(this); - - chrome_sync_title_label_= new views::Label( - l10n_util::GetString(IDS_CLEAR_DATA_CHROME_SYNC_TITLE)); - chrome_sync_title_label_->SetFont(title_font); - - chrome_sync_description_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_DATA_CLEAR_SERVER_DATA_DESCRIPTION)); - - clear_server_data_button_= new views::NativeButton( - this, l10n_util::GetString(IDS_CLEAR_DATA_CLEAR_BUTTON)); - - dashboard_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_DASHBOARD_DESCRIPTION)); - - dashboard_link_ = new views::Link(); - dashboard_link_->SetController(this); - dashboard_link_->SetText( - l10n_util::GetString(IDS_SYNC_PRIVACY_DASHBOARD_LINK_LABEL)); - - status_label_ = new views::Label( - l10n_util::GetString(IDS_CLEAR_DATA_DELETING)); - throbber_ = new views::Throbber(50, true); -} - -void ClearServerDataView::InitControlLayout() { - GridLayout* layout = CreatePanelGridLayout(this); - this->SetLayoutManager(layout); - - int centered_column_set_id = 0; - ColumnSet * column_set = layout->AddColumnSet(centered_column_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - int left_aligned_column_set_id = 1; - column_set = layout->AddColumnSet(left_aligned_column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - const int three_column_set_id = 2; - column_set = layout->AddColumnSet(three_column_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - AddWrappingLabelRow(layout, flash_title_label_, - centered_column_set_id, true); - AddWrappingLabelRow(layout, flash_description_label_, - centered_column_set_id, true); - - layout->StartRow(0, left_aligned_column_set_id); - layout->AddView(flash_link_); - layout->AddPaddingRow(0, kPanelVertMargin); - - AddWrappingLabelRow(layout, chrome_sync_title_label_, - centered_column_set_id, true); - AddWrappingLabelRow(layout, chrome_sync_description_label_, - centered_column_set_id, true); - - layout->StartRow(0, three_column_set_id); - layout->AddView(clear_server_data_button_, 1, 1, - GridLayout::LEADING, GridLayout::CENTER); - layout->AddView(status_label_, 1, 1, - GridLayout::LEADING, GridLayout::CENTER); - layout->AddView(throbber_, 1, 1, - GridLayout::TRAILING, GridLayout::CENTER); - layout->AddPaddingRow(0, kPanelVertMargin); - - AddWrappingLabelRow(layout, dashboard_label_, centered_column_set_id, true); - - layout->StartRow(0, left_aligned_column_set_id); - layout->AddView(dashboard_link_); -} - -void ClearServerDataView::InitControlVisibility() { - bool allow_clear_server_data_ui = - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableClearServerData); - - // Hide progress indicators - throbber_->SetVisible(false); - status_label_->SetVisible(false); - - // Only show the sync portion if not behind the flag - chrome_sync_title_label_->SetVisible(allow_clear_server_data_ui); - chrome_sync_description_label_->SetVisible(allow_clear_server_data_ui); - clear_server_data_button_->SetVisible(allow_clear_server_data_ui); - dashboard_label_->SetVisible(allow_clear_server_data_ui); - dashboard_link_->SetVisible(allow_clear_server_data_ui); - - // Enable our clear button, set false for delete_in_progress - UpdateClearButtonEnabledState(false); -} - -void ClearServerDataView::SetAllowClear(bool allow) { - allow_clear_ = allow; - UpdateControlEnabledState(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearServerDataView, views::View implementation: - -void ClearServerDataView::AddWrappingLabelRow(views::GridLayout* layout, - views::Label* label, - int id, - bool related_follows) { - label->SetMultiLine(true); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->StartRow(0, id); - layout->AddView(label); - AddSpacing(layout, related_follows); -} - -void ClearServerDataView::AddSpacing(views::GridLayout* layout, - bool related_follows) { - layout->AddPaddingRow(0, related_follows ? kRelatedControlVerticalSpacing - : kUnrelatedControlVerticalSpacing); -} - -gfx::Size ClearServerDataView::GetPreferredSize() { - // If we didn't return a preferred size, the containing view auto-sizes to - // the width of the narrowest button, which is not what we want - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_CLEARDATA_DIALOG_WIDTH_CHARS, - IDS_CLEARDATA_DIALOG_HEIGHT_LINES)); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearServerDataView, views::ButtonListener implementation: - -void ClearServerDataView::ButtonPressed( - views::Button* sender, const views::Event& event) { - - if (sender == clear_server_data_button_) { - // Protect against the unlikely case where the server received a - // message, and the syncer syncs and resets itself before the - // user tries pressing the Clear button in this dialog again. - // TODO(raz) Confirm whether we have an issue here - if (sync_service_->HasSyncSetupCompleted()) { - ConfirmMessageBoxDialog::Run( - GetWindow()->GetNativeWindow(), - this, - l10n_util::GetString(IDS_CONFIRM_CLEAR_DESCRIPTION), - l10n_util::GetString(IDS_CONFIRM_CLEAR_TITLE)); - } - } - - UpdateControlEnabledState(); -} - -void ClearServerDataView::LinkActivated(views::Link* source, - int event_flags) { - Browser* browser = Browser::Create(profile_); - if (source == flash_link_) { - browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), - GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); - browser->window()->Show(); - } else { - browser->OpenPrivacyDashboardTabAndActivate(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearServerDataView, ConfirmMessageBoxObserver implementation: - -void ClearServerDataView::OnConfirmMessageAccept() { - clear_data_parent_window_->StartClearingServerData(); - sync_service_->ClearServerData(); - UpdateControlEnabledState(); -} - -void ClearServerDataView::OnConfirmMessageCancel() { - UpdateControlEnabledState(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearServerDataView, ProfileSyncServiceObserver implementation: - -void ClearServerDataView::OnStateChanged() { - // Note that we are listening for all notifications here. Clearing from - // another browser should cause the "clear" button to go gray (if a - // notification nudges the syncer, causing OnStateChanged to be called with - // sync disabled) - UpdateControlEnabledState(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ClearServerDataView, private: - -void ClearServerDataView::UpdateControlEnabledState() { - bool delete_in_progress = false; - - // We only want to call Suceeded/FailedClearingServerData once, not every - // time the view is refreshed. As such, on success/failure we handle that - // state and immediately reset things back to CLEAR_NOT_STARTED. - ProfileSyncService::ClearServerDataState clear_state = - profile_->GetProfileSyncService()->GetClearServerDataState(); - profile_->GetProfileSyncService()->ResetClearServerDataState(); - - if (NULL != sync_service_) { - sync_service_->ResetClearServerDataState(); - } - - switch (clear_state) { - case ProfileSyncService::CLEAR_NOT_STARTED: - // We can get here when we first start and after a failed clear (which - // does not close the tab), do nothing. - break; - case ProfileSyncService::CLEAR_CLEARING: - // Clearing buttons on all tabs are disabled at this - // point, throbber is going - status_label_->SetText(l10n_util::GetString(IDS_CLEAR_DATA_SENDING)); - status_label_->SetVisible(true); - delete_in_progress = true; - break; - case ProfileSyncService::CLEAR_FAILED: - // Show an error and reallow clearing - clear_data_parent_window_->FailedClearingServerData(); - status_label_->SetText(l10n_util::GetString(IDS_CLEAR_DATA_ERROR)); - status_label_->SetVisible(true); - delete_in_progress = false; - break; - case ProfileSyncService::CLEAR_SUCCEEDED: - // Close the dialog box, success! - status_label_->SetVisible(false); - delete_in_progress = false; - clear_data_parent_window_->SucceededClearingServerData(); - break; - } - - // allow_clear can be false when a local browsing data clear is happening - // from the neighboring tab. delete_in_progress means that a clear is - // pending in the current tab. - UpdateClearButtonEnabledState(delete_in_progress); - - throbber_->SetVisible(delete_in_progress); - if (delete_in_progress) - throbber_->Start(); - else - throbber_->Stop(); -} - -void ClearServerDataView::UpdateClearButtonEnabledState( - bool delete_in_progress) { - this->clear_server_data_button_->SetEnabled( - sync_service_ != NULL && - sync_service_->HasSyncSetupCompleted() && - !delete_in_progress && allow_clear_); -} - diff --git a/chrome/browser/views/clear_server_data.h b/chrome/browser/views/clear_server_data.h index 647ab9a..ecce971 100644 --- a/chrome/browser/views/clear_server_data.h +++ b/chrome/browser/views/clear_server_data.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,113 +6,8 @@ #define CHROME_BROWSER_VIEWS_CLEAR_SERVER_DATA_H_ #pragma once -#include "app/combobox_model.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/views/clear_data_view.h" -#include "chrome/browser/views/confirm_message_box_dialog.h" -#include "chrome/browser/sync/profile_sync_service.h" -#include "views/controls/button/button.h" -#include "views/controls/label.h" -#include "views/controls/link.h" -#include "views/grid_layout.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Checkbox; -class ColumnSet; -class GridLayout; -class Label; -class Throbber; -class Window; -} - -class ClearDataView; -class Profile; -class MessageLoop; - -//////////////////////////////////////////////////////////////////////////////// -// -// The ClearServerData class is responsible for drawing the UI controls of the -// dialog that allows the user to delete non-local data (e.g. Chrome Sync data) -// -//////////////////////////////////////////////////////////////////////////////// -class ClearServerDataView : public views::View, - public views::ButtonListener, - public views::LinkController, - public ProfileSyncServiceObserver, - public ConfirmMessageBoxObserver { - public: - ClearServerDataView(Profile* profile, ClearDataView* clear_data_view); - - virtual ~ClearServerDataView(); - - // Initialize the controls on the dialog. - void Init(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overriden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - // Disable clearing from this tab - void SetAllowClear(bool allow); - - private: - void InitControlLayout(); - void InitControlVisibility(); - - void AddSpacing(views::GridLayout* layout, - bool related_follows); - - void AddWrappingLabelRow(views::GridLayout* layout, - views::Label* label, - int id, - bool related_follows); - - // Adds a new check-box as a child to the view. - views::Checkbox* AddCheckbox(const std::wstring& text, bool checked); - - // Sets the controls on the UI to be enabled/disabled depending on whether we - // have a delete operation in progress or not. - void UpdateControlEnabledState(); - - // Enables/disables the clear button as appropriate - void UpdateClearButtonEnabledState(bool delete_in_progress); - - // Starts the process of deleting the browsing data depending on what the - // user selected. - void OnDelete(); - - // ProfileSyncServiceObserver method. - virtual void OnStateChanged(); - - // ProfileSyncServiceObserver - virtual void OnConfirmMessageAccept(); - virtual void OnConfirmMessageCancel(); - - ClearDataView* clear_data_parent_window_; - Profile* profile_; - ProfileSyncService* sync_service_; - bool allow_clear_; - - views::Label* flash_title_label_; - views::Label* flash_description_label_; - views::Label* chrome_sync_title_label_; - views::Label* chrome_sync_description_label_; - views::Label* dashboard_label_; - views::Label* status_label_; - views::Link* flash_link_; - views::Link* dashboard_link_; - views::NativeButton* clear_server_data_button_; - views::Throbber* throbber_; - - DISALLOW_COPY_AND_ASSIGN(ClearServerDataView); -}; +#include "chrome/browser/ui/views/clear_server_data.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CLEAR_SERVER_DATA_H_ diff --git a/chrome/browser/views/collected_cookies_win.cc b/chrome/browser/views/collected_cookies_win.cc deleted file mode 100644 index 3f25992..0000000 --- a/chrome/browser/views/collected_cookies_win.cc +++ /dev/null @@ -1,391 +0,0 @@ -// 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/collected_cookies_win.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/browser/cookies_tree_model.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/notification_service.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "views/box_layout.h" -#include "views/controls/button/native_button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/standard_layout.h" -#include "views/widget/root_view.h" -#include "views/widget/widget_win.h" -#include "views/window/window.h" - -namespace browser { - -// Declared in browser_dialogs.h so others don't have to depend on our header. -void ShowCollectedCookiesDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents) { - // Deletes itself on close. - new CollectedCookiesWin(parent_window, tab_contents); -} - -} // namespace browser - -namespace { -// Spacing between the infobar frame and its contents. -const int kInfobarVerticalPadding = 3; -const int kInfobarHorizontalPadding = 8; - -// Width of the infobar frame. -const int kInfobarBorderSize = 1; - -// Dimensions of the tree views. -const int kTreeViewWidth = 400; -const int kTreeViewHeight = 125; - -} // namespace - -// A custom view that conditionally displays an infobar. -class InfobarView : public views::View { - public: - InfobarView() { - content_ = new views::View; - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kInfobarBorderSize, border_color); - content_->set_border(border); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - info_image_ = new views::ImageView(); - info_image_->SetImage(rb.GetBitmapNamed(IDR_INFO)); - label_ = new views::Label(); - } - virtual ~InfobarView() {} - - // Update the visibility of the infobar. If |is_visible| is true, a rule for - // |setting| on |domain_name| was created. - void UpdateVisibility(bool is_visible, - ContentSetting setting, - const std::wstring& domain_name) { - if (!is_visible) { - SetVisible(false); - return; - } - - std::wstring label; - switch (setting) { - case CONTENT_SETTING_BLOCK: - label = l10n_util::GetStringF( - IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, domain_name); - break; - - case CONTENT_SETTING_ALLOW: - label = l10n_util::GetStringF( - IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, domain_name); - break; - - case CONTENT_SETTING_SESSION_ONLY: - label = l10n_util::GetStringF( - IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, domain_name); - break; - - default: - NOTREACHED(); - } - label_->SetText(label); - content_->Layout(); - SetVisible(true); - } - - private: - // Initialize contents and layout. - void Init() { - AddChildView(content_); - content_->SetLayoutManager( - new views::BoxLayout(views::BoxLayout::kHorizontal, - kInfobarHorizontalPadding, - kInfobarVerticalPadding, - kRelatedControlSmallHorizontalSpacing)); - content_->AddChildView(info_image_); - content_->AddChildView(label_); - UpdateVisibility(false, CONTENT_SETTING_BLOCK, std::wstring()); - } - - // views::View overrides. - virtual gfx::Size GetPreferredSize() { - if (!IsVisible()) - return gfx::Size(); - - // Add space around the banner. - gfx::Size size(content_->GetPreferredSize()); - size.Enlarge(0, 2 * kRelatedControlVerticalSpacing); - return size; - } - - virtual void Layout() { - content_->SetBounds( - 0, kRelatedControlVerticalSpacing, - width(), height() - kRelatedControlVerticalSpacing); - } - - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); - } - - // Holds the info icon image and text label and renders the border. - views::View* content_; - // Info icon image. - views::ImageView* info_image_; - // The label responsible for rendering the text. - views::Label* label_; - - DISALLOW_COPY_AND_ASSIGN(InfobarView); -}; - -/////////////////////////////////////////////////////////////////////////////// -// CollectedCookiesWin, constructor and destructor: - -CollectedCookiesWin::CollectedCookiesWin(gfx::NativeWindow parent_window, - TabContents* tab_contents) - : tab_contents_(tab_contents), - allowed_label_(NULL), - blocked_label_(NULL), - allowed_cookies_tree_(NULL), - blocked_cookies_tree_(NULL), - block_allowed_button_(NULL), - allow_blocked_button_(NULL), - for_session_blocked_button_(NULL), - infobar_(NULL) { - TabSpecificContentSettings* content_settings = - tab_contents->GetTabSpecificContentSettings(); - registrar_.Add(this, NotificationType::COLLECTED_COOKIES_SHOWN, - Source<TabSpecificContentSettings>(content_settings)); - - Init(); - - window_ = tab_contents_->CreateConstrainedDialog(this); -} - -CollectedCookiesWin::~CollectedCookiesWin() { - allowed_cookies_tree_->SetModel(NULL); - blocked_cookies_tree_->SetModel(NULL); -} - -void CollectedCookiesWin::Init() { - TabSpecificContentSettings* content_settings = - tab_contents_->GetTabSpecificContentSettings(); - HostContentSettingsMap* host_content_settings_map = - tab_contents_->profile()->GetHostContentSettingsMap(); - - // Allowed Cookie list. - allowed_label_ = new views::Label( - l10n_util::GetString(IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL)); - allowed_cookies_tree_model_.reset( - content_settings->GetAllowedCookiesTreeModel()); - allowed_cookies_tree_ = new views::TreeView(); - allowed_cookies_tree_->SetModel(allowed_cookies_tree_model_.get()); - allowed_cookies_tree_->SetController(this); - allowed_cookies_tree_->SetRootShown(false); - allowed_cookies_tree_->SetEditable(false); - allowed_cookies_tree_->set_lines_at_root(true); - allowed_cookies_tree_->set_auto_expand_children(true); - - // Blocked Cookie list. - blocked_label_ = new views::Label( - l10n_util::GetString( - host_content_settings_map->BlockThirdPartyCookies() ? - IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED : - IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL)); - blocked_label_->SetMultiLine(true); - blocked_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - blocked_cookies_tree_model_.reset( - content_settings->GetBlockedCookiesTreeModel()); - blocked_cookies_tree_ = new views::TreeView(); - blocked_cookies_tree_->SetModel(blocked_cookies_tree_model_.get()); - blocked_cookies_tree_->SetController(this); - blocked_cookies_tree_->SetRootShown(false); - blocked_cookies_tree_->SetEditable(false); - blocked_cookies_tree_->set_lines_at_root(true); - blocked_cookies_tree_->set_auto_expand_children(true); - - using views::GridLayout; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int single_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - const int three_columns_layout_id = 1; - column_set = layout->AddColumnSet(three_columns_layout_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_layout_id); - layout->AddView(allowed_label_); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(1, single_column_layout_id); - layout->AddView( - allowed_cookies_tree_, 1, 1, GridLayout::FILL, GridLayout::FILL, - kTreeViewWidth, kTreeViewHeight); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_layout_id); - block_allowed_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_COLLECTED_COOKIES_BLOCK_BUTTON)); - layout->AddView( - block_allowed_button_, 1, 1, GridLayout::LEADING, GridLayout::CENTER); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_layout_id); - layout->AddView( - new views::Separator(), 1, 1, GridLayout::FILL, GridLayout::FILL); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_layout_id); - layout->AddView(blocked_label_, 1, 1, GridLayout::FILL, GridLayout::FILL); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(1, single_column_layout_id); - layout->AddView( - blocked_cookies_tree_, 1, 1, GridLayout::FILL, GridLayout::FILL, - kTreeViewWidth, kTreeViewHeight); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, three_columns_layout_id); - allow_blocked_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_COLLECTED_COOKIES_ALLOW_BUTTON)); - layout->AddView(allow_blocked_button_); - for_session_blocked_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON)); - layout->AddView(for_session_blocked_button_); - - layout->StartRow(0, single_column_layout_id); - infobar_ = new InfobarView(); - layout->AddView(infobar_, 1, 1, GridLayout::FILL, GridLayout::FILL); - - EnableControls(); -} - -/////////////////////////////////////////////////////////////////////////////// -// ConstrainedDialogDelegate implementation. - -std::wstring CollectedCookiesWin::GetWindowTitle() const { - return l10n_util::GetString(IDS_COLLECTED_COOKIES_DIALOG_TITLE); -} - -int CollectedCookiesWin::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring CollectedCookiesWin::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - return l10n_util::GetString(IDS_CLOSE); -} - -void CollectedCookiesWin::DeleteDelegate() { - delete this; -} - -bool CollectedCookiesWin::Cancel() { - return true; -} - -views::View* CollectedCookiesWin::GetContentsView() { - return this; -} - -/////////////////////////////////////////////////////////////////////////////// -// views::ButtonListener implementation. - -void CollectedCookiesWin::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == block_allowed_button_) - AddContentException(allowed_cookies_tree_, CONTENT_SETTING_BLOCK); - else if (sender == allow_blocked_button_) - AddContentException(blocked_cookies_tree_, CONTENT_SETTING_ALLOW); - else if (sender == for_session_blocked_button_) - AddContentException(blocked_cookies_tree_, CONTENT_SETTING_SESSION_ONLY); -} - -/////////////////////////////////////////////////////////////////////////////// -// views::View implementation. - -void CollectedCookiesWin::OnTreeViewSelectionChanged( - views::TreeView* tree_view) { - EnableControls(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CollectedCookiesWin, private methods. - -void CollectedCookiesWin::EnableControls() { - bool enable_allowed_buttons = false; - TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode(); - if (node) { - CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node); - if (cookie_node->GetDetailedInfo().node_type == - CookieTreeNode::DetailedInfo::TYPE_ORIGIN) { - enable_allowed_buttons = static_cast<CookieTreeOriginNode*>( - cookie_node)->CanCreateContentException(); - } - } - block_allowed_button_->SetEnabled(enable_allowed_buttons); - - bool enable_blocked_buttons = false; - node = blocked_cookies_tree_->GetSelectedNode(); - if (node) { - CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node); - if (cookie_node->GetDetailedInfo().node_type == - CookieTreeNode::DetailedInfo::TYPE_ORIGIN) { - enable_blocked_buttons = static_cast<CookieTreeOriginNode*>( - cookie_node)->CanCreateContentException(); - } - } - allow_blocked_button_->SetEnabled(enable_blocked_buttons); - for_session_blocked_button_->SetEnabled(enable_blocked_buttons); -} - -void CollectedCookiesWin::AddContentException(views::TreeView* tree_view, - ContentSetting setting) { - CookieTreeOriginNode* origin_node = - static_cast<CookieTreeOriginNode*>(tree_view->GetSelectedNode()); - origin_node->CreateContentException( - tab_contents_->profile()->GetHostContentSettingsMap(), setting); - infobar_->UpdateVisibility(true, setting, origin_node->GetTitle()); - gfx::Rect bounds; - GetWidget()->GetBounds(&bounds, false); - // WidgetWin::GetBounds returns the bounds relative to the parent window, - // while WidgetWin::SetBounds wants screen coordinates. Do the translation - // here until http://crbug.com/52851 is fixed. - POINT topleft = {bounds.x(), bounds.y()}; - MapWindowPoints(HWND_DESKTOP, tab_contents_->GetNativeView(), &topleft, 1); - gfx::Size size = GetRootView()->GetPreferredSize(); - bounds.SetRect(topleft.x, topleft.y, size.width(), size.height()); - GetWidget()->SetBounds(bounds); -} - -/////////////////////////////////////////////////////////////////////////////// -// NotificationObserver implementation. - -void CollectedCookiesWin::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::COLLECTED_COOKIES_SHOWN); - DCHECK_EQ(Source<TabSpecificContentSettings>(source).ptr(), - tab_contents_->GetTabSpecificContentSettings()); - window_->CloseConstrainedWindow(); -} diff --git a/chrome/browser/views/collected_cookies_win.h b/chrome/browser/views/collected_cookies_win.h index d9f3c16..a13b856 100644 --- a/chrome/browser/views/collected_cookies_win.h +++ b/chrome/browser/views/collected_cookies_win.h @@ -2,95 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This is the Views implementation of the collected Cookies dialog. - #ifndef CHROME_BROWSER_VIEWS_COLLECTED_COOKIES_WIN_H_ #define CHROME_BROWSER_VIEWS_COLLECTED_COOKIES_WIN_H_ #pragma once -#include "chrome/browser/tab_contents/constrained_window.h" -#include "chrome/common/content_settings.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "views/controls/tree/tree_view.h" -#include "views/window/dialog_delegate.h" - -class ConstrainedWindow; -class CookiesTreeModel; -class InfobarView; -class TabContents; -namespace views { -class Label; -class NativeButton; -} - -// CollectedCookiesWin is a dialog that displays the allowed and blocked -// cookies of the current tab contents. To display the dialog, invoke -// ShowCollectedCookiesDialog() on the delegate of the tab contents. - -class CollectedCookiesWin : public ConstrainedDialogDelegate, - NotificationObserver, - views::ButtonListener, - views::TreeViewController, - views::View { - public: - // Use BrowserWindow::ShowCollectedCookiesDialog to show. - CollectedCookiesWin(gfx::NativeWindow parent_window, - TabContents* tab_contents); - - // ConstrainedDialogDelegate implementation. - virtual std::wstring GetWindowTitle() const; - virtual int GetDialogButtons() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual void DeleteDelegate(); - virtual bool Cancel(); - virtual views::View* GetContentsView(); - - // views::ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::TreeViewController implementation. - virtual void OnTreeViewSelectionChanged(views::TreeView* tree_view); - - private: - virtual ~CollectedCookiesWin(); - - void Init(); - - void EnableControls(); - - void AddContentException(views::TreeView* tree_view, ContentSetting setting); - - // Notification Observer implementation. - void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - NotificationRegistrar registrar_; - - ConstrainedWindow* window_; - - // The tab contents. - TabContents* tab_contents_; - - // Assorted views. - views::Label* allowed_label_; - views::Label* blocked_label_; - - views::TreeView* allowed_cookies_tree_; - views::TreeView* blocked_cookies_tree_; - - views::NativeButton* block_allowed_button_; - views::NativeButton* allow_blocked_button_; - views::NativeButton* for_session_blocked_button_; - - scoped_ptr<CookiesTreeModel> allowed_cookies_tree_model_; - scoped_ptr<CookiesTreeModel> blocked_cookies_tree_model_; - - InfobarView* infobar_; - - DISALLOW_COPY_AND_ASSIGN(CollectedCookiesWin); -}; +#include "chrome/browser/ui/views/collected_cookies_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_COLLECTED_COOKIES_WIN_H_ + diff --git a/chrome/browser/views/confirm_message_box_dialog.cc b/chrome/browser/views/confirm_message_box_dialog.cc deleted file mode 100644 index 3f3a1a3..0000000 --- a/chrome/browser/views/confirm_message_box_dialog.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2009 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/confirm_message_box_dialog.h" - -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -// static -void ConfirmMessageBoxDialog::Run(gfx::NativeWindow parent, - ConfirmMessageBoxObserver* observer, - const std::wstring& message_text, - const std::wstring& window_title) { - DCHECK(observer); - ConfirmMessageBoxDialog* dialog = new ConfirmMessageBoxDialog(observer, - message_text, window_title); - views::Window* window = views::Window::CreateChromeWindow( - parent, gfx::Rect(), dialog); - window->Show(); -} - -// static -void ConfirmMessageBoxDialog::RunWithCustomConfiguration( - gfx::NativeWindow parent, - ConfirmMessageBoxObserver* observer, - const std::wstring& message_text, - const std::wstring& window_title, - const std::wstring& confirm_label, - const std::wstring& reject_label, - const gfx::Size& preferred_size) { - DCHECK(observer); - ConfirmMessageBoxDialog* dialog = new ConfirmMessageBoxDialog(observer, - message_text, window_title); - dialog->preferred_size_ = preferred_size; - dialog->confirm_label_ = confirm_label; - dialog->reject_label_ = reject_label; - views::Window* window = views::Window::CreateChromeWindow( - parent, gfx::Rect(), dialog); - window->Show(); -} - -ConfirmMessageBoxDialog::ConfirmMessageBoxDialog( - ConfirmMessageBoxObserver* observer, const std::wstring& message_text, - const std::wstring& window_title) - : observer_(observer), - window_title_(window_title), - preferred_size_(gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_CONFIRM_MESSAGE_BOX_DEFAULT_WIDTH_CHARS, - IDS_CONFIRM_MESSAGE_BOX_DEFAULT_HEIGHT_LINES))), - confirm_label_(l10n_util::GetString( - IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL)), - reject_label_(l10n_util::GetString( - IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL)) { - message_label_ = new views::Label(message_text); - message_label_->SetMultiLine(true); - message_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(message_label_); -} - -int ConfirmMessageBoxDialog::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_OK | - MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring ConfirmMessageBoxDialog::GetWindowTitle() const { - return window_title_; -} - -std::wstring ConfirmMessageBoxDialog::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return confirm_label_; - } - if (button == MessageBoxFlags::DIALOGBUTTON_CANCEL) - return reject_label_; - return DialogDelegate::GetDialogButtonLabel(button); -} - -bool ConfirmMessageBoxDialog::Accept() { - observer_->OnConfirmMessageAccept(); - return true; // Dialog may now be closed. -} - -bool ConfirmMessageBoxDialog::Cancel() { - observer_->OnConfirmMessageCancel(); - return true; // Dialog may now be closed. -} - -void ConfirmMessageBoxDialog::Layout() { - gfx::Size sz = message_label_->GetPreferredSize(); - message_label_->SetBounds(kPanelHorizMargin, kPanelVertMargin, - width() - 2 * kPanelHorizMargin, - sz.height()); -} - -gfx::Size ConfirmMessageBoxDialog::GetPreferredSize() { - return preferred_size_; -} diff --git a/chrome/browser/views/confirm_message_box_dialog.h b/chrome/browser/views/confirm_message_box_dialog.h index c0c5da7..26ca059 100644 --- a/chrome/browser/views/confirm_message_box_dialog.h +++ b/chrome/browser/views/confirm_message_box_dialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,95 +6,8 @@ #define CHROME_BROWSER_VIEWS_CONFIRM_MESSAGE_BOX_DIALOG_H_ #pragma once -#include <string> - -#include "base/basictypes.h" -#include "gfx/native_widget_types.h" -#include "views/controls/label.h" -#include "views/window/dialog_delegate.h" - -// An interface the confirm dialog uses to notify its clients (observers) when -// the user makes a decision to confirm or cancel. Only one method will be -// invoked per use (i.e per invocation of ConfirmMessageBoxDialog::Run). -class ConfirmMessageBoxObserver { - public: - // The user explicitly confirmed by clicking "OK". - virtual void OnConfirmMessageAccept() = 0; - // The user chose not to confirm either by clicking "Cancel" or by closing - // the dialog. - virtual void OnConfirmMessageCancel() {} -}; - -class ConfirmMessageBoxDialog : public views::DialogDelegate, - public views::View { - public: - // The method presents a modal confirmation dialog to the user with the title - // |window_title| and message |message_text|, and 'Yes' 'No' buttons. - // |observer| will be notified when the user makes a decision or closes the - // dialog. Note that this class guarantees it will call one of the observer's - // methods, so it is the caller's responsibility to ensure |observer| lives - // until one of the methods is invoked; it can be deleted thereafter from this - // class' point of view. |parent| specifies where to insert the view into the - // hierarchy and effectively assumes ownership of the dialog. - static void Run(gfx::NativeWindow parent, - ConfirmMessageBoxObserver* observer, - const std::wstring& message_text, - const std::wstring& window_title); - - // A variant of the above for when the message text is longer/shorter than - // what the default size of this dialog can accommodate. - static void RunWithCustomConfiguration(gfx::NativeWindow parent, - ConfirmMessageBoxObserver* observer, - const std::wstring& message_text, - const std::wstring& window_title, - const std::wstring& confirm_label, - const std::wstring& reject_label, - const gfx::Size& preferred_size); - - virtual ~ConfirmMessageBoxDialog() {} - - // views::DialogDelegate implementation. - virtual int GetDialogButtons() const; - virtual std::wstring GetWindowTitle() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual int GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - - virtual bool Accept(); - virtual bool Cancel(); - - // views::WindowDelegate implementation. - virtual bool IsModal() const { return true; } - virtual views::View* GetContentsView() { return this; } - - // views::View implementation. - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - private: - ConfirmMessageBoxDialog(ConfirmMessageBoxObserver* observer, - const std::wstring& message_text, - const std::wstring& window_title); - - // The message which will be shown to user. - views::Label* message_label_; - - // This is the Title bar text. - std::wstring window_title_; - - // The text for the 'OK' and 'CANCEL' buttons. - std::wstring confirm_label_; - std::wstring reject_label_; - - // The preferred size of the dialog. - gfx::Size preferred_size_; - - // The observer to notify of acceptance or cancellation. - ConfirmMessageBoxObserver* observer_; - - DISALLOW_COPY_AND_ASSIGN(ConfirmMessageBoxDialog); -}; +#include "chrome/browser/ui/views/confirm_message_box_dialog.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CONFIRM_MESSAGE_BOX_DIALOG_H_ + diff --git a/chrome/browser/views/constrained_html_delegate_win.cc b/chrome/browser/views/constrained_html_delegate_win.cc deleted file mode 100644 index 6d53e22..0000000 --- a/chrome/browser/views/constrained_html_delegate_win.cc +++ /dev/null @@ -1,113 +0,0 @@ -// 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/dom_ui/constrained_html_ui.h" - -#include "chrome/browser/dom_ui/html_dialog_tab_contents_delegate.h" -#include "chrome/browser/dom_ui/html_dialog_ui.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/tab_contents/tab_contents_container.h" -#include "gfx/rect.h" -#include "ipc/ipc_message.h" -#include "views/view.h" -#include "views/widget/widget_win.h" -#include "views/window/window_delegate.h" - -class ConstrainedHtmlDelegateWin : public TabContentsContainer, - public ConstrainedHtmlUIDelegate, - public ConstrainedWindowDelegate, - public HtmlDialogTabContentsDelegate { - public: - ConstrainedHtmlDelegateWin(Profile* profile, - HtmlDialogUIDelegate* delegate); - ~ConstrainedHtmlDelegateWin(); - - // ConstrainedHtmlUIDelegate interface. - virtual HtmlDialogUIDelegate* GetHtmlDialogUIDelegate(); - virtual void OnDialogClose(); - - // ConstrainedWindowDelegate (aka views::WindowDelegate) interface. - virtual bool CanResize() const { return true; } - virtual views::View* GetContentsView() { - return this; - } - virtual void WindowClosing() { - html_delegate_->OnDialogClosed(""); - } - - // HtmlDialogTabContentsDelegate interface. - void MoveContents(TabContents* source, const gfx::Rect& pos) {} - void ToolbarSizeChanged(TabContents* source, bool is_animating) {} - void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {} - - // Overridden from TabContentsContainer. - virtual gfx::Size GetPreferredSize() { - gfx::Size size; - html_delegate_->GetDialogSize(&size); - return size; - } - - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - TabContentsContainer::ViewHierarchyChanged(is_add, parent, child); - if (is_add && child == this) { - ChangeTabContents(&html_tab_contents_); - } - } - - void set_window(ConstrainedWindow* window) { - window_ = window; - } - -private: - TabContents html_tab_contents_; - - HtmlDialogUIDelegate* html_delegate_; - - // The constrained window that owns |this|. Saved so we can close it later. - ConstrainedWindow* window_; -}; - -ConstrainedHtmlDelegateWin::ConstrainedHtmlDelegateWin( - Profile* profile, - HtmlDialogUIDelegate* delegate) - : HtmlDialogTabContentsDelegate(profile), - html_tab_contents_(profile, NULL, MSG_ROUTING_NONE, NULL, NULL), - html_delegate_(delegate), - window_(NULL) { - CHECK(delegate); - html_tab_contents_.set_delegate(this); - - // Set |this| as a property so the ConstrainedHtmlUI can retrieve it. - ConstrainedHtmlUI::GetPropertyAccessor().SetProperty( - html_tab_contents_.property_bag(), this); - html_tab_contents_.controller().LoadURL(delegate->GetDialogContentURL(), - GURL(), - PageTransition::START_PAGE); -} - -ConstrainedHtmlDelegateWin::~ConstrainedHtmlDelegateWin() { -} - -HtmlDialogUIDelegate* ConstrainedHtmlDelegateWin::GetHtmlDialogUIDelegate() { - return html_delegate_; -} - -void ConstrainedHtmlDelegateWin::OnDialogClose() { - window_->CloseConstrainedWindow(); -} - -// static -void ConstrainedHtmlUI::CreateConstrainedHtmlDialog( - Profile* profile, - HtmlDialogUIDelegate* delegate, - TabContents* container) { - ConstrainedHtmlDelegateWin* constrained_delegate = - new ConstrainedHtmlDelegateWin(profile, delegate); - ConstrainedWindow* constrained_window = - container->CreateConstrainedDialog(constrained_delegate); - constrained_delegate->set_window(constrained_window); -} diff --git a/chrome/browser/views/constrained_window_win.cc b/chrome/browser/views/constrained_window_win.cc deleted file mode 100644 index 7fa1dc6..0000000 --- a/chrome/browser/views/constrained_window_win.cc +++ /dev/null @@ -1,673 +0,0 @@ -// 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/constrained_window_win.h" - -#include "app/resource_bundle.h" -#include "app/win_util.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "chrome/browser/toolbar_model.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/window_sizer.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas.h" -#include "gfx/font.h" -#include "gfx/path.h" -#include "gfx/rect.h" -#include "grit/app_resources.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "net/base/net_util.h" -#include "views/controls/button/image_button.h" -#include "views/focus/focus_manager.h" -#include "views/window/client_view.h" -#include "views/window/non_client_view.h" -#include "views/window/window_resources.h" -#include "views/window/window_shape.h" - -using base::TimeDelta; - -namespace views { -class ClientView; -} - -// An enumeration of bitmap resources used by this window. -enum { - FRAME_PART_BITMAP_FIRST = 0, // Must be first. - - // Window Frame Border. - FRAME_BOTTOM_EDGE, - FRAME_BOTTOM_LEFT_CORNER, - FRAME_BOTTOM_RIGHT_CORNER, - FRAME_LEFT_EDGE, - FRAME_RIGHT_EDGE, - FRAME_TOP_EDGE, - FRAME_TOP_LEFT_CORNER, - FRAME_TOP_RIGHT_CORNER, - - FRAME_PART_BITMAP_COUNT // Must be last. -}; - -static const int kXPFramePartIDs[] = { - 0, - IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER, - IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE, - IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER, - IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER, - 0 }; -static const int kVistaFramePartIDs[] = { - 0, - IDR_CONSTRAINED_BOTTOM_CENTER_V, IDR_CONSTRAINED_BOTTOM_LEFT_CORNER_V, - IDR_CONSTRAINED_BOTTOM_RIGHT_CORNER_V, IDR_CONSTRAINED_LEFT_SIDE_V, - IDR_CONSTRAINED_RIGHT_SIDE_V, IDR_CONSTRAINED_TOP_CENTER_V, - IDR_CONSTRAINED_TOP_LEFT_CORNER_V, IDR_CONSTRAINED_TOP_RIGHT_CORNER_V, - 0 }; - -class XPWindowResources : public views::WindowResources { - public: - XPWindowResources() { - InitClass(); - } - virtual ~XPWindowResources() {} - - virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part_id) const { - return bitmaps_[part_id]; - } - - private: - static void InitClass() { - static bool initialized = false; - if (!initialized) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) { - int id = kXPFramePartIDs[i]; - if (id != 0) - bitmaps_[i] = rb.GetBitmapNamed(id); - } - initialized = true; - } - } - - static SkBitmap* bitmaps_[FRAME_PART_BITMAP_COUNT]; - - DISALLOW_COPY_AND_ASSIGN(XPWindowResources); -}; - -class VistaWindowResources : public views::WindowResources { - public: - VistaWindowResources() { - InitClass(); - } - virtual ~VistaWindowResources() {} - - virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part_id) const { - return bitmaps_[part_id]; - } - - private: - static void InitClass() { - static bool initialized = false; - if (!initialized) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) { - int id = kVistaFramePartIDs[i]; - if (id != 0) - bitmaps_[i] = rb.GetBitmapNamed(id); - } - initialized = true; - } - } - - static SkBitmap* bitmaps_[FRAME_PART_BITMAP_COUNT]; - - DISALLOW_COPY_AND_ASSIGN(VistaWindowResources); -}; - -SkBitmap* XPWindowResources::bitmaps_[]; -SkBitmap* VistaWindowResources::bitmaps_[]; - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowFrameView - -class ConstrainedWindowFrameView - : public views::NonClientFrameView, - public views::ButtonListener { - public: - explicit ConstrainedWindowFrameView(ConstrainedWindowWin* container); - virtual ~ConstrainedWindowFrameView(); - - void UpdateWindowTitle(); - - // Overridden from views::NonClientFrameView: - virtual gfx::Rect GetBoundsForClientView() const; - virtual bool AlwaysUseCustomFrame() const; - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); - virtual void EnableClose(bool enable); - virtual void ResetWindowControls() { } - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual void OnThemeChanged(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - private: - // Returns the thickness of the entire nonclient left, right, and bottom - // borders, including both the window frame and any client edge. - int NonClientBorderThickness() const; - - // Returns the height of the entire nonclient top border, including the window - // frame, any title area, and any connected client edge. - int NonClientTopBorderHeight() const; - - // Returns the thickness of the nonclient portion of the 3D edge along the - // bottom of the titlebar. - int TitlebarBottomThickness() const; - - // Returns what the size of the titlebar icon would be if there was one. - int IconSize() const; - - // Returns what the titlebar icon's bounds would be if there was one. - gfx::Rect IconBounds() const; - - // Paints different parts of the window to the incoming canvas. - void PaintFrameBorder(gfx::Canvas* canvas); - void PaintTitleBar(gfx::Canvas* canvas); - void PaintClientEdge(gfx::Canvas* canvas); - - // Layout various sub-components of this view. - void LayoutWindowControls(); - void LayoutTitleBar(); - - // Returns the bounds of the client area for the specified view size. - gfx::Rect CalculateClientAreaBounds(int width, int height) const; - - SkColor GetTitleColor() const { - return (container_->owner()->profile()->IsOffTheRecord() || - !win_util::ShouldUseVistaFrame()) ? SK_ColorWHITE : SK_ColorBLACK; - } - - // Loads the appropriate set of WindowResources for the frame view. - void InitWindowResources(); - - ConstrainedWindowWin* container_; - - scoped_ptr<views::WindowResources> resources_; - - gfx::Rect title_bounds_; - - views::ImageButton* close_button_; - - // The bounds of the ClientView. - gfx::Rect client_view_bounds_; - - static void InitClass(); - - // The font to be used to render the titlebar text. - static gfx::Font* title_font_; - - DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowFrameView); -}; - -gfx::Font* ConstrainedWindowFrameView::title_font_ = NULL; - -namespace { -// The frame border is only visible in restored mode and is hardcoded to 4 px on -// each side regardless of the system window border size. -const int kFrameBorderThickness = 4; -// Various edges of the frame border have a 1 px shadow along their edges; in a -// few cases we shift elements based on this amount for visual appeal. -const int kFrameShadowThickness = 1; -// In the window corners, the resize areas don't actually expand bigger, but the -// 16 px at the end of each edge triggers diagonal resizing. -const int kResizeAreaCornerSize = 16; -// The titlebar never shrinks too short to show the caption button plus some -// padding below it. -const int kCaptionButtonHeightWithPadding = 19; -// The titlebar has a 2 px 3D edge along the top and bottom. -const int kTitlebarTopAndBottomEdgeThickness = 2; -// The icon would never shrink below 16 px on a side, if there was one. -const int kIconMinimumSize = 16; -// The title text starts 2 px from the right edge of the left frame border. -const int kTitleLeftSpacing = 2; -// There is a 5 px gap between the title text and the caption buttons. -const int kTitleCaptionSpacing = 5; - -const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowFrameView, public: - -ConstrainedWindowFrameView::ConstrainedWindowFrameView( - ConstrainedWindowWin* container) - : NonClientFrameView(), - container_(container), - close_button_(new views::ImageButton(this)) { - InitClass(); - InitWindowResources(); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_CLOSE_SA)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_CLOSE_SA_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_CLOSE_SA_P)); - close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, - views::ImageButton::ALIGN_MIDDLE); - AddChildView(close_button_); -} - -ConstrainedWindowFrameView::~ConstrainedWindowFrameView() { -} - -void ConstrainedWindowFrameView::UpdateWindowTitle() { - SchedulePaint(title_bounds_, false); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowFrameView, views::NonClientFrameView implementation: - -gfx::Rect ConstrainedWindowFrameView::GetBoundsForClientView() const { - return client_view_bounds_; -} - -bool ConstrainedWindowFrameView::AlwaysUseCustomFrame() const { - // Constrained windows always use the custom frame - they just have a - // different set of bitmaps. - return true; -} - -gfx::Rect ConstrainedWindowFrameView::GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const { - int top_height = NonClientTopBorderHeight(); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), - std::max(0, client_bounds.y() - top_height), - client_bounds.width() + (2 * border_thickness), - client_bounds.height() + top_height + border_thickness); -} - -int ConstrainedWindowFrameView::NonClientHitTest(const gfx::Point& point) { - if (!bounds().Contains(point)) - return HTNOWHERE; - - int frame_component = container_->GetClientView()->NonClientHitTest(point); - - // See if we're in the sysmenu region. (We check the ClientView first to be - // consistent with OpaqueBrowserFrameView; it's not really necessary here.) - gfx::Rect sysmenu_rect(IconBounds()); - sysmenu_rect.set_x(MirroredLeftPointForRect(sysmenu_rect)); - if (sysmenu_rect.Contains(point)) - return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; - - if (frame_component != HTNOWHERE) - return frame_component; - - // Then see if the point is within any of the window controls. - if (close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) - return HTCLOSE; - - int window_component = GetHTComponentForFrame(point, kFrameBorderThickness, - NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, - container_->GetDelegate()->CanResize()); - // Fall back to the caption if no other component matches. - return (window_component == HTNOWHERE) ? HTCAPTION : window_component; -} - -void ConstrainedWindowFrameView::GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) { - DCHECK(window_mask); - views::GetDefaultWindowMask(size, window_mask); -} - -void ConstrainedWindowFrameView::EnableClose(bool enable) { - close_button_->SetEnabled(enable); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowFrameView, views::View implementation: - -void ConstrainedWindowFrameView::Paint(gfx::Canvas* canvas) { - PaintFrameBorder(canvas); - PaintTitleBar(canvas); - PaintClientEdge(canvas); -} - -void ConstrainedWindowFrameView::Layout() { - LayoutWindowControls(); - LayoutTitleBar(); - client_view_bounds_ = CalculateClientAreaBounds(width(), height()); -} - -void ConstrainedWindowFrameView::OnThemeChanged() { - InitWindowResources(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowFrameView, views::ButtonListener implementation: - -void ConstrainedWindowFrameView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == close_button_) - container_->ExecuteSystemMenuCommand(SC_CLOSE); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowFrameView, private: - -int ConstrainedWindowFrameView::NonClientBorderThickness() const { - return kFrameBorderThickness + kClientEdgeThickness; -} - -int ConstrainedWindowFrameView::NonClientTopBorderHeight() const { - return std::max(kFrameBorderThickness + IconSize(), - kFrameShadowThickness + kCaptionButtonHeightWithPadding) + - TitlebarBottomThickness(); -} - -int ConstrainedWindowFrameView::TitlebarBottomThickness() const { - return kTitlebarTopAndBottomEdgeThickness + kClientEdgeThickness; -} - -int ConstrainedWindowFrameView::IconSize() const { -#if defined(OS_WIN) - // This metric scales up if either the titlebar height or the titlebar font - // size are increased. - return GetSystemMetrics(SM_CYSMICON); -#else - return std::max(title_font_->height(), kIconMinimumSize); -#endif -} - -gfx::Rect ConstrainedWindowFrameView::IconBounds() const { - int size = IconSize(); - // Our frame border has a different "3D look" than Windows'. Theirs has a - // more complex gradient on the top that they push their icon/title below; - // then the maximized window cuts this off and the icon/title are centered - // in the remaining space. Because the apparent shape of our border is - // simpler, using the same positioning makes things look slightly uncentered - // with restored windows, so instead of calculating the remaining space from - // below the frame border, we calculate from below the 3D edge. - int unavailable_px_at_top = kTitlebarTopAndBottomEdgeThickness; - // When the icon is shorter than the minimum space we reserve for the caption - // button, we vertically center it. We want to bias rounding to put extra - // space above the icon, since the 3D edge + client edge below looks (to the - // eye) more like additional space than does the 3D edge above; hence the +1. - int y = unavailable_px_at_top + (NonClientTopBorderHeight() - - unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2; - return gfx::Rect(kFrameBorderThickness + kTitleLeftSpacing, y, size, size); -} - -void ConstrainedWindowFrameView::PaintFrameBorder(gfx::Canvas* canvas) { - SkBitmap* top_left_corner = resources_->GetPartBitmap(FRAME_TOP_LEFT_CORNER); - SkBitmap* top_right_corner = - resources_->GetPartBitmap(FRAME_TOP_RIGHT_CORNER); - SkBitmap* top_edge = resources_->GetPartBitmap(FRAME_TOP_EDGE); - SkBitmap* right_edge = resources_->GetPartBitmap(FRAME_RIGHT_EDGE); - SkBitmap* left_edge = resources_->GetPartBitmap(FRAME_LEFT_EDGE); - SkBitmap* bottom_left_corner = - resources_->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER); - SkBitmap* bottom_right_corner = - resources_->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER); - SkBitmap* bottom_edge = resources_->GetPartBitmap(FRAME_BOTTOM_EDGE); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - SkBitmap* theme_frame = rb.GetBitmapNamed(IDR_THEME_FRAME); - SkColor frame_color = ResourceBundle::frame_color; - - // Fill with the frame color first so we have a constant background for - // areas not covered by the theme image. - canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height()); - // Now fill down the sides. - canvas->FillRectInt(frame_color, 0, theme_frame->height(), left_edge->width(), - height() - theme_frame->height()); - canvas->FillRectInt(frame_color, width() - right_edge->width(), - theme_frame->height(), right_edge->width(), - height() - theme_frame->height()); - // Now fill the bottom area. - canvas->FillRectInt(frame_color, - left_edge->width(), height() - bottom_edge->height(), - width() - left_edge->width() - right_edge->width(), - bottom_edge->height()); - - // Draw the theme frame. - canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height()); - - // Top. - canvas->DrawBitmapInt(*top_left_corner, 0, 0); - canvas->TileImageInt(*top_edge, top_left_corner->width(), 0, - width() - top_right_corner->width(), top_edge->height()); - canvas->DrawBitmapInt(*top_right_corner, - width() - top_right_corner->width(), 0); - - // Right. - canvas->TileImageInt(*right_edge, width() - right_edge->width(), - top_right_corner->height(), right_edge->width(), - height() - top_right_corner->height() - bottom_right_corner->height()); - - // Bottom. - canvas->DrawBitmapInt(*bottom_right_corner, - width() - bottom_right_corner->width(), - height() - bottom_right_corner->height()); - canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(), - height() - bottom_edge->height(), - width() - bottom_left_corner->width() - bottom_right_corner->width(), - bottom_edge->height()); - canvas->DrawBitmapInt(*bottom_left_corner, 0, - height() - bottom_left_corner->height()); - - // Left. - canvas->TileImageInt(*left_edge, 0, top_left_corner->height(), - left_edge->width(), - height() - top_left_corner->height() - bottom_left_corner->height()); -} - -void ConstrainedWindowFrameView::PaintTitleBar(gfx::Canvas* canvas) { - canvas->DrawStringInt(container_->GetWindowTitle(), *title_font_, - GetTitleColor(), MirroredLeftPointForRect(title_bounds_), - title_bounds_.y(), title_bounds_.width(), title_bounds_.height()); -} - -void ConstrainedWindowFrameView::PaintClientEdge(gfx::Canvas* canvas) { - gfx::Rect client_edge_bounds(CalculateClientAreaBounds(width(), height())); - client_edge_bounds.Inset(-kClientEdgeThickness, -kClientEdgeThickness); - gfx::Rect frame_shadow_bounds(client_edge_bounds); - frame_shadow_bounds.Inset(-kFrameShadowThickness, -kFrameShadowThickness); - - canvas->FillRectInt(kContentsBorderShadow, frame_shadow_bounds.x(), - frame_shadow_bounds.y(), frame_shadow_bounds.width(), - frame_shadow_bounds.height()); - - canvas->FillRectInt(ResourceBundle::toolbar_color, client_edge_bounds.x(), - client_edge_bounds.y(), client_edge_bounds.width(), - client_edge_bounds.height()); -} - -void ConstrainedWindowFrameView::LayoutWindowControls() { - gfx::Size close_button_size = close_button_->GetPreferredSize(); - close_button_->SetBounds( - width() - kFrameBorderThickness - close_button_size.width(), - kFrameShadowThickness, close_button_size.width(), - close_button_size.height()); -} - -void ConstrainedWindowFrameView::LayoutTitleBar() { - // The window title is based on the calculated icon position, even though' - // there is no icon in constrained windows. - gfx::Rect icon_bounds(IconBounds()); - int title_x = icon_bounds.x(); - int title_height = title_font_->GetHeight(); - // We bias the title position so that when the difference between the icon and - // title heights is odd, the extra pixel of the title is above the vertical - // midline rather than below. This compensates for how the icon is already - // biased downwards (see IconBounds()) and helps prevent descenders on the - // title from overlapping the 3D edge at the bottom of the titlebar. - title_bounds_.SetRect(title_x, - icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), - std::max(0, close_button_->x() - kTitleCaptionSpacing - title_x), - title_height); -} - -gfx::Rect ConstrainedWindowFrameView::CalculateClientAreaBounds( - int width, - int height) const { - int top_height = NonClientTopBorderHeight(); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(border_thickness, top_height, - std::max(0, width - (2 * border_thickness)), - std::max(0, height - top_height - border_thickness)); -} - -void ConstrainedWindowFrameView::InitWindowResources() { - resources_.reset(win_util::ShouldUseVistaFrame() ? - static_cast<views::WindowResources*>(new VistaWindowResources) : - new XPWindowResources); -} - -// static -void ConstrainedWindowFrameView::InitClass() { - static bool initialized = false; - if (!initialized) { - title_font_ = new gfx::Font(win_util::GetWindowTitleFont()); - initialized = true; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowWin, public: - -ConstrainedWindowWin::~ConstrainedWindowWin() { -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowWin, ConstrainedWindow implementation: - -views::NonClientFrameView* ConstrainedWindowWin::CreateFrameViewForWindow() { - return new ConstrainedWindowFrameView(this); -} - -void ConstrainedWindowWin::FocusConstrainedWindow() { - if ((!owner_->delegate() || - owner_->delegate()->ShouldFocusConstrainedWindow()) && - GetDelegate() && GetDelegate()->GetInitiallyFocusedView()) { - GetDelegate()->GetInitiallyFocusedView()->RequestFocus(); - } -} - -void ConstrainedWindowWin::ShowConstrainedWindow() { - if (owner_->delegate()) - owner_->delegate()->WillShowConstrainedWindow(owner_); - ActivateConstrainedWindow(); - FocusConstrainedWindow(); -} - -void ConstrainedWindowWin::CloseConstrainedWindow() { - // Broadcast to all observers of NOTIFY_CWINDOW_CLOSED. - // One example of such an observer is AutomationCWindowTracker in the - // automation component. - NotificationService::current()->Notify(NotificationType::CWINDOW_CLOSED, - Source<ConstrainedWindow>(this), - NotificationService::NoDetails()); - - Close(); -} - -std::wstring ConstrainedWindowWin::GetWindowTitle() const { - if (GetDelegate()) - return GetDelegate()->GetWindowTitle(); - - // TODO(pkasting): Shouldn't this be using a localized string, or else calling - // NOTREACHED()? - return std::wstring(L"Untitled"); -} - -const gfx::Rect& ConstrainedWindowWin::GetCurrentBounds() const { - return current_bounds_; -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowWin, private: - -ConstrainedWindowWin::ConstrainedWindowWin( - TabContents* owner, - views::WindowDelegate* window_delegate) - : WindowWin(window_delegate), - owner_(owner) { - GetNonClientView()->SetFrameView(CreateFrameViewForWindow()); - - set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | - WS_THICKFRAME | WS_SYSMENU); - set_focus_on_creation(false); - - WindowWin::Init(owner_->GetNativeView(), gfx::Rect()); -} - -void ConstrainedWindowWin::ActivateConstrainedWindow() { - // Other pop-ups are simply moved to the front of the z-order. - SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); -} - -//////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowWin, views::WidgetWin overrides: - -void ConstrainedWindowWin::OnDestroy() { - // TODO(jcampan): figure out focus restoration - - // Make sure we call super so that it can do its cleanup. - WindowWin::OnDestroy(); -} - -void ConstrainedWindowWin::OnFinalMessage(HWND window) { - // Tell our constraining TabContents that we've gone so it can update its - // list. - owner_->WillClose(this); - - WindowWin::OnFinalMessage(window); -} - -LRESULT ConstrainedWindowWin::OnMouseActivate(HWND window, - UINT hittest_code, - UINT message) { - // We only detach the window if the user clicked on the title bar. That - // way, users can click inside the contents of legitimate popups obtained - // with a mouse gesture. - if (hittest_code != HTCLIENT && hittest_code != HTNOWHERE && - hittest_code != HTCLOSE) { - ActivateConstrainedWindow(); - } - - return MA_ACTIVATE; -} - -void ConstrainedWindowWin::OnWindowPosChanged(WINDOWPOS* window_pos) { - // If the window was moved or sized, tell the owner. - if (!(window_pos->flags & SWP_NOMOVE) || !(window_pos->flags & SWP_NOSIZE)) - owner_->DidMoveOrResize(this); - SetMsgHandled(FALSE); -} - - -// static -ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog( - TabContents* parent, - views::WindowDelegate* window_delegate) { - ConstrainedWindowWin* window = new ConstrainedWindowWin(parent, - window_delegate); - return window; -} diff --git a/chrome/browser/views/constrained_window_win.h b/chrome/browser/views/constrained_window_win.h index 9b17bf6..61ed885 100644 --- a/chrome/browser/views/constrained_window_win.h +++ b/chrome/browser/views/constrained_window_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,72 +6,8 @@ #define CHROME_BROWSER_VIEWS_CONSTRAINED_WINDOW_WIN_H_ #pragma once -#include "chrome/browser/tab_contents/constrained_window.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "gfx/rect.h" -#include "views/window/window_win.h" - -class ConstrainedTabContentsWindowDelegate; -class ConstrainedWindowAnimation; -class ConstrainedWindowFrameView; -namespace views { -class WindowDelegate; -} - -/////////////////////////////////////////////////////////////////////////////// -// ConstrainedWindowWin -// -// A ConstrainedWindow implementation that implements a Constrained Window as -// a child HWND with a custom window frame. -// -class ConstrainedWindowWin : public ConstrainedWindow, - public views::WindowWin { - public: - virtual ~ConstrainedWindowWin(); - - // Returns the TabContents that constrains this Constrained Window. - TabContents* owner() const { return owner_; } - - // Overridden from views::Window: - virtual views::NonClientFrameView* CreateFrameViewForWindow(); - - // Overridden from ConstrainedWindow: - virtual void ShowConstrainedWindow(); - virtual void CloseConstrainedWindow(); - virtual void FocusConstrainedWindow(); - virtual std::wstring GetWindowTitle() const; - virtual const gfx::Rect& GetCurrentBounds() const; - - protected: - // Windows message handlers: - virtual void OnDestroy(); - virtual void OnFinalMessage(HWND window); - virtual LRESULT OnMouseActivate(HWND window, UINT hittest_code, UINT message); - virtual void OnWindowPosChanged(WINDOWPOS* window_pos); - - private: - friend class ConstrainedWindow; - - // Use the static factory methods on ConstrainedWindow to construct a - // ConstrainedWindow. - ConstrainedWindowWin(TabContents* owner, - views::WindowDelegate* window_delegate); - - // Moves this window to the front of the Z-order and registers us with the - // focus manager. - void ActivateConstrainedWindow(); - - // The TabContents that owns and constrains this ConstrainedWindow. - TabContents* owner_; - - // Current "anchor point", the lower right point at which we render - // the constrained title bar. - gfx::Point anchor_point_; - - // Current display rectangle (relative to owner_'s visible area). - gfx::Rect current_bounds_; - - DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowWin); -}; +#include "chrome/browser/ui/views/constrained_window_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CONSTRAINED_WINDOW_WIN_H_ + diff --git a/chrome/browser/views/content_setting_bubble_contents.cc b/chrome/browser/views/content_setting_bubble_contents.cc deleted file mode 100644 index cea404d..0000000 --- a/chrome/browser/views/content_setting_bubble_contents.cc +++ /dev/null @@ -1,379 +0,0 @@ -// 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/content_setting_bubble_contents.h" - -#if defined(OS_LINUX) -#include <gdk/gdk.h> -#endif - -#include "app/l10n_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/blocked_content_container.h" -#include "chrome/browser/content_setting_bubble_model.h" -#include "chrome/browser/host_content_settings_map.h" -#include "chrome/browser/plugin_updater.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "chrome/browser/views/info_bubble.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" -#include "grit/generated_resources.h" -#include "views/controls/button/native_button.h" -#include "views/controls/button/radio_button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "webkit/glue/plugins/plugin_list.h" - -// If we don't clamp the maximum width, then very long URLs and titles can make -// the bubble arbitrarily wide. -const int kMaxContentsWidth = 500; - -// When we have multiline labels, we should set a minimum width lest we get very -// narrow bubbles with lots of line-wrapping. -const int kMinMultiLineContentsWidth = 250; - -class ContentSettingBubbleContents::Favicon : public views::ImageView { - public: - Favicon(const SkBitmap& image, - ContentSettingBubbleContents* parent, - views::Link* link); - virtual ~Favicon(); - - private: -#if defined(OS_WIN) - static HCURSOR g_hand_cursor; -#endif - - // views::View overrides: - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - virtual gfx::NativeCursor GetCursorForPoint( - views::Event::EventType event_type, - const gfx::Point& p); - - ContentSettingBubbleContents* parent_; - views::Link* link_; -}; - -#if defined(OS_WIN) -HCURSOR ContentSettingBubbleContents::Favicon::g_hand_cursor = NULL; -#endif - -ContentSettingBubbleContents::Favicon::Favicon( - const SkBitmap& image, - ContentSettingBubbleContents* parent, - views::Link* link) - : parent_(parent), - link_(link) { - SetImage(image); -} - -ContentSettingBubbleContents::Favicon::~Favicon() { -} - -bool ContentSettingBubbleContents::Favicon::OnMousePressed( - const views::MouseEvent& event) { - return event.IsLeftMouseButton() || event.IsMiddleMouseButton(); -} - -void ContentSettingBubbleContents::Favicon::OnMouseReleased( - const views::MouseEvent& event, - bool canceled) { - if (!canceled && - (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) && - HitTest(event.location())) - parent_->LinkActivated(link_, event.GetFlags()); -} - -gfx::NativeCursor ContentSettingBubbleContents::Favicon::GetCursorForPoint( - views::Event::EventType event_type, - const gfx::Point& p) { -#if defined(OS_WIN) - if (!g_hand_cursor) - g_hand_cursor = LoadCursor(NULL, IDC_HAND); - return g_hand_cursor; -#elif defined(OS_LINUX) - return gdk_cursor_new(GDK_HAND2); -#endif -} - -ContentSettingBubbleContents::ContentSettingBubbleContents( - ContentSettingBubbleModel* content_setting_bubble_model, - Profile* profile, - TabContents* tab_contents) - : content_setting_bubble_model_(content_setting_bubble_model), - profile_(profile), - tab_contents_(tab_contents), - info_bubble_(NULL), - close_button_(NULL), - manage_link_(NULL), - clear_link_(NULL), - info_link_(NULL), - load_plugins_link_(NULL) { - registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, - Source<TabContents>(tab_contents)); -} - -ContentSettingBubbleContents::~ContentSettingBubbleContents() { -} - -gfx::Size ContentSettingBubbleContents::GetPreferredSize() { - gfx::Size preferred_size(views::View::GetPreferredSize()); - int preferred_width = - (!content_setting_bubble_model_->bubble_content().domain_lists.empty() && - (kMinMultiLineContentsWidth > preferred_size.width())) ? - kMinMultiLineContentsWidth : preferred_size.width(); - preferred_size.set_width(std::min(preferred_width, kMaxContentsWidth)); - return preferred_size; -} - -void ContentSettingBubbleContents::ViewHierarchyChanged(bool is_add, - View* parent, - View* child) { - if (is_add && (child == this)) - InitControlLayout(); -} - -void ContentSettingBubbleContents::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == close_button_) { - info_bubble_->set_fade_away_on_close(true); - info_bubble_->Close(); // CAREFUL: This deletes us. - return; - } - - for (RadioGroup::const_iterator i = radio_group_.begin(); - i != radio_group_.end(); ++i) { - if (sender == *i) { - content_setting_bubble_model_->OnRadioClicked(i - radio_group_.begin()); - return; - } - } - NOTREACHED() << "unknown radio"; -} - -void ContentSettingBubbleContents::LinkActivated(views::Link* source, - int event_flags) { - if (source == manage_link_) { - info_bubble_->set_fade_away_on_close(true); - content_setting_bubble_model_->OnManageLinkClicked(); - // CAREFUL: Showing the settings window activates it, which deactivates the - // info bubble, which causes it to close, which deletes us. - return; - } - if (source == clear_link_) { - content_setting_bubble_model_->OnClearLinkClicked(); - info_bubble_->set_fade_away_on_close(true); - info_bubble_->Close(); // CAREFUL: This deletes us. - return; - } - if (source == info_link_) { - content_setting_bubble_model_->OnInfoLinkClicked(); - info_bubble_->set_fade_away_on_close(true); - info_bubble_->Close(); // CAREFUL: This deletes us. - return; - } - if (source == load_plugins_link_) { - content_setting_bubble_model_->OnLoadPluginsLinkClicked(); - info_bubble_->set_fade_away_on_close(true); - info_bubble_->Close(); // CAREFUL: This deletes us. - return; - } - - PopupLinks::const_iterator i(popup_links_.find(source)); - DCHECK(i != popup_links_.end()); - content_setting_bubble_model_->OnPopupClicked(i->second); -} - -void ContentSettingBubbleContents::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED); - DCHECK(source == Source<TabContents>(tab_contents_)); - tab_contents_ = NULL; -} - -void ContentSettingBubbleContents::InitControlLayout() { - using views::GridLayout; - - GridLayout* layout = new views::GridLayout(this); - SetLayoutManager(layout); - - const int single_column_set_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(single_column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - const ContentSettingBubbleModel::BubbleContent& bubble_content = - content_setting_bubble_model_->bubble_content(); - - if (!bubble_content.title.empty()) { - views::Label* title_label = new views::Label(UTF8ToWide( - bubble_content.title)); - layout->StartRow(0, single_column_set_id); - layout->AddView(title_label); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - const std::set<std::string>& plugins = bubble_content.resource_identifiers; - if (!plugins.empty()) { - for (std::set<std::string>::const_iterator it = plugins.begin(); - it != plugins.end(); ++it) { - std::wstring name; - NPAPI::PluginList::PluginMap groups; - NPAPI::PluginList::Singleton()->GetPluginGroups(false, &groups); - if (groups.find(*it) != groups.end()) - name = UTF16ToWide(groups[*it]->GetGroupName()); - else - name = UTF8ToWide(*it); - layout->StartRow(0, single_column_set_id); - layout->AddView(new views::Label(name)); - } - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - if (content_setting_bubble_model_->content_type() == - CONTENT_SETTINGS_TYPE_POPUPS) { - const int popup_column_set_id = 2; - views::ColumnSet* popup_column_set = - layout->AddColumnSet(popup_column_set_id); - popup_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 0, - GridLayout::USE_PREF, 0, 0); - popup_column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - popup_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - for (std::vector<ContentSettingBubbleModel::PopupItem>::const_iterator - i(bubble_content.popup_items.begin()); - i != bubble_content.popup_items.end(); ++i) { - if (i != bubble_content.popup_items.begin()) - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, popup_column_set_id); - - views::Link* link = new views::Link(UTF8ToWide(i->title)); - link->SetController(this); - link->SetElideInMiddle(true); - popup_links_[link] = i - bubble_content.popup_items.begin(); - layout->AddView(new Favicon((*i).bitmap, this, link)); - layout->AddView(link); - } - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - views::Separator* separator = new views::Separator; - layout->StartRow(0, single_column_set_id); - layout->AddView(separator); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - const ContentSettingBubbleModel::RadioGroup& radio_group = - bubble_content.radio_group; - for (ContentSettingBubbleModel::RadioItems::const_iterator i = - radio_group.radio_items.begin(); - i != radio_group.radio_items.end(); ++i) { - views::RadioButton* radio = new views::RadioButton(UTF8ToWide(*i), 0); - radio->set_listener(this); - radio_group_.push_back(radio); - layout->StartRow(0, single_column_set_id); - layout->AddView(radio); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - if (!radio_group_.empty()) { - views::Separator* separator = new views::Separator; - layout->StartRow(0, single_column_set_id); - layout->AddView(separator, 1, 1, GridLayout::FILL, GridLayout::FILL); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - // Now that the buttons have been added to the view hierarchy, it's safe - // to call SetChecked() on them. - radio_group_[radio_group.default_item]->SetChecked(true); - } - - gfx::Font domain_font = - views::Label().font().DeriveFont(0, gfx::Font::BOLD); - const int indented_single_column_set_id = 3; - // Insert a column set to indent the domain list. - views::ColumnSet* indented_single_column_set = - layout->AddColumnSet(indented_single_column_set_id); - indented_single_column_set->AddPaddingColumn(0, kPanelHorizIndentation); - indented_single_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, - 1, GridLayout::USE_PREF, 0, 0); - for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i = - bubble_content.domain_lists.begin(); - i != bubble_content.domain_lists.end(); ++i) { - layout->StartRow(0, single_column_set_id); - views::Label* section_title = new views::Label(UTF8ToWide(i->title)); - section_title->SetMultiLine(true); - section_title->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->AddView(section_title, 1, 1, GridLayout::FILL, GridLayout::LEADING); - for (std::set<std::string>::const_iterator j = i->hosts.begin(); - j != i->hosts.end(); ++j) { - layout->StartRow(0, indented_single_column_set_id); - layout->AddView(new views::Label(UTF8ToWide(*j), domain_font)); - } - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - if (!bubble_content.clear_link.empty()) { - clear_link_ = new views::Link(UTF8ToWide(bubble_content.clear_link)); - clear_link_->SetController(this); - layout->StartRow(0, single_column_set_id); - layout->AddView(clear_link_); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_set_id); - layout->AddView(new views::Separator, 1, 1, - GridLayout::FILL, GridLayout::FILL); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - if (!bubble_content.info_link.empty()) { - info_link_ = new views::Link(UTF8ToWide(bubble_content.info_link)); - info_link_->SetController(this); - layout->StartRow(0, single_column_set_id); - layout->AddView(info_link_); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_set_id); - layout->AddView(new views::Separator, 1, 1, - GridLayout::FILL, GridLayout::FILL); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - if (!bubble_content.load_plugins_link_title.empty()) { - load_plugins_link_ = new views::Link( - UTF8ToWide(bubble_content.load_plugins_link_title)); - load_plugins_link_->SetEnabled(bubble_content.load_plugins_link_enabled); - load_plugins_link_->SetController(this); - layout->StartRow(0, single_column_set_id); - layout->AddView(load_plugins_link_); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_set_id); - layout->AddView(new views::Separator, 1, 1, - GridLayout::FILL, GridLayout::FILL); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - const int double_column_set_id = 1; - views::ColumnSet* double_column_set = - layout->AddColumnSet(double_column_set_id); - double_column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - double_column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing); - double_column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, double_column_set_id); - manage_link_ = new views::Link(UTF8ToWide(bubble_content.manage_link)); - manage_link_->SetController(this); - layout->AddView(manage_link_); - - close_button_ = - new views::NativeButton(this, l10n_util::GetString(IDS_DONE)); - layout->AddView(close_button_); -} diff --git a/chrome/browser/views/content_setting_bubble_contents.h b/chrome/browser/views/content_setting_bubble_contents.h index b35744f..03ac993 100644 --- a/chrome/browser/views/content_setting_bubble_contents.h +++ b/chrome/browser/views/content_setting_bubble_contents.h @@ -6,99 +6,8 @@ #define CHROME_BROWSER_VIEWS_CONTENT_SETTING_BUBBLE_CONTENTS_H_ #pragma once -#include <map> - -#include "chrome/common/content_settings_types.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "views/controls/button/button.h" -#include "views/controls/link.h" - -// ContentSettingBubbleContents is used when the user turns on different kinds -// of content blocking (e.g. "block images"). When viewing a page with blocked -// content, icons appear in the omnibox corresponding to the content types that -// were blocked, and the user can click one to get a bubble hosting a few -// controls. This class provides the content of that bubble. In general, -// these bubbles typically have a title, a pair of radio buttons for toggling -// the blocking settings for the current site, a close button, and a link to -// get to a more comprehensive settings management dialog. A few types have -// more or fewer controls than this. - -class ContentSettingBubbleModel; -class InfoBubble; -class Profile; -class TabContents; - -namespace views { -class NativeButton; -class RadioButton; -} - -class ContentSettingBubbleContents : public views::View, - public views::ButtonListener, - public views::LinkController, - public NotificationObserver { - public: - ContentSettingBubbleContents( - ContentSettingBubbleModel* content_setting_bubble_model, - Profile* profile, TabContents* tab_contents); - virtual ~ContentSettingBubbleContents(); - - // Sets |info_bubble_|, so we can close the bubble if needed. The caller owns - // the bubble and must keep it alive. - void set_info_bubble(InfoBubble* info_bubble) { info_bubble_ = info_bubble; } - - virtual gfx::Size GetPreferredSize(); - - private: - class Favicon; - - typedef std::map<views::Link*, int> PopupLinks; - - // Overridden from views::View: - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - - // views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - // NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Creates the child views. - void InitControlLayout(); - - // Provides data for this bubble. - scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model_; - - // The active profile. - Profile* profile_; - - // The active tab contents. - TabContents* tab_contents_; - - // A registrar for listening for TAB_CONTENTS_DESTROYED notifications. - NotificationRegistrar registrar_; - - // The InfoBubble holding us. - InfoBubble* info_bubble_; - - // Some of our controls, so we can tell what's been clicked when we get a - // message. - PopupLinks popup_links_; - typedef std::vector<views::RadioButton*> RadioGroup; - RadioGroup radio_group_; - views::NativeButton* close_button_; - views::Link* manage_link_; - views::Link* clear_link_; - views::Link* info_link_; - views::Link* load_plugins_link_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ContentSettingBubbleContents); -}; +#include "chrome/browser/ui/views/content_setting_bubble_contents.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CONTENT_SETTING_BUBBLE_CONTENTS_H_ + diff --git a/chrome/browser/views/cookie_info_view.cc b/chrome/browser/views/cookie_info_view.cc deleted file mode 100644 index f2a1bb1..0000000 --- a/chrome/browser/views/cookie_info_view.cc +++ /dev/null @@ -1,278 +0,0 @@ -// 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/cookie_info_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "base/i18n/time_formatting.h" -#include "base/message_loop.h" -#include "base/string16.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/cookies_tree_model.h" -#include "chrome/browser/profile.h" -#include "gfx/canvas.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/border.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/button/native_button.h" -#include "views/controls/tree/tree_view.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" - -static const int kCookieInfoViewBorderSize = 1; -static const int kCookieInfoViewInsetSize = 3; - -/////////////////////////////////////////////////////////////////////////////// -// CookieInfoView, public: - -CookieInfoView::CookieInfoView(bool editable_expiration_date) - : name_label_(NULL), - name_value_field_(NULL), - content_label_(NULL), - content_value_field_(NULL), - domain_label_(NULL), - domain_value_field_(NULL), - path_label_(NULL), - path_value_field_(NULL), - send_for_label_(NULL), - send_for_value_field_(NULL), - created_label_(NULL), - created_value_field_(NULL), - expires_label_(NULL), - expires_value_field_(NULL), - expires_value_combobox_(NULL), - expire_view_(NULL), - editable_expiration_date_(editable_expiration_date), - delegate_(NULL) { -} - -CookieInfoView::~CookieInfoView() { -} - -void CookieInfoView::SetCookie( - const std::string& domain, - const net::CookieMonster::CanonicalCookie& cookie) { - name_value_field_->SetText(UTF8ToWide(cookie.Name())); - content_value_field_->SetText(UTF8ToWide(cookie.Value())); - domain_value_field_->SetText(UTF8ToWide(domain)); - path_value_field_->SetText(UTF8ToWide(cookie.Path())); - created_value_field_->SetText( - base::TimeFormatFriendlyDateAndTime(cookie.CreationDate())); - - std::wstring expire_text = cookie.DoesExpire() ? - base::TimeFormatFriendlyDateAndTime(cookie.ExpiryDate()) : - l10n_util::GetString(IDS_COOKIES_COOKIE_EXPIRES_SESSION); - - if (editable_expiration_date_) { - expire_combo_values_.clear(); - if (cookie.DoesExpire()) - expire_combo_values_.push_back(expire_text); - expire_combo_values_.push_back( - l10n_util::GetString(IDS_COOKIES_COOKIE_EXPIRES_SESSION)); - expires_value_combobox_->ModelChanged(); - expires_value_combobox_->SetSelectedItem(0); - expires_value_combobox_->SetEnabled(true); - expires_value_combobox_->set_listener(this); - } else { - expires_value_field_->SetText(expire_text); - } - - send_for_value_field_->SetText(cookie.IsSecure() ? - l10n_util::GetString(IDS_COOKIES_COOKIE_SENDFOR_SECURE) : - l10n_util::GetString(IDS_COOKIES_COOKIE_SENDFOR_ANY)); - EnableCookieDisplay(true); - Layout(); -} - -void CookieInfoView::SetCookieString(const GURL& url, - const std::string& cookie_line) { - net::CookieMonster::ParsedCookie pc(cookie_line); - net::CookieMonster::CanonicalCookie cookie(url, pc); - SetCookie(pc.HasDomain() ? pc.Domain() : url.host(), cookie); -} - - -void CookieInfoView::ClearCookieDisplay() { - std::wstring no_cookie_string = - l10n_util::GetString(IDS_COOKIES_COOKIE_NONESELECTED); - name_value_field_->SetText(no_cookie_string); - content_value_field_->SetText(no_cookie_string); - domain_value_field_->SetText(no_cookie_string); - path_value_field_->SetText(no_cookie_string); - send_for_value_field_->SetText(no_cookie_string); - created_value_field_->SetText(no_cookie_string); - if (expires_value_field_) - expires_value_field_->SetText(no_cookie_string); - EnableCookieDisplay(false); -} - -void CookieInfoView::EnableCookieDisplay(bool enabled) { - name_value_field_->SetEnabled(enabled); - content_value_field_->SetEnabled(enabled); - domain_value_field_->SetEnabled(enabled); - path_value_field_->SetEnabled(enabled); - send_for_value_field_->SetEnabled(enabled); - created_value_field_->SetEnabled(enabled); - if (expires_value_field_) - expires_value_field_->SetEnabled(enabled); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieInfoView, views::View overrides. - -void CookieInfoView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieInfoView, views::Combobox::Listener overrides. - -void CookieInfoView::ItemChanged(views::Combobox* combo_box, - int prev_index, - int new_index) { - DCHECK(combo_box == expires_value_combobox_); - if (delegate_) - delegate_->ModifyExpireDate(new_index != 0); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieInfoView, ComboboxModel overrides. -int CookieInfoView::GetItemCount() { - return static_cast<int>(expire_combo_values_.size()); -} - -string16 CookieInfoView::GetItemAt(int index) { - return WideToUTF16Hack(expire_combo_values_[index]); -} - -void CookieInfoView::AddLabelRow(int layout_id, views::GridLayout* layout, - views::View* label, views::View* value) { - layout->StartRow(0, layout_id); - layout->AddView(label); - layout->AddView(value, 2, 1, views::GridLayout::FILL, - views::GridLayout::CENTER); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); -} - -void CookieInfoView::AddControlRow(int layout_id, views::GridLayout* layout, - views::View* label, views::View* control) { - layout->StartRow(0, layout_id); - layout->AddView(label); - layout->AddView(control, 1, 1); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieInfoView, private: - -void CookieInfoView::Init() { - // Ensure we don't run this more than once and leak memory. - DCHECK(!name_label_); - - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kCookieInfoViewBorderSize, border_color); - set_border(border); - - name_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_NAME_LABEL)); - name_value_field_ = new views::Textfield; - content_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_CONTENT_LABEL)); - content_value_field_ = new views::Textfield; - domain_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_DOMAIN_LABEL)); - domain_value_field_ = new views::Textfield; - path_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_PATH_LABEL)); - path_value_field_ = new views::Textfield; - send_for_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_SENDFOR_LABEL)); - send_for_value_field_ = new views::Textfield; - created_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_CREATED_LABEL)); - created_value_field_ = new views::Textfield; - expires_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_EXPIRES_LABEL)); - if (editable_expiration_date_) - expires_value_combobox_ = new views::Combobox(this); - else - expires_value_field_ = new views::Textfield; - - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kCookieInfoViewInsetSize, - kCookieInfoViewInsetSize, - kCookieInfoViewInsetSize, - kCookieInfoViewInsetSize); - SetLayoutManager(layout); - - int three_column_layout_id = 0; - ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - AddLabelRow(three_column_layout_id, layout, name_label_, name_value_field_); - AddLabelRow(three_column_layout_id, layout, content_label_, - content_value_field_); - AddLabelRow(three_column_layout_id, layout, domain_label_, - domain_value_field_); - AddLabelRow(three_column_layout_id, layout, path_label_, path_value_field_); - AddLabelRow(three_column_layout_id, layout, send_for_label_, - send_for_value_field_); - AddLabelRow(three_column_layout_id, layout, created_label_, - created_value_field_); - - if (editable_expiration_date_) { - AddControlRow(three_column_layout_id, layout, expires_label_, - expires_value_combobox_); - } else { - AddLabelRow(three_column_layout_id, layout, expires_label_, - expires_value_field_); - } - - // Color these borderless text areas the same as the containing dialog. - SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); - // Now that the Textfields are in the view hierarchy, we can initialize them. - name_value_field_->SetReadOnly(true); - name_value_field_->RemoveBorder(); - name_value_field_->SetBackgroundColor(text_area_background); - content_value_field_->SetReadOnly(true); - content_value_field_->RemoveBorder(); - content_value_field_->SetBackgroundColor(text_area_background); - domain_value_field_->SetReadOnly(true); - domain_value_field_->RemoveBorder(); - domain_value_field_->SetBackgroundColor(text_area_background); - path_value_field_->SetReadOnly(true); - path_value_field_->RemoveBorder(); - path_value_field_->SetBackgroundColor(text_area_background); - send_for_value_field_->SetReadOnly(true); - send_for_value_field_->RemoveBorder(); - send_for_value_field_->SetBackgroundColor(text_area_background); - created_value_field_->SetReadOnly(true); - created_value_field_->RemoveBorder(); - created_value_field_->SetBackgroundColor(text_area_background); - if (expires_value_field_) { - expires_value_field_->SetReadOnly(true); - expires_value_field_->RemoveBorder(); - expires_value_field_->SetBackgroundColor(text_area_background); - } -} - diff --git a/chrome/browser/views/cookie_info_view.h b/chrome/browser/views/cookie_info_view.h index 2099a004..6eb19e5 100644 --- a/chrome/browser/views/cookie_info_view.h +++ b/chrome/browser/views/cookie_info_view.h @@ -6,118 +6,8 @@ #define CHROME_BROWSER_VIEWS_COOKIE_INFO_VIEW_H_ #pragma once -#include <string> -#include <vector> - -#include "app/combobox_model.h" -#include "base/string16.h" -#include "net/base/cookie_monster.h" -#include "views/controls/combobox/combobox.h" -#include "views/view.h" - -namespace views { -class GridLayout; -class Label; -class NativeButton; -class Textfield; -} - - -/////////////////////////////////////////////////////////////////////////////// -// CookieInfoViewDelegate -// -class CookieInfoViewDelegate { - public: - virtual void ModifyExpireDate(bool session_expire) = 0; - - protected: - virtual ~CookieInfoViewDelegate() {} -}; - -/////////////////////////////////////////////////////////////////////////////// -// CookieInfoView -// -// Responsible for displaying a tabular grid of Cookie information. -class CookieInfoView : public views::View, - public views::Combobox::Listener, - public ComboboxModel { - public: - explicit CookieInfoView(bool editable_expiration_date); - virtual ~CookieInfoView(); - - // Update the display from the specified CookieNode. - void SetCookie(const std::string& domain, - const net::CookieMonster::CanonicalCookie& cookie_node); - - // Update the display from the specified cookie string. - void SetCookieString(const GURL& url, const std::string& cookie_line); - - // Clears the cookie display to indicate that no or multiple cookies are - // selected. - void ClearCookieDisplay(); - - // Enables or disables the cookie property text fields. - void EnableCookieDisplay(bool enabled); - - void set_delegate(CookieInfoViewDelegate* delegate) { delegate_ = delegate; } - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // views::Combobox::Listener override. - virtual void ItemChanged(views::Combobox* combo_box, - int prev_index, - int new_index); - - // ComboboxModel overrides for expires_value_combobox_. - virtual int GetItemCount(); - virtual string16 GetItemAt(int index); - - private: - // Layout helper routines. - void AddLabelRow(int layout_id, views::GridLayout* layout, - views::View* label, views::View* value); - void AddControlRow(int layout_id, views::GridLayout* layout, - views::View* label, views::View* control); - - // Sets up the view layout. - void Init(); - - // Individual property labels - views::Label* name_label_; - views::Textfield* name_value_field_; - views::Label* content_label_; - views::Textfield* content_value_field_; - views::Label* domain_label_; - views::Textfield* domain_value_field_; - views::Label* path_label_; - views::Textfield* path_value_field_; - views::Label* send_for_label_; - views::Textfield* send_for_value_field_; - views::Label* created_label_; - views::Textfield* created_value_field_; - views::Label* expires_label_; - views::Textfield* expires_value_field_; - views::Combobox* expires_value_combobox_; - views::View* expire_view_; - - // Option values for expires_value_combobox_. - std::vector<std::wstring> expire_combo_values_; - - // True if expiration date can be edited. In this case we will show - // expires_value_combobox_ instead of expires_value_field_. The cookie's - // expiration date is editable only this class is used in - // CookiesPromptView (alert before cookie is set), in all other cases we - // don't let user directly change cookie setting. - bool editable_expiration_date_; - - CookieInfoViewDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(CookieInfoView); -}; +#include "chrome/browser/ui/views/cookie_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_COOKIE_INFO_VIEW_H_ diff --git a/chrome/browser/views/create_application_shortcut_view.cc b/chrome/browser/views/create_application_shortcut_view.cc deleted file mode 100644 index 77e2ea6..0000000 --- a/chrome/browser/views/create_application_shortcut_view.cc +++ /dev/null @@ -1,458 +0,0 @@ -// 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/create_application_shortcut_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/callback.h" -#include "base/utf_string_conversions.h" -#include "base/win/windows_version.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas_skia.h" -#include "gfx/codec/png_codec.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/base/load_flags.h" -#include "net/url_request/url_request.h" -#include "third_party/skia/include/core/SkRect.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "base/win_util.h" -#endif // defined(OS_WIN) - -namespace { - -const int kAppIconSize = 32; - -// AppInfoView shows the application icon and title. -class AppInfoView : public views::View { - public: - AppInfoView(const string16& title, - const string16& description, - const SkBitmap& icon); - - // Updates the title/description of the web app. - void UpdateText(const string16& title, const string16& description); - - // Updates the icon of the web app. - void UpdateIcon(const SkBitmap& new_icon); - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - - private: - // Initializes the controls - void Init(const string16& title, - const string16& description, const SkBitmap& icon); - - // Creates or updates description label. - void PrepareDescriptionLabel(const string16& description); - - // Sets up layout manager. - void SetupLayout(); - - views::ImageView* icon_; - views::Label* title_; - views::Label* description_; -}; - -AppInfoView::AppInfoView(const string16& title, - const string16& description, - const SkBitmap& icon) - : icon_(NULL), - title_(NULL), - description_(NULL) { - Init(title, description, icon); -} - -void AppInfoView::Init(const string16& title_text, - const string16& description_text, - const SkBitmap& icon) { - icon_ = new views::ImageView(); - icon_->SetImage(icon); - icon_->SetImageSize(gfx::Size(kAppIconSize, kAppIconSize)); - - title_ = new views::Label(UTF16ToWide(title_text)); - title_->SetMultiLine(true); - title_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - title_->SetFont(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD)); - - if (!description_text.empty()) { - PrepareDescriptionLabel(description_text); - } - - SetupLayout(); -} - -void AppInfoView::PrepareDescriptionLabel(const string16& description) { - DCHECK(!description.empty()); - - static const size_t kMaxLength = 200; - static const wchar_t* const kEllipsis = L" ... "; - - std::wstring text = UTF16ToWide(description); - if (text.length() > kMaxLength) { - text = text.substr(0, kMaxLength); - text += kEllipsis; - } - - if (description_) { - description_->SetText(text); - } else { - description_ = new views::Label(text); - description_->SetMultiLine(true); - description_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - } -} - -void AppInfoView::SetupLayout() { - views::GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - static const int kColumnSetId = 0; - views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId); - column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING, - 20.0f, views::GridLayout::FIXED, - kAppIconSize, kAppIconSize); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 80.0f, views::GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, kColumnSetId); - layout->AddView(icon_, 1, description_ ? 2 : 1); - layout->AddView(title_); - - if (description_) { - layout->StartRow(0, kColumnSetId); - layout->SkipColumns(1); - layout->AddView(description_); - } -} - -void AppInfoView::UpdateText(const string16& title, - const string16& description) { - title_->SetText(UTF16ToWide(title)); - PrepareDescriptionLabel(description); - - SetupLayout(); -} - -void AppInfoView::UpdateIcon(const SkBitmap& new_icon) { - DCHECK(icon_ != NULL); - - icon_->SetImage(new_icon); -} - -void AppInfoView::Paint(gfx::Canvas* canvas) { - gfx::Rect bounds = GetLocalBounds(true); - - SkRect border_rect = { - SkIntToScalar(bounds.x()), - SkIntToScalar(bounds.y()), - SkIntToScalar(bounds.right()), - SkIntToScalar(bounds.bottom()) - }; - - SkPaint border_paint; - border_paint.setAntiAlias(true); - border_paint.setARGB(0xFF, 0xC8, 0xC8, 0xC8); - - canvas->AsCanvasSkia()->drawRoundRect( - border_rect, SkIntToScalar(2), SkIntToScalar(2), border_paint); - - SkRect inner_rect = { - border_rect.fLeft + SkDoubleToScalar(0.5), - border_rect.fTop + SkDoubleToScalar(0.5), - border_rect.fRight - SkDoubleToScalar(0.5), - border_rect.fBottom - SkDoubleToScalar(0.5), - }; - - SkPaint inner_paint; - inner_paint.setAntiAlias(true); - inner_paint.setARGB(0xFF, 0xF8, 0xF8, 0xF8); - canvas->AsCanvasSkia()->drawRoundRect( - inner_rect, SkIntToScalar(1.5), SkIntToScalar(1.5), inner_paint); -} - -}; // namespace - -namespace browser { - -void ShowCreateShortcutsDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents) { - views::Window::CreateChromeWindow(parent_window, gfx::Rect(), - new CreateApplicationShortcutView(tab_contents))->Show(); -} - -}; // namespace browser - -class CreateApplicationShortcutView::IconDownloadCallbackFunctor { - public: - explicit IconDownloadCallbackFunctor(CreateApplicationShortcutView* owner) - : owner_(owner) { - } - - void Run(int download_id, bool errored, const SkBitmap& image) { - if (owner_) - owner_->OnIconDownloaded(errored, image); - delete this; - } - - void Cancel() { - owner_ = NULL; - } - - private: - CreateApplicationShortcutView* owner_; -}; - -CreateApplicationShortcutView::CreateApplicationShortcutView( - TabContents* tab_contents) - : tab_contents_(tab_contents), - pending_download_(NULL) { - Init(); -} - -CreateApplicationShortcutView::~CreateApplicationShortcutView() { - if (pending_download_) - pending_download_->Cancel(); -} - -void CreateApplicationShortcutView::Init() { - // Prepare data - web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_); - - const webkit_glue::WebApplicationInfo& app_info = - tab_contents_->web_app_info(); - if (!app_info.icons.empty()) { - web_app::GetIconsInfo(app_info, &unprocessed_icons_); - FetchIcon(); - } - - // Create controls - app_info_ = new AppInfoView(shortcut_info_.title, shortcut_info_.description, - shortcut_info_.favicon); - create_shortcuts_label_ = new views::Label( - l10n_util::GetString(IDS_CREATE_SHORTCUTS_LABEL)); - create_shortcuts_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - Profile* profile = tab_contents_->profile(); - - desktop_check_box_ = AddCheckbox( - l10n_util::GetString(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX), - profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateOnDesktop)); - - menu_check_box_ = NULL; - quick_launch_check_box_ = NULL; - -#if defined(OS_WIN) - menu_check_box_ = AddCheckbox( - l10n_util::GetString(IDS_CREATE_SHORTCUTS_START_MENU_CHKBOX), - profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu)); - - quick_launch_check_box_ = AddCheckbox( - (base::win::GetVersion() >= base::win::VERSION_WIN7) ? - l10n_util::GetString(IDS_PIN_TO_TASKBAR_CHKBOX) : - l10n_util::GetString(IDS_CREATE_SHORTCUTS_QUICK_LAUNCH_BAR_CHKBOX), - profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateInQuickLaunchBar)); -#elif defined(OS_LINUX) - menu_check_box_ = AddCheckbox( - l10n_util::GetString(IDS_CREATE_SHORTCUTS_MENU_CHKBOX), - profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu)); -#endif - - // Layout controls - views::GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - static const int kHeaderColumnSetId = 0; - views::ColumnSet* column_set = layout->AddColumnSet(kHeaderColumnSetId); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 100.0f, views::GridLayout::FIXED, 0, 0); - - static const int kTableColumnSetId = 1; - column_set = layout->AddColumnSet(kTableColumnSetId); - column_set->AddPaddingColumn(5.0f, 10); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, - 100.0f, views::GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, kHeaderColumnSetId); - layout->AddView(app_info_); - - layout->AddPaddingRow(0, kPanelSubVerticalSpacing); - layout->StartRow(0, kHeaderColumnSetId); - layout->AddView(create_shortcuts_label_); - - layout->AddPaddingRow(0, kLabelToControlVerticalSpacing); - layout->StartRow(0, kTableColumnSetId); - layout->AddView(desktop_check_box_); - - if (menu_check_box_ != NULL) { - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, kTableColumnSetId); - layout->AddView(menu_check_box_); - } - - if (quick_launch_check_box_ != NULL) { - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, kTableColumnSetId); - layout->AddView(quick_launch_check_box_); - } -} - -gfx::Size CreateApplicationShortcutView::GetPreferredSize() { - // TODO(evanm): should this use IDS_CREATE_SHORTCUTS_DIALOG_WIDTH_CHARS? - static const int kDialogWidth = 360; - int height = GetLayoutManager()->GetPreferredHeightForWidth(this, - kDialogWidth); - return gfx::Size(kDialogWidth, height); -} - -std::wstring CreateApplicationShortcutView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return l10n_util::GetString(IDS_CREATE_SHORTCUTS_COMMIT); - } - - return std::wstring(); -} - -bool CreateApplicationShortcutView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - return desktop_check_box_->checked() || - ((menu_check_box_ != NULL) && - menu_check_box_->checked()) || - ((quick_launch_check_box_ != NULL) && - quick_launch_check_box_->checked()); - - return true; -} - -bool CreateApplicationShortcutView::CanResize() const { - return false; -} - -bool CreateApplicationShortcutView::CanMaximize() const { - return false; -} - -bool CreateApplicationShortcutView::IsAlwaysOnTop() const { - return false; -} - -bool CreateApplicationShortcutView::HasAlwaysOnTopMenu() const { - return false; -} - -bool CreateApplicationShortcutView::IsModal() const { - return true; -} - -std::wstring CreateApplicationShortcutView::GetWindowTitle() const { - return l10n_util::GetString(IDS_CREATE_SHORTCUTS_TITLE); -} - -bool CreateApplicationShortcutView::Accept() { - if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) { - return false; - } - - shortcut_info_.create_on_desktop = desktop_check_box_->checked(); - shortcut_info_.create_in_applications_menu = menu_check_box_ == NULL ? false : - menu_check_box_->checked(); - -#if defined(OS_WIN) - shortcut_info_.create_in_quick_launch_bar = quick_launch_check_box_ == NULL ? - NULL : quick_launch_check_box_->checked(); -#elif defined(OS_POSIX) - // Create shortcut in Mac dock or as Linux (gnome/kde) application launcher - // are not implemented yet. - shortcut_info_.create_in_quick_launch_bar = false; -#endif - - web_app::CreateShortcut(tab_contents_->profile()->GetPath(), - shortcut_info_, - NULL); - - tab_contents_->SetAppIcon(shortcut_info_.favicon); - if (tab_contents_->delegate()) - tab_contents_->delegate()->ConvertContentsToApplication(tab_contents_); - return true; -} - -views::View* CreateApplicationShortcutView::GetContentsView() { - return this; -} - -views::Checkbox* CreateApplicationShortcutView::AddCheckbox( - const std::wstring& text, bool checked) { - views::Checkbox* checkbox = new views::Checkbox(text); - checkbox->SetChecked(checked); - checkbox->set_listener(this); - return checkbox; -} - -void CreateApplicationShortcutView::FetchIcon() { - // There should only be fetch job at a time. - DCHECK(pending_download_ == NULL); - - if (unprocessed_icons_.empty()) { - // No icons to fetch. - return; - } - - pending_download_ = new IconDownloadCallbackFunctor(this); - DCHECK(pending_download_); - - tab_contents_->fav_icon_helper().DownloadImage( - unprocessed_icons_.back().url, - std::max(unprocessed_icons_.back().width, - unprocessed_icons_.back().height), - NewCallback(pending_download_, &IconDownloadCallbackFunctor::Run)); - - unprocessed_icons_.pop_back(); -} - -void CreateApplicationShortcutView::ButtonPressed(views::Button* sender, - const views::Event& event) { - Profile* profile = tab_contents_->profile(); - if (sender == desktop_check_box_) - profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateOnDesktop, - desktop_check_box_->checked() ? true : false); - else if (sender == menu_check_box_) - profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInAppsMenu, - menu_check_box_->checked() ? true : false); - else if (sender == quick_launch_check_box_) - profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInQuickLaunchBar, - quick_launch_check_box_->checked() ? true : false); - - // When no checkbox is checked we should not have the action button enabled. - GetDialogClientView()->UpdateDialogButtons(); -} - -void CreateApplicationShortcutView::OnIconDownloaded(bool errored, - const SkBitmap& image) { - pending_download_ = NULL; - - if (!errored && !image.isNull()) { - shortcut_info_.favicon = image; - static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon); - } else { - FetchIcon(); - } -} diff --git a/chrome/browser/views/create_application_shortcut_view.h b/chrome/browser/views/create_application_shortcut_view.h index d3112f2..d117ab2 100644 --- a/chrome/browser/views/create_application_shortcut_view.h +++ b/chrome/browser/views/create_application_shortcut_view.h @@ -6,88 +6,8 @@ #define CHROME_BROWSER_VIEWS_CREATE_APPLICATION_SHORTCUT_VIEW_H_ #pragma once -#include <string> - -#include "chrome/browser/web_applications/web_app.h" -#include "views/controls/label.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" -#include "third_party/skia/include/core/SkBitmap.h" - -namespace views { -class Checkbox; -class Label; -class Window; -}; // namespace views - -class MessageLoop; -class Profile; -class TabContents; - -// CreateShortcutView implements a dialog that asks user where to create -// the shortcut for given web app. -class CreateApplicationShortcutView : public views::View, - public views::DialogDelegate, - public views::ButtonListener { - public: - explicit CreateApplicationShortcutView(TabContents* tab_contents); - virtual ~CreateApplicationShortcutView(); - - // Initialize the controls on the dialog. - void Init(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - - // Overridden from views::DialogDelegate: - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool CanResize() const; - virtual bool CanMaximize() const; - virtual bool IsAlwaysOnTop() const; - virtual bool HasAlwaysOnTopMenu() const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool Accept(); - virtual views::View* GetContentsView(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - private: - // Adds a new check-box as a child to the view. - views::Checkbox* AddCheckbox(const std::wstring& text, bool checked); - - // Fetch the largest unprocessed icon. - // The first largest icon downloaded and decoded successfully will be used. - void FetchIcon(); - - // Callback of icon download. - void OnIconDownloaded(bool errored, const SkBitmap& image); - - // TabContents of the page that we want to create shortcut. - TabContents* tab_contents_; - - // UI elements on the dialog. - views::View* app_info_; - views::Label* create_shortcuts_label_; - views::Checkbox* desktop_check_box_; - views::Checkbox* menu_check_box_; - views::Checkbox* quick_launch_check_box_; - - // Target shortcut info. - ShellIntegration::ShortcutInfo shortcut_info_; - - // Unprocessed icons from the WebApplicationInfo passed in. - web_app::IconInfoList unprocessed_icons_; - - // Pending app icon download tracked by us. - class IconDownloadCallbackFunctor; - IconDownloadCallbackFunctor* pending_download_; - - DISALLOW_COPY_AND_ASSIGN(CreateApplicationShortcutView); -}; +#include "chrome/browser/ui/views/create_application_shortcut_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_CREATE_APPLICATION_SHORTCUT_VIEW_H_ + diff --git a/chrome/browser/views/database_info_view.cc b/chrome/browser/views/database_info_view.cc deleted file mode 100644 index 70596e3..0000000 --- a/chrome/browser/views/database_info_view.cc +++ /dev/null @@ -1,144 +0,0 @@ -// 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/database_info_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "base/i18n/time_formatting.h" -#include "base/utf_string_conversions.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" - -static const int kDatabaseInfoViewBorderSize = 1; -static const int kDatabaseInfoViewInsetSize = 3; - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseInfoView, public: - -DatabaseInfoView::DatabaseInfoView() - : name_value_field_(NULL), - description_value_field_(NULL), - size_value_field_(NULL), - last_modified_value_field_(NULL) { -} - -DatabaseInfoView::~DatabaseInfoView() { -} - -void DatabaseInfoView::SetDatabaseInfo( - const BrowsingDataDatabaseHelper::DatabaseInfo& database_info) { - name_value_field_->SetText(database_info.database_name.empty() ? - l10n_util::GetString(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) : - UTF8ToWide(database_info.database_name)); - description_value_field_->SetText(UTF8ToWide(database_info.description)); - size_value_field_->SetText( - FormatBytes(database_info.size, - GetByteDisplayUnits(database_info.size), - true)); - last_modified_value_field_->SetText( - base::TimeFormatFriendlyDateAndTime(database_info.last_modified)); - EnableDatabaseDisplay(true); -} - -void DatabaseInfoView::EnableDatabaseDisplay(bool enabled) { - name_value_field_->SetEnabled(enabled); - description_value_field_->SetEnabled(enabled); - size_value_field_->SetEnabled(enabled); - last_modified_value_field_->SetEnabled(enabled); -} - -void DatabaseInfoView::ClearDatabaseDisplay() { - const std::wstring kEmpty; - description_value_field_->SetText(kEmpty); - size_value_field_->SetText(kEmpty); - last_modified_value_field_->SetText(kEmpty); - EnableDatabaseDisplay(false); -} - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseInfoView, views::View overrides: - -void DatabaseInfoView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseInfoView, private: - -void DatabaseInfoView::Init() { - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kDatabaseInfoViewBorderSize, border_color); - set_border(border); - - views::Label* name_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_NAME_LABEL)); - name_value_field_ = new views::Textfield; - views::Label* description_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL)); - description_value_field_ = new views::Textfield; - views::Label* size_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL)); - size_value_field_ = new views::Textfield; - views::Label* last_modified_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL)); - last_modified_value_field_ = new views::Textfield; - - using views::GridLayout; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kDatabaseInfoViewInsetSize, - kDatabaseInfoViewInsetSize, - kDatabaseInfoViewInsetSize, - kDatabaseInfoViewInsetSize); - SetLayoutManager(layout); - - int three_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, three_column_layout_id); - layout->AddView(name_label); - layout->AddView(name_value_field_); - layout->StartRow(0, three_column_layout_id); - layout->AddView(description_label); - layout->AddView(description_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(size_label); - layout->AddView(size_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(last_modified_label); - layout->AddView(last_modified_value_field_); - - // Color these borderless text areas the same as the containing dialog. - SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); - // Now that the Textfields are in the view hierarchy, we can initialize them. - name_value_field_->SetReadOnly(true); - name_value_field_->RemoveBorder(); - name_value_field_->SetBackgroundColor(text_area_background); - description_value_field_->SetReadOnly(true); - description_value_field_->RemoveBorder(); - description_value_field_->SetBackgroundColor(text_area_background); - size_value_field_->SetReadOnly(true); - size_value_field_->RemoveBorder(); - size_value_field_->SetBackgroundColor(text_area_background); - last_modified_value_field_->SetReadOnly(true); - last_modified_value_field_->RemoveBorder(); - last_modified_value_field_->SetBackgroundColor(text_area_background); -} diff --git a/chrome/browser/views/database_info_view.h b/chrome/browser/views/database_info_view.h index 269d3c4..5f7e747 100644 --- a/chrome/browser/views/database_info_view.h +++ b/chrome/browser/views/database_info_view.h @@ -6,51 +6,8 @@ #define CHROME_BROWSER_VIEWS_DATABASE_INFO_VIEW_H_ #pragma once -#include "views/view.h" -#include "chrome/browser/browsing_data_database_helper.h" - -namespace views { -class Label; -class Textfield; -} - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseInfoView -// -// Responsible for displaying a tabular grid of Database information. -class DatabaseInfoView : public views::View { - public: - DatabaseInfoView(); - virtual ~DatabaseInfoView(); - - // Update the display from the specified Database info. - void SetDatabaseInfo( - const BrowsingDataDatabaseHelper::DatabaseInfo& database_info); - - // Clears the cookie display to indicate that no or multiple databases are - // selected. - void ClearDatabaseDisplay(); - - // Enables or disables the database property text fields. - void EnableDatabaseDisplay(bool enabled); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child); - - private: - // Set up the view layout. - void Init(); - - // Individual property labels. - views::Textfield* name_value_field_; - views::Textfield* description_value_field_; - views::Textfield* size_value_field_; - views::Textfield* last_modified_value_field_; - - DISALLOW_COPY_AND_ASSIGN(DatabaseInfoView); -}; - +#include "chrome/browser/ui/views/database_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_DATABASE_INFO_VIEW_H_ + diff --git a/chrome/browser/views/database_open_info_view.cc b/chrome/browser/views/database_open_info_view.cc deleted file mode 100644 index 02e7fae..0000000 --- a/chrome/browser/views/database_open_info_view.cc +++ /dev/null @@ -1,40 +0,0 @@ -// 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/database_open_info_view.h" - -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "grit/generated_resources.h" - -namespace { -const int kInfoLabelIds[] = { - IDS_COOKIES_COOKIE_DOMAIN_LABEL, - IDS_COOKIES_WEB_DATABASE_NAME, - IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL, - IDS_COOKIES_SIZE_LABEL -}; -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseOpenInfoView, public: - -DatabaseOpenInfoView::DatabaseOpenInfoView() - : GenericInfoView(ARRAYSIZE(kInfoLabelIds), kInfoLabelIds) { -} - -void DatabaseOpenInfoView::SetFields(const std::string& host, - const string16& database_name, - const string16& display_name, - unsigned long estimated_size) { - string16 url = UTF8ToUTF16(host); - string16 size = FormatBytes(estimated_size, - GetByteDisplayUnits(estimated_size), - true); - int row = 0; - SetValue(row++, url); - SetValue(row++, database_name); - SetValue(row++, display_name); - SetValue(row++, size); -} diff --git a/chrome/browser/views/database_open_info_view.h b/chrome/browser/views/database_open_info_view.h index 81926ae..be808238 100644 --- a/chrome/browser/views/database_open_info_view.h +++ b/chrome/browser/views/database_open_info_view.h @@ -6,28 +6,8 @@ #define CHROME_BROWSER_VIEWS_DATABASE_OPEN_INFO_VIEW_H_ #pragma once -#include "base/string16.h" -#include "chrome/browser/views/generic_info_view.h" - -/////////////////////////////////////////////////////////////////////////////// -// DatabaseOpenInfoView -// -// Responsible for displaying a tabular grid of Database information when -// prompting for permission to open a new database. -class DatabaseOpenInfoView : public GenericInfoView { - public: - DatabaseOpenInfoView(); - - // Update the display from the specified Database data. - void SetFields(const std::string& host, - const string16& database_name, - const string16& display_name, - unsigned long estimated_size); - - private: - DISALLOW_COPY_AND_ASSIGN(DatabaseOpenInfoView); -}; - +#include "chrome/browser/ui/views/database_open_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_DATABASE_OPEN_INFO_VIEW_H_ diff --git a/chrome/browser/views/default_search_view.cc b/chrome/browser/views/default_search_view.cc deleted file mode 100644 index a90461f..0000000 --- a/chrome/browser/views/default_search_view.cc +++ /dev/null @@ -1,103 +0,0 @@ -// 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/default_search_view.h" - -#include <string> - -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" - -// static -void DefaultSearchView::Show(TabContents* tab_contents, - TemplateURL* default_url, - TemplateURLModel* template_url_model) { - scoped_ptr<TemplateURL> template_url(default_url); - if (!template_url_model->CanMakeDefault(default_url) || - default_url->url()->GetHost().empty()) - return; - - // When the window closes, it will delete itself. - new DefaultSearchView(tab_contents, template_url.release(), - template_url_model); -} - -std::wstring DefaultSearchView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString(IDS_DEFAULT_SEARCH_PROMPT_OK); - - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return l10n_util::GetString(IDS_DEFAULT_SEARCH_PROMPT_CANCEL); - - case MessageBoxFlags::DIALOGBUTTON_NONE: - NOTREACHED(); - break; - } - - NOTREACHED(); - return std::wstring(); -} - -std::wstring DefaultSearchView::GetWindowTitle() const { - return l10n_util::GetString(IDS_DEFAULT_SEARCH_PROMPT_TITLE); -} - -void DefaultSearchView::DeleteDelegate() { - delete this; -} - -views::View* DefaultSearchView::GetContentsView() { - return message_box_view_; -} - -int DefaultSearchView::GetDefaultDialogButton() const { - // To less the likelihood of an accidental default search engine change, make - // the cancel button the default dialog button. - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -bool DefaultSearchView::Accept() { - // Check this again in case the default became managed while this dialog was - // displayed. - if (!template_url_model_->CanMakeDefault(default_url_.get())) - return true; - - TemplateURL* set_as_default = default_url_.get(); - template_url_model_->Add(default_url_.release()); - template_url_model_->SetDefaultSearchProvider(set_as_default); - return true; -} - -DefaultSearchView::DefaultSearchView(TabContents* tab_contents, - TemplateURL* default_url, - TemplateURLModel* template_url_model) - : default_url_(default_url), - template_url_model_(template_url_model) { - const int kDialogWidth = 420; - - // Also deleted when the window closes. - message_box_view_ = new MessageBoxView( - 0, - l10n_util::GetStringF(IDS_DEFAULT_SEARCH_PROMPT, - DefaultHostName()), - std::wstring(), - kDialogWidth); - tab_contents->CreateConstrainedDialog(this); -} - -DefaultSearchView::~DefaultSearchView() { -} - -string16 DefaultSearchView::DefaultHostName() const { - return UTF8ToUTF16(default_url_->url()->GetHost()); -} diff --git a/chrome/browser/views/default_search_view.h b/chrome/browser/views/default_search_view.h index 052664d..12651c4 100644 --- a/chrome/browser/views/default_search_view.h +++ b/chrome/browser/views/default_search_view.h @@ -6,60 +6,8 @@ #define CHROME_BROWSER_VIEWS_DEFAULT_SEARCH_VIEW_H_ #pragma once -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/string16.h" -#include "chrome/browser/tab_contents/constrained_window.h" -#include "views/window/dialog_delegate.h" - -#if defined(TOOLKIT_USES_GTK) -#include "chrome/browser/gtk/constrained_window_gtk.h" -#endif - -class MessageBoxView; -class TabContents; -class TemplateURL; -class TemplateURLModel; - -namespace views { -class View; -} - -// This class is responsible for displaying the contents of the default search -// prompt for when InstallSearchProvider(url, true) is called. -class DefaultSearchView : public ConstrainedDialogDelegate { - public: - static void Show(TabContents* tab_contents, - TemplateURL* default_url, - TemplateURLModel* template_url_model); - - protected: - // ConstrainedDialogDelegate: - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual std::wstring GetWindowTitle() const; - virtual void DeleteDelegate(); - virtual views::View* GetContentsView(); - virtual int GetDefaultDialogButton() const; - virtual bool Accept(); - - private: - DefaultSearchView(TabContents* tab_contents, - TemplateURL* default_url, - TemplateURLModel* template_url_model); - ~DefaultSearchView(); - - // The host name for the possible default search provider. - string16 DefaultHostName() const; - - // The possible new default url. - scoped_ptr<TemplateURL> default_url_; - TemplateURLModel* template_url_model_; - - // The message box view whose commands we handle. - MessageBoxView* message_box_view_; - - DISALLOW_COPY_AND_ASSIGN(DefaultSearchView); -}; +#include "chrome/browser/ui/views/default_search_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_DEFAULT_SEARCH_VIEW_H_ + diff --git a/chrome/browser/views/detachable_toolbar_view.cc b/chrome/browser/views/detachable_toolbar_view.cc deleted file mode 100644 index e2aaa3a..0000000 --- a/chrome/browser/views/detachable_toolbar_view.cc +++ /dev/null @@ -1,119 +0,0 @@ -// 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/detachable_toolbar_view.h" - -#include "app/resource_bundle.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "gfx/canvas_skia.h" -#include "gfx/skia_util.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkShader.h" -#include "views/window/non_client_view.h" - -// How round the 'new tab' style bookmarks bar is. -static const int kNewtabBarRoundness = 5; - -const SkColor DetachableToolbarView::kEdgeDividerColor = - SkColorSetRGB(222, 234, 248); -const SkColor DetachableToolbarView::kMiddleDividerColor = - SkColorSetRGB(194, 205, 212); - -// static -void DetachableToolbarView::PaintBackgroundAttachedMode( - gfx::Canvas* canvas, - views::View* view, - const gfx::Point& background_origin) { - ThemeProvider* tp = view->GetThemeProvider(); - SkColor theme_toolbar_color = - tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); - canvas->FillRectInt(theme_toolbar_color, 0, 0, - view->width(), view->height()); - canvas->TileImageInt(*tp->GetBitmapNamed(IDR_THEME_TOOLBAR), - background_origin.x(), background_origin.y(), 0, 0, - view->width(), view->height()); -} - -// static -void DetachableToolbarView::CalculateContentArea( - double animation_state, double horizontal_padding, - double vertical_padding, SkRect* rect, - double* roundness, views::View* view) { - // The 0.5 is to correct for Skia's "draw on pixel boundaries"ness. - rect->set(SkDoubleToScalar(horizontal_padding - 0.5), - SkDoubleToScalar(vertical_padding - 0.5), - SkDoubleToScalar(view->width() - horizontal_padding - 0.5), - SkDoubleToScalar(view->height() - vertical_padding - 0.5)); - - *roundness = static_cast<double>(kNewtabBarRoundness) * animation_state; -} - -// static -void DetachableToolbarView::PaintHorizontalBorder(gfx::Canvas* canvas, - DetachableToolbarView* view) { - // Border can be at the top or at the bottom of the view depending on whether - // the view (bar/shelf) is attached or detached. - int thickness = views::NonClientFrameView::kClientEdgeThickness; - int y = view->IsDetached() ? 0 : (view->height() - thickness); - canvas->FillRectInt(ResourceBundle::toolbar_separator_color, - 0, y, view->width(), thickness); -} - -// static -void DetachableToolbarView::PaintContentAreaBackground( - gfx::Canvas* canvas, ThemeProvider* theme_provider, - const SkRect& rect, double roundness) { - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(theme_provider->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); - - canvas->AsCanvasSkia()->drawRoundRect( - rect, SkDoubleToScalar(roundness), SkDoubleToScalar(roundness), paint); -} - -// static -void DetachableToolbarView::PaintContentAreaBorder( - gfx::Canvas* canvas, ThemeProvider* theme_provider, - const SkRect& rect, double roundness) { - SkPaint border_paint; - border_paint.setColor( - theme_provider->GetColor(BrowserThemeProvider::COLOR_NTP_HEADER)); - border_paint.setStyle(SkPaint::kStroke_Style); - border_paint.setAlpha(96); - border_paint.setAntiAlias(true); - - canvas->AsCanvasSkia()->drawRoundRect( - rect, SkDoubleToScalar(roundness), SkDoubleToScalar(roundness), - border_paint); -} - -// static -void DetachableToolbarView::PaintVerticalDivider( - gfx::Canvas* canvas, int x, int height, int vertical_padding, - const SkColor& top_color, - const SkColor& middle_color, - const SkColor& bottom_color) { - // Draw the upper half of the divider. - SkPaint paint; - SkSafeUnref(paint.setShader(gfx::CreateGradientShader(vertical_padding + 1, - height / 2, - top_color, - middle_color))); - SkRect rc = { SkIntToScalar(x), - SkIntToScalar(vertical_padding + 1), - SkIntToScalar(x + 1), - SkIntToScalar(height / 2) }; - canvas->AsCanvasSkia()->drawRect(rc, paint); - - // Draw the lower half of the divider. - SkPaint paint_down; - SkSafeUnref(paint_down.setShader(gfx::CreateGradientShader( - height / 2, height - vertical_padding, middle_color, bottom_color))); - SkRect rc_down = { SkIntToScalar(x), - SkIntToScalar(height / 2), - SkIntToScalar(x + 1), - SkIntToScalar(height - vertical_padding) }; - canvas->AsCanvasSkia()->drawRect(rc_down, paint_down); -} diff --git a/chrome/browser/views/detachable_toolbar_view.h b/chrome/browser/views/detachable_toolbar_view.h index fe6137b..68c967b 100644 --- a/chrome/browser/views/detachable_toolbar_view.h +++ b/chrome/browser/views/detachable_toolbar_view.h @@ -6,86 +6,8 @@ #define CHROME_BROWSER_VIEWS_DETACHABLE_TOOLBAR_VIEW_H_ #pragma once -#include "chrome/browser/views/accessible_pane_view.h" - -class SkBitmap; -struct SkRect; - -// DetachableToolbarView contains functionality common to views that can detach -// from the Chrome frame, such as the BookmarkBarView and the Extension shelf. -class DetachableToolbarView : public AccessiblePaneView { - public: - // The color gradient start value close to the edge of the divider. - static const SkColor kEdgeDividerColor; - // The color gradient value for the middle of the divider. - static const SkColor kMiddleDividerColor; - - DetachableToolbarView() {} - virtual ~DetachableToolbarView() {} - - // Whether the view is currently detached from the Chrome frame. - virtual bool IsDetached() const = 0; - - // Gets the current state of the resize animation (show/hide). - virtual double GetAnimationValue() const = 0; - - // Gets the current amount of overlap atop the browser toolbar. - virtual int GetToolbarOverlap() const = 0; - - // Paints the background (including the theme image behind content area) when - // the bar/shelf is attached to the top toolbar. |background_origin| is the - // origin to use for painting the theme image. - static void PaintBackgroundAttachedMode(gfx::Canvas* canvas, - views::View* view, - const gfx::Point& background_origin); - - // Calculate the rect for the content area of the bar/shelf. This is only - // needed when the bar/shelf is detached from the Chrome frame (otherwise the - // content area is the whole area of the bar/shelf. When detached, however, - // only a small round rectangle is for drawing our content on. This calculates - // how big this area is, where it is located within the shelf and how round - // the edges should be. - static void CalculateContentArea(double animation_state, - double horizontal_padding, - double vertical_padding, - SkRect* rect, - double* roundness, - views::View* view); - - // Paint the horizontal border separating the shelf/bar from the page content. - static void PaintHorizontalBorder(gfx::Canvas* canvas, - DetachableToolbarView* view); - - // Paint the background of the content area (the surface behind the - // bookmarks or extension toolstrips). |rect| is the rectangle to paint - // the background within. |roundness| describes the roundness of the corners. - static void PaintContentAreaBackground(gfx::Canvas* canvas, - ThemeProvider* theme_provider, - const SkRect& rect, - double roundness); - // Paint the border around the content area (when in detached mode). - static void PaintContentAreaBorder(gfx::Canvas* canvas, - ThemeProvider* theme_provider, - const SkRect& rect, - double roundness); - - // Paint a themed gradient divider at location |x|. |height| is the full - // height of the view you want to paint the divider into, not the height of - // the divider. The height of the divider will become: - // |height| - 2 * |vertical_padding|. - // The color of the divider is a gradient starting with |top_color| at the - // top, and changing into |middle_color| and then over to |bottom_color| as - // you go further down. - static void PaintVerticalDivider(gfx::Canvas* canvas, - int x, - int height, - int vertical_padding, - const SkColor& top_color, - const SkColor& middle_color, - const SkColor& bottom_color); - - private: - DISALLOW_COPY_AND_ASSIGN(DetachableToolbarView); -}; +#include "chrome/browser/ui/views/detachable_toolbar_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_DETACHABLE_TOOLBAR_VIEW_H_ + diff --git a/chrome/browser/views/dialog_stubs_gtk.cc b/chrome/browser/views/dialog_stubs_gtk.cc deleted file mode 100644 index a8e4535..0000000 --- a/chrome/browser/views/dialog_stubs_gtk.cc +++ /dev/null @@ -1,79 +0,0 @@ -// 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. - -// This file contains stub implementations of the functions declared in -// browser_dialogs.h that are currently unimplemented in GTK-views. - -#include <gtk/gtk.h> - -#include "base/logging.h" -#include "chrome/browser/gtk/about_chrome_dialog.h" -#include "chrome/browser/fonts_languages_window.h" -#include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h" -#include "chrome/browser/gtk/collected_cookies_gtk.h" -#include "chrome/browser/gtk/edit_search_engine_dialog.h" -#include "chrome/browser/gtk/keyword_editor_view.h" -#include "chrome/browser/gtk/options/content_settings_window_gtk.h" -#include "chrome/browser/gtk/options/passwords_exceptions_window_gtk.h" -#include "chrome/browser/gtk/repost_form_warning_gtk.h" -#include "chrome/browser/gtk/task_manager_gtk.h" -#include "chrome/browser/options_window.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "views/widget/widget.h" - -namespace browser { - -void ShowClearBrowsingDataView(views::Widget* parent, - Profile* profile) { - ClearBrowsingDataDialogGtk::Show(GTK_WINDOW(parent->GetNativeView()), - profile); -} - -void ShowImporterView(views::Widget* parent, Profile* profile) { - // Import currently doesn't matter. - NOTIMPLEMENTED(); -} - -void ShowPasswordsExceptionsWindowView(Profile* profile) { - ShowPasswordsExceptionsWindow(profile); -} - -void ShowKeywordEditorView(Profile* profile) { - KeywordEditorView::Show(profile); -} - -void ShowNewProfileDialog() { - // Hasn't been implemented yet on linux. - NOTIMPLEMENTED(); -} - -void ShowTaskManager() { - TaskManagerGtk::Show(); -} - -void EditSearchEngine(gfx::NativeWindow parent, - const TemplateURL* template_url, - EditSearchEngineControllerDelegate* delegate, - Profile* profile) { - new EditSearchEngineDialog(GTK_WINDOW(parent), template_url, NULL, profile); -} - -void ShowRepostFormWarningDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents) { - new RepostFormWarningGtk(GTK_WINDOW(parent_window), tab_contents); -} - -void ShowContentSettingsWindow(gfx::NativeWindow parent_window, - ContentSettingsType content_type, - Profile* profile) { - ContentSettingsWindowGtk::Show(parent_window, content_type, profile); -} - -void ShowCollectedCookiesDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents) { - new CollectedCookiesGtk(GTK_WINDOW(parent_window), tab_contents); -} - -} // namespace browser diff --git a/chrome/browser/views/dom_view.cc b/chrome/browser/views/dom_view.cc deleted file mode 100644 index a4cc19a..0000000 --- a/chrome/browser/views/dom_view.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2006-2008 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/dom_view.h" - -#include "chrome/browser/tab_contents/tab_contents.h" -#include "ipc/ipc_message.h" -#include "views/focus/focus_manager.h" - -DOMView::DOMView() : tab_contents_(NULL), initialized_(false) { - SetFocusable(true); -} - -DOMView::~DOMView() { - if (native_view()) - Detach(); -} - -bool DOMView::Init(Profile* profile, SiteInstance* instance) { - if (initialized_) - return true; - - initialized_ = true; - tab_contents_.reset(CreateTabContents(profile, instance)); - // Attach the native_view now if the view is already added to Widget. - if (GetWidget()) - Attach(tab_contents_->GetNativeView()); - return true; -} - -TabContents* DOMView::CreateTabContents(Profile* profile, - SiteInstance* instance) { - return new TabContents(profile, instance, MSG_ROUTING_NONE, NULL, NULL); -} - -void DOMView::LoadURL(const GURL& url) { - DCHECK(initialized_); - tab_contents_->controller().LoadURL(url, GURL(), PageTransition::START_PAGE); -} - -bool DOMView::SkipDefaultKeyEventProcessing(const views::KeyEvent& e) { - // Don't move the focus to the next view when tab is pressed, we want the - // key event to be propagated to the render view for doing the tab traversal - // there. - return views::FocusManager::IsTabTraversalKeyEvent(e); -} - -void DOMView::Focus() { - tab_contents_->Focus(); -} - -void DOMView::ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child) { - // Attach the native_view when this is added to Widget if - // the native view has not been attached yet and tab_contents_ exists. - views::NativeViewHost::ViewHierarchyChanged(is_add, parent, child); - if (is_add && GetWidget() && !native_view() && tab_contents_.get()) - Attach(tab_contents_->GetNativeView()); - else if (!is_add && child == this && native_view()) - Detach(); -} diff --git a/chrome/browser/views/dom_view.h b/chrome/browser/views/dom_view.h index 4a804f8..095fcb7 100644 --- a/chrome/browser/views/dom_view.h +++ b/chrome/browser/views/dom_view.h @@ -1,59 +1,13 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. -// DOMView is a ChromeView that displays the content of a web DOM. -// It should be used with data: URLs. - #ifndef CHROME_BROWSER_VIEWS_DOM_VIEW_H_ #define CHROME_BROWSER_VIEWS_DOM_VIEW_H_ #pragma once -#include "base/scoped_ptr.h" -#include "googleurl/src/gurl.h" -#include "views/controls/native/native_view_host.h" -#include "views/event.h" - -class Profile; -class SiteInstance; -class TabContents; - -class DOMView : public views::NativeViewHost { - public: - DOMView(); - virtual ~DOMView(); - - // Initialize the view, creating the contents. This should be - // called once the view has been added to a container. - // - // If |instance| is not null, then the view will be loaded in the same - // process as the given instance. - bool Init(Profile* profile, SiteInstance* instance); - - // Loads the given URL into the page. You must have previously called Init(). - void LoadURL(const GURL& url); - - // The tab contents displaying the actual contents. - TabContents* tab_contents() const { return tab_contents_.get(); } - - protected: - // Overridden from View. - virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e); - virtual void Focus(); - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - // Returns new allocated TabContents instance, caller is responsible deleting. - // Override in derived classes to replace TabContents with derivative. - virtual TabContents* CreateTabContents(Profile* profile, - SiteInstance* instance); - - scoped_ptr<TabContents> tab_contents_; - - private: - bool initialized_; - - DISALLOW_COPY_AND_ASSIGN(DOMView); -}; +#include "chrome/browser/ui/views/dom_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_DOM_VIEW_H_ + diff --git a/chrome/browser/views/dom_view_browsertest.cc b/chrome/browser/views/dom_view_browsertest.cc deleted file mode 100644 index 8aa51b6..0000000 --- a/chrome/browser/views/dom_view_browsertest.cc +++ /dev/null @@ -1,93 +0,0 @@ -// 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/browser.h" -#include "chrome/browser/views/dom_view.h" -#include "chrome/test/in_process_browser_test.h" -#include "chrome/test/ui_test_utils.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" - -using namespace views; - -class DOMViewTest : public InProcessBrowserTest { - public: - Widget* CreatePopupWindow() { - Widget* window = - Widget::CreatePopupWidget(Widget::NotTransparent, - Widget::AcceptEvents, - Widget::DeleteOnDestroy, - Widget::DontMirrorOriginInRTL); - window->Init(NULL, gfx::Rect(0, 0, 400, 400)); - return window; - } -}; - -// Tests if creating and deleting dom_view -// does not crash and leak memory. -IN_PROC_BROWSER_TEST_F(DOMViewTest, TestShowAndHide) { - Widget* one = CreatePopupWindow(); - - DOMView* dom_view = new DOMView(); - one->GetRootView()->AddChildView(dom_view); - - dom_view->Init(browser()->profile(), NULL); - dom_view->LoadURL(GURL("http://www.google.com")); - ui_test_utils::WaitForNotification(NotificationType::LOAD_STOP); - one->Show(); - - ui_test_utils::RunAllPendingInMessageLoop(); - - one->Hide(); -} - -// Tests if removing from tree then deleting dom_view -// does not crash and leak memory. -IN_PROC_BROWSER_TEST_F(DOMViewTest, TestRemoveAndDelete) { - Widget* one = CreatePopupWindow(); - - DOMView* dom_view = new DOMView(); - one->GetRootView()->AddChildView(dom_view); - - dom_view->Init(browser()->profile(), NULL); - dom_view->LoadURL(GURL("http://www.google.com")); - ui_test_utils::WaitForNotification(NotificationType::LOAD_STOP); - one->Show(); - - ui_test_utils::RunAllPendingInMessageLoop(); - - one->GetRootView()->RemoveChildView(dom_view); - - delete dom_view; - - one->Hide(); -} - -// Tests if reparenting dom_view does not crash and does not leak -// memory. -IN_PROC_BROWSER_TEST_F(DOMViewTest, TestReparent) { - Widget* one = CreatePopupWindow(); - - DOMView* dom_view = new DOMView(); - one->GetRootView()->AddChildView(dom_view); - - dom_view->Init(browser()->profile(), NULL); - dom_view->LoadURL(GURL("http://www.google.com")); - ui_test_utils::WaitForNotification(NotificationType::LOAD_STOP); - one->Show(); - - ui_test_utils::RunAllPendingInMessageLoop(); - - one->GetRootView()->RemoveChildView(dom_view); - one->Hide(); - - // Re-attach to another Widget. - Widget* two = CreatePopupWindow(); - two->GetRootView()->AddChildView(dom_view); - two->Show(); - - ui_test_utils::RunAllPendingInMessageLoop(); - - two->Hide(); -} diff --git a/chrome/browser/views/download_item_view.cc b/chrome/browser/views/download_item_view.cc deleted file mode 100644 index 3ceaf52..0000000 --- a/chrome/browser/views/download_item_view.cc +++ /dev/null @@ -1,1077 +0,0 @@ -// 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/download_item_view.h" - -#include <vector> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/text_elider.h" -#include "base/callback.h" -#include "base/file_path.h" -#include "base/i18n/rtl.h" -#include "base/metrics/histogram.h" -#include "base/string_util.h" -#include "base/sys_string_conversions.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/download/download_item_model.h" -#include "chrome/browser/download/download_util.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/views/download_shelf_view.h" -#include "gfx/canvas_skia.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/native_button.h" -#include "views/controls/menu/menu_2.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" - -using base::TimeDelta; - -// TODO(paulg): These may need to be adjusted when download progress -// animation is added, and also possibly to take into account -// different screen resolutions. -static const int kTextWidth = 140; // Pixels -static const int kDangerousTextWidth = 200; // Pixels -static const int kHorizontalTextPadding = 2; // Pixels -static const int kVerticalPadding = 3; // Pixels -static const int kVerticalTextSpacer = 2; // Pixels -static const int kVerticalTextPadding = 2; // Pixels - -// The maximum number of characters we show in a file name when displaying the -// dangerous download message. -static const int kFileNameMaxLength = 20; - -// We add some padding before the left image so that the progress animation icon -// hides the corners of the left image. -static const int kLeftPadding = 0; // Pixels. - -// The space between the Save and Discard buttons when prompting for a dangerous -// download. -static const int kButtonPadding = 5; // Pixels. - -// The space on the left and right side of the dangerous download label. -static const int kLabelPadding = 4; // Pixels. - -static const SkColor kFileNameDisabledColor = SkColorSetRGB(171, 192, 212); - -// How long the 'download complete' animation should last for. -static const int kCompleteAnimationDurationMs = 2500; - -// How long we keep the item disabled after the user clicked it to open the -// downloaded item. -static const int kDisabledOnOpenDuration = 3000; - -// Darken light-on-dark download status text by 20% before drawing, thus -// creating a "muted" version of title text for both dark-on-light and -// light-on-dark themes. -static const double kDownloadItemLuminanceMod = 0.8; - -// DownloadShelfContextMenuWin ------------------------------------------------- - -class DownloadShelfContextMenuWin : public DownloadShelfContextMenu { - public: - explicit DownloadShelfContextMenuWin(BaseDownloadItemModel* model) - : DownloadShelfContextMenu(model) { - DCHECK(model); - } - - void Run(const gfx::Point& point) { - if (download_->state() == DownloadItem::COMPLETE) - menu_.reset(new views::Menu2(GetFinishedMenuModel())); - else - menu_.reset(new views::Menu2(GetInProgressMenuModel())); - - // The menu's alignment is determined based on the UI layout. - views::Menu2::Alignment alignment; - if (base::i18n::IsRTL()) - alignment = views::Menu2::ALIGN_TOPRIGHT; - else - alignment = views::Menu2::ALIGN_TOPLEFT; - menu_->RunMenuAt(point, alignment); - } - - // This method runs when the caller has been deleted and we should not attempt - // to access |download_|. - void Stop() { - download_ = NULL; - } - - private: - scoped_ptr<views::Menu2> menu_; -}; - -// DownloadItemView ------------------------------------------------------------ - -DownloadItemView::DownloadItemView(DownloadItem* download, - DownloadShelfView* parent, - BaseDownloadItemModel* model) - : warning_icon_(NULL), - download_(download), - parent_(parent), - status_text_(l10n_util::GetString(IDS_DOWNLOAD_STATUS_STARTING)), - show_status_text_(true), - body_state_(NORMAL), - drop_down_state_(NORMAL), - progress_angle_(download_util::kStartAngleDegrees), - drop_down_pressed_(false), - dragging_(false), - starting_drag_(false), - model_(model), - save_button_(NULL), - discard_button_(NULL), - dangerous_download_label_(NULL), - dangerous_download_label_sized_(false), - disabled_while_opening_(false), - creation_time_(base::Time::Now()), - ALLOW_THIS_IN_INITIALIZER_LIST(reenable_method_factory_(this)), - deleted_(NULL) { - DCHECK(download_); - download_->AddObserver(this); - - ResourceBundle &rb = ResourceBundle::GetSharedInstance(); - - BodyImageSet normal_body_image_set = { - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM) - }; - normal_body_image_set_ = normal_body_image_set; - - DropDownImageSet normal_drop_down_image_set = { - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM) - }; - normal_drop_down_image_set_ = normal_drop_down_image_set; - - BodyImageSet hot_body_image_set = { - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_H) - }; - hot_body_image_set_ = hot_body_image_set; - - DropDownImageSet hot_drop_down_image_set = { - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_H), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_H) - }; - hot_drop_down_image_set_ = hot_drop_down_image_set; - - BodyImageSet pushed_body_image_set = { - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_P) - }; - pushed_body_image_set_ = pushed_body_image_set; - - DropDownImageSet pushed_drop_down_image_set = { - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P) - }; - pushed_drop_down_image_set_ = pushed_drop_down_image_set; - - BodyImageSet dangerous_mode_body_image_set = { - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_NO_DD), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_NO_DD), - rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_NO_DD) - }; - dangerous_mode_body_image_set_ = dangerous_mode_body_image_set; - - LoadIcon(); - tooltip_text_ = download_->GetFileNameToReportUser().ToWStringHack(); - - font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); - box_height_ = std::max<int>(2 * kVerticalPadding + font_.GetHeight() + - kVerticalTextPadding + font_.GetHeight(), - 2 * kVerticalPadding + - normal_body_image_set_.top_left->height() + - normal_body_image_set_.bottom_left->height()); - - if (download_util::kSmallProgressIconSize > box_height_) - box_y_ = (download_util::kSmallProgressIconSize - box_height_) / 2; - else - box_y_ = kVerticalPadding; - - gfx::Size size = GetPreferredSize(); - if (base::i18n::IsRTL()) { - // Drop down button is glued to the left of the download shelf. - drop_down_x_left_ = 0; - drop_down_x_right_ = normal_drop_down_image_set_.top->width(); - } else { - // Drop down button is glued to the right of the download shelf. - drop_down_x_left_ = - size.width() - normal_drop_down_image_set_.top->width(); - drop_down_x_right_ = size.width(); - } - - body_hover_animation_.reset(new SlideAnimation(this)); - drop_hover_animation_.reset(new SlideAnimation(this)); - - if (download->safety_state() == DownloadItem::DANGEROUS) { - tooltip_text_.clear(); - body_state_ = DANGEROUS; - drop_down_state_ = DANGEROUS; - - warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); - save_button_ = new views::NativeButton(this, l10n_util::GetString( - download->is_extension_install() ? - IDS_CONTINUE_EXTENSION_DOWNLOAD : IDS_SAVE_DOWNLOAD)); - save_button_->set_ignore_minimum_size(true); - discard_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_DISCARD_DOWNLOAD)); - discard_button_->set_ignore_minimum_size(true); - AddChildView(save_button_); - AddChildView(discard_button_); - - // Ensure the file name is not too long. - - // Extract the file extension (if any). - FilePath filename(download->target_name()); -#if defined(OS_LINUX) - std::wstring extension = base::SysNativeMBToWide(filename.Extension()); -#else - std::wstring extension = filename.Extension(); -#endif - - // Remove leading '.' - if (extension.length() > 0) - extension = extension.substr(1); -#if defined(OS_LINUX) - std::wstring rootname = - base::SysNativeMBToWide(filename.RemoveExtension().value()); -#else - std::wstring rootname = filename.RemoveExtension().value(); -#endif - - // Elide giant extensions (this shouldn't currently be hit, but might - // in future, should we ever notice unsafe giant extensions). - if (extension.length() > kFileNameMaxLength / 2) - ElideString(extension, kFileNameMaxLength / 2, &extension); - - // The dangerous download label text is different for an extension file. - if (download->is_extension_install()) { - dangerous_download_label_ = new views::Label( - l10n_util::GetString(IDS_PROMPT_DANGEROUS_DOWNLOAD_EXTENSION)); - } else { - ElideString(rootname, kFileNameMaxLength - extension.length(), &rootname); - std::wstring filename = rootname + L"." + extension; - filename = UTF16ToWide(base::i18n::GetDisplayStringInLTRDirectionality( - WideToUTF16(filename))); - dangerous_download_label_ = new views::Label( - l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, filename)); - } - dangerous_download_label_->SetMultiLine(true); - dangerous_download_label_->SetHorizontalAlignment( - views::Label::ALIGN_LEFT); - AddChildView(dangerous_download_label_); - SizeLabelToMinWidth(); - } - - UpdateAccessibleName(); - set_accessibility_focusable(true); - - // Set up our animation. - StartDownloadProgress(); -} - -DownloadItemView::~DownloadItemView() { - if (context_menu_.get()) { - context_menu_->Stop(); - } - icon_consumer_.CancelAllRequests(); - StopDownloadProgress(); - download_->RemoveObserver(this); - if (deleted_) - *deleted_ = true; -} - -// Progress animation handlers. - -void DownloadItemView::UpdateDownloadProgress() { - progress_angle_ = (progress_angle_ + - download_util::kUnknownIncrementDegrees) % - download_util::kMaxDegrees; - SchedulePaint(); -} - -void DownloadItemView::StartDownloadProgress() { - if (progress_timer_.IsRunning()) - return; - progress_timer_.Start( - TimeDelta::FromMilliseconds(download_util::kProgressRateMs), this, - &DownloadItemView::UpdateDownloadProgress); -} - -void DownloadItemView::StopDownloadProgress() { - progress_timer_.Stop(); -} - -// DownloadObserver interface. - -// Update the progress graphic on the icon and our text status label -// to reflect our current bytes downloaded, time remaining. -void DownloadItemView::OnDownloadUpdated(DownloadItem* download) { - DCHECK(download == download_); - - if (body_state_ == DANGEROUS && - download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) { - // We have been approved. - ClearDangerousMode(); - } - - std::wstring status_text = model_->GetStatusText(); - switch (download_->state()) { - case DownloadItem::IN_PROGRESS: - download_->is_paused() ? StopDownloadProgress() : StartDownloadProgress(); - break; - case DownloadItem::COMPLETE: - if (download_->auto_opened()) { - parent_->RemoveDownloadView(this); // This will delete us! - return; - } - StopDownloadProgress(); - complete_animation_.reset(new SlideAnimation(this)); - complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs); - complete_animation_->SetTweenType(Tween::LINEAR); - complete_animation_->Show(); - if (status_text.empty()) - show_status_text_ = false; - SchedulePaint(); - LoadIcon(); - break; - case DownloadItem::CANCELLED: - StopDownloadProgress(); - LoadIcon(); - break; - case DownloadItem::REMOVING: - parent_->RemoveDownloadView(this); // This will delete us! - return; - default: - NOTREACHED(); - } - - status_text_ = status_text; - UpdateAccessibleName(); - - // We use the parent's (DownloadShelfView's) SchedulePaint, since there - // are spaces between each DownloadItemView that the parent is responsible - // for painting. - GetParent()->SchedulePaint(); -} - -void DownloadItemView::OnDownloadOpened(DownloadItem* download) { - disabled_while_opening_ = true; - SetEnabled(false); - MessageLoop::current()->PostDelayedTask( - FROM_HERE, - reenable_method_factory_.NewRunnableMethod(&DownloadItemView::Reenable), - kDisabledOnOpenDuration); - - // Notify our parent. - parent_->OpenedDownload(this); -} - -// View overrides - -// In dangerous mode we have to layout our buttons. -void DownloadItemView::Layout() { - if (IsDangerousMode()) { - dangerous_download_label_->SetColor( - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT)); - - int x = kLeftPadding + dangerous_mode_body_image_set_.top_left->width() + - warning_icon_->width() + kLabelPadding; - int y = (height() - dangerous_download_label_->height()) / 2; - dangerous_download_label_->SetBounds(x, y, - dangerous_download_label_->width(), - dangerous_download_label_->height()); - gfx::Size button_size = GetButtonSize(); - x += dangerous_download_label_->width() + kLabelPadding; - y = (height() - button_size.height()) / 2; - save_button_->SetBounds(x, y, button_size.width(), button_size.height()); - x += button_size.width() + kButtonPadding; - discard_button_->SetBounds(x, y, button_size.width(), button_size.height()); - } -} - -void DownloadItemView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == discard_button_) { - UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", - base::Time::Now() - creation_time_); - if (download_->state() == DownloadItem::IN_PROGRESS) - download_->Cancel(true); - download_->Remove(true); - // WARNING: we are deleted at this point. Don't access 'this'. - } else if (sender == save_button_) { - // The user has confirmed a dangerous download. We'd record how quickly the - // user did this to detect whether we're being clickjacked. - UMA_HISTOGRAM_LONG_TIMES("clickjacking.save_download", - base::Time::Now() - creation_time_); - // This will change the state and notify us. - download_->DangerousDownloadValidated(); - } -} - -// Load an icon for the file type we're downloading, and animate any in progress -// download state. -void DownloadItemView::Paint(gfx::Canvas* canvas) { - BodyImageSet* body_image_set = NULL; - switch (body_state_) { - case NORMAL: - case HOT: - body_image_set = &normal_body_image_set_; - break; - case PUSHED: - body_image_set = &pushed_body_image_set_; - break; - case DANGEROUS: - body_image_set = &dangerous_mode_body_image_set_; - break; - default: - NOTREACHED(); - } - DropDownImageSet* drop_down_image_set = NULL; - switch (drop_down_state_) { - case NORMAL: - case HOT: - drop_down_image_set = &normal_drop_down_image_set_; - break; - case PUSHED: - drop_down_image_set = &pushed_drop_down_image_set_; - break; - case DANGEROUS: - drop_down_image_set = NULL; // No drop-down in dangerous mode. - break; - default: - NOTREACHED(); - } - - int center_width = width() - kLeftPadding - - body_image_set->left->width() - - body_image_set->right->width() - - (drop_down_image_set ? - normal_drop_down_image_set_.center->width() : - 0); - - // May be caused by animation. - if (center_width <= 0) - return; - - // Draw status before button image to effectively lighten text. - if (!IsDangerousMode()) { - if (show_status_text_) { - int mirrored_x = MirroredXWithWidthInsideView( - download_util::kSmallProgressIconSize, kTextWidth); - // Add font_.height() to compensate for title, which is drawn later. - int y = box_y_ + kVerticalPadding + font_.GetHeight() + - kVerticalTextPadding; - SkColor file_name_color = GetThemeProvider()->GetColor( - BrowserThemeProvider::COLOR_BOOKMARK_TEXT); - // If text is light-on-dark, lightening it alone will do nothing. - // Therefore we mute luminance a wee bit before drawing in this case. - if (color_utils::RelativeLuminance(file_name_color) > 0.5) - file_name_color = SkColorSetRGB( - static_cast<int>(kDownloadItemLuminanceMod * - SkColorGetR(file_name_color)), - static_cast<int>(kDownloadItemLuminanceMod * - SkColorGetG(file_name_color)), - static_cast<int>(kDownloadItemLuminanceMod * - SkColorGetB(file_name_color))); - canvas->DrawStringInt(status_text_, font_, file_name_color, - mirrored_x, y, kTextWidth, font_.GetHeight()); - } - } - - // Paint the background images. - int x = kLeftPadding; - canvas->Save(); - if (base::i18n::IsRTL()) { - // Since we do not have the mirrored images for - // (hot_)body_image_set->top_left, (hot_)body_image_set->left, - // (hot_)body_image_set->bottom_left, and drop_down_image_set, - // for RTL UI, we flip the canvas to draw those images mirrored. - // Consequently, we do not need to mirror the x-axis of those images. - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } - PaintBitmaps(canvas, - body_image_set->top_left, body_image_set->left, - body_image_set->bottom_left, - x, box_y_, box_height_, body_image_set->top_left->width()); - x += body_image_set->top_left->width(); - PaintBitmaps(canvas, - body_image_set->top, body_image_set->center, - body_image_set->bottom, - x, box_y_, box_height_, center_width); - x += center_width; - PaintBitmaps(canvas, - body_image_set->top_right, body_image_set->right, - body_image_set->bottom_right, - x, box_y_, box_height_, body_image_set->top_right->width()); - - // Overlay our body hot state. - if (body_hover_animation_->GetCurrentValue() > 0) { - canvas->SaveLayerAlpha( - static_cast<int>(body_hover_animation_->GetCurrentValue() * 255)); - canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); - - int x = kLeftPadding; - PaintBitmaps(canvas, - hot_body_image_set_.top_left, hot_body_image_set_.left, - hot_body_image_set_.bottom_left, - x, box_y_, box_height_, hot_body_image_set_.top_left->width()); - x += body_image_set->top_left->width(); - PaintBitmaps(canvas, - hot_body_image_set_.top, hot_body_image_set_.center, - hot_body_image_set_.bottom, - x, box_y_, box_height_, center_width); - x += center_width; - PaintBitmaps(canvas, - hot_body_image_set_.top_right, hot_body_image_set_.right, - hot_body_image_set_.bottom_right, - x, box_y_, box_height_, - hot_body_image_set_.top_right->width()); - canvas->Restore(); - } - - x += body_image_set->top_right->width(); - - // Paint the drop-down. - if (drop_down_image_set) { - PaintBitmaps(canvas, - drop_down_image_set->top, drop_down_image_set->center, - drop_down_image_set->bottom, - x, box_y_, box_height_, drop_down_image_set->top->width()); - - // Overlay our drop-down hot state. - if (drop_hover_animation_->GetCurrentValue() > 0) { - canvas->SaveLayerAlpha( - static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255)); - canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, - SkXfermode::kClear_Mode); - - PaintBitmaps(canvas, - drop_down_image_set->top, drop_down_image_set->center, - drop_down_image_set->bottom, - x, box_y_, box_height_, drop_down_image_set->top->width()); - - canvas->Restore(); - } - } - - // Restore the canvas to avoid file name etc. text are drawn flipped. - // Consequently, the x-axis of following canvas->DrawXXX() method should be - // mirrored so the text and images are down in the right positions. - canvas->Restore(); - - // Print the text, left aligned and always print the file extension. - // Last value of x was the end of the right image, just before the button. - // Note that in dangerous mode we use a label (as the text is multi-line). - if (!IsDangerousMode()) { - string16 filename; - if (!disabled_while_opening_) { - filename = gfx::ElideFilename(download_->GetFileNameToReportUser(), - font_, kTextWidth); - } else { - // First, Calculate the download status opening string width. - std::wstring empty_string; - std::wstring status_string = - l10n_util::GetStringF(IDS_DOWNLOAD_STATUS_OPENING, empty_string); - int status_string_width = font_.GetStringWidth(status_string); - // Then, elide the file name. - string16 filename_string = - gfx::ElideFilename(download_->GetFileNameToReportUser(), font_, - kTextWidth - status_string_width); - // Last, concat the whole string. - filename = l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING, - filename_string); - } - - int mirrored_x = MirroredXWithWidthInsideView( - download_util::kSmallProgressIconSize, kTextWidth); - SkColor file_name_color = GetThemeProvider()->GetColor( - BrowserThemeProvider::COLOR_BOOKMARK_TEXT); - int y = - box_y_ + (show_status_text_ ? kVerticalPadding : - (box_height_ - font_.GetHeight()) / 2); - - // Draw the file's name. - canvas->DrawStringInt(UTF16ToWide(filename), font_, - IsEnabled() ? file_name_color : - kFileNameDisabledColor, - mirrored_x, y, kTextWidth, font_.GetHeight()); - } - - // Paint the icon. - IconManager* im = g_browser_process->icon_manager(); - SkBitmap* icon = IsDangerousMode() ? warning_icon_ : - im->LookupIcon(download_->GetUserVerifiedFileName(), IconLoader::SMALL); - - // We count on the fact that the icon manager will cache the icons and if one - // is available, it will be cached here. We *don't* want to request the icon - // to be loaded here, since this will also get called if the icon can't be - // loaded, in which case LookupIcon will always be NULL. The loading will be - // triggered only when we think the status might change. - if (icon) { - if (!IsDangerousMode()) { - if (download_->state() == DownloadItem::IN_PROGRESS) { - download_util::PaintDownloadProgress(canvas, this, 0, 0, - progress_angle_, - download_->PercentComplete(), - download_util::SMALL); - } else if (download_->state() == DownloadItem::COMPLETE && - complete_animation_.get() && - complete_animation_->is_animating()) { - download_util::PaintDownloadComplete(canvas, this, 0, 0, - complete_animation_->GetCurrentValue(), - download_util::SMALL); - } - } - - // Draw the icon image. - int mirrored_x = MirroredXWithWidthInsideView( - download_util::kSmallProgressIconOffset, icon->width()); - if (IsEnabled()) { - canvas->DrawBitmapInt(*icon, mirrored_x, - download_util::kSmallProgressIconOffset); - } else { - // Use an alpha to make the image look disabled. - SkPaint paint; - paint.setAlpha(120); - canvas->DrawBitmapInt(*icon, mirrored_x, - download_util::kSmallProgressIconOffset, paint); - } - } -} - -void DownloadItemView::PaintBitmaps(gfx::Canvas* canvas, - const SkBitmap* top_bitmap, - const SkBitmap* center_bitmap, - const SkBitmap* bottom_bitmap, - int x, int y, int height, int width) { - int middle_height = height - top_bitmap->height() - bottom_bitmap->height(); - // Draw the top. - canvas->DrawBitmapInt(*top_bitmap, - 0, 0, top_bitmap->width(), top_bitmap->height(), - x, y, width, top_bitmap->height(), false); - y += top_bitmap->height(); - // Draw the center. - canvas->DrawBitmapInt(*center_bitmap, - 0, 0, center_bitmap->width(), center_bitmap->height(), - x, y, width, middle_height, false); - y += middle_height; - // Draw the bottom. - canvas->DrawBitmapInt(*bottom_bitmap, - 0, 0, bottom_bitmap->width(), bottom_bitmap->height(), - x, y, width, bottom_bitmap->height(), false); -} - -void DownloadItemView::SetState(State body_state, State drop_down_state) { - if (body_state_ == body_state && drop_down_state_ == drop_down_state) - return; - - body_state_ = body_state; - drop_down_state_ = drop_down_state; - SchedulePaint(); -} - -void DownloadItemView::ClearDangerousMode() { - DCHECK(download_->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED && - body_state_ == DANGEROUS && drop_down_state_ == DANGEROUS); - - body_state_ = NORMAL; - drop_down_state_ = NORMAL; - - // Remove the views used by the dangerous mode. - RemoveChildView(save_button_); - delete save_button_; - save_button_ = NULL; - RemoveChildView(discard_button_); - delete discard_button_; - discard_button_ = NULL; - RemoveChildView(dangerous_download_label_); - delete dangerous_download_label_; - dangerous_download_label_ = NULL; - - // Set the accessible name back to the status and filename instead of the - // download warning. - UpdateAccessibleName(); - - // We need to load the icon now that the download_ has the real path. - LoadIcon(); - tooltip_text_ = download_->GetFileNameToReportUser().ToWStringHack(); - - // Force the shelf to layout again as our size has changed. - parent_->Layout(); - parent_->SchedulePaint(); -} - -gfx::Size DownloadItemView::GetPreferredSize() { - int width, height; - - // First, we set the height to the height of two rows or text plus margins. - height = 2 * kVerticalPadding + 2 * font_.GetHeight() + kVerticalTextPadding; - // Then we increase the size if the progress icon doesn't fit. - height = std::max<int>(height, download_util::kSmallProgressIconSize); - - if (IsDangerousMode()) { - width = kLeftPadding + dangerous_mode_body_image_set_.top_left->width(); - width += warning_icon_->width() + kLabelPadding; - width += dangerous_download_label_->width() + kLabelPadding; - gfx::Size button_size = GetButtonSize(); - // Make sure the button fits. - height = std::max<int>(height, 2 * kVerticalPadding + button_size.height()); - // Then we make sure the warning icon fits. - height = std::max<int>(height, 2 * kVerticalPadding + - warning_icon_->height()); - width += button_size.width() * 2 + kButtonPadding; - width += dangerous_mode_body_image_set_.top_right->width(); - } else { - width = kLeftPadding + normal_body_image_set_.top_left->width(); - width += download_util::kSmallProgressIconSize; - width += kTextWidth; - width += normal_body_image_set_.top_right->width(); - width += normal_drop_down_image_set_.top->width(); - } - return gfx::Size(width, height); -} - -void DownloadItemView::OnMouseExited(const views::MouseEvent& event) { - // Mouse should not activate us in dangerous mode. - if (IsDangerousMode()) - return; - - SetState(NORMAL, drop_down_pressed_ ? PUSHED : NORMAL); - body_hover_animation_->Hide(); - drop_hover_animation_->Hide(); -} - -// Handle a mouse click and open the context menu if the mouse is -// over the drop-down region. -bool DownloadItemView::OnMousePressed(const views::MouseEvent& event) { - // Mouse should not activate us in dangerous mode. - if (IsDangerousMode()) - return true; - - // Stop any completion animation. - if (complete_animation_.get() && complete_animation_->is_animating()) - complete_animation_->End(); - - if (event.IsOnlyLeftMouseButton()) { - if (!InDropDownButtonXCoordinateRange(event.x())) { - SetState(PUSHED, NORMAL); - return true; - } - - ShowContextMenu(event.location(), false); - } - return true; -} - -void DownloadItemView::OnMouseMoved(const views::MouseEvent& event) { - // Mouse should not activate us in dangerous mode. - if (IsDangerousMode()) - return; - - bool on_body = !InDropDownButtonXCoordinateRange(event.x()); - SetState(on_body ? HOT : NORMAL, on_body ? NORMAL : HOT); - if (on_body) { - body_hover_animation_->Show(); - drop_hover_animation_->Hide(); - } else { - body_hover_animation_->Hide(); - drop_hover_animation_->Show(); - } -} - -void DownloadItemView::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - // Mouse should not activate us in dangerous mode. - if (IsDangerousMode()) - return; - - if (dragging_) { - // Starting a drag results in a MouseReleased, we need to ignore it. - dragging_ = false; - starting_drag_ = false; - return; - } - if (event.IsOnlyLeftMouseButton() && - !InDropDownButtonXCoordinateRange(event.x())) { - OpenDownload(); - } - - SetState(NORMAL, NORMAL); -} - -// Handle drag (file copy) operations. -bool DownloadItemView::OnMouseDragged(const views::MouseEvent& event) { - // Mouse should not activate us in dangerous mode. - if (IsDangerousMode()) - return true; - - if (!starting_drag_) { - starting_drag_ = true; - drag_start_point_ = event.location(); - } - if (dragging_) { - if (download_->state() == DownloadItem::COMPLETE) { - IconManager* im = g_browser_process->icon_manager(); - SkBitmap* icon = im->LookupIcon(download_->GetUserVerifiedFileName(), - IconLoader::SMALL); - if (icon) { - views::Widget* widget = GetWidget(); - download_util::DragDownload(download_, icon, - widget ? widget->GetNativeView() : NULL); - } - } - } else if (ExceededDragThreshold( - event.location().x() - drag_start_point_.x(), - event.location().y() - drag_start_point_.y())) { - dragging_ = true; - } - return true; -} - -bool DownloadItemView::OnKeyPressed(const views::KeyEvent& e) { - // Key press should not activate us in dangerous mode. - if (IsDangerousMode()) - return true; - - if (e.GetKeyCode() == app::VKEY_SPACE || - e.GetKeyCode() == app::VKEY_RETURN) { - OpenDownload(); - return true; - } - return false; -} - -void DownloadItemView::ShowContextMenu(const gfx::Point& p, - bool is_mouse_gesture) { - gfx::Point point = p; - drop_down_pressed_ = true; - SetState(NORMAL, PUSHED); - - // Similar hack as in MenuButton. - // We're about to show the menu from a mouse press. By showing from the - // mouse press event we block RootView in mouse dispatching. This also - // appears to cause RootView to get a mouse pressed BEFORE the mouse - // release is seen, which means RootView sends us another mouse press no - // matter where the user pressed. To force RootView to recalculate the - // mouse target during the mouse press we explicitly set the mouse handler - // to NULL. - GetRootView()->SetMouseHandler(NULL); - - // The menu's position is different depending on the UI layout. - // DownloadShelfContextMenu will take care of setting the right anchor for - // the menu depending on the locale. - point.set_y(height()); - if (base::i18n::IsRTL()) - point.set_x(drop_down_x_right_); - else - point.set_x(drop_down_x_left_); - - views::View::ConvertPointToScreen(this, &point); - - if (!context_menu_.get()) - context_menu_.reset(new DownloadShelfContextMenuWin(model_.get())); - // When we call the Run method on the menu, it runs an inner message loop - // that might causes us to be deleted. - bool deleted = false; - deleted_ = &deleted; - context_menu_->Run(point); - if (deleted) - return; // We have been deleted! Don't access 'this'. - deleted_ = NULL; - - // If the menu action was to remove the download, this view will also be - // invalid so we must not access 'this' in this case. - if (context_menu_->download()) { - drop_down_pressed_ = false; - // Showing the menu blocks. Here we revert the state. - SetState(NORMAL, NORMAL); - } -} - -AccessibilityTypes::Role DownloadItemView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PUSHBUTTON; -} - -AccessibilityTypes::State DownloadItemView::GetAccessibleState() { - if (download_->safety_state() == DownloadItem::DANGEROUS) { - return AccessibilityTypes::STATE_UNAVAILABLE; - } else { - return AccessibilityTypes::STATE_HASPOPUP; - } -} - -void DownloadItemView::AnimationProgressed(const Animation* animation) { - // We don't care if what animation (body button/drop button/complete), - // is calling back, as they all have to go through the same paint call. - SchedulePaint(); -} - -void DownloadItemView::OpenDownload() { - // We're interested in how long it takes users to open downloads. If they - // open downloads super quickly, we should be concerned about clickjacking. - UMA_HISTOGRAM_LONG_TIMES("clickjacking.open_download", - base::Time::Now() - creation_time_); - download_->OpenDownload(); - UpdateAccessibleName(); -} - -void DownloadItemView::OnExtractIconComplete(IconManager::Handle handle, - SkBitmap* icon_bitmap) { - if (icon_bitmap) - GetParent()->SchedulePaint(); -} - -void DownloadItemView::LoadIcon() { - IconManager* im = g_browser_process->icon_manager(); - im->LoadIcon(download_->GetUserVerifiedFileName(), - IconLoader::SMALL, &icon_consumer_, - NewCallback(this, &DownloadItemView::OnExtractIconComplete)); -} - -bool DownloadItemView::GetTooltipText(const gfx::Point& p, - std::wstring* tooltip) { - if (tooltip_text_.empty()) - return false; - - tooltip->assign(tooltip_text_); - return true; -} - -gfx::Size DownloadItemView::GetButtonSize() { - DCHECK(save_button_ && discard_button_); - gfx::Size size; - - // We cache the size when successfully retrieved, not for performance reasons - // but because if this DownloadItemView is being animated while the tab is - // not showing, the native buttons are not parented and their preferred size - // is 0, messing-up the layout. - if (cached_button_size_.width() != 0) - return cached_button_size_; - - size = save_button_->GetMinimumSize(); - gfx::Size discard_size = discard_button_->GetMinimumSize(); - - size.SetSize(std::max(size.width(), discard_size.width()), - std::max(size.height(), discard_size.height())); - - if (size.width() != 0) - cached_button_size_ = size; - - return size; -} - -// This method computes the minimum width of the label for displaying its text -// on 2 lines. It just breaks the string in 2 lines on the spaces and keeps the -// configuration with minimum width. -void DownloadItemView::SizeLabelToMinWidth() { - if (dangerous_download_label_sized_) - return; - - std::wstring text = dangerous_download_label_->GetText(); - TrimWhitespace(text, TRIM_ALL, &text); - DCHECK_EQ(std::wstring::npos, text.find(L"\n")); - - // Make the label big so that GetPreferredSize() is not constrained by the - // current width. - dangerous_download_label_->SetBounds(0, 0, 1000, 1000); - - gfx::Size size; - int min_width = -1; - size_t sp_index = text.find(L" "); - while (sp_index != std::wstring::npos) { - text.replace(sp_index, 1, L"\n"); - dangerous_download_label_->SetText(text); - size = dangerous_download_label_->GetPreferredSize(); - - if (min_width == -1) - min_width = size.width(); - - // If the width is growing again, it means we passed the optimal width spot. - if (size.width() > min_width) - break; - else - min_width = size.width(); - - // Restore the string. - text.replace(sp_index, 1, L" "); - - sp_index = text.find(L" ", sp_index + 1); - } - - // If we have a line with no space, we won't cut it. - if (min_width == -1) - size = dangerous_download_label_->GetPreferredSize(); - - dangerous_download_label_->SetBounds(0, 0, size.width(), size.height()); - dangerous_download_label_sized_ = true; -} - -void DownloadItemView::Reenable() { - disabled_while_opening_ = false; - SetEnabled(true); // Triggers a repaint. -} - -bool DownloadItemView::InDropDownButtonXCoordinateRange(int x) { - if (x > drop_down_x_left_ && x < drop_down_x_right_) - return true; - return false; -} - -void DownloadItemView::UpdateAccessibleName() { - std::wstring current_name; - GetAccessibleName(¤t_name); - - std::wstring new_name; - if (download_->safety_state() == DownloadItem::DANGEROUS) { - new_name = dangerous_download_label_->GetText(); - } else { - new_name = status_text_ + L" " + - download_->GetFileNameToReportUser().ToWStringHack(); - } - - // If the name has changed, call SetAccessibleName and notify - // assistive technology that the name has changed so they can - // announce it immediately. - if (new_name != current_name) { - SetAccessibleName(new_name); - if (GetWidget()) - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_NAME_CHANGED); - } -} diff --git a/chrome/browser/views/download_item_view.h b/chrome/browser/views/download_item_view.h index bd76c0d..cb7dd5c 100644 --- a/chrome/browser/views/download_item_view.h +++ b/chrome/browser/views/download_item_view.h @@ -1,276 +1,13 @@ // 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. -// -// A ChromeView that implements one download on the Download shelf. -// Each DownloadItemView contains an application icon, a text label -// indicating the download's file name, a text label indicating the -// download's status (such as the number of bytes downloaded so far) -// and a button for canceling an in progress download, or opening -// the completed download. -// -// The DownloadItemView lives in the Browser, and has a corresponding -// DownloadController that receives / writes data which lives in the -// Renderer. -#ifndef CHROME_BROWSER_VIEWS_DOWNLOAD_ITEM_VIEW_H__ -#define CHROME_BROWSER_VIEWS_DOWNLOAD_ITEM_VIEW_H__ +#ifndef CHROME_BROWSER_VIEWS_DOWNLOAD_ITEM_VIEW_H_ +#define CHROME_BROWSER_VIEWS_DOWNLOAD_ITEM_VIEW_H_ #pragma once -#include <string> +#include "chrome/browser/ui/views/download_item_view.h" +// TODO(beng): remove this file once all includes have been updated. -#include "app/slide_animation.h" -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/time.h" -#include "base/timer.h" -#include "chrome/browser/cancelable_request.h" -#include "chrome/browser/download/download_item.h" -#include "chrome/browser/download/download_manager.h" -#include "chrome/browser/icon_manager.h" -#include "gfx/font.h" -#include "views/event.h" -#include "views/controls/button/button.h" -#include "views/view.h" +#endif // CHROME_BROWSER_VIEWS_DOWNLOAD_ITEM_VIEW_H_ -namespace views { -class Label; -class NativeButton; -} -class BaseDownloadItemModel; -class DownloadShelfView; -class SkBitmap; -class DownloadShelfContextMenuWin; - -class DownloadItemView : public views::ButtonListener, - public views::View, - public DownloadItem::Observer, - public AnimationDelegate { - public: - DownloadItemView(DownloadItem* download, - DownloadShelfView* parent, - BaseDownloadItemModel* model); - virtual ~DownloadItemView(); - - // DownloadObserver method - virtual void OnDownloadUpdated(DownloadItem* download); - virtual void OnDownloadFileCompleted(DownloadItem* download) { } - virtual void OnDownloadOpened(DownloadItem* download); - - // View overrides - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - virtual gfx::Size GetPreferredSize(); - virtual void OnMouseExited(const views::MouseEvent& event); - virtual void OnMouseMoved(const views::MouseEvent& event); - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - virtual bool OnMouseDragged(const views::MouseEvent& event); - virtual bool OnKeyPressed(const views::KeyEvent& e); - virtual void ShowContextMenu(const gfx::Point& p, bool is_mouse_gesture); - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual AccessibilityTypes::State GetAccessibleState(); - - // ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // AnimationDelegate implementation. - virtual void AnimationProgressed(const Animation* animation); - - // Timer callback for handling animations - void UpdateDownloadProgress(); - void StartDownloadProgress(); - void StopDownloadProgress(); - - // IconManager::Client interface. - void OnExtractIconComplete(IconManager::Handle handle, SkBitmap* icon_bitmap); - - // Returns the DownloadItem model object belonging to this item. - DownloadItem* download() const { return download_; } - - private: - enum State { - NORMAL = 0, - HOT, - PUSHED, - DANGEROUS - }; - - // The image set associated with the part containing the icon and text. - struct BodyImageSet { - SkBitmap* top_left; - SkBitmap* left; - SkBitmap* bottom_left; - SkBitmap* top; - SkBitmap* center; - SkBitmap* bottom; - SkBitmap* top_right; - SkBitmap* right; - SkBitmap* bottom_right; - }; - - // The image set associated with the drop-down button on the right. - struct DropDownImageSet { - SkBitmap* top; - SkBitmap* center; - SkBitmap* bottom; - }; - - void OpenDownload(); - - void LoadIcon(); - - virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip); - - // Convenience method to paint the 3 vertical bitmaps (bottom, middle, top) - // that form the background. - void PaintBitmaps(gfx::Canvas* canvas, - const SkBitmap* top_bitmap, - const SkBitmap* center_bitmap, - const SkBitmap* bottom_bitmap, - int x, - int y, - int height, - int width); - - // Sets the state and triggers a repaint. - void SetState(State body_state, State drop_down_state); - - // Whether we are in the dangerous mode. - bool IsDangerousMode() { return body_state_ == DANGEROUS; } - - // Reverts from dangerous mode to normal download mode. - void ClearDangerousMode(); - - // Sets |size| with the size of the Save and Discard buttons (they have the - // same size). - gfx::Size GetButtonSize(); - - // Sizes the dangerous download label to a minimum width available using 2 - // lines. The size is computed only the first time this method is invoked - // and simply returned on subsequent calls. - void SizeLabelToMinWidth(); - - // Reenables the item after it has been disabled when a user clicked it to - // open the downloaded file. - void Reenable(); - - // Given |x|, returns whether |x| is within the x coordinate range of - // the drop-down button or not. - bool InDropDownButtonXCoordinateRange(int x); - - // Update the accessible name to reflect the current state of the control, - // so that screenreaders can access the filename, status text, and - // dangerous download warning message (if any). - void UpdateAccessibleName(); - - // The different images used for the background. - BodyImageSet normal_body_image_set_; - BodyImageSet hot_body_image_set_; - BodyImageSet pushed_body_image_set_; - BodyImageSet dangerous_mode_body_image_set_; - DropDownImageSet normal_drop_down_image_set_; - DropDownImageSet hot_drop_down_image_set_; - DropDownImageSet pushed_drop_down_image_set_; - - // The warning icon showns for dangerous downloads. - SkBitmap* warning_icon_; - - // The model we query for display information - DownloadItem* download_; - - // Our parent view that owns us. - DownloadShelfView* parent_; - - // Elements of our particular download - std::wstring status_text_; - bool show_status_text_; - - // The font used to print the file name and status. - gfx::Font font_; - - // The tooltip. - std::wstring tooltip_text_; - - // The current state (normal, hot or pushed) of the body and drop-down. - State body_state_; - State drop_down_state_; - - // In degrees, for downloads with no known total size. - int progress_angle_; - - // The left and right x coordinates of the drop-down button. - int drop_down_x_left_; - int drop_down_x_right_; - - // Used when we are showing the menu to show the drop-down as pressed. - bool drop_down_pressed_; - - // The height of the box formed by the background images and its labels. - int box_height_; - - // The y coordinate of the box formed by the background images and its labels. - int box_y_; - - // Whether we are dragging the download button. - bool dragging_; - - // Whether we are tracking a possible drag. - bool starting_drag_; - - // Position that a possible drag started at. - gfx::Point drag_start_point_; - - // For canceling an in progress icon request. - CancelableRequestConsumerT<int, 0> icon_consumer_; - - // A model class to control the status text we display and the cancel - // behavior. - // This class owns the pointer. - scoped_ptr<BaseDownloadItemModel> model_; - - // Hover animations for our body and drop buttons. - scoped_ptr<SlideAnimation> body_hover_animation_; - scoped_ptr<SlideAnimation> drop_hover_animation_; - - // Animation for download complete. - scoped_ptr<SlideAnimation> complete_animation_; - - // Progress animation - base::RepeatingTimer<DownloadItemView> progress_timer_; - - // Dangerous mode buttons. - views::NativeButton* save_button_; - views::NativeButton* discard_button_; - - // Dangerous mode label. - views::Label* dangerous_download_label_; - - // Whether the dangerous mode label has been sized yet. - bool dangerous_download_label_sized_; - - // The size of the buttons. Cached so animation works when hidden. - gfx::Size cached_button_size_; - - // Whether we are currently disabled as part of opening the downloaded file. - bool disabled_while_opening_; - - // The time at which this view was created. - base::Time creation_time_; - - // Method factory used to delay reenabling of the item when opening the - // downloaded file. - ScopedRunnableMethodFactory<DownloadItemView> reenable_method_factory_; - - // The currently running download context menu. - scoped_ptr<DownloadShelfContextMenuWin> context_menu_; - - // If non-NULL, set to true when this object is deleted. - // (Used when showing the context menu as it runs an inner message loop that - // might delete us). - bool* deleted_; - - DISALLOW_COPY_AND_ASSIGN(DownloadItemView); -}; - -#endif // CHROME_BROWSER_VIEWS_DOWNLOAD_ITEM_VIEW_H__ diff --git a/chrome/browser/views/download_shelf_view.cc b/chrome/browser/views/download_shelf_view.cc deleted file mode 100644 index 43df5c7..0000000 --- a/chrome/browser/views/download_shelf_view.cc +++ /dev/null @@ -1,439 +0,0 @@ -// 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/download_shelf_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/logging.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/download/download_item.h" -#include "chrome/browser/download/download_item_model.h" -#include "chrome/browser/download/download_manager.h" -#include "chrome/browser/tab_contents/navigation_entry.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/download_item_view.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "gfx/canvas.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/background.h" -#include "views/controls/button/image_button.h" -#include "views/controls/image_view.h" - -// Max number of download views we'll contain. Any time a view is added and -// we already have this many download views, one is removed. -static const size_t kMaxDownloadViews = 15; - -// Padding from left edge and first download view. -static const int kLeftPadding = 2; - -// Padding from right edge and close button/show downloads link. -static const int kRightPadding = 10; - -// Padding between the show all link and close button. -static const int kCloseAndLinkPadding = 14; - -// Padding between the download views. -static const int kDownloadPadding = 10; - -// Padding between the top/bottom and the content. -static const int kTopBottomPadding = 2; - -// Padding between the icon and 'show all downloads' link -static const int kDownloadsTitlePadding = 4; - -// Border color. -static const SkColor kBorderColor = SkColorSetRGB(214, 214, 214); - -// New download item animation speed in milliseconds. -static const int kNewItemAnimationDurationMs = 800; - -// Shelf show/hide speed. -static const int kShelfAnimationDurationMs = 120; - -// Amount of time to delay if the mouse leaves the shelf by way of entering -// another window. This is much larger than the normal delay as openning a -// download is most likely going to trigger a new window to appear over the -// button. Delay the time so that the user has a chance to quickly close the -// other app and return to chrome with the download shelf still open. -static const int kNotifyOnExitTimeMS = 5000; - -namespace { - -// Sets size->width() to view's preferred width + size->width().s -// Sets size->height() to the max of the view's preferred height and -// size->height(); -void AdjustSize(views::View* view, gfx::Size* size) { - gfx::Size view_preferred = view->GetPreferredSize(); - size->Enlarge(view_preferred.width(), 0); - size->set_height(std::max(view_preferred.height(), size->height())); -} - -int CenterPosition(int size, int target_size) { - return std::max((target_size - size) / 2, kTopBottomPadding); -} - -} // namespace - -DownloadShelfView::DownloadShelfView(Browser* browser, BrowserView* parent) - : browser_(browser), - parent_(parent), - ALLOW_THIS_IN_INITIALIZER_LIST( - mouse_watcher_(this, this, gfx::Insets())) { - mouse_watcher_.set_notify_on_exit_time_ms(kNotifyOnExitTimeMS); - SetID(VIEW_ID_DOWNLOAD_SHELF); - parent->AddChildView(this); - Init(); -} - -DownloadShelfView::~DownloadShelfView() { - parent_->RemoveChildView(this); -} - -void DownloadShelfView::Init() { - ResourceBundle &rb = ResourceBundle::GetSharedInstance(); - arrow_image_ = new views::ImageView(); - arrow_image_->SetImage(rb.GetBitmapNamed(IDR_DOWNLOADS_FAVICON)); - AddChildView(arrow_image_); - - show_all_view_ = - new views::Link(l10n_util::GetString(IDS_SHOW_ALL_DOWNLOADS)); - show_all_view_->SetController(this); - AddChildView(show_all_view_); - - close_button_ = new views::ImageButton(this); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_CLOSE_BAR)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); - close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); - UpdateButtonColors(); - AddChildView(close_button_); - - new_item_animation_.reset(new SlideAnimation(this)); - new_item_animation_->SetSlideDuration(kNewItemAnimationDurationMs); - - shelf_animation_.reset(new SlideAnimation(this)); - shelf_animation_->SetSlideDuration(kShelfAnimationDurationMs); - Show(); -} - -void DownloadShelfView::AddDownloadView(DownloadItemView* view) { - mouse_watcher_.Stop(); - - Show(); - - DCHECK(view); - download_views_.push_back(view); - AddChildView(view); - if (download_views_.size() > kMaxDownloadViews) - RemoveDownloadView(*download_views_.begin()); - - new_item_animation_->Reset(); - new_item_animation_->Show(); -} - -void DownloadShelfView::AddDownload(BaseDownloadItemModel* download_model) { - DownloadItemView* view = new DownloadItemView( - download_model->download(), this, download_model); - AddDownloadView(view); -} - -void DownloadShelfView::MouseMovedOutOfView() { - Close(); -} - -void DownloadShelfView::FocusWillChange(views::View* focused_before, - views::View* focused_now) { - SchedulePaintForDownloadItem(focused_before); - SchedulePaintForDownloadItem(focused_now); - AccessiblePaneView::FocusWillChange(focused_before, focused_now); -} - -void DownloadShelfView::RemoveDownloadView(View* view) { - DCHECK(view); - std::vector<DownloadItemView*>::iterator i = - find(download_views_.begin(), download_views_.end(), view); - DCHECK(i != download_views_.end()); - download_views_.erase(i); - RemoveChildView(view); - delete view; - if (download_views_.empty()) - Close(); - else if (CanAutoClose()) - mouse_watcher_.Start(); - Layout(); - SchedulePaint(); -} - -views::View* DownloadShelfView::GetDefaultFocusableChild() { - if (!download_views_.empty()) - return download_views_[0]; - else - return show_all_view_; -} - -void DownloadShelfView::Paint(gfx::Canvas* canvas) { - PaintBackground(canvas); - PaintBorder(canvas); - - // Draw the focus rect here, since it's outside the bounds of the item. - for (size_t i = 0; i < download_views_.size(); ++i) { - if (download_views_[i]->HasFocus()) { - gfx::Rect r = GetFocusRectBounds(download_views_[i]); - canvas->DrawFocusRect(r.x(), r.y(), r.width(), r.height() - 1); - break; - } - } -} - -void DownloadShelfView::PaintBorder(gfx::Canvas* canvas) { - canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); -} - -void DownloadShelfView::OpenedDownload(DownloadItemView* view) { - if (CanAutoClose()) - mouse_watcher_.Start(); -} - -gfx::Size DownloadShelfView::GetPreferredSize() { - gfx::Size prefsize(kRightPadding + kLeftPadding + kCloseAndLinkPadding, 0); - AdjustSize(close_button_, &prefsize); - AdjustSize(show_all_view_, &prefsize); - // Add one download view to the preferred size. - if (download_views_.size() > 0) { - AdjustSize(*download_views_.begin(), &prefsize); - prefsize.Enlarge(kDownloadPadding, 0); - } - prefsize.Enlarge(0, kTopBottomPadding + kTopBottomPadding); - if (shelf_animation_->is_animating()) { - prefsize.set_height(static_cast<int>( - static_cast<double>(prefsize.height()) * - shelf_animation_->GetCurrentValue())); - } - return prefsize; -} - -void DownloadShelfView::AnimationProgressed(const Animation *animation) { - if (animation == new_item_animation_.get()) { - Layout(); - SchedulePaint(); - } else if (animation == shelf_animation_.get()) { - // Force a re-layout of the parent, which will call back into - // GetPreferredSize, where we will do our animation. In the case where the - // animation is hiding, we do a full resize - the fast resizing would - // otherwise leave blank white areas where the shelf was and where the - // user's eye is. Thankfully bottom-resizing is a lot faster than - // top-resizing. - parent_->SelectedTabToolbarSizeChanged(shelf_animation_->IsShowing()); - } -} - -void DownloadShelfView::AnimationEnded(const Animation *animation) { - if (animation == shelf_animation_.get()) { - parent_->SetDownloadShelfVisible(shelf_animation_->IsShowing()); - if (!shelf_animation_->IsShowing()) - Closed(); - } -} - -void DownloadShelfView::Layout() { - // Now that we know we have a parent, we can safely set our theme colors. - show_all_view_->SetColor( - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT)); - set_background(views::Background::CreateSolidBackground( - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR))); - - // Let our base class layout our child views - views::View::Layout(); - - // If there is not enough room to show the first download item, show the - // "Show all downloads" link to the left to make it more visible that there is - // something to see. - bool show_link_only = !CanFitFirstDownloadItem(); - - gfx::Size image_size = arrow_image_->GetPreferredSize(); - gfx::Size close_button_size = close_button_->GetPreferredSize(); - gfx::Size show_all_size = show_all_view_->GetPreferredSize(); - int max_download_x = - std::max<int>(0, width() - kRightPadding - close_button_size.width() - - kCloseAndLinkPadding - show_all_size.width() - - kDownloadsTitlePadding - image_size.width() - - kDownloadPadding); - int next_x = show_link_only ? kLeftPadding : - max_download_x + kDownloadPadding; - // Align vertically with show_all_view_. - arrow_image_->SetBounds(next_x, - CenterPosition(show_all_size.height(), height()), - image_size.width(), image_size.height()); - next_x += image_size.width() + kDownloadsTitlePadding; - show_all_view_->SetBounds(next_x, - CenterPosition(show_all_size.height(), height()), - show_all_size.width(), - show_all_size.height()); - next_x += show_all_size.width() + kCloseAndLinkPadding; - close_button_->SetBounds(next_x, - CenterPosition(close_button_size.height(), height()), - close_button_size.width(), - close_button_size.height()); - if (show_link_only) { - // Let's hide all the items. - std::vector<DownloadItemView*>::reverse_iterator ri; - for (ri = download_views_.rbegin(); ri != download_views_.rend(); ++ri) - (*ri)->SetVisible(false); - return; - } - - next_x = kLeftPadding; - std::vector<DownloadItemView*>::reverse_iterator ri; - for (ri = download_views_.rbegin(); ri != download_views_.rend(); ++ri) { - gfx::Size view_size = (*ri)->GetPreferredSize(); - - int x = next_x; - - // Figure out width of item. - int item_width = view_size.width(); - if (new_item_animation_->is_animating() && ri == download_views_.rbegin()) { - item_width = static_cast<int>(static_cast<double>(view_size.width()) * - new_item_animation_->GetCurrentValue()); - } - - next_x += item_width; - - // Make sure our item can be contained within the shelf. - if (next_x < max_download_x) { - (*ri)->SetVisible(true); - (*ri)->SetBounds(x, CenterPosition(view_size.height(), height()), - item_width, view_size.height()); - } else { - (*ri)->SetVisible(false); - } - } -} - -bool DownloadShelfView::CanFitFirstDownloadItem() { - if (download_views_.empty()) - return true; - - gfx::Size image_size = arrow_image_->GetPreferredSize(); - gfx::Size close_button_size = close_button_->GetPreferredSize(); - gfx::Size show_all_size = show_all_view_->GetPreferredSize(); - - // Let's compute the width available for download items, which is the width - // of the shelf minus the "Show all downloads" link, arrow and close button - // and the padding. - int available_width = width() - kRightPadding - close_button_size.width() - - kCloseAndLinkPadding - show_all_size.width() - kDownloadsTitlePadding - - image_size.width() - kDownloadPadding - kLeftPadding; - if (available_width <= 0) - return false; - - gfx::Size item_size = (*download_views_.rbegin())->GetPreferredSize(); - return item_size.width() < available_width; -} - -void DownloadShelfView::UpdateButtonColors() { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - if (GetThemeProvider()) { - close_button_->SetBackground( - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TAB_TEXT), - rb.GetBitmapNamed(IDR_CLOSE_BAR), - rb.GetBitmapNamed(IDR_CLOSE_BAR_MASK)); - } -} - -void DownloadShelfView::OnThemeChanged() { - UpdateButtonColors(); -} - -void DownloadShelfView::LinkActivated(views::Link* source, int event_flags) { - browser_->ShowDownloadsTab(); -} - -void DownloadShelfView::ButtonPressed( - views::Button* button, const views::Event& event) { - Close(); -} - -bool DownloadShelfView::IsShowing() const { - return shelf_animation_->IsShowing(); -} - -bool DownloadShelfView::IsClosing() const { - return shelf_animation_->IsClosing(); -} - -void DownloadShelfView::Show() { - shelf_animation_->Show(); -} - -void DownloadShelfView::Close() { - parent_->SetDownloadShelfVisible(false); - shelf_animation_->Hide(); -} - -void DownloadShelfView::Closed() { - // When the close animation is complete, remove all completed downloads. - size_t i = 0; - while (i < download_views_.size()) { - DownloadItem* download = download_views_[i]->download(); - bool is_transfer_done = download->state() == DownloadItem::COMPLETE || - download->state() == DownloadItem::CANCELLED; - if (is_transfer_done && - download->safety_state() != DownloadItem::DANGEROUS) { - RemoveDownloadView(download_views_[i]); - } else { - // Treat the item as opened when we close. This way if we get shown again - // the user need not open this item for the shelf to auto-close. - download->set_opened(true); - ++i; - } - } -} - -bool DownloadShelfView::CanAutoClose() { - for (size_t i = 0; i < download_views_.size(); ++i) { - if (!download_views_[i]->download()->opened()) - return false; - } - return true; -} - -void DownloadShelfView::SchedulePaintForDownloadItem(views::View* view) { - // Make sure it's not NULL. (Focus sometimes changes to or from NULL.) - if (!view) - return; - - // Make sure it's one of our DownloadItemViews. - bool found = false; - for (size_t i = 0; i < download_views_.size(); ++i) { - if (download_views_[i] == view) - found = true; - } - if (!found) - return; - - // Invalidate it - gfx::Rect invalid_rect = - GetFocusRectBounds(static_cast<DownloadItemView*>(view)); - SchedulePaint(invalid_rect, false); -} - -gfx::Rect DownloadShelfView::GetFocusRectBounds( - const DownloadItemView* download_item_view) { - gfx::Rect bounds = download_item_view->bounds(); - -#if defined(TOOLKIT_VIEWS) - bounds.set_height(bounds.height() - 1); - bounds.Offset(0, 3); -#endif - - return bounds; -} diff --git a/chrome/browser/views/download_shelf_view.h b/chrome/browser/views/download_shelf_view.h index d307d6d..628abba 100644 --- a/chrome/browser/views/download_shelf_view.h +++ b/chrome/browser/views/download_shelf_view.h @@ -2,154 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_DOWNLOAD_SHELF_VIEW_H_ -#define CHROME_BROWSER_VIEWS_DOWNLOAD_SHELF_VIEW_H_ +#ifndef CHROME_BROWSER_DOWNLOAD_SHELF_VIEW_H_ +#define CHROME_BROWSER_DOWNLOAD_SHELF_VIEW_H_ #pragma once -#include "app/slide_animation.h" -#include "chrome/browser/download/download_shelf.h" -#include "chrome/browser/views/accessible_pane_view.h" -#include "views/controls/button/button.h" -#include "views/controls/link.h" -#include "views/mouse_watcher.h" +#include "chrome/browser/ui/views/download_shelf_view.h" +// TODO(beng): remove this file once all includes have been updated. -namespace views { -class ImageButton; -class ImageView; -} +#endif // CHROME_BROWSER_DOWNLOAD_SHELF_VIEW_H_ -class BaseDownloadItemModel; -class Browser; -class BrowserView; - -class DownloadAnimation; -class DownloadItemView; - -// DownloadShelfView is a view that contains individual views for each download, -// as well as a close button and a link to show all downloads. -// -// DownloadShelfView does not hold an infinite number of download views, rather -// it'll automatically remove views once a certain point is reached. -class DownloadShelfView : public AccessiblePaneView, - public AnimationDelegate, - public DownloadShelf, - public views::ButtonListener, - public views::LinkController, - public views::MouseWatcherListener { - public: - DownloadShelfView(Browser* browser, BrowserView* parent); - virtual ~DownloadShelfView(); - - // Sent from the DownloadItemView when the user opens an item. - void OpenedDownload(DownloadItemView* view); - - // Implementation of View. - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - - // Implementation of AnimationDelegate. - virtual void AnimationProgressed(const Animation* animation); - virtual void AnimationEnded(const Animation* animation); - - // Implementation of LinkController. - // Invoked when the user clicks the 'show all downloads' link button. - virtual void LinkActivated(views::Link* source, int event_flags); - - // Implementation of ButtonListener. - // Invoked when the user clicks the close button. Asks the browser to - // hide the download shelf. - virtual void ButtonPressed(views::Button* button, const views::Event& event); - - // Implementation of DownloadShelf. - virtual void AddDownload(BaseDownloadItemModel* download_model); - virtual bool IsShowing() const; - virtual bool IsClosing() const; - virtual void Show(); - virtual void Close(); - virtual Browser* browser() const { return browser_; } - - // Implementation of MouseWatcherDelegate. - virtual void MouseMovedOutOfView(); - - // Override views::FocusChangeListener method from AccessiblePaneView. - virtual void FocusWillChange(View* focused_before, - View* focused_now); - - // Removes a specified download view. The supplied view is deleted after - // it's removed. - void RemoveDownloadView(views::View* view); - - protected: - // From AccessiblePaneView - virtual views::View* GetDefaultFocusableChild(); - - private: - void Init(); - - // Adds a View representing a download to this DownloadShelfView. - // DownloadShelfView takes ownership of the View, and will delete it as - // necessary. - void AddDownloadView(DownloadItemView* view); - - // Paints the border. - void PaintBorder(gfx::Canvas* canvas); - - // Returns true if the shelf is wide enough to show the first download item. - bool CanFitFirstDownloadItem(); - - // Called on theme change. - void UpdateButtonColors(); - - // Overridden from views::View. - virtual void OnThemeChanged(); - - // Called when the "close shelf" animation ended. - void Closed(); - - // Returns true if we can auto close. We can auto-close if all the items on - // the shelf have been opened. - bool CanAutoClose(); - - // Called when any view |view| gains or loses focus. If it's one of our - // DownloadItemView children, call SchedulePaint on its bounds - // so that its focus rect is repainted. - void SchedulePaintForDownloadItem(views::View* view); - - // Get the rect that perfectly surrounds a DownloadItemView so we can - // draw a focus rect around it. - gfx::Rect GetFocusRectBounds(const DownloadItemView* download_item_view); - - // The browser for this shelf. - Browser* browser_; - - // The animation for adding new items to the shelf. - scoped_ptr<SlideAnimation> new_item_animation_; - - // The show/hide animation for the shelf itself. - scoped_ptr<SlideAnimation> shelf_animation_; - - // The download views. These are also child Views, and deleted when - // the DownloadShelfView is deleted. - std::vector<DownloadItemView*> download_views_; - - // An image displayed on the right of the "Show all downloads..." link. - views::ImageView* arrow_image_; - - // Link for showing all downloads. This is contained as a child, and deleted - // by View. - views::Link* show_all_view_; - - // Button for closing the downloads. This is contained as a child, and - // deleted by View. - views::ImageButton* close_button_; - - // The window this shelf belongs to. - BrowserView* parent_; - - views::MouseWatcher mouse_watcher_; - - DISALLOW_COPY_AND_ASSIGN(DownloadShelfView); -}; - -#endif // CHROME_BROWSER_VIEWS_DOWNLOAD_SHELF_VIEW_H_ diff --git a/chrome/browser/views/download_started_animation_win.cc b/chrome/browser/views/download_started_animation_win.cc deleted file mode 100644 index e142b14..0000000 --- a/chrome/browser/views/download_started_animation_win.cc +++ /dev/null @@ -1,180 +0,0 @@ -// 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/download/download_started_animation.h" - -#include "app/linear_animation.h" -#include "app/resource_bundle.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "gfx/rect.h" -#include "grit/theme_resources.h" -#include "views/controls/image_view.h" -#include "views/widget/widget_win.h" - -// How long to spend moving downwards and fading out after waiting. -static const int kMoveTimeMs = 600; - -// The animation framerate. -static const int kFrameRateHz = 60; - -// What fraction of the frame height to move downward from the frame center. -// Note that setting this greater than 0.5 will mean moving past the bottom of -// the frame. -static const double kMoveFraction = 1.0 / 3.0; - -namespace { - -// DownloadStartAnimation creates an animation (which begins running -// immediately) that animates an image downward from the center of the frame -// provided on the constructor, while simultaneously fading it out. To use, -// simply call "new DownloadStartAnimation"; the class cleans itself up when it -// finishes animating. -class DownloadStartedAnimationWin : public LinearAnimation, - public NotificationObserver, - public views::ImageView { - public: - explicit DownloadStartedAnimationWin(TabContents* tab_contents); - - private: - // Move the animation to wherever it should currently be. - void Reposition(); - - // Shut down the animation cleanly. - void Close(); - - // Animation - virtual void AnimateToState(double state); - - // NotificationObserver - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // We use a HWND for the popup so that it may float above any HWNDs in our UI. - views::WidgetWin* popup_; - - // The content area holding us. - TabContents* tab_contents_; - - // The content area at the start of the animation. We store this so that the - // download shelf's resizing of the content area doesn't cause the animation - // to move around. This means that once started, the animation won't move - // with the parent window, but it's so fast that this shouldn't cause too - // much heartbreak. - gfx::Rect tab_contents_bounds_; - - // A scoped container for notification registries. - NotificationRegistrar registrar_; - - DISALLOW_COPY_AND_ASSIGN(DownloadStartedAnimationWin); -}; - -DownloadStartedAnimationWin::DownloadStartedAnimationWin( - TabContents* tab_contents) - : LinearAnimation(kMoveTimeMs, kFrameRateHz, NULL), - popup_(NULL), - tab_contents_(tab_contents) { - static SkBitmap* kDownloadImage = NULL; - if (!kDownloadImage) { - kDownloadImage = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_DOWNLOAD_ANIMATION_BEGIN); - } - - // If we're too small to show the download image, then don't bother - - // the shelf will be enough. - tab_contents_->GetContainerBounds(&tab_contents_bounds_); - if (tab_contents_bounds_.height() < kDownloadImage->height()) - return; - - registrar_.Add( - this, - NotificationType::TAB_CONTENTS_HIDDEN, - Source<TabContents>(tab_contents_)); - registrar_.Add( - this, - NotificationType::TAB_CONTENTS_DESTROYED, - Source<TabContents>(tab_contents_)); - - SetImage(kDownloadImage); - - gfx::Rect rc(0, 0, 0, 0); - popup_ = new views::WidgetWin; - popup_->set_window_style(WS_POPUP); - popup_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | - WS_EX_TRANSPARENT); - popup_->SetOpacity(0x00); - popup_->Init(tab_contents_->GetNativeView(), rc); - popup_->SetContentsView(this); - Reposition(); - popup_->Show(); - - Start(); -} - -void DownloadStartedAnimationWin::Reposition() { - if (!tab_contents_) - return; - - // Align the image with the bottom left of the web contents (so that it - // points to the newly created download). - gfx::Size size = GetPreferredSize(); - int x = base::i18n::IsRTL() ? - tab_contents_bounds_.right() - size.width() : tab_contents_bounds_.x(); - popup_->MoveWindow( - x, - static_cast<int>(tab_contents_bounds_.bottom() - - size.height() - size.height() * (1 - GetCurrentValue())), - size.width(), - size.height()); -} - -void DownloadStartedAnimationWin::Close() { - if (!tab_contents_) - return; - - registrar_.Remove( - this, - NotificationType::TAB_CONTENTS_HIDDEN, - Source<TabContents>(tab_contents_)); - registrar_.Remove( - this, - NotificationType::TAB_CONTENTS_DESTROYED, - Source<TabContents>(tab_contents_)); - tab_contents_ = NULL; - popup_->Close(); -} - -void DownloadStartedAnimationWin::AnimateToState(double state) { - if (state >= 1.0) { - Close(); - } else { - Reposition(); - - // Start at zero, peak halfway and end at zero. - double opacity = std::min(1.0 - pow(GetCurrentValue() - 0.5, 2) * 4.0, - static_cast<double>(1.0)); - - popup_->SetOpacity( - static_cast<SkColor>(opacity * 255.0)); - SchedulePaint(); // Reposition() calls MoveWindow() which never picks up - // alpha changes, so we need to force a paint. - } -} - -void DownloadStartedAnimationWin::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - Close(); -} - -} // namespace - -// static -void DownloadStartedAnimation::Show(TabContents* tab_contents) { - // The animation will delete itself when it's finished or when the tab - // contents is hidden or destroyed. - new DownloadStartedAnimationWin(tab_contents); -} diff --git a/chrome/browser/views/dropdown_bar_host.cc b/chrome/browser/views/dropdown_bar_host.cc deleted file mode 100644 index e55365b..0000000 --- a/chrome/browser/views/dropdown_bar_host.cc +++ /dev/null @@ -1,310 +0,0 @@ -// 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/dropdown_bar_host.h" - -#include "app/keyboard_codes.h" -#include "app/slide_animation.h" -#include "base/scoped_handle.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/dropdown_bar_view.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "gfx/path.h" -#include "gfx/scrollbar_size.h" -#include "views/focus/external_focus_tracker.h" -#include "views/focus/view_storage.h" -#include "views/widget/widget.h" - -#if defined(OS_LINUX) -#include "app/scoped_handle_gtk.h" -#endif - -using gfx::Path; - -// static -bool DropdownBarHost::disable_animations_during_testing_ = false; - -//////////////////////////////////////////////////////////////////////////////// -// DropdownBarHost, public: - -DropdownBarHost::DropdownBarHost(BrowserView* browser_view) - : browser_view_(browser_view), - animation_offset_(0), - esc_accel_target_registered_(false), - is_visible_(false) { -} - -void DropdownBarHost::Init(DropdownBarView* view) { - view_ = view; - - // Initialize the host. - host_.reset(CreateHost()); - host_->InitWithWidget(browser_view_->GetWidget(), gfx::Rect()); - host_->SetContentsView(view_); - - // Start listening to focus changes, so we can register and unregister our - // own handler for Escape. - focus_manager_ = - views::FocusManager::GetFocusManagerForNativeView(host_->GetNativeView()); - if (focus_manager_) { - focus_manager_->AddFocusChangeListener(this); - } else { - // In some cases (see bug http://crbug.com/17056) it seems we may not have - // a focus manager. Please reopen the bug if you hit this. - NOTREACHED(); - } - - // Start the process of animating the opening of the widget. - animation_.reset(new SlideAnimation(this)); -} - -DropdownBarHost::~DropdownBarHost() { - focus_manager_->RemoveFocusChangeListener(this); - focus_tracker_.reset(NULL); -} - -void DropdownBarHost::Show(bool animate) { - // Stores the currently focused view, and tracks focus changes so that we can - // restore focus when the dropdown widget is closed. - focus_tracker_.reset(new views::ExternalFocusTracker(view_, focus_manager_)); - - if (!animate || disable_animations_during_testing_) { - is_visible_ = true; - animation_->Reset(1); - AnimationProgressed(animation_.get()); - } else { - if (!is_visible_) { - // Don't re-start the animation. - is_visible_ = true; - animation_->Reset(); - animation_->Show(); - } - } -} - -void DropdownBarHost::SetFocusAndSelection() { - view_->SetFocusAndSelection(true); -} - -bool DropdownBarHost::IsAnimating() const { - return animation_->is_animating(); -} - -void DropdownBarHost::Hide(bool animate) { - if (!IsVisible()) - return; - if (animate && !disable_animations_during_testing_) { - animation_->Reset(1.0); - animation_->Hide(); - } else { - StopAnimation(); - is_visible_ = false; - host_->Hide(); - } -} - -void DropdownBarHost::StopAnimation() { - animation_->End(); -} - -bool DropdownBarHost::IsVisible() const { - return is_visible_; -} - -//////////////////////////////////////////////////////////////////////////////// -// DropdownBarHost, views::FocusChangeListener implementation: -void DropdownBarHost::FocusWillChange(views::View* focused_before, - views::View* focused_now) { - // First we need to determine if one or both of the views passed in are child - // views of our view. - bool our_view_before = focused_before && view_->IsParentOf(focused_before); - bool our_view_now = focused_now && view_->IsParentOf(focused_now); - - // When both our_view_before and our_view_now are false, it means focus is - // changing hands elsewhere in the application (and we shouldn't do anything). - // Similarly, when both are true, focus is changing hands within the dropdown - // widget (and again, we should not do anything). We therefore only need to - // look at when we gain initial focus and when we loose it. - if (!our_view_before && our_view_now) { - // We are gaining focus from outside the dropdown widget so we must register - // a handler for Escape. - RegisterAccelerators(); - } else if (our_view_before && !our_view_now) { - // We are losing focus to something outside our widget so we restore the - // original handler for Escape. - UnregisterAccelerators(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// DropdownBarHost, AnimationDelegate implementation: - -void DropdownBarHost::AnimationProgressed(const Animation* animation) { - // First, we calculate how many pixels to slide the widget. - gfx::Size pref_size = view_->GetPreferredSize(); - animation_offset_ = static_cast<int>((1.0 - animation_->GetCurrentValue()) * - pref_size.height()); - - // This call makes sure it appears in the right location, the size and shape - // is correct and that it slides in the right direction. - gfx::Rect dlg_rect = GetDialogPosition(gfx::Rect()); - SetDialogPosition(dlg_rect, false); - - // Let the view know if we are animating, and at which offset to draw the - // edges. - view_->set_animation_offset(animation_offset_); - view_->SchedulePaint(); -} - -void DropdownBarHost::AnimationEnded(const Animation* animation) { - // Place the dropdown widget in its fully opened state. - animation_offset_ = 0; - - if (!animation_->IsShowing()) { - // Animation has finished closing. - host_->Hide(); - is_visible_ = false; - } else { - // Animation has finished opening. - } -} - -//////////////////////////////////////////////////////////////////////////////// -// DropdownBarHost protected: - -void DropdownBarHost::ResetFocusTracker() { - focus_tracker_.reset(NULL); -} - -void DropdownBarHost::GetWidgetBounds(gfx::Rect* bounds) { - DCHECK(bounds); - *bounds = browser_view_->bounds(); -} - -void DropdownBarHost::UpdateWindowEdges(const gfx::Rect& new_pos) { - // |w| is used to make it easier to create the part of the polygon that curves - // the right side of the Find window. It essentially keeps track of the - // x-pixel position of the right-most background image inside the view. - // TODO(finnur): Let the view tell us how to draw the curves or convert - // this to a CustomFrameWindow. - int w = new_pos.width() - 6; // -6 positions us at the left edge of the - // rightmost background image of the view. - int h = new_pos.height(); - - // This polygon array represents the outline of the background image for the - // window. Basically, it encompasses only the visible pixels of the - // concatenated find_dlg_LMR_bg images (where LMR = [left | middle | right]). - const Path::Point polygon[] = { - {0, 0}, {0, 1}, {2, 3}, {2, h - 3}, {4, h - 1}, - {4, h}, {w+0, h}, - {w+0, h - 1}, {w+1, h - 1}, {w+3, h - 3}, {w+3, 3}, {w+6, 0} - }; - - // Find the largest x and y value in the polygon. - int max_x = 0, max_y = 0; - for (size_t i = 0; i < arraysize(polygon); i++) { - max_x = std::max(max_x, static_cast<int>(polygon[i].x)); - max_y = std::max(max_y, static_cast<int>(polygon[i].y)); - } - - // We then create the polygon and use SetWindowRgn to force the window to draw - // only within that area. This region may get reduced in size below. - Path path(polygon, arraysize(polygon)); - ScopedRegion region(path.CreateNativeRegion()); - - // Are we animating? - if (animation_offset() > 0) { - // The animation happens in two steps: First, we clip the window and then in - // GetWidgetPosition we offset the window position so that it still looks - // attached to the toolbar as it grows. We clip the window by creating a - // rectangle region (that gradually increases as the animation progresses) - // and find the intersection between the two regions using CombineRgn. - - // |y| shrinks as the animation progresses from the height of the view down - // to 0 (and reverses when closing). - int y = animation_offset(); - // |y| shrinking means the animation (visible) region gets larger. In other - // words: the rectangle grows upward (when the widget is opening). - Path animation_path; - SkRect animation_rect = { SkIntToScalar(0), SkIntToScalar(y), - SkIntToScalar(max_x), SkIntToScalar(max_y) }; - animation_path.addRect(animation_rect); - ScopedRegion animation_region(animation_path.CreateNativeRegion()); - region.Set(Path::IntersectRegions(animation_region.Get(), region.Get())); - - // Next, we need to increase the region a little bit to account for the - // curved edges that the view will draw to make it look like grows out of - // the toolbar. - Path::Point left_curve[] = { - {0, y+0}, {0, y+1}, {2, y+3}, {2, y+0}, {0, y+0} - }; - Path::Point right_curve[] = { - {w+3, y+3}, {w+6, y+0}, {w+3, y+0}, {w+3, y+3} - }; - - // Combine the region for the curve on the left with our main region. - Path left_path(left_curve, arraysize(left_curve)); - ScopedRegion r(left_path.CreateNativeRegion()); - region.Set(Path::CombineRegions(r.Get(), region.Get())); - - // Combine the region for the curve on the right with our main region. - Path right_path(right_curve, arraysize(right_curve)); - region.Set(Path::CombineRegions(r.Get(), region.Get())); - } - - // Now see if we need to truncate the region because parts of it obscures - // the main window border. - gfx::Rect widget_bounds; - GetWidgetBounds(&widget_bounds); - - // Calculate how much our current position overlaps our boundaries. If we - // overlap, it means we have too little space to draw the whole widget and - // we allow overwriting the scrollbar before we start truncating our widget. - // - // TODO(brettw) this constant is evil. This is the amount of room we've added - // to the window size, when we set the region, it can change the size. - static const int kAddedWidth = 7; - int difference = new_pos.right() - kAddedWidth - widget_bounds.right() - - gfx::scrollbar_size() + 1; - if (difference > 0) { - Path::Point exclude[4]; - exclude[0].x = max_x - difference; // Top left corner. - exclude[0].y = 0; - - exclude[1].x = max_x; // Top right corner. - exclude[1].y = 0; - - exclude[2].x = max_x; // Bottom right corner. - exclude[2].y = max_y; - - exclude[3].x = max_x - difference; // Bottom left corner. - exclude[3].y = max_y; - - // Subtract this region from the original region. - gfx::Path exclude_path(exclude, arraysize(exclude)); - ScopedRegion exclude_region(exclude_path.CreateNativeRegion()); - region.Set(Path::SubtractRegion(region.Get(), exclude_region.Get())); - } - - // Window takes ownership of the region. - host()->SetShape(region.release()); -} - -void DropdownBarHost::RegisterAccelerators() { - DCHECK(!esc_accel_target_registered_); - views::Accelerator escape(app::VKEY_ESCAPE, false, false, false); - focus_manager_->RegisterAccelerator(escape, this); - esc_accel_target_registered_ = true; -} - -void DropdownBarHost::UnregisterAccelerators() { - DCHECK(esc_accel_target_registered_); - views::Accelerator escape(app::VKEY_ESCAPE, false, false, false); - focus_manager_->UnregisterAccelerator(escape, this); - esc_accel_target_registered_ = false; -} diff --git a/chrome/browser/views/dropdown_bar_host.h b/chrome/browser/views/dropdown_bar_host.h index 72b9aac..23c9053 100644 --- a/chrome/browser/views/dropdown_bar_host.h +++ b/chrome/browser/views/dropdown_bar_host.h @@ -6,183 +6,8 @@ #define CHROME_BROWSER_VIEWS_DROPDOWN_BAR_HOST_H_ #pragma once -#include "app/animation.h" -#include "base/scoped_ptr.h" -#include "chrome/common/native_web_keyboard_event.h" -#include "gfx/native_widget_types.h" -#include "gfx/rect.h" -#include "views/controls/textfield/textfield.h" -#include "views/focus/focus_manager.h" - -class BrowserView; -class DropdownBarView; -class SlideAnimation; -class TabContents; - -namespace views { -class ExternalFocusTracker; -class View; -class Widget; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// The DropdownBarHost implements the container widget for the UI that -// is shown at the top of browser contents. It uses the appropriate -// implementation from dropdown_bar_host_win.cc or dropdown_bar_host_gtk.cc to -// draw its content and is responsible for showing, hiding, animating, closing, -// and moving the bar if needed, for example if the widget is -// obscuring the selection results in FindBar. -// -//////////////////////////////////////////////////////////////////////////////// -class DropdownBarHost : public views::AcceleratorTarget, - public views::FocusChangeListener, - public AnimationDelegate { - public: - explicit DropdownBarHost(BrowserView* browser_view); - virtual ~DropdownBarHost(); - - // Initializes the dropdown bar host with the give view. - void Init(DropdownBarView* view); - - // Whether we are animating the position of the dropdown widget. - bool IsAnimating() const; - // Returns true if the dropdown bar view is visible, or false otherwise. - bool IsVisible() const; - // Selects text in the entry field and set focus. - void SetFocusAndSelection(); - // Stops the animation. - void StopAnimation(); - - // Shows the dropdown bar. - virtual void Show(bool animate); - // Hides the dropdown bar. - virtual void Hide(bool animate); - - // Returns the rectangle representing where to position the dropdown widget. - virtual gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect) = 0; - - // Moves the widget to the provided location, moves it to top - // in the z-order (HWND_TOP, not HWND_TOPMOST for windows) and shows - // the widget (if hidden). - virtual void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) = 0; - - // Overridden from views::FocusChangeListener: - virtual void FocusWillChange(views::View* focused_before, - views::View* focused_now); - - // Overridden from views::AcceleratorTarget: - virtual bool AcceleratorPressed(const views::Accelerator& accelerator) = 0; - - // AnimationDelegate implementation: - virtual void AnimationProgressed(const Animation* animation); - virtual void AnimationEnded(const Animation* animation); - - // During testing we can disable animations by setting this flag to true, - // so that opening and closing the dropdown bar is shown instantly, instead of - // having to poll it while it animates to open/closed status. - static bool disable_animations_during_testing_; - - // Returns the browser view that the dropdown belongs to. - BrowserView* browser_view() const { return browser_view_; } - - // Registers this class as the handler for when Escape is pressed. Once we - // loose focus we will unregister Escape and (any accelerators the derived - // classes registers by using overrides of RegisterAccelerators). See also: - // SetFocusChangeListener(). - virtual void RegisterAccelerators(); - - // When we loose focus, we unregister all accelerator handlers. See also: - // SetFocusChangeListener(). - virtual void UnregisterAccelerators(); - - protected: - // Returns the dropdown bar view. - DropdownBarView* view() const { return view_; } - - // Returns the focus tracker. - views::ExternalFocusTracker* focus_tracker() const { - return focus_tracker_.get(); - } - - // Resets the focus tracker. - void ResetFocusTracker(); - - // The focus manager we register with to keep track of focus changes. - views::FocusManager* focus_manager() const { return focus_manager_; } - - // Returns the host widget. - views::Widget* host() const { return host_.get(); } - - // Returns the animation offset. - int animation_offset() const { return animation_offset_; } - - // Retrieves the boundary that the dropdown widget has to work with - // within the Chrome frame window. The boundary differs depending on - // the dropdown bar implementation. The default implementation - // returns the boundary of browser_view and the drop down - // can be shown in any client area. - virtual void GetWidgetBounds(gfx::Rect* bounds); - - // The find bar widget needs rounded edges, so we create a polygon - // that corresponds to the background images for this window (and - // make the polygon only contain the pixels that we want to - // draw). The polygon is then given to SetWindowRgn which changes - // the window from being a rectangle in shape, to being a rect with - // curved edges. We also check to see if the region should be - // truncated to prevent from drawing onto Chrome's window border. - void UpdateWindowEdges(const gfx::Rect& new_pos); - - // Creates and returns the native Widget. - views::Widget* CreateHost(); - - // Allows implementation to tweak widget position. - void SetWidgetPositionNative(const gfx::Rect& new_pos, bool no_redraw); - - // Returns a keyboard event suitable for fowarding. - NativeWebKeyboardEvent GetKeyboardEvent( - const TabContents* contents, - const views::Textfield::Keystroke& key_stroke); - - // Returns the animation for the dropdown. - SlideAnimation* animation() { - return animation_.get(); - } - - private: - // The BrowserView that created us. - BrowserView* browser_view_; - - // Our view, which is responsible for drawing the UI. - DropdownBarView* view_; - - // The y position pixel offset of the widget while animating the - // dropdown widget. - int animation_offset_; - - // The animation class to use when opening the Dropdown widget. - scoped_ptr<SlideAnimation> animation_; - - // The focus manager we register with to keep track of focus changes. - views::FocusManager* focus_manager_; - - // True if the accelerator target for Esc key is registered. - bool esc_accel_target_registered_; - - // Tracks and stores the last focused view which is not the DropdownBarView - // or any of its children. Used to restore focus once the DropdownBarView is - // closed. - scoped_ptr<views::ExternalFocusTracker> focus_tracker_; - - // Host is the Widget implementation that is created and maintained by the - // dropdown bar. It contains the DropdownBarView. - scoped_ptr<views::Widget> host_; - - // A flag to manually manage visibility. GTK/X11 is asynchrnous and - // the state of the widget can be out of sync. - bool is_visible_; - - DISALLOW_COPY_AND_ASSIGN(DropdownBarHost); -}; +#include "chrome/browser/ui/views/dropdown_bar_host.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_DROPDOWN_BAR_HOST_H_ + diff --git a/chrome/browser/views/dropdown_bar_host_gtk.cc b/chrome/browser/views/dropdown_bar_host_gtk.cc deleted file mode 100644 index 2a4e4be..0000000 --- a/chrome/browser/views/dropdown_bar_host_gtk.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2006-2009 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/dropdown_bar_host.h" - -#include <gdk/gdkkeysyms.h> - -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "views/widget/widget_gtk.h" -#include "views/controls/textfield/textfield.h" - -views::Widget* DropdownBarHost::CreateHost() { - views::WidgetGtk* host = new views::WidgetGtk(views::WidgetGtk::TYPE_CHILD); - // We own the host. - host->set_delete_on_destroy(false); - return host; -} - -void DropdownBarHost::SetWidgetPositionNative(const gfx::Rect& new_pos, - bool no_redraw) { - host_->SetBounds(new_pos); - host_->Show(); -} - -NativeWebKeyboardEvent DropdownBarHost::GetKeyboardEvent( - const TabContents* contents, - const views::Textfield::Keystroke& key_stroke) { - return NativeWebKeyboardEvent(key_stroke.event()); -} diff --git a/chrome/browser/views/dropdown_bar_host_win.cc b/chrome/browser/views/dropdown_bar_host_win.cc deleted file mode 100644 index c14fb21..0000000 --- a/chrome/browser/views/dropdown_bar_host_win.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2006-2009 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/dropdown_bar_host.h" - -#include "chrome/browser/find_bar_controller.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "views/controls/scrollbar/native_scroll_bar.h" -#include "views/widget/widget_win.h" - -NativeWebKeyboardEvent DropdownBarHost::GetKeyboardEvent( - const TabContents* contents, - const views::Textfield::Keystroke& key_stroke) { - HWND hwnd = contents->GetContentNativeView(); - return NativeWebKeyboardEvent( - hwnd, key_stroke.message(), key_stroke.key(), 0); -} - -views::Widget* DropdownBarHost::CreateHost() { - views::WidgetWin* widget = new views::WidgetWin(); - // Don't let WidgetWin manage our lifetime. We want our lifetime to - // coincide with TabContents. - widget->set_delete_on_destroy(false); - widget->set_window_style(WS_CHILD | WS_CLIPCHILDREN); - widget->set_window_ex_style(WS_EX_TOPMOST); - - return widget; -} - -void DropdownBarHost::SetWidgetPositionNative(const gfx::Rect& new_pos, - bool no_redraw) { - gfx::Rect window_rect; - host_->GetBounds(&window_rect, true); - DWORD swp_flags = SWP_NOOWNERZORDER; - if (!window_rect.IsEmpty()) - swp_flags |= SWP_NOSIZE; - if (no_redraw) - swp_flags |= SWP_NOREDRAW; - if (!host_->IsVisible()) - swp_flags |= SWP_SHOWWINDOW; - - ::SetWindowPos(host_->GetNativeView(), HWND_TOP, new_pos.x(), new_pos.y(), - new_pos.width(), new_pos.height(), swp_flags); -} diff --git a/chrome/browser/views/dropdown_bar_view.h b/chrome/browser/views/dropdown_bar_view.h index 1486509..9ae52cc 100644 --- a/chrome/browser/views/dropdown_bar_view.h +++ b/chrome/browser/views/dropdown_bar_view.h @@ -6,49 +6,8 @@ #define CHROME_BROWSER_VIEWS_DROPDOWN_BAR_VIEW_H_ #pragma once -#include "views/view.h" - -class DropdownBarHost; - -//////////////////////////////////////////////////////////////////////////////// -// -// The DropdownBarView is an abstract view to draw the UI controls of the -// DropdownBarHost. -// -//////////////////////////////////////////////////////////////////////////////// -class DropdownBarView : public views::View { - public: - explicit DropdownBarView(DropdownBarHost* host) - : host_(host), - animation_offset_(0) { - } - virtual ~DropdownBarView() {} - - // Claims focus for the text field and selects its contents. - virtual void SetFocusAndSelection(bool select_all) = 0; - - // Updates the view to let it know where the host is clipping the - // dropdown widget (while animating the opening or closing of the widget). - void set_animation_offset(int offset) { animation_offset_ = offset; } - - // Returns the offset used while animating. - int animation_offset() const { return animation_offset_; } - - protected: - // Returns the DropdownBarHost that manages this view. - DropdownBarHost* host() const { return host_; } - - private: - // The dropdown bar host that controls this view. - DropdownBarHost* host_; - - // While animating, the host clips the widget and draws only the bottom - // part of it. The view needs to know the pixel offset at which we are drawing - // the widget so that we can draw the curved edges that attach to the toolbar - // in the right location. - int animation_offset_; - - DISALLOW_COPY_AND_ASSIGN(DropdownBarView); -}; +#include "chrome/browser/ui/views/dropdown_bar_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_DROPDOWN_BAR_VIEW_H_ + diff --git a/chrome/browser/views/edit_search_engine_dialog.cc b/chrome/browser/views/edit_search_engine_dialog.cc deleted file mode 100644 index 8919d9d..0000000 --- a/chrome/browser/views/edit_search_engine_dialog.cc +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2009 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/edit_search_engine_dialog.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/i18n/rtl.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/search_engines/edit_search_engine_controller.h" -#include "chrome/browser/search_engines/template_url.h" -#include "googleurl/src/gurl.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/label.h" -#include "views/controls/image_view.h" -#include "views/controls/table/table_view.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -using views::GridLayout; -using views::ImageView; -using views::Textfield; - - -namespace { -// Converts a URL as understood by TemplateURL to one appropriate for display -// to the user. -std::wstring GetDisplayURL(const TemplateURL& turl) { - return turl.url() ? turl.url()->DisplayURL() : std::wstring(); -} -} // namespace - -namespace browser { - -void EditSearchEngine(gfx::NativeWindow parent, - const TemplateURL* template_url, - EditSearchEngineControllerDelegate* delegate, - Profile* profile) { - EditSearchEngineDialog::Show(parent, template_url, delegate, profile); -} - -} // namespace browser - -EditSearchEngineDialog::EditSearchEngineDialog( - const TemplateURL* template_url, - EditSearchEngineControllerDelegate* delegate, - Profile* profile) - : controller_(new EditSearchEngineController(template_url, - delegate, - profile)) { - Init(); -} - -// static -void EditSearchEngineDialog::Show(gfx::NativeWindow parent, - const TemplateURL* template_url, - EditSearchEngineControllerDelegate* delegate, - Profile* profile) { - EditSearchEngineDialog* contents = - new EditSearchEngineDialog(template_url, delegate, profile); - // Window interprets an empty rectangle as needing to query the content for - // the size as well as centering relative to the parent. - views::Window::CreateChromeWindow(parent, gfx::Rect(), contents); - contents->window()->Show(); - contents->GetDialogClientView()->UpdateDialogButtons(); - contents->title_tf_->SelectAll(); - contents->title_tf_->RequestFocus(); -} - -bool EditSearchEngineDialog::IsModal() const { - return true; -} - -std::wstring EditSearchEngineDialog::GetWindowTitle() const { - return l10n_util::GetString(controller_->template_url() ? - IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE : - IDS_SEARCH_ENGINES_EDITOR_NEW_WINDOW_TITLE); -} - -bool EditSearchEngineDialog::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return (controller_->IsKeywordValid(WideToUTF16(keyword_tf_->text())) && - controller_->IsTitleValid(WideToUTF16(title_tf_->text())) && - controller_->IsURLValid(WideToUTF8(url_tf_->text()))); - } - return true; -} - -bool EditSearchEngineDialog::Cancel() { - controller_->CleanUpCancelledAdd(); - return true; -} - -bool EditSearchEngineDialog::Accept() { - controller_->AcceptAddOrEdit(WideToUTF16(title_tf_->text()), - WideToUTF16(keyword_tf_->text()), - WideToUTF8(url_tf_->text())); - return true; -} - -views::View* EditSearchEngineDialog::GetContentsView() { - return this; -} - -void EditSearchEngineDialog::ContentsChanged(Textfield* sender, - const std::wstring& new_contents) { - GetDialogClientView()->UpdateDialogButtons(); - UpdateImageViews(); -} - -bool EditSearchEngineDialog::HandleKeystroke( - Textfield* sender, - const views::Textfield::Keystroke& key) { - return false; -} - -void EditSearchEngineDialog::Init() { - // Create the views we'll need. - if (controller_->template_url()) { - title_tf_ = - CreateTextfield(controller_->template_url()->short_name(), false); - keyword_tf_ = CreateTextfield(controller_->template_url()->keyword(), true); - url_tf_ = - CreateTextfield(GetDisplayURL(*controller_->template_url()), false); - // We don't allow users to edit prepopulate URLs. This is done as - // occasionally we need to update the URL of prepopulated TemplateURLs. - url_tf_->SetReadOnly(controller_->template_url()->prepopulate_id() != 0); - } else { - title_tf_ = CreateTextfield(std::wstring(), false); - keyword_tf_ = CreateTextfield(std::wstring(), true); - url_tf_ = CreateTextfield(std::wstring(), false); - } - title_iv_ = new ImageView(); - keyword_iv_ = new ImageView(); - url_iv_ = new ImageView(); - - UpdateImageViews(); - - const int related_x = kRelatedControlHorizontalSpacing; - const int related_y = kRelatedControlVerticalSpacing; - const int unrelated_y = kUnrelatedControlVerticalSpacing; - - // View and GridLayout take care of deleting GridLayout for us. - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - // Define the structure of the layout. - - // For the buttons. - views::ColumnSet* column_set = layout->AddColumnSet(0); - column_set->AddPaddingColumn(1, 0); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, related_x); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->LinkColumnSizes(1, 3, -1); - - // For the Textfields. - column_set = layout->AddColumnSet(1); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, related_x); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, related_x); - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - // For the description. - column_set = layout->AddColumnSet(2); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - // Add the contents. - layout->StartRow(0, 1); - layout->AddView(CreateLabel(IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_LABEL)); - layout->AddView(title_tf_); - layout->AddView(title_iv_); - - layout->StartRowWithPadding(0, 1, 0, related_y); - layout->AddView(CreateLabel(IDS_SEARCH_ENGINES_EDITOR_KEYWORD_LABEL)); - layout->AddView(keyword_tf_); - layout->AddView(keyword_iv_); - - layout->StartRowWithPadding(0, 1, 0, related_y); - layout->AddView(CreateLabel(IDS_SEARCH_ENGINES_EDITOR_URL_LABEL)); - layout->AddView(url_tf_); - layout->AddView(url_iv_); - - // On RTL UIs (such as Arabic and Hebrew) the description text is not - // displayed correctly since it contains the substring "%s". This substring - // is not interpreted by the Unicode BiDi algorithm as an LTR string and - // therefore the end result is that the following right to left text is - // displayed: ".three two s% one" (where 'one', 'two', etc. are words in - // Hebrew). - // - // In order to fix this problem we transform the substring "%s" so that it - // is displayed correctly when rendered in an RTL context. - layout->StartRowWithPadding(0, 2, 0, unrelated_y); - std::wstring description = - l10n_util::GetString(IDS_SEARCH_ENGINES_EDITOR_URL_DESCRIPTION_LABEL); - if (base::i18n::IsRTL()) { - const std::wstring reversed_percent(L"s%"); - std::wstring::size_type percent_index = - description.find(L"%s", static_cast<std::wstring::size_type>(0)); - if (percent_index != std::wstring::npos) - description.replace(percent_index, - reversed_percent.length(), - reversed_percent); - } - - views::Label* description_label = new views::Label(description); - description_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->AddView(description_label); - - layout->AddPaddingRow(0, related_y); -} - -views::Label* EditSearchEngineDialog::CreateLabel(int message_id) { - views::Label* label = new views::Label(l10n_util::GetString(message_id)); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - return label; -} - -Textfield* EditSearchEngineDialog::CreateTextfield(const std::wstring& text, - bool lowercase) { - Textfield* text_field = new Textfield( - lowercase ? Textfield::STYLE_LOWERCASE : Textfield::STYLE_DEFAULT); - text_field->SetText(text); - text_field->SetController(this); - return text_field; -} - -void EditSearchEngineDialog::UpdateImageViews() { - UpdateImageView(keyword_iv_, - controller_->IsKeywordValid(WideToUTF16(keyword_tf_->text())), - IDS_SEARCH_ENGINES_INVALID_KEYWORD_TT); - UpdateImageView(url_iv_, controller_->IsURLValid(WideToUTF8(url_tf_->text())), - IDS_SEARCH_ENGINES_INVALID_URL_TT); - UpdateImageView(title_iv_, - controller_->IsTitleValid(WideToUTF16(title_tf_->text())), - IDS_SEARCH_ENGINES_INVALID_TITLE_TT); -} - -void EditSearchEngineDialog::UpdateImageView(ImageView* image_view, - bool is_valid, - int invalid_message_id) { - if (is_valid) { - image_view->SetTooltipText(std::wstring()); - image_view->SetImage( - ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_INPUT_GOOD)); - } else { - image_view->SetTooltipText(l10n_util::GetString(invalid_message_id)); - image_view->SetImage( - ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_INPUT_ALERT)); - } -} diff --git a/chrome/browser/views/edit_search_engine_dialog.h b/chrome/browser/views/edit_search_engine_dialog.h index 43c4dd0..f5881ec 100644 --- a/chrome/browser/views/edit_search_engine_dialog.h +++ b/chrome/browser/views/edit_search_engine_dialog.h @@ -1,105 +1,13 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. -// EditSearchEngineDialog provides text fields for editing a keyword: the title, -// url and actual keyword. It is used by the KeywordEditorView of the Options -// dialog, and also on its own to confirm the addition of a keyword added by -// the ExternalJSObject via the RenderView. - #ifndef CHROME_BROWSER_VIEWS_EDIT_SEARCH_ENGINE_DIALOG_H_ #define CHROME_BROWSER_VIEWS_EDIT_SEARCH_ENGINE_DIALOG_H_ #pragma once -#include <windows.h> - -#include "views/controls/textfield/textfield.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Label; -class ImageView; -class Window; -} - -class EditSearchEngineController; -class EditSearchEngineControllerDelegate; -class Profile; -class TemplateURL; -class TemplateURLModel; - -class EditSearchEngineDialog : public views::View, - public views::Textfield::Controller, - public views::DialogDelegate { - public: - // The |template_url| and/or |delegate| may be NULL. - EditSearchEngineDialog(const TemplateURL* template_url, - EditSearchEngineControllerDelegate* delegate, - Profile* profile); - virtual ~EditSearchEngineDialog() {} - - // Shows the dialog to the user. - static void Show(gfx::NativeWindow parent, - const TemplateURL* template_url, - EditSearchEngineControllerDelegate* delegate, - Profile* profile); - - // views::DialogDelegate overrides. - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool Cancel(); - virtual bool Accept(); - virtual views::View* GetContentsView(); - - // views::Textfield::Controller overrides. Updates whether the user can - // accept the dialog as well as updating image views showing whether value is - // valid. - virtual void ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key); - - private: - void Init(); - - // Create a Label containing the text with the specified message id. - views::Label* CreateLabel(int message_id); - - // Creates a text field with the specified text. If |lowercase| is true, the - // Textfield is configured to map all input to lower case. - views::Textfield* CreateTextfield(const std::wstring& text, bool lowercase); - - // Invokes UpdateImageView for each of the images views. - void UpdateImageViews(); - - // Updates the tooltip and image of the image view based on is_valid. If - // is_valid is false the tooltip of the image view is set to the message with - // id invalid_message_id, otherwise the tooltip is set to the empty text. - void UpdateImageView(views::ImageView* image_view, - bool is_valid, - int invalid_message_id); - - // Used to parent window to. May be NULL or an invalid window. - HWND parent_; - - // View containing the buttons, text fields ... - views::View* view_; - - // Text fields. - views::Textfield* title_tf_; - views::Textfield* keyword_tf_; - views::Textfield* url_tf_; - - // Shows error images. - views::ImageView* title_iv_; - views::ImageView* keyword_iv_; - views::ImageView* url_iv_; - - scoped_ptr<EditSearchEngineController> controller_; - - DISALLOW_COPY_AND_ASSIGN(EditSearchEngineDialog); -}; +#include "chrome/browser/ui/views/edit_search_engine_dialog.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_EDIT_SEARCH_ENGINE_DIALOG_H_ + diff --git a/chrome/browser/views/event_utils.cc b/chrome/browser/views/event_utils.cc deleted file mode 100644 index 06b9f0d..0000000 --- a/chrome/browser/views/event_utils.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2006-2008 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/event_utils.h" - -#include "views/event.h" - -using views::Event; - -namespace event_utils { - -WindowOpenDisposition DispositionFromEventFlags(int event_flags) { - if (((event_flags & Event::EF_MIDDLE_BUTTON_DOWN) == - Event::EF_MIDDLE_BUTTON_DOWN) || - ((event_flags & Event::EF_CONTROL_DOWN) == - Event::EF_CONTROL_DOWN)) { - return ((event_flags & Event::EF_SHIFT_DOWN) == Event::EF_SHIFT_DOWN) ? - NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; - } - - if ((event_flags & Event::EF_SHIFT_DOWN) == Event::EF_SHIFT_DOWN) - return NEW_WINDOW; - return false /*event.IsAltDown()*/ ? SAVE_TO_DISK : CURRENT_TAB; -} - -bool IsPossibleDispositionEvent(const views::MouseEvent& event) { - return event.IsLeftMouseButton() || event.IsMiddleMouseButton(); -} - -} diff --git a/chrome/browser/views/event_utils.h b/chrome/browser/views/event_utils.h index 188041f..7d7d370 100644 --- a/chrome/browser/views/event_utils.h +++ b/chrome/browser/views/event_utils.h @@ -1,28 +1,13 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. -#ifndef CHROME_BROWSER_VIEWS_EVENT_UTILS_H__ -#define CHROME_BROWSER_VIEWS_EVENT_UTILS_H__ +#ifndef CHROME_BROWSER_VIEWS_EVENT_UTILS_H_ +#define CHROME_BROWSER_VIEWS_EVENT_UTILS_H_ #pragma once -#include "webkit/glue/window_open_disposition.h" +#include "chrome/browser/ui/views/event_utils.h" +// TODO(beng): remove this file once all includes have been updated. -namespace views { -class MouseEvent; -} +#endif // CHROME_BROWSER_VIEWS_EVENT_UTILS_H_ -namespace event_utils { - -// Translates event flags into what kind of disposition they represents. -// For example, a middle click would mean to open a background tab. -// event_flags are the flags as understood by views::MouseEvent. -WindowOpenDisposition DispositionFromEventFlags(int event_flags); - -// Returns true if the specified mouse event may have a -// WindowOptionDisposition. -bool IsPossibleDispositionEvent(const views::MouseEvent& event); - -} - -#endif // CHROME_BROWSER_VIEWS_EVENT_UTILS_H__ diff --git a/chrome/browser/views/extensions/browser_action_drag_data.cc b/chrome/browser/views/extensions/browser_action_drag_data.cc deleted file mode 100644 index 6ab54ce..0000000 --- a/chrome/browser/views/extensions/browser_action_drag_data.cc +++ /dev/null @@ -1,89 +0,0 @@ -// 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/extensions/browser_action_drag_data.h" - -#include "base/logging.h" -#include "base/pickle.h" -#include "base/string_util.h" -#include "chrome/browser/profile.h" - -const char* BrowserActionDragData::kClipboardFormatString = - "chromium/x-browser-actions"; - -BrowserActionDragData::BrowserActionDragData() - : profile_id_(0), index_(-1) { -} - -BrowserActionDragData::BrowserActionDragData( - const std::string& id, int index) - : profile_id_(0), id_(id), index_(index) { -} - -bool BrowserActionDragData::IsFromProfile(Profile* profile) const { - return (profile_id_ == profile->GetRuntimeId()); -} - -#if defined(TOOLKIT_VIEWS) -void BrowserActionDragData::Write( - Profile* profile, OSExchangeData* data) const { - DCHECK(data); - Pickle data_pickle; - WriteToPickle(profile, &data_pickle); - data->SetPickledData(GetBrowserActionCustomFormat(), data_pickle); -} - -bool BrowserActionDragData::Read(const OSExchangeData& data) { - if (!data.HasCustomFormat(GetBrowserActionCustomFormat())) - return false; - - Pickle drag_data_pickle; - if (!data.GetPickledData(GetBrowserActionCustomFormat(), &drag_data_pickle)) - return false; - - if (!ReadFromPickle(&drag_data_pickle)) - return false; - - return true; -} - -// static -OSExchangeData::CustomFormat - BrowserActionDragData::GetBrowserActionCustomFormat() { - static OSExchangeData::CustomFormat format; - static bool format_valid = false; - - if (!format_valid) { - format_valid = true; - format = OSExchangeData::RegisterCustomFormat( - BrowserActionDragData::kClipboardFormatString); - } - return format; -} -#endif - -void BrowserActionDragData::WriteToPickle( - Profile* profile, Pickle* pickle) const { - ProfileId profile_id = profile->GetRuntimeId(); - pickle->WriteBytes(&profile_id, sizeof(profile_id)); - pickle->WriteString(id_); - pickle->WriteSize(index_); -} - -bool BrowserActionDragData::ReadFromPickle(Pickle* pickle) { - void* data_iterator = NULL; - - const char* tmp; - if (!pickle->ReadBytes(&data_iterator, &tmp, sizeof(profile_id_))) - return false; - memcpy(&profile_id_, tmp, sizeof(profile_id_)); - - if (!pickle->ReadString(&data_iterator, &id_)) - return false; - - if (!pickle->ReadSize(&data_iterator, &index_)) - return false; - - return true; -} diff --git a/chrome/browser/views/extensions/browser_action_drag_data.h b/chrome/browser/views/extensions/browser_action_drag_data.h index 33995fd..ee3ac8f 100644 --- a/chrome/browser/views/extensions/browser_action_drag_data.h +++ b/chrome/browser/views/extensions/browser_action_drag_data.h @@ -6,59 +6,8 @@ #define CHROME_BROWSER_VIEWS_EXTENSIONS_BROWSER_ACTION_DRAG_DATA_H_ #pragma once -#include <string> - -#include "base/basictypes.h" -#include "chrome/browser/profile.h" - -#if defined(TOOLKIT_VIEWS) -#include "app/os_exchange_data.h" -#endif - -class BrowserActionButton; -class FilePath; -class Pickle; -class Profile; - -class BrowserActionDragData { - public: - BrowserActionDragData(); - BrowserActionDragData(const std::string& id, int index); - - const std::string& id() const { return id_; } - - size_t index() const { return index_; } - - // Returns true if this data is from the specified profile. - bool IsFromProfile(Profile* profile) const; - -#if defined(TOOLKIT_VIEWS) - void Write(Profile* profile, OSExchangeData* data) const; - - // Restores this data from the clipboard, returning true on success. - bool Read(const OSExchangeData& data); - - // Returns the Custom Format this class supports (for Browser Actions). - static OSExchangeData::CustomFormat GetBrowserActionCustomFormat(); -#endif - - private: - void WriteToPickle(Profile* profile, Pickle* pickle) const; - bool ReadFromPickle(Pickle* pickle); - - // ID of the profile we originated from. - ProfileId profile_id_; - - // The id of the view being dragged. - std::string id_; - - // The index of the view being dragged. - size_t index_; - - // The MIME type for the clipboard format for BrowserActionDragData. - static const char* kClipboardFormatString; - - DISALLOW_COPY_AND_ASSIGN(BrowserActionDragData); -}; +#include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_EXTENSIONS_BROWSER_ACTION_DRAG_DATA_H_ + diff --git a/chrome/browser/views/extensions/browser_action_drag_data_unittest.cc b/chrome/browser/views/extensions/browser_action_drag_data_unittest.cc deleted file mode 100644 index 226591f..0000000 --- a/chrome/browser/views/extensions/browser_action_drag_data_unittest.cc +++ /dev/null @@ -1,56 +0,0 @@ -// 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 "app/os_exchange_data.h" -#include "app/os_exchange_data_provider_win.h" -#include "base/pickle.h" -#include "chrome/browser/views/extensions/browser_action_drag_data.h" -#include "chrome/test/testing_profile.h" -#include "googleurl/src/gurl.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -OSExchangeData::Provider* CloneProvider(const OSExchangeData& data) { - return new OSExchangeDataProviderWin( - OSExchangeDataProviderWin::GetIDataObject(data)); -} - -} // namespace - -typedef testing::Test BrowserActionDragDataTest; - -TEST_F(BrowserActionDragDataTest, ArbitraryFormat) { - TestingProfile profile; - profile.SetID(L"id"); - - OSExchangeData data; - data.SetURL(GURL("http://www.google.com"), L"Title"); - - // We only support our format, so this should not succeed. - BrowserActionDragData drag_data; - EXPECT_FALSE(drag_data.Read(OSExchangeData(CloneProvider(data)))); -} - -TEST_F(BrowserActionDragDataTest, BrowserActionDragDataFormat) { - TestingProfile profile; - profile.SetID(L"id"); - - const std::string extension_id = "42"; - const ProfileId profile_id = profile.GetRuntimeId(); - Pickle pickle; - pickle.WriteBytes(&profile_id, sizeof(profile_id)); - pickle.WriteString(extension_id); - pickle.WriteInt(42); - - OSExchangeData data; - data.SetPickledData(BrowserActionDragData::GetBrowserActionCustomFormat(), - pickle); - - BrowserActionDragData drag_data; - EXPECT_TRUE(drag_data.Read(OSExchangeData(CloneProvider(data)))); - ASSERT_TRUE(drag_data.IsFromProfile(profile.GetOriginalProfile())); - ASSERT_STREQ(extension_id.c_str(), drag_data.id().c_str()); - ASSERT_EQ(42, drag_data.index()); -} diff --git a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.cc b/chrome/browser/views/extensions/browser_action_overflow_menu_controller.cc deleted file mode 100644 index aa072f6..0000000 --- a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.cc +++ /dev/null @@ -1,209 +0,0 @@ -// 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/extensions/browser_action_overflow_menu_controller.h" - -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/extensions/extension_context_menu_model.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/browser_actions_container.h" -#include "chrome/browser/views/extensions/browser_action_drag_data.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/extension_action.h" -#include "gfx/canvas_skia.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/controls/menu/menu_2.h" - -BrowserActionOverflowMenuController::BrowserActionOverflowMenuController( - BrowserActionsContainer* owner, - views::MenuButton* menu_button, - const std::vector<BrowserActionView*>& views, - int start_index) - : owner_(owner), - observer_(NULL), - menu_button_(menu_button), - views_(&views), - start_index_(start_index), - for_drop_(false) { - menu_.reset(new views::MenuItemView(this)); - menu_->set_has_icons(true); - - size_t command_id = 1; // Menu id 0 is reserved, start with 1. - for (size_t i = start_index; i < views_->size(); ++i) { - BrowserActionView* view = (*views_)[i]; - scoped_ptr<gfx::Canvas> canvas(view->GetIconWithBadge()); - menu_->AppendMenuItemWithIcon( - command_id, - UTF8ToWide(view->button()->extension()->name()), - canvas->AsCanvasSkia()->ExtractBitmap()); - - // Set the tooltip for this item. - std::wstring tooltip = UTF8ToWide( - view->button()->extension()->browser_action()->GetTitle( - owner_->GetCurrentTabId())); - menu_->SetTooltip(tooltip, command_id); - - ++command_id; - } -} - -BrowserActionOverflowMenuController::~BrowserActionOverflowMenuController() { - if (observer_) - observer_->NotifyMenuDeleted(this); -} - -bool BrowserActionOverflowMenuController::RunMenu(gfx::NativeWindow window, - bool for_drop) { - for_drop_ = for_drop; - - gfx::Rect bounds = menu_button_->GetBounds( - views::View::IGNORE_MIRRORING_TRANSFORMATION); - gfx::Point screen_loc; - views::View::ConvertPointToScreen(menu_button_, &screen_loc); - bounds.set_x(screen_loc.x()); - bounds.set_y(screen_loc.y()); - - views::MenuItemView::AnchorPosition anchor = base::i18n::IsRTL() ? - views::MenuItemView::TOPLEFT : views::MenuItemView::TOPRIGHT; - if (for_drop) { - menu_->RunMenuForDropAt(window, bounds, anchor); - } else { - menu_->RunMenuAt(window, menu_button_, bounds, anchor, false); - // Give the context menu (if any) a chance to execute the user-selected - // command. - MessageLoop::current()->DeleteSoon(FROM_HERE, this); - } - return true; -} - -void BrowserActionOverflowMenuController::CancelMenu() { - menu_->Cancel(); -} - -void BrowserActionOverflowMenuController::ExecuteCommand(int id) { - BrowserActionView* view = (*views_)[start_index_ + id - 1]; - owner_->OnBrowserActionExecuted(view->button(), - false); // inspect_with_devtools -} - -bool BrowserActionOverflowMenuController::ShowContextMenu( - views::MenuItemView* source, - int id, - const gfx::Point& p, - bool is_mouse_gesture) { - context_menu_contents_ = new ExtensionContextMenuModel( - (*views_)[start_index_ + id - 1]->button()->extension(), - owner_->browser(), - owner_); - context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get())); - // This blocks until the user choses something or dismisses the menu. - context_menu_menu_->RunContextMenuAt(p); - - // The user is done with the context menu, so we can close the underlying - // menu. - menu_->Cancel(); - - return true; -} - -void BrowserActionOverflowMenuController::DropMenuClosed( - views::MenuItemView* menu) { - delete this; -} - -bool BrowserActionOverflowMenuController::GetDropFormats( - views::MenuItemView* menu, - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats) { - custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat()); - return true; -} - -bool BrowserActionOverflowMenuController::AreDropTypesRequired( - views::MenuItemView* menu) { - return true; -} - -bool BrowserActionOverflowMenuController::CanDrop( - views::MenuItemView* menu, const OSExchangeData& data) { - BrowserActionDragData drop_data; - if (!drop_data.Read(data)) - return false; - return drop_data.IsFromProfile(owner_->profile()); -} - -int BrowserActionOverflowMenuController::GetDropOperation( - views::MenuItemView* item, - const views::DropTargetEvent& event, - DropPosition* position) { - // Don't allow dropping from the BrowserActionContainer into slot 0 of the - // overflow menu since once the move has taken place the item you are dragging - // falls right out of the menu again once the user releases the button - // (because we don't shrink the BrowserActionContainer when you do this). - if ((item->GetCommand() == 0) && (*position == DROP_BEFORE)) { - BrowserActionDragData drop_data; - if (!drop_data.Read(event.GetData())) - return DragDropTypes::DRAG_NONE; - - if (drop_data.index() < owner_->VisibleBrowserActions()) - return DragDropTypes::DRAG_NONE; - } - - return DragDropTypes::DRAG_MOVE; -} - -int BrowserActionOverflowMenuController::OnPerformDrop( - views::MenuItemView* menu, - DropPosition position, - const views::DropTargetEvent& event) { - BrowserActionDragData drop_data; - if (!drop_data.Read(event.GetData())) - return DragDropTypes::DRAG_NONE; - - size_t drop_index; - ViewForId(menu->GetCommand(), &drop_index); - - // When not dragging within the overflow menu (dragging an icon into the menu) - // subtract one to get the right index. - if (position == DROP_BEFORE && - drop_data.index() < owner_->VisibleBrowserActions()) - --drop_index; - - owner_->MoveBrowserAction(drop_data.id(), drop_index); - - if (for_drop_) - delete this; - return DragDropTypes::DRAG_MOVE; -} - -bool BrowserActionOverflowMenuController::CanDrag(views::MenuItemView* menu) { - return true; -} - -void BrowserActionOverflowMenuController::WriteDragData( - views::MenuItemView* sender, OSExchangeData* data) { - size_t drag_index; - BrowserActionView* view = ViewForId(sender->GetCommand(), &drag_index); - std::string id = view->button()->extension()->id(); - - BrowserActionDragData drag_data(id, drag_index); - drag_data.Write(owner_->profile(), data); -} - -int BrowserActionOverflowMenuController::GetDragOperations( - views::MenuItemView* sender) { - return DragDropTypes::DRAG_MOVE; -} - -BrowserActionView* BrowserActionOverflowMenuController::ViewForId( - int id, size_t* index) { - // The index of the view being dragged (GetCommand gives a 1-based index into - // the overflow menu). - size_t view_index = owner_->VisibleBrowserActions() + id - 1; - if (index) - *index = view_index; - return owner_->GetBrowserActionViewAt(view_index); -} diff --git a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h b/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h index 08a0d55..5023765 100644 --- a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h +++ b/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h @@ -6,112 +6,8 @@ #define CHROME_BROWSER_VIEWS_EXTENSIONS_BROWSER_ACTION_OVERFLOW_MENU_CONTROLLER_H_ #pragma once -#include <set> -#include <vector> - -#include "base/scoped_ptr.h" -#include "base/task.h" -#include "views/controls/menu/menu_delegate.h" - -class BrowserActionsContainer; -class BrowserActionView; -class ExtensionContextMenuModel; - -namespace views { -class Menu2; -} - -// This class handles the overflow menu for browser actions (showing the menu, -// drag and drop, etc). This class manages its own lifetime. -class BrowserActionOverflowMenuController : public views::MenuDelegate { - public: - // The observer is notified prior to the menu being deleted. - class Observer { - public: - virtual void NotifyMenuDeleted( - BrowserActionOverflowMenuController* controller) = 0; - }; - - BrowserActionOverflowMenuController( - BrowserActionsContainer* owner, - views::MenuButton* menu_button, - const std::vector<BrowserActionView*>& views, - int start_index); - - void set_observer(Observer* observer) { observer_ = observer; } - - // Shows the overflow menu. - bool RunMenu(gfx::NativeWindow window, bool for_drop); - - // Closes the overflow menu (and its context menu if open as well). - void CancelMenu(); - - // Overridden from views::MenuDelegate: - virtual void ExecuteCommand(int id); - virtual bool ShowContextMenu(views::MenuItemView* source, - int id, - const gfx::Point& p, - bool is_mouse_gesture); - virtual void DropMenuClosed(views::MenuItemView* menu); - // These drag functions offer support for dragging icons into the overflow - // menu. - virtual bool GetDropFormats( - views::MenuItemView* menu, - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats); - virtual bool AreDropTypesRequired(views::MenuItemView* menu); - virtual bool CanDrop(views::MenuItemView* menu, const OSExchangeData& data); - virtual int GetDropOperation(views::MenuItemView* item, - const views::DropTargetEvent& event, - DropPosition* position); - virtual int OnPerformDrop(views::MenuItemView* menu, - DropPosition position, - const views::DropTargetEvent& event); - // These three drag functions offer support for dragging icons out of the - // overflow menu. - virtual bool CanDrag(views::MenuItemView* menu); - virtual void WriteDragData(views::MenuItemView* sender, OSExchangeData* data); - virtual int GetDragOperations(views::MenuItemView* sender); - - private: - // This class manages its own lifetime. - virtual ~BrowserActionOverflowMenuController(); - - // Converts a menu item |id| into a BrowserActionView by adding the |id| value - // to the number of visible views (according to the container owner). If - // |index| is specified, it will point to the absolute index of the view. - BrowserActionView* ViewForId(int id, size_t* index); - - // A pointer to the browser action container that owns the overflow menu. - BrowserActionsContainer* owner_; - - // The observer, may be null. - Observer* observer_; - - // A pointer to the overflow menu button that we are showing the menu for. - views::MenuButton* menu_button_; - - // The overflow menu for the menu button. - scoped_ptr<views::MenuItemView> menu_; - - // The views vector of all the browser actions the container knows about. We - // won't show all items, just the one starting at |start_index| and above. - const std::vector<BrowserActionView*>* views_; - - // The index into the BrowserActionView vector, indicating where to start - // picking browser actions to draw. - int start_index_; - - // Whether this controller is being used for drop. - bool for_drop_; - - // The browser action context menu and model. - scoped_refptr<ExtensionContextMenuModel> context_menu_contents_; - scoped_ptr<views::Menu2> context_menu_menu_; - - friend class DeleteTask<BrowserActionOverflowMenuController>; - - DISALLOW_COPY_AND_ASSIGN(BrowserActionOverflowMenuController); -}; +#include "chrome/browser/ui/views/extensions/browser_action_overflow_menu_controller.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_EXTENSIONS_BROWSER_ACTION_OVERFLOW_MENU_CONTROLLER_H_ + diff --git a/chrome/browser/views/extensions/extension_install_prompt.cc b/chrome/browser/views/extensions/extension_install_prompt.cc deleted file mode 100644 index 5cf1e7b..0000000 --- a/chrome/browser/views/extensions/extension_install_prompt.cc +++ /dev/null @@ -1,167 +0,0 @@ -// 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 "app/l10n_util.h" -#include "base/file_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/extensions/extension_install_ui.h" -#include "chrome/browser/views/window.h" -#include "chrome/common/extensions/extension.h" -#include "grit/generated_resources.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/link.h" -#include "views/standard_layout.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "app/win_util.h" -#endif - -class Profile; - -namespace { - -const int kRightColumnWidth = 210; -const int kIconSize = 69; - -// Implements the extension installation prompt for Windows. -class InstallDialogContent : public views::View, public views::DialogDelegate { - public: - InstallDialogContent(ExtensionInstallUI::Delegate* delegate, - const Extension* extension, - SkBitmap* icon, - ExtensionInstallUI::PromptType type) - : delegate_(delegate), icon_(NULL), type_(type) { - // Scale down to icon size, but allow smaller icons (don't scale up). - gfx::Size size(icon->width(), icon->height()); - if (size.width() > kIconSize || size.height() > kIconSize) - size = gfx::Size(kIconSize, kIconSize); - icon_ = new views::ImageView(); - icon_->SetImageSize(size); - icon_->SetImage(*icon); - AddChildView(icon_); - - heading_ = new views::Label( - l10n_util::GetStringF(ExtensionInstallUI::kHeadingIds[type_], - UTF8ToWide(extension->name()))); - heading_->SetMultiLine(true); - heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(heading_); - } - - private: - // DialogDelegate - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString(ExtensionInstallUI::kButtonIds[type_]); - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return l10n_util::GetString(IDS_CANCEL); - default: - NOTREACHED(); - return L""; - } - } - - virtual int GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - - virtual bool Accept() { - delegate_->InstallUIProceed(); - return true; - } - - virtual bool Cancel() { - delegate_->InstallUIAbort(); - return true; - } - - // WindowDelegate - virtual bool IsModal() const { return true; } - virtual std::wstring GetWindowTitle() const { - return l10n_util::GetString(ExtensionInstallUI::kTitleIds[type_]); - } - virtual views::View* GetContentsView() { return this; } - - // View - virtual gfx::Size GetPreferredSize() { - int width = kRightColumnWidth; - width += kIconSize; - width += kPanelHorizMargin * 3; - - int height = kPanelVertMargin * 2; - height += heading_->GetHeightForWidth(kRightColumnWidth); - - return gfx::Size(width, - std::max(height, kIconSize + kPanelVertMargin * 2)); - } - - virtual void Layout() { - int x = kPanelHorizMargin; - int y = kPanelVertMargin; - - heading_->SizeToFit(kRightColumnWidth); - - if (heading_->height() <= kIconSize) { - icon_->SetBounds(x, y, kIconSize, kIconSize); - x += kIconSize; - x += kPanelHorizMargin; - - heading_->SetX(x); - heading_->SetY(y + (kIconSize - heading_->height()) / 2); - } else { - icon_->SetBounds(x, - y + (heading_->height() - kIconSize) / 2, - kIconSize, - kIconSize); - x += kIconSize; - x += kPanelHorizMargin; - - heading_->SetX(x); - heading_->SetY(y); - } - } - - ExtensionInstallUI::Delegate* delegate_; - views::ImageView* icon_; - views::Label* heading_; - ExtensionInstallUI::PromptType type_; - - DISALLOW_COPY_AND_ASSIGN(InstallDialogContent); -}; - -} // namespace - -// static -void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl( - Profile* profile, - Delegate* delegate, - const Extension* extension, - SkBitmap* icon, - PromptType type) { - Browser* browser = BrowserList::GetLastActiveWithProfile(profile); - if (!browser) { - delegate->InstallUIAbort(); - return; - } - - BrowserWindow* window = browser->window(); - if (!window) { - delegate->InstallUIAbort(); - return; - } - - browser::CreateViewsWindow(window->GetNativeHandle(), gfx::Rect(), - new InstallDialogContent(delegate, extension, icon, - type))->Show(); -} diff --git a/chrome/browser/views/extensions/extension_install_prompt2.cc b/chrome/browser/views/extensions/extension_install_prompt2.cc deleted file mode 100644 index ba9631e..0000000 --- a/chrome/browser/views/extensions/extension_install_prompt2.cc +++ /dev/null @@ -1,320 +0,0 @@ -// 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 "app/l10n_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/extensions/extension_install_ui.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/browser/views/window.h" -#include "grit/generated_resources.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/standard_layout.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -class Profile; - -namespace { - -// Size of extension icon in top left of dialog. -const int kIconSize = 69; - -// Width of the white permission box. This also is the max width of all -// elements in the right column of the dialog in the case where the extension -// requests permissions. -const int kPermissionBoxWidth = 270; - -// Width of the right column of the dialog when the extension requests no -// permissions. -const int kNoPermissionsRightColumnWidth = 210; - -// Width of the gray border around the permission box. -const int kPermissionBoxBorderWidth = 1; - -// Width of the horizontal padding inside the permission box border. -const int kPermissionBoxHorizontalPadding = 10; - -// Width of the vertical padding inside the permission box border. -const int kPermissionBoxVerticalPadding = 11; - -// The max width of the individual permission strings inside the permission -// box. -const int kPermissionLabelWidth = - kPermissionBoxWidth - - kPermissionBoxBorderWidth * 2 - - kPermissionBoxHorizontalPadding * 2; - -} // namespace - - -// Implements the extension installation prompt for TOOLKIT_VIEWS. -class InstallDialogContent2 - : public views::View, public views::DialogDelegate { - public: - InstallDialogContent2(ExtensionInstallUI::Delegate* delegate, - const Extension* extension, - SkBitmap* icon, - const std::vector<string16>& permissions); - - private: - // DialogDelegate overrides. - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual int GetDefaultDialogButton() const; - virtual bool Accept(); - virtual bool Cancel(); - - // WindowDelegate overrides. - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual views::View* GetContentsView(); - - // View overrides. - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - // The delegate that we will call back to when the user accepts or rejects - // the installation. - ExtensionInstallUI::Delegate* delegate_; - - // Displays the extension's icon. - views::ImageView* icon_; - - // Displays the main heading "Install FooBar?". - views::Label* heading_; - - // Displays the permission box header "The extension will have access to:". - views::Label* will_have_access_to_; - - // The white box containing the list of permissions the extension requires. - // This can be NULL if the extension requires no permissions. - views::View* permission_box_; - - // The labels describing each of the permissions the extension requires. - std::vector<views::Label*> permissions_; - - // The width of the right column of the dialog. Will be either - // kPermissionBoxWidth or kNoPermissionsRightColumnWidth, depending on - // whether the extension requires any permissions. - int right_column_width_; - - DISALLOW_COPY_AND_ASSIGN(InstallDialogContent2); -}; - - -InstallDialogContent2::InstallDialogContent2( - ExtensionInstallUI::Delegate* delegate, const Extension* extension, - SkBitmap* icon, const std::vector<string16>& permissions) - : delegate_(delegate), - icon_(NULL), - heading_(NULL), - will_have_access_to_(NULL), - permission_box_(NULL), - right_column_width_(0) { - // Scale down to icon size, but allow smaller icons (don't scale up). - gfx::Size size(icon->width(), icon->height()); - if (size.width() > kIconSize || size.height() > kIconSize) - size = gfx::Size(kIconSize, kIconSize); - icon_ = new views::ImageView(); - icon_->SetImageSize(size); - icon_->SetImage(*icon); - icon_->SetHorizontalAlignment(views::ImageView::CENTER); - icon_->SetVerticalAlignment(views::ImageView::CENTER); - AddChildView(icon_); - - heading_ = new views::Label( - l10n_util::GetStringF(IDS_EXTENSION_INSTALL_PROMPT_HEADING, - UTF8ToWide(extension->name()))); - heading_->SetFont(heading_->font().DeriveFont(1, gfx::Font::BOLD)); - heading_->SetMultiLine(true); - heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(heading_); - - if (permissions.size() == 0) { - right_column_width_ = kNoPermissionsRightColumnWidth; - } else { - right_column_width_ = kPermissionBoxWidth; - int label = extension->is_app() ? - IDS_EXTENSION_PROMPT2_APP_WILL_HAVE_ACCESS_TO : - IDS_EXTENSION_PROMPT2_WILL_HAVE_ACCESS_TO; - will_have_access_to_ = new views::Label(l10n_util::GetString(label)); - will_have_access_to_->SetMultiLine(true); - will_have_access_to_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(will_have_access_to_); - - permission_box_ = new views::View(); - permission_box_->set_background( - views::Background::CreateSolidBackground(SK_ColorWHITE)); - permission_box_->set_border( - views::Border::CreateSolidBorder(kPermissionBoxBorderWidth, - SK_ColorLTGRAY)); - AddChildView(permission_box_); - } - - for (size_t i = 0; i < permissions.size(); ++i) { - views::Label* label = new views::Label(UTF16ToWide(permissions[i])); - label->SetMultiLine(true); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - permission_box_->AddChildView(label); - permissions_.push_back(label); - } -} - -std::wstring InstallDialogContent2::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString(IDS_EXTENSION_PROMPT_INSTALL_BUTTON); - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return l10n_util::GetString(IDS_CANCEL); - default: - NOTREACHED(); - return L""; - } -} - -int InstallDialogContent2::GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -bool InstallDialogContent2::Accept() { - delegate_->InstallUIProceed(); - return true; -} - -bool InstallDialogContent2::Cancel() { - delegate_->InstallUIAbort(); - return true; -} - -bool InstallDialogContent2::IsModal() const { - return true; -} - -std::wstring InstallDialogContent2::GetWindowTitle() const { - return l10n_util::GetString(IDS_EXTENSION_INSTALL_PROMPT_TITLE); -} - -views::View* InstallDialogContent2::GetContentsView() { - return this; -} - -gfx::Size InstallDialogContent2::GetPreferredSize() { - int width = kPanelHorizMargin * 2; - width += kIconSize; - width += kPanelHorizMargin; // Gutter. - width += right_column_width_; - - int height = kPanelVertMargin * 2; - height += heading_->GetHeightForWidth(right_column_width_); - - if (permission_box_) { - height += kRelatedControlVerticalSpacing; - height += will_have_access_to_->GetHeightForWidth(right_column_width_); - - height += kRelatedControlVerticalSpacing; - height += kPermissionBoxBorderWidth * 2; - height += kPermissionBoxVerticalPadding * 2; - - for (size_t i = 0; i < permissions_.size(); ++i) { - if (i > 0) - height += kRelatedControlVerticalSpacing; - height += permissions_[0]->GetHeightForWidth(kPermissionLabelWidth); - } - } - - return gfx::Size(width, std::max(height, kIconSize + kPanelVertMargin * 2)); -} - -void InstallDialogContent2::Layout() { - int x = kPanelHorizMargin; - int y = kPanelVertMargin; - - icon_->SetBounds(x, y, kIconSize, kIconSize); - x += kIconSize; - x += kPanelHorizMargin; - - heading_->SizeToFit(right_column_width_); - heading_->SetX(x); - - // If there's no special permissions, we do a slightly different layout with - // the heading centered vertically wrt the icon. - if (!permission_box_) { - heading_->SetY((GetPreferredSize().height() - heading_->height()) / 2); - return; - } - - // Otherwise, do the layout with the permission box. - heading_->SetY(y); - y += heading_->height(); - - y += kRelatedControlVerticalSpacing; - will_have_access_to_->SizeToFit(right_column_width_); - will_have_access_to_->SetX(x); - will_have_access_to_->SetY(y); - y += will_have_access_to_->height(); - - y += kRelatedControlVerticalSpacing; - permission_box_->SetX(x); - permission_box_->SetY(y); - - // First we layout the labels inside the permission box, so that we know how - // big the box will have to be. - int label_x = kPermissionBoxBorderWidth + kPermissionBoxHorizontalPadding; - int label_y = kPermissionBoxBorderWidth + kPermissionBoxVerticalPadding; - int permission_box_height = kPermissionBoxBorderWidth * 2; - permission_box_height += kPermissionBoxVerticalPadding * 2; - - for (size_t i = 0; i < permissions_.size(); ++i) { - if (i > 0) { - label_y += kRelatedControlVerticalSpacing; - permission_box_height += kPanelVertMargin; - } - - permissions_[i]->SizeToFit(kPermissionLabelWidth); - permissions_[i]->SetX(label_x); - permissions_[i]->SetY(label_y); - - label_y += permissions_[i]->height(); - permission_box_height += permissions_[i]->height(); - } - - // Now finally we can size the permission box itself. - permission_box_->SetBounds(permission_box_->x(), permission_box_->y(), - right_column_width_, permission_box_height); -} - -// static -void ExtensionInstallUI::ShowExtensionInstallUIPrompt2Impl( - Profile* profile, Delegate* delegate, const Extension* extension, - SkBitmap* icon, - const std::vector<string16>& permissions) { -#if defined(OS_CHROMEOS) - // Use a normal browser window as parent on ChromeOS. - Browser* browser = BrowserList::FindBrowserWithType(profile, - Browser::TYPE_NORMAL, - true); -#else - Browser* browser = BrowserList::GetLastActiveWithProfile(profile); -#endif - if (!browser) { - delegate->InstallUIAbort(); - return; - } - - BrowserWindow* window = browser->window(); - if (!window) { - delegate->InstallUIAbort(); - return; - } - - browser::CreateViewsWindow(window->GetNativeHandle(), gfx::Rect(), - new InstallDialogContent2(delegate, extension, icon, permissions)) - ->Show(); -} diff --git a/chrome/browser/views/extensions/extension_installed_bubble.cc b/chrome/browser/views/extensions/extension_installed_bubble.cc deleted file mode 100644 index 8cb9397..0000000 --- a/chrome/browser/views/extensions/extension_installed_bubble.cc +++ /dev/null @@ -1,389 +0,0 @@ -// 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/extensions/extension_installed_bubble.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/message_loop.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/shell_integration.h" -#include "chrome/browser/views/browser_actions_container.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "chrome/browser/views/tabs/base_tab.h" -#include "chrome/browser/views/tabs/base_tab_strip.h" -#include "chrome/browser/views/toolbar_view.h" -#include "chrome/browser/web_applications/web_app.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/extension_action.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/button/image_button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/standard_layout.h" -#include "views/view.h" - -namespace { - -const int kIconSize = 43; - -const int kRightColumnWidth = 285; - -// The InfoBubble uses a BubbleBorder which adds about 6 pixels of whitespace -// around the content view. We compensate by reducing our outer borders by this -// amount + 4px. -const int kOuterMarginInset = 10; -const int kHorizOuterMargin = kPanelHorizMargin - kOuterMarginInset; -const int kVertOuterMargin = kPanelVertMargin - kOuterMarginInset; - -// Interior vertical margin is 8px smaller than standard -const int kVertInnerMargin = kPanelVertMargin - 8; - -// The image we use for the close button has three pixels of whitespace padding. -const int kCloseButtonPadding = 3; - -// We want to shift the right column (which contains the header and text) up -// 4px to align with icon. -const int kRightcolumnVerticalShift = -4; - -// How long to wait for browser action animations to complete before retrying. -const int kAnimationWaitTime = 50; - -// How often we retry when waiting for browser action animation to end. -const int kAnimationWaitMaxRetry = 10; - -} // namespace - -// InstalledBubbleContent is the content view which is placed in the -// ExtensionInstalledBubble. It displays the install icon and explanatory -// text about the installed extension. -class InstalledBubbleContent : public views::View, - public views::ButtonListener { - public: - InstalledBubbleContent(const Extension* extension, - ExtensionInstalledBubble::BubbleType type, - SkBitmap* icon) - : info_bubble_(NULL), - type_(type), - info_(NULL), - create_shortcut_(false) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& font = rb.GetFont(ResourceBundle::BaseFont); - - // Scale down to 43x43, but allow smaller icons (don't scale up). - gfx::Size size(icon->width(), icon->height()); - if (size.width() > kIconSize || size.height() > kIconSize) - size = gfx::Size(kIconSize, kIconSize); - icon_ = new views::ImageView(); - icon_->SetImageSize(size); - icon_->SetImage(*icon); - AddChildView(icon_); - - heading_ = new views::Label( - l10n_util::GetStringF(IDS_EXTENSION_INSTALLED_HEADING, - UTF8ToWide(extension->name()))); - heading_->SetFont(font.DeriveFont(3, gfx::Font::NORMAL)); - heading_->SetMultiLine(true); - heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(heading_); - - if (type_ == ExtensionInstalledBubble::PAGE_ACTION) { - info_ = new views::Label(l10n_util::GetString( - IDS_EXTENSION_INSTALLED_PAGE_ACTION_INFO)); - info_->SetFont(font); - info_->SetMultiLine(true); - info_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(info_); - } - - std::wstring text; - if (type_ == ExtensionInstalledBubble::EXTENSION_APP) - text = l10n_util::GetString(IDS_EXTENSION_APP_INSTALLED_MANAGE_INFO); - else - text = l10n_util::GetString(IDS_EXTENSION_INSTALLED_MANAGE_INFO); - manage_ = new views::Label(text); - manage_->SetFont(font); - manage_->SetMultiLine(true); - manage_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(manage_); - - close_button_ = new views::ImageButton(this); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_CLOSE_BAR)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); - AddChildView(close_button_); - - if (type_ == ExtensionInstalledBubble::EXTENSION_APP) { - create_shortcut_view_ = new views::Checkbox( - l10n_util::GetString(IDS_EXTENSION_PROMPT_CREATE_SHORTCUT)); - create_shortcut_view_->set_listener(this); - create_shortcut_view_->SetMultiLine(true); - AddChildView(create_shortcut_view_); - } - } - - // Whether to create a shortcut once the bubble closes. - bool create_shortcut() { return create_shortcut_;} - - void set_info_bubble(InfoBubble* info_bubble) { info_bubble_ = info_bubble; } - - virtual void ButtonPressed( - views::Button* sender, - const views::Event& event) { - if (sender == close_button_) { - info_bubble_->set_fade_away_on_close(true); - GetWidget()->Close(); - } else if (sender == create_shortcut_view_) { - create_shortcut_ = create_shortcut_view_->checked(); - } else { - NOTREACHED() << "Unknown view"; - } - } - - private: - virtual gfx::Size GetPreferredSize() { - int width = kHorizOuterMargin; - width += kIconSize; - width += kPanelHorizMargin; - width += kRightColumnWidth; - width += 2*kPanelHorizMargin; - width += kHorizOuterMargin; - - int height = kVertOuterMargin; - height += heading_->GetHeightForWidth(kRightColumnWidth); - height += kVertInnerMargin; - if (type_ == ExtensionInstalledBubble::PAGE_ACTION) { - height += info_->GetHeightForWidth(kRightColumnWidth); - height += kVertInnerMargin; - } - height += manage_->GetHeightForWidth(kRightColumnWidth); - height += kVertOuterMargin; - if (type_ == ExtensionInstalledBubble::EXTENSION_APP) { - height += create_shortcut_view_->GetHeightForWidth(kRightColumnWidth); - height += kVertInnerMargin; - } - return gfx::Size(width, std::max(height, kIconSize + 2 * kVertOuterMargin)); - } - - virtual void Layout() { - int x = kHorizOuterMargin; - int y = kVertOuterMargin; - - icon_->SetBounds(x, y, kIconSize, kIconSize); - x += kIconSize; - x += kPanelHorizMargin; - - y += kRightcolumnVerticalShift; - heading_->SizeToFit(kRightColumnWidth); - heading_->SetX(x); - heading_->SetY(y); - y += heading_->height(); - y += kVertInnerMargin; - - if (type_ == ExtensionInstalledBubble::PAGE_ACTION) { - info_->SizeToFit(kRightColumnWidth); - info_->SetX(x); - info_->SetY(y); - y += info_->height(); - y += kVertInnerMargin; - } - - manage_->SizeToFit(kRightColumnWidth); - manage_->SetX(x); - manage_->SetY(y); - y += manage_->height(); - y += kVertInnerMargin; - - gfx::Size sz; - if (type_ == ExtensionInstalledBubble::EXTENSION_APP) { - sz.set_height( - create_shortcut_view_->GetHeightForWidth(kRightColumnWidth)); - sz.set_width(kRightColumnWidth); - create_shortcut_view_->SetBounds(x, y, sz.width(), sz.height()); - y += create_shortcut_view_->height(); - y += kVertInnerMargin; - } - - x += kRightColumnWidth + 2*kPanelHorizMargin + kHorizOuterMargin - - close_button_->GetPreferredSize().width(); - y = kVertOuterMargin; - sz = close_button_->GetPreferredSize(); - // x-1 & y-1 is just slop to get the close button visually aligned with the - // title text and bubble arrow. - close_button_->SetBounds(x - 1, y - 1, sz.width(), sz.height()); - } - - // The InfoBubble showing us. - InfoBubble* info_bubble_; - - ExtensionInstalledBubble::BubbleType type_; - views::ImageView* icon_; - views::Label* heading_; - views::Label* info_; - views::Label* manage_; - views::Checkbox* create_shortcut_view_; - views::ImageButton* close_button_; - - bool create_shortcut_; - - DISALLOW_COPY_AND_ASSIGN(InstalledBubbleContent); -}; - -void ExtensionInstalledBubble::Show(const Extension* extension, - Browser *browser, - SkBitmap icon) { - new ExtensionInstalledBubble(extension, browser, icon); -} - -ExtensionInstalledBubble::ExtensionInstalledBubble(const Extension* extension, - Browser *browser, - SkBitmap icon) - : extension_(extension), - browser_(browser), - icon_(icon), - animation_wait_retries_(0) { - AddRef(); // Balanced in InfoBubbleClosing. - - if (extension->GetFullLaunchURL().is_valid()) { - type_ = EXTENSION_APP; - } else if (extension_->browser_action()) { - type_ = BROWSER_ACTION; - } else if (extension->page_action() && - !extension->page_action()->default_icon_path().empty()) { - type_ = PAGE_ACTION; - } else { - type_ = GENERIC; - } - - // |extension| has been initialized but not loaded at this point. We need - // to wait on showing the Bubble until not only the EXTENSION_LOADED gets - // fired, but all of the EXTENSION_LOADED Observers have run. Only then can we - // be sure that a BrowserAction or PageAction has had views created which we - // can inspect for the purpose of previewing of pointing to them. - registrar_.Add(this, NotificationType::EXTENSION_LOADED, - Source<Profile>(browser->profile())); - registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, - Source<Profile>(browser->profile())); -} - -void ExtensionInstalledBubble::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::EXTENSION_LOADED) { - const Extension* extension = Details<const Extension>(details).ptr(); - if (extension == extension_) { - animation_wait_retries_ = 0; - // PostTask to ourself to allow all EXTENSION_LOADED Observers to run. - MessageLoopForUI::current()->PostTask(FROM_HERE, NewRunnableMethod(this, - &ExtensionInstalledBubble::ShowInternal)); - } - } else if (type == NotificationType::EXTENSION_UNLOADED) { - const Extension* extension = Details<const Extension>(details).ptr(); - if (extension == extension_) - extension_ = NULL; - } else { - NOTREACHED() << L"Received unexpected notification"; - } -} - -void ExtensionInstalledBubble::ShowInternal() { - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( - browser_->window()->GetNativeHandle()); - - const views::View* reference_view = NULL; - if (type_ == BROWSER_ACTION) { - BrowserActionsContainer* container = - browser_view->GetToolbarView()->browser_actions(); - if (container->animating() && - animation_wait_retries_++ < kAnimationWaitMaxRetry) { - // We don't know where the view will be until the container has stopped - // animating, so check back in a little while. - MessageLoopForUI::current()->PostDelayedTask( - FROM_HERE, NewRunnableMethod(this, - &ExtensionInstalledBubble::ShowInternal), kAnimationWaitTime); - return; - } - reference_view = container->GetBrowserActionView( - extension_->browser_action()); - // If the view is not visible then it is in the chevron, so point the - // install bubble to the chevron instead. If this is an incognito window, - // both could be invisible. - if (!reference_view || !reference_view->IsVisible()) { - reference_view = container->chevron(); - if (!reference_view || !reference_view->IsVisible()) - reference_view = NULL; // fall back to app menu below. - } - } else if (type_ == PAGE_ACTION) { - LocationBarView* location_bar_view = browser_view->GetLocationBarView(); - location_bar_view->SetPreviewEnabledPageAction(extension_->page_action(), - true); // preview_enabled - reference_view = location_bar_view->GetPageActionView( - extension_->page_action()); - DCHECK(reference_view); - } else if (type_ == EXTENSION_APP) { - BaseTabStrip* tabstrip = browser_view->tabstrip(); - BaseTab* tab = tabstrip->GetSelectedBaseTab(); - DCHECK(tab->data().app); - reference_view = tab; - } - - // Default case. - if (reference_view == NULL) - reference_view = browser_view->GetToolbarView()->app_menu(); - - gfx::Point origin; - views::View::ConvertPointToScreen(reference_view, &origin); - gfx::Rect bounds = reference_view->bounds(); - bounds.set_x(origin.x()); - bounds.set_y(origin.y()); - - bubble_content_ = new InstalledBubbleContent(extension_, type_, - &icon_); - InfoBubble* info_bubble = - InfoBubble::Show(browser_view->GetWidget(), bounds, - BubbleBorder::TOP_RIGHT, - bubble_content_, this); - bubble_content_->set_info_bubble(info_bubble); -} - -// InfoBubbleDelegate -void ExtensionInstalledBubble::InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape) { - if (extension_) { - if (type_ == PAGE_ACTION) { - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( - browser_->window()->GetNativeHandle()); - browser_view->GetLocationBarView()->SetPreviewEnabledPageAction( - extension_->page_action(), - false); // preview_enabled - } else if (type_ == EXTENSION_APP) { - if (bubble_content_->create_shortcut()) { - ShellIntegration::ShortcutInfo shortcut_info; - shortcut_info.url = extension_->GetFullLaunchURL(); - shortcut_info.extension_id = UTF8ToUTF16(extension_->id()); - shortcut_info.title = UTF8ToUTF16(extension_->name()); - shortcut_info.description = UTF8ToUTF16(extension_->description()); - shortcut_info.favicon = icon_; - shortcut_info.create_on_desktop = true; - shortcut_info.create_in_applications_menu = false; - shortcut_info.create_in_quick_launch_bar = false; - web_app::CreateShortcut(browser_->profile()->GetPath(), shortcut_info, - NULL); - } - } - } - - Release(); // Balanced in ctor. -} diff --git a/chrome/browser/views/extensions/extension_installed_bubble.h b/chrome/browser/views/extensions/extension_installed_bubble.h index a35f820..ab1c498 100644 --- a/chrome/browser/views/extensions/extension_installed_bubble.h +++ b/chrome/browser/views/extensions/extension_installed_bubble.h @@ -6,80 +6,8 @@ #define CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_INSTALLED_BUBBLE_H_ #pragma once -#include "base/ref_counted.h" -#include "chrome/browser/views/info_bubble.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "third_party/skia/include/core/SkBitmap.h" - -class Browser; -class Extension; -class InstalledBubbleContent; -class SkBitmap; - -// Provides feedback to the user upon successful installation of an -// extension. Depending on the type of extension, the InfoBubble will -// point to: -// BROWSER_ACTION -> The browserAction icon in the toolbar. -// PAGE_ACTION -> A preview of the pageAction icon in the location -// bar which is shown while the InfoBubble is shown. -// GENERIC -> The wrench menu. This case includes pageActions that -// don't specify a default icon. -// -// ExtensionInstallBubble manages its own lifetime. -class ExtensionInstalledBubble - : public InfoBubbleDelegate, - public NotificationObserver, - public base::RefCountedThreadSafe<ExtensionInstalledBubble> { - public: - // The behavior and content of this InfoBubble comes in these varieties: - enum BubbleType { - BROWSER_ACTION, - PAGE_ACTION, - EXTENSION_APP, - GENERIC - }; - - // Creates the ExtensionInstalledBubble and schedules it to be shown once - // the extension has loaded. |extension| is the installed extension. |browser| - // is the browser window which will host the bubble. |icon| is the install - // icon of the extension. - static void Show(const Extension* extension, Browser *browser, SkBitmap icon); - - private: - friend class base::RefCountedThreadSafe<ExtensionInstalledBubble>; - - // Private ctor. Registers a listener for EXTENSION_LOADED. - ExtensionInstalledBubble(const Extension* extension, Browser *browser, - SkBitmap icon); - - ~ExtensionInstalledBubble() {} - - // Shows the bubble. Called internally via PostTask. - void ShowInternal(); - - // NotificationObserver - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // InfoBubbleDelegate - virtual void InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape); - virtual bool CloseOnEscape() { return true; } - virtual bool FadeInOnShow() { return true; } - - const Extension* extension_; - Browser* browser_; - SkBitmap icon_; - NotificationRegistrar registrar_; - InstalledBubbleContent* bubble_content_; - BubbleType type_; - - // How many times we've deferred due to animations being in progress. - int animation_wait_retries_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionInstalledBubble); -}; +#include "chrome/browser/ui/views/extensions/extension_installed_bubble.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_INSTALLED_BUBBLE_H_ + diff --git a/chrome/browser/views/extensions/extension_popup.cc b/chrome/browser/views/extensions/extension_popup.cc deleted file mode 100644 index 0db98f6..0000000 --- a/chrome/browser/views/extensions/extension_popup.cc +++ /dev/null @@ -1,423 +0,0 @@ -// Copyright (c) 2009 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/extensions/extension_popup.h" - -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/debugger/devtools_manager.h" -#include "chrome/browser/debugger/devtools_toggle_action.h" -#include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/extensions/extension_process_manager.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" -#include "third_party/skia/include/core/SkColor.h" -#include "views/widget/root_view.h" -#include "views/window/window.h" - -#if defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/wm_ipc.h" -#include "cros/chromeos_wm_ipc_enums.h" -#endif - -using views::Widget; - -// The minimum/maximum dimensions of the popup. -// The minimum is just a little larger than the size of the button itself. -// The maximum is an arbitrary number that should be smaller than most screens. -const int ExtensionPopup::kMinWidth = 25; -const int ExtensionPopup::kMinHeight = 25; -const int ExtensionPopup::kMaxWidth = 800; -const int ExtensionPopup::kMaxHeight = 600; - -namespace { - -// The width, in pixels, of the black-border on a popup. -const int kPopupBorderWidth = 1; - -const int kPopupBubbleCornerRadius = BubbleBorder::GetCornerRadius() / 2; - -} // namespace - -ExtensionPopup::ExtensionPopup(ExtensionHost* host, - views::Widget* frame, - const gfx::Rect& relative_to, - BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show, - bool inspect_with_devtools, - PopupChrome chrome, - Observer* observer) - : BrowserBubble(host->view(), - frame, - gfx::Point(), - RECTANGLE_CHROME == chrome), // If no bubble chrome is to - // be displayed, then enable a - // drop-shadow on the bubble - // widget. - relative_to_(relative_to), - extension_host_(host), - activate_on_show_(activate_on_show), - inspect_with_devtools_(inspect_with_devtools), - close_on_lost_focus_(true), - closing_(false), - border_widget_(NULL), - border_(NULL), - border_view_(NULL), - popup_chrome_(chrome), - observer_(observer), - anchor_position_(arrow_location), - instance_lifetime_(new InternalRefCounter()){ - AddRef(); // Balanced in Close(); - set_delegate(this); - host->view()->SetContainer(this); - - // We wait to show the popup until the contained host finishes loading. - registrar_.Add(this, - NotificationType::EXTENSION_HOST_DID_STOP_LOADING, - Source<Profile>(host->profile())); - - // Listen for the containing view calling window.close(); - registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, - Source<Profile>(host->profile())); - - // TODO(erikkay) Some of this border code is derived from InfoBubble. - // We should see if we can unify these classes. - - // Keep relative_to_ in frame-relative coordinates to aid in drag - // positioning. - gfx::Point origin = relative_to_.origin(); - views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); - relative_to_.set_origin(origin); - - // The bubble chrome requires a separate window, so construct it here. - if (BUBBLE_CHROME == popup_chrome_) { - gfx::NativeView native_window = frame->GetNativeView(); -#if defined(OS_LINUX) - border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW); - static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent(); - static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent(); -#else - border_widget_ = Widget::CreatePopupWidget(Widget::Transparent, - Widget::NotAcceptEvents, - Widget::DeleteOnDestroy, - Widget::MirrorOriginInRTL); -#endif - border_widget_->Init(native_window, bounds()); -#if defined(OS_CHROMEOS) - chromeos::WmIpc::instance()->SetWindowType( - border_widget_->GetNativeView(), - chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE, - NULL); -#endif - border_ = new BubbleBorder(arrow_location); - border_view_ = new views::View; - border_view_->set_background(new BubbleBackground(border_)); - - border_view_->set_border(border_); - border_widget_->SetContentsView(border_view_); - // Ensure that the popup contents are always displayed ontop of the border - // widget. - border_widget_->MoveAbove(popup_); - } else { - // Otherwise simply set a black-border on the view containing the popup - // extension view. - views::Border* border = views::Border::CreateSolidBorder(kPopupBorderWidth, - SK_ColorBLACK); - view()->set_border(border); - } -} - -ExtensionPopup::~ExtensionPopup() { - // The widget is set to delete on destroy, so no leak here. - if (border_widget_) - border_widget_->Close(); -} - -void ExtensionPopup::SetArrowPosition( - BubbleBorder::ArrowLocation arrow_location) { - DCHECK_NE(BubbleBorder::NONE, arrow_location) << - "Extension popups must be positioned relative to an arrow."; - - anchor_position_ = arrow_location; - if (border_) - border_->set_arrow_location(anchor_position_); -} - -void ExtensionPopup::Hide() { - BrowserBubble::Hide(); - if (border_widget_) - border_widget_->Hide(); -} - -void ExtensionPopup::Show(bool activate) { - if (visible()) - return; - -#if defined(OS_WIN) - if (frame_->GetWindow()) - frame_->GetWindow()->DisableInactiveRendering(); -#endif - - ResizeToView(); - - // Show the border first, then the popup overlaid on top. - if (border_widget_) - border_widget_->Show(); - BrowserBubble::Show(activate); -} - -void ExtensionPopup::ResizeToView() { - if (observer_) - observer_->ExtensionPopupResized(this); - - gfx::Rect rect = GetOuterBounds(); - - gfx::Point origin = rect.origin(); - views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); - - if (border_widget_) { - // Set the bubble-chrome widget according to the outer bounds of the entire - // popup. - border_widget_->SetBounds(rect); - - // Now calculate the inner bounds. This is a bit more convoluted than - // it should be because BrowserBubble coordinates are in Browser coordinates - // while |rect| is in screen coordinates. - gfx::Insets border_insets; - border_->GetInsets(&border_insets); - - origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius); - origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius); - - gfx::Size new_size = view()->size(); - SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height()); - } else { - SetBounds(origin.x(), origin.y(), rect.width(), rect.height()); - } -} - -void ExtensionPopup::BubbleBrowserWindowMoved(BrowserBubble* bubble) { - ResizeToView(); -} - -void ExtensionPopup::BubbleBrowserWindowClosing(BrowserBubble* bubble) { - if (!closing_) - Close(); -} - -void ExtensionPopup::BubbleGotFocus(BrowserBubble* bubble) { - // Forward the focus to the renderer. - host()->render_view_host()->view()->Focus(); -} - -void ExtensionPopup::BubbleLostFocus(BrowserBubble* bubble, - bool lost_focus_to_child) { - if (closing_ || // We are already closing. - inspect_with_devtools_ || // The popup is being inspected. - !close_on_lost_focus_ || // Our client is handling focus listening. - lost_focus_to_child) // A child of this view got focus. - return; - - // When we do close on BubbleLostFocus, we do it in the next event loop - // because a subsequent event in this loop may also want to close this popup - // and if so, we want to allow that. Example: Clicking the same browser - // action button that opened the popup. If we closed immediately, the - // browser action container would fail to discover that the same button - // was pressed. - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, - &ExtensionPopup::Close)); -} - - -void ExtensionPopup::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - switch (type.value) { - case NotificationType::EXTENSION_HOST_DID_STOP_LOADING: - // Once we receive did stop loading, the content will be complete and - // the width will have been computed. Now it's safe to show. - if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) { - Show(activate_on_show_); - - if (inspect_with_devtools_) { - // Listen for the the devtools window closing. - registrar_.Add(this, NotificationType::DEVTOOLS_WINDOW_CLOSING, - Source<Profile>(extension_host_->profile())); - DevToolsManager::GetInstance()->ToggleDevToolsWindow( - extension_host_->render_view_host(), - DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE); - } - } - break; - case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE: - // If we aren't the host of the popup, then disregard the notification. - if (Details<ExtensionHost>(host()) != details) - return; - Close(); - - break; - case NotificationType::DEVTOOLS_WINDOW_CLOSING: - // Make sure its the devtools window that inspecting our popup. - if (Details<RenderViewHost>(extension_host_->render_view_host()) != - details) - return; - - // If the devtools window is closing, we post a task to ourselves to - // close the popup. This gives the devtools window a chance to finish - // detaching from the inspected RenderViewHost. - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, - &ExtensionPopup::Close)); - - break; - default: - NOTREACHED() << L"Received unexpected notification"; - } -} - -void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) { - // Constrain the size to popup min/max. - gfx::Size sz = view->GetPreferredSize(); - view->SetBounds(view->x(), view->y(), - std::max(kMinWidth, std::min(kMaxWidth, sz.width())), - std::max(kMinHeight, std::min(kMaxHeight, sz.height()))); - - // If popup_chrome_ == RECTANGLE_CHROME, the border is drawn in the client - // area of the ExtensionView, rather than in a window which sits behind it. - // In this case, the actual size of the view must be enlarged so that the - // web contents portion of the view gets its full PreferredSize area. - if (view->border()) { - gfx::Insets border_insets; - view->border()->GetInsets(&border_insets); - - gfx::Rect bounds(view->bounds()); - gfx::Size size(bounds.size()); - size.Enlarge(border_insets.width(), border_insets.height()); - view->SetBounds(bounds.x(), bounds.y(), size.width(), size.height()); - } - - ResizeToView(); -} - -gfx::Rect ExtensionPopup::GetOuterBounds() const { - gfx::Rect relative_rect = relative_to_; - gfx::Point origin = relative_rect.origin(); - views::View::ConvertPointToScreen(frame_->GetRootView(), &origin); - relative_rect.set_origin(origin); - - gfx::Size contents_size = view()->size(); - - // If the popup has a bubble-chrome, then let the BubbleBorder compute - // the bounds. - if (BUBBLE_CHROME == popup_chrome_) { - // The rounded corners cut off more of the view than the border insets - // claim. Since we can't clip the ExtensionView's corners, we need to - // increase the inset by half the corner radius as well as lying about the - // size of the contents size to compensate. - contents_size.Enlarge(2 * kPopupBubbleCornerRadius, - 2 * kPopupBubbleCornerRadius); - return border_->GetBounds(relative_rect, contents_size); - } - - // Position the bounds according to the location of the |anchor_position_|. - int y; - if (BubbleBorder::is_arrow_on_top(anchor_position_)) - y = relative_rect.bottom(); - else - y = relative_rect.y() - contents_size.height(); - - int x; - if (BubbleBorder::is_arrow_on_left(anchor_position_)) - x = relative_rect.x(); - else - // Note that if the arrow is on the right, that the x position of the popup - // is assigned so that the rightmost edge of the popup is aligned with the - // rightmost edge of the relative region. - x = relative_rect.right() - contents_size.width(); - - return gfx::Rect(x, y, contents_size.width(), contents_size.height()); -} - -// static -ExtensionPopup* ExtensionPopup::Show( - const GURL& url, - Browser* browser, - Profile* profile, - gfx::NativeWindow frame_window, - const gfx::Rect& relative_to, - BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show, - bool inspect_with_devtools, - PopupChrome chrome, - Observer* observer) { - DCHECK(profile); - DCHECK(frame_window); - ExtensionProcessManager* manager = profile->GetExtensionProcessManager(); - DCHECK(manager); - if (!manager) - return NULL; - - // If no Browser instance was given, attempt to look up one matching the given - // profile. - if (!browser) - browser = BrowserList::FindBrowserWithProfile(profile); - - Widget* frame_widget = Widget::GetWidgetFromNativeWindow(frame_window); - DCHECK(frame_widget); - if (!frame_widget) - return NULL; - - ExtensionHost* host = manager->CreatePopup(url, browser); - if (observer) - observer->ExtensionHostCreated(host); - - ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to, - arrow_location, activate_on_show, - inspect_with_devtools, chrome, - observer); - - // If the host had somehow finished loading, then we'd miss the notification - // and not show. This seems to happen in single-process mode. - if (host->did_stop_loading()) - popup->Show(activate_on_show); - - return popup; -} - -void ExtensionPopup::Close() { - if (closing_) - return; - closing_ = true; - DetachFromBrowser(); - - if (observer_) - observer_->ExtensionPopupIsClosing(this); - - Release(); // Balanced in ctor. -} - -void ExtensionPopup::Release() { - bool final_release = instance_lifetime_->HasOneRef(); - instance_lifetime_->Release(); - if (final_release) { - DCHECK(closing_) << "ExtensionPopup to be destroyed before being closed."; - ExtensionPopup::Observer* observer = observer_; - delete this; - - // |this| is passed only as a 'cookie'. The observer API explicitly takes a - // void* argument to emphasize this. - if (observer) - observer->ExtensionPopupClosed(this); - } -} diff --git a/chrome/browser/views/extensions/extension_popup.h b/chrome/browser/views/extensions/extension_popup.h index 9d656be..6bfa6f6 100644 --- a/chrome/browser/views/extensions/extension_popup.h +++ b/chrome/browser/views/extensions/extension_popup.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,219 +6,8 @@ #define CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_ #pragma once -#include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/views/browser_bubble.h" -#include "chrome/browser/views/extensions/extension_view.h" -#include "chrome/browser/views/bubble_border.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "gfx/native_widget_types.h" -#include "googleurl/src/gurl.h" - - -class Browser; -class ExtensionHost; -class Profile; - -namespace views { -class Widget; -} - -class ExtensionPopup : public BrowserBubble, - public BrowserBubble::Delegate, - public NotificationObserver, - public ExtensionView::Container { - public: - // Observer to ExtensionPopup events. - class Observer { - public: - // Called when the ExtensionPopup is closing. Note that it - // is ref-counted, and thus will be released shortly after - // making this delegate call. - virtual void ExtensionPopupIsClosing(ExtensionPopup* popup) {} - - // Called after the ExtensionPopup has been closed and deleted. - // |popup_token| is the address of the deleted ExtensionPopup. - virtual void ExtensionPopupClosed(void* popup_token) {} - - // Called when the ExtensionHost is first created for the pop-up view. - // Note that this is invoked BEFORE the ExtensionPopup is created, and can - // be used to provide extra configuration of the host before it is pushed - // into the popup. An example use is for automation resource routing in - // Chrome-Frame. See extension_popup_api.cc. - virtual void ExtensionHostCreated(ExtensionHost* host) {} - - // Called when the ExtensionPopup is resized. Note that the popup may have - // an empty bounds, if a popup is repositioned before the hosted content - // has loaded. - virtual void ExtensionPopupResized(ExtensionPopup* popup) {} - }; - - enum PopupChrome { - BUBBLE_CHROME, - RECTANGLE_CHROME - }; - - virtual ~ExtensionPopup(); - - // Create and show a popup with |url| positioned adjacent to |relative_to| in - // screen coordinates. - // |browser| is the browser to which the pop-up will be attached. NULL is a - // valid parameter for pop-ups not associated with a browser. - // |profile| is the user profile instance associated with the popup. A - // non NULL value must be given. - // |frame_window| is the native window that hosts the view inside which the - // popup will be anchored. - // The positioning of the pop-up is determined by |arrow_location| according - // to the following logic: The popup is anchored so that the corner indicated - // by value of |arrow_location| remains fixed during popup resizes. - // If |arrow_location| is BOTTOM_*, then the popup 'pops up', otherwise - // the popup 'drops down'. - // Pass |activate_on_show| as true to activate the popup window. - // Pass |inspect_with_devtools| as true to pin the popup open and show the - // devtools window for it. - // The |chrome| argument controls the chrome that surrounds the pop-up. - // Passing BUBBLE_CHROME will give the pop-up a bubble-like appearance, - // including the arrow mentioned above. Passing RECTANGLE_CHROME will give - // the popup a rectangular, black border with a drop-shadow with no arrow. - // The positioning of the popup is still governed by the arrow-location - // parameter. - // - // The actual display of the popup is delayed until the page contents - // finish loading in order to minimize UI flashing and resizing. - static ExtensionPopup* Show(const GURL& url, Browser* browser, - Profile* profile, - gfx::NativeWindow frame_window, - const gfx::Rect& relative_to, - BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show, - bool inspect_with_devtools, - PopupChrome chrome, - Observer* observer); - - // Closes the ExtensionPopup (this will cause the delegate - // ExtensionPopupIsClosing and ExtensionPopupClosed to fire. - void Close(); - - // Some clients wish to do their own custom focus change management. If this - // is set to false, then the ExtensionPopup will not do anything in response - // to the BubbleLostFocus() calls it gets from the BrowserBubble. - void set_close_on_lost_focus(bool close_on_lost_focus) { - close_on_lost_focus_ = close_on_lost_focus; - } - - ExtensionHost* host() const { return extension_host_.get(); } - - // Assigns the arrow location of the popup view, and updates the popup - // border widget, if necessary. - void SetArrowPosition(BubbleBorder::ArrowLocation arrow_location); - BubbleBorder::ArrowLocation arrow_position() const { - return anchor_position_; - } - - // Gives the desired bounds (in screen coordinates) given the rect to point - // to and the size of the contained contents. Includes all of the - // border-chrome surrounding the pop-up as well. - gfx::Rect GetOuterBounds() const; - - // BrowserBubble overrides. - virtual void Hide(); - virtual void Show(bool activate); - virtual void ResizeToView(); - - // BrowserBubble::Delegate methods. - virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble); - virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble); - virtual void BubbleGotFocus(BrowserBubble* bubble); - virtual void BubbleLostFocus(BrowserBubble* bubble, - bool lost_focus_to_child); - - // NotificationObserver overrides. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // ExtensionView::Container overrides. - virtual void OnExtensionMouseMove(ExtensionView* view) { } - virtual void OnExtensionMouseLeave(ExtensionView* view) { } - virtual void OnExtensionPreferredSizeChanged(ExtensionView* view); - - // Export the refrence-counted interface required for use as template - // arguments for RefCounted. ExtensionPopup does not inherit from RefCounted - // because it must override the behaviour of Release. - void AddRef() { instance_lifetime_->AddRef(); } - static bool ImplementsThreadSafeReferenceCounting() { - return InternalRefCounter::ImplementsThreadSafeReferenceCounting(); - } - - // Implements the standard RefCounted<T>::Release behaviour, except - // signals Observer::ExtensionPopupClosed after final release. - void Release(); - - // The min/max height of popups. - static const int kMinWidth; - static const int kMinHeight; - static const int kMaxWidth; - static const int kMaxHeight; - - private: - ExtensionPopup(ExtensionHost* host, - views::Widget* frame, - const gfx::Rect& relative_to, - BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show, - bool inspect_with_devtools, - PopupChrome chrome, - Observer* observer); - - // The area on the screen that the popup should be positioned relative to. - gfx::Rect relative_to_; - - // The contained host for the view. - scoped_ptr<ExtensionHost> extension_host_; - - // Flag used to indicate if the pop-up should be activated upon first display. - bool activate_on_show_; - - // Flag used to indicate if the pop-up should open a devtools window once - // it is shown inspecting it. - bool inspect_with_devtools_; - - // If false, ignore BrowserBubble::Delegate::BubbleLostFocus() calls. - bool close_on_lost_focus_; - - // Whether the ExtensionPopup is current going about closing itself. - bool closing_; - - NotificationRegistrar registrar_; - - // A separate widget and associated pieces to draw a border behind the - // popup. This has to be a separate window in order to support transparency. - // Layered windows can't contain native child windows, so we wouldn't be - // able to have the ExtensionView child. - views::Widget* border_widget_; - BubbleBorder* border_; - views::View* border_view_; - - // The type of chrome associated with the popup window. - PopupChrome popup_chrome_; - - // The observer of this popup. - Observer* observer_; - - // A cached copy of the arrow-position for the bubble chrome. - // If a black-border was requested, we still need this value to determine - // the position of the pop-up in relation to |relative_to_|. - BubbleBorder::ArrowLocation anchor_position_; - - // ExtensionPopup's lifetime is managed via reference counting, but it does - // not expose the RefCounted interface. Instead, the lifetime is tied to - // this member variable. - class InternalRefCounter : public base::RefCounted<InternalRefCounter> { - }; - InternalRefCounter* instance_lifetime_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionPopup); -}; +#include "chrome/browser/ui/views/extensions/extension_popup.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_ + diff --git a/chrome/browser/views/extensions/extension_view.cc b/chrome/browser/views/extensions/extension_view.cc deleted file mode 100644 index fcace1a..0000000 --- a/chrome/browser/views/extensions/extension_view.cc +++ /dev/null @@ -1,207 +0,0 @@ -// 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/extensions/extension_view.h" - -#include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/views/extensions/extension_popup.h" -#include "views/widget/widget.h" - -#if defined(OS_WIN) -#include "chrome/browser/renderer_host/render_widget_host_view_win.h" -#elif defined(TOUCH_UI) -#include "chrome/browser/renderer_host/render_widget_host_view_views.h" -#elif defined(OS_LINUX) -#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" -#endif - -ExtensionView::ExtensionView(ExtensionHost* host, Browser* browser) - : host_(host), - browser_(browser), - initialized_(false), - container_(NULL), - is_clipped_(false) { - host_->set_view(this); - - // This view needs to be focusable so it can act as the focused view for the - // focus manager. This is required to have SkipDefaultKeyEventProcessing - // called so the tab key events are forwarded to the renderer. - SetFocusable(true); -} - -ExtensionView::~ExtensionView() { - View* parent = GetParent(); - if (parent) - parent->RemoveChildView(this); - CleanUp(); -} - -const Extension* ExtensionView::extension() const { - return host_->extension(); -} - -RenderViewHost* ExtensionView::render_view_host() const { - return host_->render_view_host(); -} - -void ExtensionView::DidStopLoading() { - ShowIfCompletelyLoaded(); -} - -void ExtensionView::SetIsClipped(bool is_clipped) { - if (is_clipped_ != is_clipped) { - is_clipped_ = is_clipped; - if (IsVisible()) - ShowIfCompletelyLoaded(); - } -} - -void ExtensionView::SetVisible(bool is_visible) { - if (is_visible != IsVisible()) { - NativeViewHost::SetVisible(is_visible); - - // Also tell RenderWidgetHostView the new visibility. Despite its name, it - // is not part of the View hierarchy and does not know about the change - // unless we tell it. - if (render_view_host()->view()) { - if (is_visible) - render_view_host()->view()->Show(); - else - render_view_host()->view()->Hide(); - } - } -} - -void ExtensionView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - View::DidChangeBounds(previous, current); - // Propagate the new size to RenderWidgetHostView. - // We can't send size zero because RenderWidget DCHECKs that. - if (render_view_host()->view() && !current.IsEmpty()) - render_view_host()->view()->SetSize(gfx::Size(width(), height())); -} - -void ExtensionView::CreateWidgetHostView() { - DCHECK(!initialized_); - initialized_ = true; - RenderWidgetHostView* view = - RenderWidgetHostView::CreateViewForWidget(render_view_host()); - - // TODO(mpcomplete): RWHV needs a cross-platform Init function. -#if defined(OS_WIN) - // Create the HWND. Note: - // RenderWidgetHostHWND supports windowed plugins, but if we ever also - // wanted to support constrained windows with this, we would need an - // additional HWND to parent off of because windowed plugin HWNDs cannot - // exist in the same z-order as constrained windows. - RenderWidgetHostViewWin* view_win = - static_cast<RenderWidgetHostViewWin*>(view); - HWND hwnd = view_win->Create(GetWidget()->GetNativeView()); - view_win->ShowWindow(SW_SHOW); - Attach(hwnd); -#elif defined(TOUCH_UI) - RenderWidgetHostViewViews* view_views = - static_cast<RenderWidgetHostViewViews*>(view); - view_views->InitAsChild(); - Attach(view_views->GetNativeView()); -#elif defined(OS_LINUX) - RenderWidgetHostViewGtk* view_gtk = - static_cast<RenderWidgetHostViewGtk*>(view); - view_gtk->InitAsChild(); - Attach(view_gtk->GetNativeView()); -#else - NOTIMPLEMENTED(); -#endif - - host_->CreateRenderViewSoon(view); - SetVisible(false); -} - -void ExtensionView::ShowIfCompletelyLoaded() { - if (IsVisible() || is_clipped_) - return; - - // We wait to show the ExtensionView until it has loaded, and the view has - // actually been created. These can happen in different orders. - if (host_->did_stop_loading()) { - SetVisible(true); - UpdatePreferredSize(pending_preferred_size_); - } -} - -void ExtensionView::CleanUp() { - if (!initialized_) - return; - if (native_view()) - Detach(); - initialized_ = false; -} - -void ExtensionView::SetBackground(const SkBitmap& background) { - if (render_view_host()->IsRenderViewLive() && render_view_host()->view()) { - render_view_host()->view()->SetBackground(background); - } else { - pending_background_ = background; - } - ShowIfCompletelyLoaded(); -} - -void ExtensionView::UpdatePreferredSize(const gfx::Size& new_size) { - // Don't actually do anything with this information until we have been shown. - // Size changes will not be honored by lower layers while we are hidden. - if (!IsVisible()) { - pending_preferred_size_ = new_size; - return; - } - - gfx::Size preferred_size = GetPreferredSize(); - if (new_size != preferred_size) - SetPreferredSize(new_size); -} - -void ExtensionView::ViewHierarchyChanged(bool is_add, - views::View *parent, - views::View *child) { - NativeViewHost::ViewHierarchyChanged(is_add, parent, child); - if (is_add && GetWidget() && !initialized_) - CreateWidgetHostView(); -} - -void ExtensionView::PreferredSizeChanged() { - View::PreferredSizeChanged(); - if (container_) { - container_->OnExtensionPreferredSizeChanged(this); - } -} - -bool ExtensionView::SkipDefaultKeyEventProcessing(const views::KeyEvent& e) { - // Let the tab key event be processed by the renderer (instead of moving the - // focus to the next focusable view). - return (e.GetKeyCode() == app::VKEY_TAB); -} - -void ExtensionView::HandleMouseMove() { - if (container_) - container_->OnExtensionMouseMove(this); -} - -void ExtensionView::HandleMouseLeave() { - if (container_) - container_->OnExtensionMouseLeave(this); -} - -void ExtensionView::RenderViewCreated() { - if (!pending_background_.empty() && render_view_host()->view()) { - render_view_host()->view()->SetBackground(pending_background_); - pending_background_.reset(); - } - - // Tell the renderer not to draw scroll bars in popups unless the - // popups are at the maximum allowed size. - gfx::Size largest_popup_size(ExtensionPopup::kMaxWidth, - ExtensionPopup::kMaxHeight); - host_->DisableScrollbarsForSmallWindows(largest_popup_size); -} diff --git a/chrome/browser/views/extensions/extension_view.h b/chrome/browser/views/extensions/extension_view.h index 037c2e8e..f7b4e8d 100644 --- a/chrome/browser/views/extensions/extension_view.h +++ b/chrome/browser/views/extensions/extension_view.h @@ -6,107 +6,8 @@ #define CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_VIEW_H_ #pragma once -#include "build/build_config.h" - -#include "third_party/skia/include/core/SkBitmap.h" -#include "views/controls/native/native_view_host.h" - -class Browser; -class Extension; -class ExtensionHost; -class ExtensionView; -class RenderViewHost; - -// This handles the display portion of an ExtensionHost. -class ExtensionView : public views::NativeViewHost { - public: - ExtensionView(ExtensionHost* host, Browser* browser); - ~ExtensionView(); - - // A class that represents the container that this view is in. - // (bottom shelf, side bar, etc.) - class Container { - public: - virtual ~Container() {} - // Mouse event notifications from the view. (useful for hover UI). - virtual void OnExtensionMouseMove(ExtensionView* view) = 0; - virtual void OnExtensionMouseLeave(ExtensionView* view) = 0; - virtual void OnExtensionPreferredSizeChanged(ExtensionView* view) {} - }; - - ExtensionHost* host() const { return host_; } - Browser* browser() const { return browser_; } - const Extension* extension() const; - RenderViewHost* render_view_host() const; - void DidStopLoading(); - void SetIsClipped(bool is_clipped); - - // Notification from ExtensionHost. - void UpdatePreferredSize(const gfx::Size& new_size); - void HandleMouseMove(); - void HandleMouseLeave(); - - // Method for the ExtensionHost to notify us when the RenderViewHost has a - // connection. - void RenderViewCreated(); - - // Set a custom background for the view. The background will be tiled. - void SetBackground(const SkBitmap& background); - - // Sets the container for this view. - void SetContainer(Container* container) { container_ = container; } - - // Overridden from views::NativeViewHost: - virtual void SetVisible(bool is_visible); - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - virtual void ViewHierarchyChanged(bool is_add, - views::View *parent, views::View *child); - - protected: - // Overridden from views::View. - virtual void PreferredSizeChanged(); - virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e); - - private: - friend class ExtensionHost; - - // Initializes the RenderWidgetHostView for this object. - void CreateWidgetHostView(); - - // We wait to show the ExtensionView until several things have loaded. - void ShowIfCompletelyLoaded(); - - // Restore object to initial state. Called on shutdown or after a renderer - // crash. - void CleanUp(); - - // The running extension instance that we're displaying. - // Note that host_ owns view - ExtensionHost* host_; - - // The browser window that this view is in. - Browser* browser_; - - // True if we've been initialized. - bool initialized_; - - // The background the view should have once it is initialized. This is set - // when the view has a custom background, but hasn't been initialized yet. - SkBitmap pending_background_; - - // What we should set the preferred width to once the ExtensionView has - // loaded. - gfx::Size pending_preferred_size_; - - // The container this view is in (not necessarily its direct superview). - // Note: the view does not own its container. - Container* container_; - - // Whether this extension view is clipped. - bool is_clipped_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionView); -}; +#include "chrome/browser/ui/views/extensions/extension_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_VIEW_H_ + diff --git a/chrome/browser/views/external_protocol_dialog.cc b/chrome/browser/views/external_protocol_dialog.cc deleted file mode 100644 index 5b6d975..0000000 --- a/chrome/browser/views/external_protocol_dialog.cc +++ /dev/null @@ -1,181 +0,0 @@ -// 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/external_protocol_dialog.h" - -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "base/metrics/histogram.h" -#include "base/string_util.h" -#include "base/thread.h" -#include "base/thread_restrictions.h" -#include "base/utf_string_conversions.h" -#include "base/win/registry.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/external_protocol_handler.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_util.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" -#include "views/window/window.h" - -namespace { - -const int kMessageWidth = 400; - -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// ExternalProtocolHandler - -// static -void ExternalProtocolHandler::RunExternalProtocolDialog( - const GURL& url, int render_process_host_id, int routing_id) { - std::wstring command = - ExternalProtocolDialog::GetApplicationForProtocol(url); - if (command.empty()) { - // ShellExecute won't do anything. Don't bother warning the user. - return; - } - TabContents* tab_contents = tab_util::GetTabContentsByID( - render_process_host_id, routing_id); - DCHECK(tab_contents); - ExternalProtocolDialog* handler = - new ExternalProtocolDialog(tab_contents, url, command); -} - -/////////////////////////////////////////////////////////////////////////////// -// ExternalProtocolDialog - -ExternalProtocolDialog::~ExternalProtocolDialog() { -} - -////////////////////////////////////////////////////////////////////////////// -// ExternalProtocolDialog, views::DialogDelegate implementation: - -int ExternalProtocolDialog::GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring ExternalProtocolDialog::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - return l10n_util::GetString(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT); - else - return l10n_util::GetString(IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT); -} - -std::wstring ExternalProtocolDialog::GetWindowTitle() const { - return l10n_util::GetString(IDS_EXTERNAL_PROTOCOL_TITLE); -} - -void ExternalProtocolDialog::DeleteDelegate() { - delete this; -} - -bool ExternalProtocolDialog::Cancel() { - // We also get called back here if the user closes the dialog or presses - // escape. In these cases it would be preferable to ignore the state of the - // check box but MessageBox doesn't distinguish this from pressing the cancel - // button. - if (message_box_view_->IsCheckBoxSelected()) { - ExternalProtocolHandler::SetBlockState( - url_.scheme(), ExternalProtocolHandler::BLOCK); - } - - // Returning true closes the dialog. - return true; -} - -bool ExternalProtocolDialog::Accept() { - // We record how long it takes the user to accept an external protocol. If - // users start accepting these dialogs too quickly, we should worry about - // clickjacking. - UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", - base::TimeTicks::Now() - creation_time_); - - if (message_box_view_->IsCheckBoxSelected()) { - ExternalProtocolHandler::SetBlockState( - url_.scheme(), ExternalProtocolHandler::DONT_BLOCK); - } - - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url_); - // Returning true closes the dialog. - return true; -} - -views::View* ExternalProtocolDialog::GetContentsView() { - return message_box_view_; -} - -/////////////////////////////////////////////////////////////////////////////// -// ExternalProtocolDialog, private: - -ExternalProtocolDialog::ExternalProtocolDialog(TabContents* tab_contents, - const GURL& url, - const std::wstring& command) - : tab_contents_(tab_contents), - url_(url), - creation_time_(base::TimeTicks::Now()) { - const int kMaxUrlWithoutSchemeSize = 256; - const int kMaxCommandSize = 256; - std::wstring elided_url_without_scheme; - std::wstring elided_command; - ElideString(ASCIIToWide(url.possibly_invalid_spec()), - kMaxUrlWithoutSchemeSize, &elided_url_without_scheme); - ElideString(command, kMaxCommandSize, &elided_command); - - std::wstring message_text = l10n_util::GetStringF( - IDS_EXTERNAL_PROTOCOL_INFORMATION, - ASCIIToWide(url.scheme() + ":"), - elided_url_without_scheme) + L"\n\n"; - - message_text += l10n_util::GetStringF( - IDS_EXTERNAL_PROTOCOL_APPLICATION_TO_LAUNCH, elided_command) + L"\n\n"; - - message_text += l10n_util::GetString(IDS_EXTERNAL_PROTOCOL_WARNING); - - message_box_view_ = new MessageBoxView(MessageBoxFlags::kIsConfirmMessageBox, - message_text, - std::wstring(), - kMessageWidth); - message_box_view_->SetCheckBoxLabel( - l10n_util::GetString(IDS_EXTERNAL_PROTOCOL_CHECKBOX_TEXT)); - - HWND root_hwnd; - if (tab_contents_) { - root_hwnd = GetAncestor(tab_contents_->GetContentNativeView(), GA_ROOT); - } else { - // Dialog is top level if we don't have a tab_contents associated with us. - root_hwnd = NULL; - } - - views::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this)->Show(); -} - -// static -std::wstring ExternalProtocolDialog::GetApplicationForProtocol( - const GURL& url) { - // We shouldn't be accessing the registry from the UI thread, since it can go - // to disk. http://crbug.com/61996 - base::ThreadRestrictions::ScopedAllowIO allow_io; - - std::wstring url_spec = ASCIIToWide(url.possibly_invalid_spec()); - std::wstring cmd_key_path = - ASCIIToWide(url.scheme() + "\\shell\\open\\command"); - base::win::RegKey cmd_key(HKEY_CLASSES_ROOT, cmd_key_path.c_str(), KEY_READ); - size_t split_offset = url_spec.find(L':'); - if (split_offset == std::wstring::npos) - return std::wstring(); - std::wstring parameters = url_spec.substr(split_offset + 1, - url_spec.length() - 1); - std::wstring application_to_launch; - if (cmd_key.ReadValue(NULL, &application_to_launch)) { - ReplaceSubstringsAfterOffset(&application_to_launch, 0, L"%1", parameters); - return application_to_launch; - } else { - return std::wstring(); - } -} diff --git a/chrome/browser/views/external_protocol_dialog.h b/chrome/browser/views/external_protocol_dialog.h index 3932f58..9925dd4 100644 --- a/chrome/browser/views/external_protocol_dialog.h +++ b/chrome/browser/views/external_protocol_dialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,54 +6,8 @@ #define CHROME_BROWSER_VIEWS_EXTERNAL_PROTOCOL_DIALOG_H_ #pragma once -#include "base/time.h" -#include "googleurl/src/gurl.h" -#include "views/window/dialog_delegate.h" - -class MessageBoxView; -class TabContents; - -class ExternalProtocolDialog : public views::DialogDelegate { - public: - // RunExternalProtocolDialog calls this private constructor. - ExternalProtocolDialog(TabContents* tab_contents, - const GURL& url, - const std::wstring& command); - - // Returns the path of the application to be launched given the protocol - // of the requested url. Returns an empty string on failure. - static std::wstring GetApplicationForProtocol(const GURL& url); - - virtual ~ExternalProtocolDialog(); - - // views::DialogDelegate Methods: - virtual int GetDefaultDialogButton() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual std::wstring GetWindowTitle() const; - virtual void DeleteDelegate(); - virtual bool Cancel(); - virtual bool Accept(); - virtual views::View* GetContentsView(); - - // views::WindowDelegate Methods: - virtual bool IsAlwaysOnTop() const { return false; } - virtual bool IsModal() const { return false; } - - private: - // The message box view whose commands we handle. - MessageBoxView* message_box_view_; - - // The associated TabContents. - TabContents* tab_contents_; - - // URL of the external protocol request. - GURL url_; - - // The time at which this dialog was created. - base::TimeTicks creation_time_; - - DISALLOW_COPY_AND_ASSIGN(ExternalProtocolDialog); -}; +#include "chrome/browser/ui/views/external_protocol_dialog.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_EXTERNAL_PROTOCOL_DIALOG_H_ + diff --git a/chrome/browser/views/find_bar_host.cc b/chrome/browser/views/find_bar_host.cc deleted file mode 100644 index 3926e70..0000000 --- a/chrome/browser/views/find_bar_host.cc +++ /dev/null @@ -1,297 +0,0 @@ -// 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/find_bar_host.h" - -#include "app/keyboard_codes.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/find_bar_controller.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/find_bar_view.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "views/focus/external_focus_tracker.h" -#include "views/focus/view_storage.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" - -namespace browser { - -// Declared in browser_dialogs.h so others don't have to depend on our header. -FindBar* CreateFindBar(BrowserView* browser_view) { - return new FindBarHost(browser_view); -} - -} // namespace browser - -//////////////////////////////////////////////////////////////////////////////// -// FindBarHost, public: - -FindBarHost::FindBarHost(BrowserView* browser_view) - : DropdownBarHost(browser_view), - find_bar_controller_(NULL) { - Init(new FindBarView(this)); -} - -FindBarHost::~FindBarHost() { -} - -bool FindBarHost::MaybeForwardKeystrokeToWebpage( - const views::Textfield::Keystroke& key_stroke) { - if (!ShouldForwardKeystrokeToWebpageNative(key_stroke)) { - // Native implementation says not to forward these events. - return false; - } - - switch (key_stroke.GetKeyboardCode()) { - case app::VKEY_DOWN: - case app::VKEY_UP: - case app::VKEY_PRIOR: - case app::VKEY_NEXT: - break; - case app::VKEY_HOME: - case app::VKEY_END: - if (key_stroke.IsControlHeld()) - break; - // Fall through. - default: - return false; - } - - TabContents* contents = find_bar_controller_->tab_contents(); - if (!contents) - return false; - - RenderViewHost* render_view_host = contents->render_view_host(); - - // Make sure we don't have a text field element interfering with keyboard - // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". - render_view_host->ClearFocusedNode(); - NativeWebKeyboardEvent event = GetKeyboardEvent(contents, key_stroke); - render_view_host->ForwardKeyboardEvent(event); - return true; -} - -FindBarController* FindBarHost::GetFindBarController() const { - return find_bar_controller_; -} - -void FindBarHost::SetFindBarController(FindBarController* find_bar_controller) { - find_bar_controller_ = find_bar_controller; -} - -void FindBarHost::Show(bool animate) { - DropdownBarHost::Show(animate); -} - -void FindBarHost::Hide(bool animate) { - DropdownBarHost::Hide(animate); -} - -void FindBarHost::SetFocusAndSelection() { - DropdownBarHost::SetFocusAndSelection(); -} - -void FindBarHost::ClearResults(const FindNotificationDetails& results) { - find_bar_view()->UpdateForResult(results, string16()); -} - -void FindBarHost::StopAnimation() { - DropdownBarHost::StopAnimation(); -} - -void FindBarHost::MoveWindowIfNecessary(const gfx::Rect& selection_rect, - bool no_redraw) { - // We only move the window if one is active for the current TabContents. If we - // don't check this, then SetWidgetPosition below will end up making the Find - // Bar visible. - if (!find_bar_controller_->tab_contents() || - !find_bar_controller_->tab_contents()->find_ui_active()) { - return; - } - - gfx::Rect new_pos = GetDialogPosition(selection_rect); - SetDialogPosition(new_pos, no_redraw); - - // May need to redraw our frame to accommodate bookmark bar styles. - view()->SchedulePaint(); -} - -void FindBarHost::SetFindText(const string16& find_text) { - find_bar_view()->SetFindText(find_text); -} - -void FindBarHost::UpdateUIForFindResult(const FindNotificationDetails& result, - const string16& find_text) { - if (!find_text.empty()) - find_bar_view()->UpdateForResult(result, find_text); - - // We now need to check if the window is obscuring the search results. - if (!result.selection_rect().IsEmpty()) - MoveWindowIfNecessary(result.selection_rect(), false); - - // Once we find a match we no longer want to keep track of what had - // focus. EndFindSession will then set the focus to the page content. - if (result.number_of_matches() > 0) - ResetFocusTracker(); -} - -bool FindBarHost::IsFindBarVisible() { - return DropdownBarHost::IsVisible(); -} - -void FindBarHost::RestoreSavedFocus() { - if (focus_tracker() == NULL) { - // TODO(brettw) Focus() should be on TabContentsView. - find_bar_controller_->tab_contents()->Focus(); - } else { - focus_tracker()->FocusLastFocusedExternalView(); - } -} - -FindBarTesting* FindBarHost::GetFindBarTesting() { - return this; -} - -//////////////////////////////////////////////////////////////////////////////// -// FindBarWin, views::AcceleratorTarget implementation: - -bool FindBarHost::AcceleratorPressed(const views::Accelerator& accelerator) { - app::KeyboardCode key = accelerator.GetKeyCode(); - if (key == app::VKEY_RETURN && accelerator.IsCtrlDown()) { - // Ctrl+Enter closes the Find session and navigates any link that is active. - find_bar_controller_->EndFindSession(FindBarController::kActivateSelection); - } else if (key == app::VKEY_ESCAPE) { - // This will end the Find session and hide the window, causing it to loose - // focus and in the process unregister us as the handler for the Escape - // accelerator through the FocusWillChange event. - find_bar_controller_->EndFindSession(FindBarController::kKeepSelection); - } else { - NOTREACHED() << "Unknown accelerator"; - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// FindBarTesting implementation: - -bool FindBarHost::GetFindBarWindowInfo(gfx::Point* position, - bool* fully_visible) { - if (!find_bar_controller_ || -#if defined(OS_WIN) - !::IsWindow(host()->GetNativeView())) { -#else - false) { - // TODO(sky): figure out linux side. - // This is tricky due to asynchronous nature of x11. - // See bug http://crbug.com/28629. -#endif - if (position) - *position = gfx::Point(); - if (fully_visible) - *fully_visible = false; - return false; - } - - gfx::Rect window_rect; - host()->GetBounds(&window_rect, true); - if (position) - *position = window_rect.origin(); - if (fully_visible) - *fully_visible = IsVisible() && !IsAnimating(); - return true; -} - -string16 FindBarHost::GetFindText() { - return find_bar_view()->GetFindText(); -} - -//////////////////////////////////////////////////////////////////////////////// -// Overridden from DropdownBarHost: - -gfx::Rect FindBarHost::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { - // Find the area we have to work with (after accounting for scrollbars, etc). - gfx::Rect widget_bounds; - GetWidgetBounds(&widget_bounds); - if (widget_bounds.IsEmpty()) - return gfx::Rect(); - - // Ask the view how large an area it needs to draw on. - gfx::Size prefsize = view()->GetPreferredSize(); - - // Place the view in the top right corner of the widget boundaries (top left - // for RTL languages). - gfx::Rect view_location; - int x = widget_bounds.x(); - if (!base::i18n::IsRTL()) - x += widget_bounds.width() - prefsize.width(); - int y = widget_bounds.y(); - view_location.SetRect(x, y, prefsize.width(), prefsize.height()); - - // When we get Find results back, we specify a selection rect, which we - // should strive to avoid overlapping. But first, we need to offset the - // selection rect (if one was provided). - if (!avoid_overlapping_rect.IsEmpty()) { - // For comparison (with the Intersects function below) we need to account - // for the fact that we draw the Find widget relative to the Chrome frame, - // whereas the selection rect is relative to the page. - GetWidgetPositionNative(&avoid_overlapping_rect); - } - - gfx::Rect new_pos = FindBarController::GetLocationForFindbarView( - view_location, widget_bounds, avoid_overlapping_rect); - - // While we are animating, the Find window will grow bottoms up so we need to - // re-position the widget so that it appears to grow out of the toolbar. - if (animation_offset() > 0) - new_pos.Offset(0, std::min(0, -animation_offset())); - - return new_pos; -} - -void FindBarHost::SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) { - if (new_pos.IsEmpty()) - return; - - // Make sure the window edges are clipped to just the visible region. We need - // to do this before changing position, so that when we animate the closure - // of it it doesn't look like the window crumbles into the toolbar. - UpdateWindowEdges(new_pos); - - SetWidgetPositionNative(new_pos, no_redraw); -} - -void FindBarHost::GetWidgetBounds(gfx::Rect* bounds) { - DCHECK(bounds); - // The BrowserView does Layout for the components that we care about - // positioning relative to, so we ask it to tell us where we should go. - *bounds = browser_view()->GetFindBarBoundingBox(); -} - -void FindBarHost::RegisterAccelerators() { - DropdownBarHost::RegisterAccelerators(); - - // Register for Ctrl+Return. - views::Accelerator escape(app::VKEY_RETURN, false, true, false); - focus_manager()->RegisterAccelerator(escape, this); -} - -void FindBarHost::UnregisterAccelerators() { - // Unregister Ctrl+Return. - views::Accelerator escape(app::VKEY_RETURN, false, true, false); - focus_manager()->UnregisterAccelerator(escape, this); - - DropdownBarHost::UnregisterAccelerators(); -} - -//////////////////////////////////////////////////////////////////////////////// -// private: - -FindBarView* FindBarHost::find_bar_view() { - return static_cast<FindBarView*>(view()); -} diff --git a/chrome/browser/views/find_bar_host.h b/chrome/browser/views/find_bar_host.h index d675b3c8..4e34679 100644 --- a/chrome/browser/views/find_bar_host.h +++ b/chrome/browser/views/find_bar_host.h @@ -6,125 +6,8 @@ #define CHROME_BROWSER_VIEWS_FIND_BAR_HOST_H_ #pragma once -#include "chrome/browser/find_bar.h" -#include "chrome/browser/renderer_host/render_view_host_delegate.h" -#include "chrome/browser/views/dropdown_bar_host.h" -#include "gfx/native_widget_types.h" -#include "gfx/rect.h" -#include "views/controls/textfield/textfield.h" - -class BrowserView; -class FindBarController; -class FindBarView; -class FindNotificationDetails; - -//////////////////////////////////////////////////////////////////////////////// -// -// The FindBarHost implements the container widget for the -// find-in-page functionality. It uses the appropriate implementation from -// find_bar_host_win.cc or find_bar_host_gtk.cc to draw its content and is -// responsible for showing, hiding, closing, and moving the widget if needed, -// for example if the widget is obscuring the selection results. It also -// receives notifications about the search results and communicates that to -// the view. -// -// There is one FindBarHost per BrowserView, and its state is updated -// whenever the selected Tab is changed. The FindBarHost is created when -// the BrowserView is attached to the frame's Widget for the first time. -// -//////////////////////////////////////////////////////////////////////////////// -class FindBarHost : public DropdownBarHost, - public FindBar, - public FindBarTesting { - public: - explicit FindBarHost(BrowserView* browser_view); - virtual ~FindBarHost(); - - // Forwards selected keystrokes to the renderer. This is useful to make sure - // that arrow keys and PageUp and PageDown result in scrolling, instead of - // being eaten because the FindBar has focus. Returns true if the keystroke - // was forwarded, false if not. - bool MaybeForwardKeystrokeToWebpage( - const views::Textfield::Keystroke& key_stroke); - - // FindBar implementation: - virtual FindBarController* GetFindBarController() const; - virtual void SetFindBarController(FindBarController* find_bar_controller); - virtual void Show(bool animate); - virtual void Hide(bool animate); - virtual void SetFocusAndSelection(); - virtual void ClearResults(const FindNotificationDetails& results); - virtual void StopAnimation(); - virtual void MoveWindowIfNecessary(const gfx::Rect& selection_rect, - bool no_redraw); - virtual void SetFindText(const string16& find_text); - virtual void UpdateUIForFindResult(const FindNotificationDetails& result, - const string16& find_text); - virtual void AudibleAlert(); - virtual bool IsFindBarVisible(); - virtual void RestoreSavedFocus(); - virtual FindBarTesting* GetFindBarTesting(); - - // Overridden from views::AcceleratorTarget in DropdownBarHost class: - virtual bool AcceleratorPressed(const views::Accelerator& accelerator); - - // FindBarTesting implementation: - virtual bool GetFindBarWindowInfo(gfx::Point* position, - bool* fully_visible); - virtual string16 GetFindText(); - - // Overridden from DropdownBarHost: - // Returns the rectangle representing where to position the find bar. It uses - // GetDialogBounds and positions itself within that, either to the left (if an - // InfoBar is present) or to the right (no InfoBar). If - // |avoid_overlapping_rect| is specified, the return value will be a rectangle - // located immediately to the left of |avoid_overlapping_rect|, as long as - // there is enough room for the dialog to draw within the bounds. If not, the - // dialog position returned will overlap |avoid_overlapping_rect|. - // Note: |avoid_overlapping_rect| is expected to use coordinates relative to - // the top of the page area, (it will be converted to coordinates relative to - // the top of the browser window, when comparing against the dialog - // coordinates). The returned value is relative to the browser window. - virtual gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect); - // Moves the dialog window to the provided location, moves it to top in the - // z-order (HWND_TOP, not HWND_TOPMOST) and shows the window (if hidden). - // It then calls UpdateWindowEdges to make sure we don't overwrite the Chrome - // window border. If |no_redraw| is set, the window is getting moved but not - // sized, and should not be redrawn to reduce update flicker. - virtual void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw); - - // Retrieves the boundaries that the find bar widget has to work with - // within the Chrome frame window. The resulting rectangle will be a - // rectangle that overlaps the bottom of the Chrome toolbar by one - // pixel (so we can create the illusion that the dropdown widget is - // part of the toolbar) and covers the page area, except that we - // deflate the rect width by subtracting (from both sides) the width - // of the toolbar and some extra pixels to account for the width of - // the Chrome window borders. |bounds| is relative to the browser - // window. If the function fails to determine the browser - // window/client area rectangle or the rectangle for the page area - // then |bounds| will be an empty rectangle. - virtual void GetWidgetBounds(gfx::Rect* bounds); - - // Additional accelerator handling (on top of what DropDownBarHost does). - virtual void RegisterAccelerators(); - virtual void UnregisterAccelerators(); - - private: - // Allows implementation to tweak widget position. - void GetWidgetPositionNative(gfx::Rect* avoid_overlapping_rect); - - // Allows native implementation to prevent keystrokes from being forwarded. - bool ShouldForwardKeystrokeToWebpageNative( - const views::Textfield::Keystroke& key_stroke); - - // Returns the FindBarView. - FindBarView* find_bar_view(); - - // A pointer back to the owning controller. - FindBarController* find_bar_controller_; - - DISALLOW_COPY_AND_ASSIGN(FindBarHost); -}; +#include "chrome/browser/ui/views/find_bar_host.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FIND_BAR_HOST_H_ + diff --git a/chrome/browser/views/find_bar_host_gtk.cc b/chrome/browser/views/find_bar_host_gtk.cc deleted file mode 100644 index d9f8986..0000000 --- a/chrome/browser/views/find_bar_host_gtk.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2006-2009 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/find_bar_host.h" - -#include "chrome/browser/find_bar_controller.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/tab_contents/tab_contents_view_gtk.h" -#include "views/widget/widget_gtk.h" - -void FindBarHost::AudibleAlert() { - // TODO(davemoore) implement. - NOTIMPLEMENTED(); -} - -void FindBarHost::GetWidgetPositionNative(gfx::Rect* avoid_overlapping_rect) { - gfx::Rect frame_rect, webcontents_rect; - host()->GetRootWidget()->GetBounds(&frame_rect, true); - TabContentsView* tab_view = find_bar_controller_->tab_contents()->view(); - static_cast<TabContentsViewGtk*>(tab_view)->GetBounds(&webcontents_rect, - true); - avoid_overlapping_rect->Offset(0, webcontents_rect.y() - frame_rect.y()); -} - -bool FindBarHost::ShouldForwardKeystrokeToWebpageNative( - const views::Textfield::Keystroke& key_stroke) { - return true; -} diff --git a/chrome/browser/views/find_bar_host_interactive_uitest.cc b/chrome/browser/views/find_bar_host_interactive_uitest.cc deleted file mode 100644 index 12537fb..0000000 --- a/chrome/browser/views/find_bar_host_interactive_uitest.cc +++ /dev/null @@ -1,176 +0,0 @@ -// 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 "app/keyboard_codes.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/find_bar_controller.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/views/find_bar_host.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/view_ids.h" -#include "chrome/test/in_process_browser_test.h" -#include "chrome/test/ui_test_utils.h" -#include "net/test/test_server.h" -#include "views/focus/focus_manager.h" -#include "views/view.h" - -namespace { - -// The delay waited after sending an OS simulated event. -static const int kActionDelayMs = 500; -static const char kSimplePage[] = "files/find_in_page/simple.html"; - -class FindInPageTest : public InProcessBrowserTest { - public: - FindInPageTest() { - set_show_window(true); - FindBarHost::disable_animations_during_testing_ = true; - } - - string16 GetFindBarText() { - FindBarTesting* find_bar = - browser()->GetFindBarController()->find_bar()->GetFindBarTesting(); - return find_bar->GetFindText(); - } -}; - -} // namespace - -IN_PROC_BROWSER_TEST_F(FindInPageTest, CrashEscHandlers) { - ASSERT_TRUE(test_server()->Start()); - - // First we navigate to our test page (tab A). - GURL url = test_server()->GetURL(kSimplePage); - ui_test_utils::NavigateToURL(browser(), url); - - browser()->Find(); - - // Open another tab (tab B). - browser()->AddSelectedTabWithURL(url, PageTransition::TYPED); - - browser()->Find(); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), - VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); - - // Select tab A. - browser()->SelectTabContentsAt(0, true); - - // Close tab B. - browser()->CloseTabContents(browser()->GetTabContentsAt(1)); - - // Click on the location bar so that Find box loses focus. - ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(), - VIEW_ID_LOCATION_BAR)); -#if defined(TOOLKIT_VIEWS) || defined(OS_WIN) - // Check the location bar is focused. - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); -#endif - - // This used to crash until bug 1303709 was fixed. - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), app::VKEY_ESCAPE, false, false, false, false)); -} - -IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestore) { - ASSERT_TRUE(test_server()->Start()); - - GURL url = test_server()->GetURL("title1.html"); - ui_test_utils::NavigateToURL(browser(), url); - - // Focus the location bar, open and close the find-in-page, focus should - // return to the location bar. - browser()->FocusLocationBar(); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); - // Ensure the creation of the find bar controller. - browser()->GetFindBarController()->Show(); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), - VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); - browser()->GetFindBarController()->EndFindSession( - FindBarController::kKeepSelection); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); - - // Focus the location bar, find something on the page, close the find box, - // focus should go to the page. - browser()->FocusLocationBar(); - browser()->Find(); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), - VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); - ui_test_utils::FindInPage(browser()->GetSelectedTabContents(), - ASCIIToUTF16("a"), true, false, NULL); - browser()->GetFindBarController()->EndFindSession( - FindBarController::kKeepSelection); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), - VIEW_ID_TAB_CONTAINER_FOCUS_VIEW)); - - // Focus the location bar, open and close the find box, focus should return to - // the location bar (same as before, just checking that http://crbug.com/23599 - // is fixed). - browser()->FocusLocationBar(); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); - browser()->GetFindBarController()->Show(); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), - VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); - browser()->GetFindBarController()->EndFindSession( - FindBarController::kKeepSelection); - EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); -} - -// This tests that whenever you clear values from the Find box and close it that -// it respects that and doesn't show you the last search, as reported in bug: -// http://crbug.com/40121. -IN_PROC_BROWSER_TEST_F(FindInPageTest, PrepopulateRespectBlank) { -#if defined(OS_MACOSX) - // FindInPage on Mac doesn't use prepopulated values. Search there is global. - return; -#endif - - ASSERT_TRUE(test_server()->Start()); - - // First we navigate to any page. - GURL url = test_server()->GetURL(kSimplePage); - ui_test_utils::NavigateToURL(browser(), url); - - // Show the Find bar. - browser()->GetFindBarController()->Show(); - - // Search for "a". - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), app::VKEY_A, false, false, false, false)); - - // We should find "a" here. - EXPECT_EQ(ASCIIToUTF16("a"), GetFindBarText()); - - // Delete "a". - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), app::VKEY_BACK, false, false, false, false)); - - // Validate we have cleared the text. - EXPECT_EQ(string16(), GetFindBarText()); - - // Close the Find box. - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), app::VKEY_ESCAPE, false, false, false, false)); - - // Show the Find bar. - browser()->GetFindBarController()->Show(); - - // After the Find box has been reopened, it should not have been prepopulated - // with "a" again. - EXPECT_EQ(string16(), GetFindBarText()); - - // Close the Find box. - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), app::VKEY_ESCAPE, false, false, false, false)); - - // Press F3 to trigger FindNext. - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), app::VKEY_F3, false, false, false, false)); - - // After the Find box has been reopened, it should still have no prepopulate - // value. - EXPECT_EQ(string16(), GetFindBarText()); -} diff --git a/chrome/browser/views/find_bar_host_uitest.cc b/chrome/browser/views/find_bar_host_uitest.cc deleted file mode 100644 index 8dd6dbb..0000000 --- a/chrome/browser/views/find_bar_host_uitest.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2009 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/app/chrome_command_ids.h" -#include "chrome/test/automation/browser_proxy.h" -#include "chrome/test/automation/tab_proxy.h" -#include "chrome/test/ui/ui_test.h" -#include "net/test/test_server.h" - -class FindInPageControllerTest : public UITest { - public: - FindInPageControllerTest() { - show_window_ = true; - } -}; - -const std::string kSimplePage = "404_is_enough_for_us.html"; - -#if !defined(OS_WIN) -// Has never been enabled on other platforms http://crbug.com/45753 -#define FindMovesOnTabClose_Issue1343052 \ - DISABLED_FindMovesOnTabClose_Issue1343052 -#endif -// The find window should not change its location just because we open and close -// a new tab. -TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) { - net::TestServer test_server(net::TestServer::TYPE_HTTP, - FilePath(FILE_PATH_LITERAL("chrome/test/data"))); - ASSERT_TRUE(test_server.Start()); - - GURL url = test_server.GetURL(kSimplePage); - scoped_refptr<TabProxy> tabA(GetActiveTab()); - ASSERT_TRUE(tabA.get()); - ASSERT_TRUE(tabA->NavigateToURL(url)); - WaitUntilTabCount(1); - - scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser.get() != NULL); - - // Toggle the bookmark bar state. - EXPECT_TRUE(browser->ApplyAccelerator(IDC_SHOW_BOOKMARK_BAR)); - EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), true)); - - // Open the Find window and wait for it to animate. - EXPECT_TRUE(browser->OpenFindInPage()); - EXPECT_TRUE(WaitForFindWindowVisibilityChange(browser.get(), true)); - - // Find its location. - int x = -1, y = -1; - EXPECT_TRUE(browser->GetFindWindowLocation(&x, &y)); - - // Open another tab (tab B). - EXPECT_TRUE(browser->AppendTab(url)); - scoped_refptr<TabProxy> tabB(GetActiveTab()); - ASSERT_TRUE(tabB.get()); - - // Close tab B. - EXPECT_TRUE(tabB->Close(true)); - - // See if the Find window has moved. - int new_x = -1, new_y = -1; - EXPECT_TRUE(browser->GetFindWindowLocation(&new_x, &new_y)); - - EXPECT_EQ(x, new_x); - EXPECT_EQ(y, new_y); - - // Now reset the bookmark bar state and try the same again. - EXPECT_TRUE(browser->ApplyAccelerator(IDC_SHOW_BOOKMARK_BAR)); - EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), false)); - - // Bookmark bar has moved, reset our coordinates. - EXPECT_TRUE(browser->GetFindWindowLocation(&x, &y)); - - // Open another tab (tab C). - EXPECT_TRUE(browser->AppendTab(url)); - scoped_refptr<TabProxy> tabC(GetActiveTab()); - ASSERT_TRUE(tabC.get()); - - // Close it. - EXPECT_TRUE(tabC->Close(true)); - - // See if the Find window has moved. - EXPECT_TRUE(browser->GetFindWindowLocation(&new_x, &new_y)); - - EXPECT_EQ(x, new_x); - EXPECT_EQ(y, new_y); -} diff --git a/chrome/browser/views/find_bar_host_win.cc b/chrome/browser/views/find_bar_host_win.cc deleted file mode 100644 index e1e5a50..0000000 --- a/chrome/browser/views/find_bar_host_win.cc +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2006-2009 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/find_bar_host.h" - -#include "chrome/browser/find_bar_controller.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "views/controls/scrollbar/native_scroll_bar.h" -#include "views/widget/widget_win.h" - -void FindBarHost::AudibleAlert() { - MessageBeep(MB_OK); -} - -void FindBarHost::GetWidgetPositionNative(gfx::Rect* avoid_overlapping_rect) { - RECT frame_rect = {0}, webcontents_rect = {0}; - ::GetWindowRect( - static_cast<views::WidgetWin*>(host())->GetParent(), &frame_rect); - ::GetWindowRect( - find_bar_controller_->tab_contents()->view()->GetNativeView(), - &webcontents_rect); - avoid_overlapping_rect->Offset(0, webcontents_rect.top - frame_rect.top); -} - -bool FindBarHost::ShouldForwardKeystrokeToWebpageNative( - const views::Textfield::Keystroke& key_stroke) { - // We specifically ignore WM_CHAR. See http://crbug.com/10509. - return key_stroke.message() == WM_KEYDOWN || key_stroke.message() == WM_KEYUP; -} diff --git a/chrome/browser/views/find_bar_view.cc b/chrome/browser/views/find_bar_view.cc deleted file mode 100644 index 7132553..0000000 --- a/chrome/browser/views/find_bar_view.cc +++ /dev/null @@ -1,526 +0,0 @@ -// 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/find_bar_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/string_number_conversions.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/find_bar_controller.h" -#include "chrome/browser/find_bar_state.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/find_bar_host.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "gfx/canvas.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/effects/SkGradientShader.h" -#include "views/background.h" -#include "views/controls/button/image_button.h" -#include "views/controls/label.h" -#include "views/widget/widget.h" - -// The amount of whitespace to have before the find button. -static const int kWhiteSpaceAfterMatchCountLabel = 1; - -// The margins around the search field and the close button. -static const int kMarginLeftOfCloseButton = 3; -static const int kMarginRightOfCloseButton = 7; -static const int kMarginLeftOfFindTextfield = 12; - -// The margins around the match count label (We add extra space so that the -// background highlight extends beyond just the text). -static const int kMatchCountExtraWidth = 9; - -// Minimum width for the match count label. -static const int kMatchCountMinWidth = 30; - -// The text color for the match count label. -static const SkColor kTextColorMatchCount = SkColorSetRGB(178, 178, 178); - -// The text color for the match count label when no matches are found. -static const SkColor kTextColorNoMatch = SK_ColorBLACK; - -// The background color of the match count label when results are found. -static const SkColor kBackgroundColorMatch = SK_ColorWHITE; - -// The background color of the match count label when no results are found. -static const SkColor kBackgroundColorNoMatch = SkColorSetRGB(255, 102, 102); - -// The background images for the dialog. They are split into a left, a middle -// and a right part. The middle part determines the height of the dialog. The -// middle part is stretched to fill any remaining part between the left and the -// right image, after sizing the dialog to kWindowWidth. -static const SkBitmap* kDialog_left = NULL; -static const SkBitmap* kDialog_middle = NULL; -static const SkBitmap* kDialog_right = NULL; - -// When we are animating, we draw only the top part of the left and right -// edges to give the illusion that the find dialog is attached to the -// window during this animation; this is the height of the items we draw. -static const int kAnimatingEdgeHeight = 5; - -// The background image for the Find text box, which we draw behind the Find box -// to provide the Chrome look to the edge of the text box. -static const SkBitmap* kBackground = NULL; - -// The rounded edge on the left side of the Find text box. -static const SkBitmap* kBackground_left = NULL; - -// The default number of average characters that the text box will be. This -// number brings the width on a "regular fonts" system to about 300px. -static const int kDefaultCharWidth = 43; - -//////////////////////////////////////////////////////////////////////////////// -// FindBarView, public: - -FindBarView::FindBarView(FindBarHost* host) - : DropdownBarView(host), -#if defined(OS_LINUX) - ignore_contents_changed_(false), -#endif - find_text_(NULL), - match_count_text_(NULL), - focus_forwarder_view_(NULL), - find_previous_button_(NULL), - find_next_button_(NULL), - close_button_(NULL) { - SetID(VIEW_ID_FIND_IN_PAGE); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - find_text_ = new views::Textfield(); - find_text_->SetID(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD); - find_text_->SetFont(rb.GetFont(ResourceBundle::BaseFont)); - find_text_->set_default_width_in_chars(kDefaultCharWidth); - find_text_->SetController(this); - find_text_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_FIND)); - AddChildView(find_text_); - - match_count_text_ = new views::Label(); - match_count_text_->SetFont(rb.GetFont(ResourceBundle::BaseFont)); - match_count_text_->SetColor(kTextColorMatchCount); - match_count_text_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); - AddChildView(match_count_text_); - - // Create a focus forwarder view which sends focus to find_text_. - focus_forwarder_view_ = new FocusForwarderView(find_text_); - AddChildView(focus_forwarder_view_); - - find_previous_button_ = new views::ImageButton(this); - find_previous_button_->set_tag(FIND_PREVIOUS_TAG); - find_previous_button_->SetFocusable(true); - find_previous_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_FINDINPAGE_PREV)); - find_previous_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_FINDINPAGE_PREV_H)); - find_previous_button_->SetImage(views::CustomButton::BS_DISABLED, - rb.GetBitmapNamed(IDR_FINDINPAGE_PREV_P)); - find_previous_button_->SetTooltipText( - l10n_util::GetString(IDS_FIND_IN_PAGE_PREVIOUS_TOOLTIP)); - find_previous_button_->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_PREVIOUS)); - AddChildView(find_previous_button_); - - find_next_button_ = new views::ImageButton(this); - find_next_button_->set_tag(FIND_NEXT_TAG); - find_next_button_->SetFocusable(true); - find_next_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_FINDINPAGE_NEXT)); - find_next_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_FINDINPAGE_NEXT_H)); - find_next_button_->SetImage(views::CustomButton::BS_DISABLED, - rb.GetBitmapNamed(IDR_FINDINPAGE_NEXT_P)); - find_next_button_->SetTooltipText( - l10n_util::GetString(IDS_FIND_IN_PAGE_NEXT_TOOLTIP)); - find_next_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_NEXT)); - AddChildView(find_next_button_); - - close_button_ = new views::ImageButton(this); - close_button_->set_tag(CLOSE_TAG); - close_button_->SetFocusable(true); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_CLOSE_BAR)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); - close_button_->SetTooltipText( - l10n_util::GetString(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP)); - close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); - AddChildView(close_button_); - - if (kDialog_left == NULL) { - // Background images for the dialog. - kDialog_left = rb.GetBitmapNamed(IDR_FIND_DIALOG_LEFT); - kDialog_middle = rb.GetBitmapNamed(IDR_FIND_DIALOG_MIDDLE); - kDialog_right = rb.GetBitmapNamed(IDR_FIND_DIALOG_RIGHT); - - // Background images for the Find edit box. - kBackground = rb.GetBitmapNamed(IDR_FIND_BOX_BACKGROUND); - kBackground_left = rb.GetBitmapNamed(IDR_FIND_BOX_BACKGROUND_LEFT); - } -} - -FindBarView::~FindBarView() { -} - -void FindBarView::SetFindText(const string16& find_text) { -#if defined(OS_LINUX) - ignore_contents_changed_ = true; -#endif - find_text_->SetText(find_text); -#if defined(OS_LINUX) - ignore_contents_changed_ = false; -#endif -} - -string16 FindBarView::GetFindText() const { - return find_text_->text(); -} - -void FindBarView::UpdateForResult(const FindNotificationDetails& result, - const string16& find_text) { - bool have_valid_range = - result.number_of_matches() != -1 && result.active_match_ordinal() != -1; - - // http://crbug.com/34970: some IMEs get confused if we change the text - // composed by them. To avoid this problem, we should check the IME status and - // update the text only when the IME is not composing text. - if (find_text_->text() != find_text && !find_text_->IsIMEComposing()) { - find_text_->SetText(find_text); - find_text_->SelectAll(); - } - - if (!find_text.empty() && have_valid_range) { - match_count_text_->SetText( - l10n_util::GetStringF(IDS_FIND_IN_PAGE_COUNT, - UTF8ToWide(base::IntToString(result.active_match_ordinal())), - UTF8ToWide(base::IntToString(result.number_of_matches())))); - - UpdateMatchCountAppearance(result.number_of_matches() == 0 && - result.final_update()); - } else { - // If there was no text entered, we don't show anything in the result count - // area. - match_count_text_->SetText(std::wstring()); - - UpdateMatchCountAppearance(false); - } - - // The match_count label may have increased/decreased in size so we need to - // do a layout and repaint the dialog so that the find text field doesn't - // partially overlap the match-count label when it increases on no matches. - Layout(); - SchedulePaint(); -} - -void FindBarView::SetFocusAndSelection(bool select_all) { - find_text_->RequestFocus(); - if (select_all && !find_text_->text().empty()) - find_text_->SelectAll(); -} - -/////////////////////////////////////////////////////////////////////////////// -// FindBarView, views::View overrides: - -void FindBarView::Paint(gfx::Canvas* canvas) { - SkPaint paint; - - // Determine the find bar size as well as the offset from which to tile the - // toolbar background image. First, get the widget bounds. - gfx::Rect bounds; - GetWidget()->GetBounds(&bounds, true); - // Now convert from screen to parent coordinates. - gfx::Point origin(bounds.origin()); - BrowserView* browser_view = host()->browser_view(); - ConvertPointToView(NULL, browser_view, &origin); - bounds.set_origin(origin); - // Finally, calculate the background image tiling offset. - origin = browser_view->OffsetPointForToolbarBackgroundImage(origin); - - // First, we draw the background image for the whole dialog (3 images: left, - // middle and right). Note, that the window region has been set by the - // controller, so the whitespace in the left and right background images is - // actually outside the window region and is therefore not drawn. See - // FindInPageWidgetWin::CreateRoundedWindowEdges() for details. - ThemeProvider* tp = GetThemeProvider(); - canvas->TileImageInt(*tp->GetBitmapNamed(IDR_THEME_TOOLBAR), origin.x(), - origin.y(), 0, 0, bounds.width(), bounds.height()); - - // Now flip the canvas for the rest of the graphics if in RTL mode. - canvas->Save(); - if (base::i18n::IsRTL()) { - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } - - canvas->DrawBitmapInt(*kDialog_left, 0, 0); - - // Stretch the middle background to cover all of the area between the two - // other images. - canvas->TileImageInt(*kDialog_middle, kDialog_left->width(), 0, - bounds.width() - kDialog_left->width() - kDialog_right->width(), - kDialog_middle->height()); - - canvas->DrawBitmapInt(*kDialog_right, bounds.width() - kDialog_right->width(), - 0); - - // Then we draw the background image for the Find Textfield. We start by - // calculating the position of background images for the Find text box. - int find_text_x = find_text_->x(); - gfx::Point back_button_origin = find_previous_button_->bounds().origin(); - - // Draw the image to the left that creates a curved left edge for the box. - canvas->TileImageInt(*kBackground_left, - find_text_x - kBackground_left->width(), back_button_origin.y(), - kBackground_left->width(), kBackground_left->height()); - - // Draw the top and bottom border for whole text box (encompasses both the - // find_text_ edit box and the match_count_text_ label). - canvas->TileImageInt(*kBackground, find_text_x, back_button_origin.y(), - back_button_origin.x() - find_text_x, - kBackground->height()); - - if (animation_offset() > 0) { - // While animating we draw the curved edges at the point where the - // controller told us the top of the window is: |animation_offset()|. - canvas->TileImageInt(*kDialog_left, bounds.x(), animation_offset(), - kDialog_left->width(), kAnimatingEdgeHeight); - canvas->TileImageInt(*kDialog_right, - bounds.width() - kDialog_right->width(), animation_offset(), - kDialog_right->width(), kAnimatingEdgeHeight); - } - - canvas->Restore(); -} - -void FindBarView::Layout() { - gfx::Size panel_size = GetPreferredSize(); - - // First we draw the close button on the far right. - gfx::Size sz = close_button_->GetPreferredSize(); - close_button_->SetBounds(panel_size.width() - sz.width() - - kMarginRightOfCloseButton, - (height() - sz.height()) / 2, - sz.width(), - sz.height()); - // Set the color. - OnThemeChanged(); - - // Next, the FindNext button to the left the close button. - sz = find_next_button_->GetPreferredSize(); - find_next_button_->SetBounds(close_button_->x() - - find_next_button_->width() - - kMarginLeftOfCloseButton, - (height() - sz.height()) / 2, - sz.width(), - sz.height()); - - // Then, the FindPrevious button to the left the FindNext button. - sz = find_previous_button_->GetPreferredSize(); - find_previous_button_->SetBounds(find_next_button_->x() - - find_previous_button_->width(), - (height() - sz.height()) / 2, - sz.width(), - sz.height()); - - // Then the label showing the match count number. - sz = match_count_text_->GetPreferredSize(); - // We want to make sure the red "no-match" background almost completely fills - // up the amount of vertical space within the text box. We therefore fix the - // size relative to the button heights. We use the FindPrev button, which has - // a 1px outer whitespace margin, 1px border and we want to appear 1px below - // the border line so we subtract 3 for top and 3 for bottom. - sz.set_height(find_previous_button_->height() - 6); // Subtract 3px x 2. - - // We extend the label bounds a bit to give the background highlighting a bit - // of breathing room (margins around the text). - sz.Enlarge(kMatchCountExtraWidth, 0); - sz.set_width(std::max(kMatchCountMinWidth, static_cast<int>(sz.width()))); - int match_count_x = find_previous_button_->x() - - kWhiteSpaceAfterMatchCountLabel - - sz.width(); - match_count_text_->SetBounds(match_count_x, - (height() - sz.height()) / 2, - sz.width(), - sz.height()); - - // And whatever space is left in between, gets filled up by the find edit box. - sz = find_text_->GetPreferredSize(); - sz.set_width(match_count_x - kMarginLeftOfFindTextfield); - find_text_->SetBounds(match_count_x - sz.width(), - (height() - sz.height()) / 2 + 1, - sz.width(), - sz.height()); - - // The focus forwarder view is a hidden view that should cover the area - // between the find text box and the find button so that when the user clicks - // in that area we focus on the find text box. - int find_text_edge = find_text_->x() + find_text_->width(); - focus_forwarder_view_->SetBounds(find_text_edge, - find_previous_button_->y(), - find_previous_button_->x() - - find_text_edge, - find_previous_button_->height()); -} - -void FindBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { - if (is_add && child == this) { - find_text_->SetHorizontalMargins(3, 3); // Left and Right margins. - find_text_->RemoveBorder(); // We draw our own border (a background image). - } -} - -gfx::Size FindBarView::GetPreferredSize() { - gfx::Size prefsize = find_text_->GetPreferredSize(); - prefsize.set_height(kDialog_middle->height()); - - // Add up all the preferred sizes and margins of the rest of the controls. - prefsize.Enlarge(kMarginLeftOfCloseButton + kMarginRightOfCloseButton + - kMarginLeftOfFindTextfield, - 0); - prefsize.Enlarge(find_previous_button_->GetPreferredSize().width(), 0); - prefsize.Enlarge(find_next_button_->GetPreferredSize().width(), 0); - prefsize.Enlarge(close_button_->GetPreferredSize().width(), 0); - return prefsize; -} - -//////////////////////////////////////////////////////////////////////////////// -// FindBarView, views::ButtonListener implementation: - -void FindBarView::ButtonPressed( - views::Button* sender, const views::Event& event) { - switch (sender->tag()) { - case FIND_PREVIOUS_TAG: - case FIND_NEXT_TAG: - if (!find_text_->text().empty()) { - find_bar_host()->GetFindBarController()->tab_contents()-> - StartFinding(find_text_->text(), - sender->tag() == FIND_NEXT_TAG, - false); // Not case sensitive. - } - if (event.IsMouseEvent()) { - // If mouse event, we move the focus back to the text-field, so that the - // user doesn't have to click on the text field to change the search. We - // don't want to do this for keyboard clicks on the button, since the - // user is more likely to press FindNext again than change the search - // query. - find_text_->RequestFocus(); - } - break; - case CLOSE_TAG: - find_bar_host()->GetFindBarController()->EndFindSession( - FindBarController::kKeepSelection); - break; - default: - NOTREACHED() << L"Unknown button"; - break; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// FindBarView, views::Textfield::Controller implementation: - -void FindBarView::ContentsChanged(views::Textfield* sender, - const string16& new_contents) { -#if defined(OS_LINUX) - // On gtk setting the text in the find view causes a notification. - if (ignore_contents_changed_) - return; -#endif - - FindBarController* controller = find_bar_host()->GetFindBarController(); - DCHECK(controller); - // We must guard against a NULL tab_contents, which can happen if the text - // in the Find box is changed right after the tab is destroyed. Otherwise, it - // can lead to crashes, as exposed by automation testing in issue 8048. - if (!controller->tab_contents()) - return; - - // When the user changes something in the text box we check the contents and - // if the textbox contains something we set it as the new search string and - // initiate search (even though old searches might be in progress). - if (!new_contents.empty()) { - // The last two params here are forward (true) and case sensitive (false). - controller->tab_contents()->StartFinding(new_contents, true, false); - } else { - controller->tab_contents()->StopFinding(FindBarController::kClearSelection); - UpdateForResult(controller->tab_contents()->find_result(), string16()); - - // Clearing the text box should clear the prepopulate state so that when - // we close and reopen the Find box it doesn't show the search we just - // deleted. We can't do this on ChromeOS yet because we get ContentsChanged - // sent for a lot more things than just the user nulling out the search - // terms. See http://crbug.com/45372. - FindBarState* find_bar_state = - controller->tab_contents()->profile()->GetFindBarState(); - find_bar_state->set_last_prepopulate_text(string16()); - } -} - -bool FindBarView::HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key) { - // If the dialog is not visible, there is no reason to process keyboard input. - if (!host()->IsVisible()) - return false; - - if (find_bar_host()->MaybeForwardKeystrokeToWebpage(key)) - return true; // Handled, we are done! - - if (key.GetKeyboardCode() == app::VKEY_RETURN) { - // Pressing Return/Enter starts the search (unless text box is empty). - string16 find_string = find_text_->text(); - if (!find_string.empty()) { - // Search forwards for enter, backwards for shift-enter. - find_bar_host()->GetFindBarController()->tab_contents()->StartFinding( - find_string, - !key.IsShiftHeld(), - false); // Not case sensitive. - } - } - - return false; -} - -void FindBarView::UpdateMatchCountAppearance(bool no_match) { - if (no_match) { - match_count_text_->set_background( - views::Background::CreateSolidBackground(kBackgroundColorNoMatch)); - match_count_text_->SetColor(kTextColorNoMatch); - } else { - match_count_text_->set_background( - views::Background::CreateSolidBackground(kBackgroundColorMatch)); - match_count_text_->SetColor(kTextColorMatchCount); - } -} - -bool FindBarView::FocusForwarderView::OnMousePressed( - const views::MouseEvent& event) { - if (view_to_focus_on_mousedown_) { - view_to_focus_on_mousedown_->ClearSelection(); - view_to_focus_on_mousedown_->RequestFocus(); - } - return true; -} - -FindBarHost* FindBarView::find_bar_host() const { - return static_cast<FindBarHost*>(host()); -} - -void FindBarView::OnThemeChanged() { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - if (GetThemeProvider()) { - close_button_->SetBackground( - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TAB_TEXT), - rb.GetBitmapNamed(IDR_CLOSE_BAR), - rb.GetBitmapNamed(IDR_CLOSE_BAR_MASK)); - } -} diff --git a/chrome/browser/views/find_bar_view.h b/chrome/browser/views/find_bar_view.h index ab119b9..bb980df 100644 --- a/chrome/browser/views/find_bar_view.h +++ b/chrome/browser/views/find_bar_view.h @@ -6,121 +6,8 @@ #define CHROME_BROWSER_VIEWS_FIND_BAR_VIEW_H_ #pragma once -#include "base/string16.h" -#include "chrome/browser/find_notification_details.h" -#include "chrome/browser/views/dropdown_bar_view.h" -#include "gfx/size.h" -#include "views/controls/button/button.h" -#include "views/controls/textfield/textfield.h" - -class FindBarHost; - -namespace views { -class ImageButton; -class Label; -class MouseEvent; -class View; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// The FindBarView is responsible for drawing the UI controls of the -// FindBar, the find text box, the 'Find' button and the 'Close' -// button. It communicates the user search words to the FindBarHost. -// -//////////////////////////////////////////////////////////////////////////////// -class FindBarView : public DropdownBarView, - public views::ButtonListener, - public views::Textfield::Controller { - public: - // A tag denoting which button the user pressed. - enum ButtonTag { - FIND_PREVIOUS_TAG = 0, // The Find Previous button. - FIND_NEXT_TAG, // The Find Next button. - CLOSE_TAG, // The Close button (the 'X'). - }; - - explicit FindBarView(FindBarHost* host); - virtual ~FindBarView(); - - // Gets/sets the text displayed in the text box. - string16 GetFindText() const; - void SetFindText(const string16& find_text); - - // Updates the label inside the Find text box that shows the ordinal of the - // active item and how many matches were found. - void UpdateForResult(const FindNotificationDetails& result, - const string16& find_text); - - // Claims focus for the text field and selects its contents. - virtual void SetFocusAndSelection(bool select_all); - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from views::Textfield::Controller: - virtual void ContentsChanged(views::Textfield* sender, - const string16& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key); - - private: - // Update the appearance for the match count label. - void UpdateMatchCountAppearance(bool no_match); - - // Overridden from views::View. - virtual void OnThemeChanged(); - - // We use a hidden view to grab mouse clicks and bring focus to the find - // text box. This is because although the find text box may look like it - // extends all the way to the find button, it only goes as far as to the - // match_count label. The user, however, expects being able to click anywhere - // inside what looks like the find text box (including on or around the - // match_count label) and have focus brought to the find box. - class FocusForwarderView : public views::View { - public: - explicit FocusForwarderView( - views::Textfield* view_to_focus_on_mousedown) - : view_to_focus_on_mousedown_(view_to_focus_on_mousedown) {} - - private: - virtual bool OnMousePressed(const views::MouseEvent& event); - - views::Textfield* view_to_focus_on_mousedown_; - - DISALLOW_COPY_AND_ASSIGN(FocusForwarderView); - }; - - // Returns the OS-specific view for the find bar that acts as an intermediary - // between us and the TabContentsView. - FindBarHost* find_bar_host() const; - -#if defined(OS_LINUX) - // In gtk we get changed signals if we programatically set the text. If we - // don't ignore them we run into problems. For example, switching tabs back - // to one with the find bar visible will cause a search to the next found - // text. Also if the find bar had been visible and then hidden and the user - // switches back, found text will be highlighted again. - bool ignore_contents_changed_; -#endif - - // The controls in the window. - views::Textfield* find_text_; - views::Label* match_count_text_; - FocusForwarderView* focus_forwarder_view_; - views::ImageButton* find_previous_button_; - views::ImageButton* find_next_button_; - views::ImageButton* close_button_; - - DISALLOW_COPY_AND_ASSIGN(FindBarView); -}; +#include "chrome/browser/ui/views/find_bar_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FIND_BAR_VIEW_H_ + diff --git a/chrome/browser/views/first_run_bubble.cc b/chrome/browser/views/first_run_bubble.cc deleted file mode 100644 index fae2cfa..0000000 --- a/chrome/browser/views/first_run_bubble.cc +++ /dev/null @@ -1,537 +0,0 @@ -// 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/first_run_bubble.h" - -#include "app/gfx/font_util.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/win_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/first_run/first_run.h" -#include "chrome/browser/search_engines/util.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "views/event.h" -#include "views/controls/button/native_button.h" -#include "views/controls/button/image_button.h" -#include "views/controls/label.h" -#include "views/focus/focus_manager.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -namespace { - -// How much extra padding to put around our content over what the InfoBubble -// provides. -const int kBubblePadding = 4; - -// How much extra padding to put around our content over what the InfoBubble -// provides in alternative OEM bubble. -const int kOEMBubblePadding = 4; - -// Padding between parts of strings on the same line (for instance, -// "New!" and "Search from the address bar!" -const int kStringSeparationPadding = 2; - -// Margin around close button. -const int kMarginRightOfCloseButton = 7; - -} // namespace - -// Base class for implementations of the client view which appears inside the -// first run bubble. It is a dialog-ish view, but is not a true dialog. -class FirstRunBubbleViewBase : public views::View, - public views::ButtonListener, - public views::FocusChangeListener { - public: - // Called by FirstRunBubble::Show to request focus for the proper button - // in the FirstRunBubbleView when it is shown. - virtual void BubbleShown() = 0; -}; - -// FirstRunBubbleView --------------------------------------------------------- - -class FirstRunBubbleView : public FirstRunBubbleViewBase { - public: - FirstRunBubbleView(FirstRunBubble* bubble_window, Profile* profile); - - private: - virtual ~FirstRunBubbleView() {} - - // FirstRunBubbleViewBase: - virtual void BubbleShown(); - - // Overridden from View: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - // FocusChangeListener: - virtual void FocusWillChange(View* focused_before, View* focused_now); - - FirstRunBubble* bubble_window_; - views::Label* label1_; - views::Label* label2_; - views::Label* label3_; - views::NativeButton* change_button_; - views::NativeButton* keep_button_; - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(FirstRunBubbleView); -}; - -FirstRunBubbleView::FirstRunBubbleView(FirstRunBubble* bubble_window, - Profile* profile) - : bubble_window_(bubble_window), - label1_(NULL), - label2_(NULL), - label3_(NULL), - keep_button_(NULL), - change_button_(NULL), - profile_(profile) { - const gfx::Font& font = - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont); - - label1_ = new views::Label(l10n_util::GetString(IDS_FR_BUBBLE_TITLE)); - label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); - label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label1_); - - gfx::Size ps = GetPreferredSize(); - - label2_ = new views::Label(l10n_util::GetString(IDS_FR_BUBBLE_SUBTEXT)); - label2_->SetMultiLine(true); - label2_->SetFont(font); - label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label2_->SizeToFit(ps.width() - kBubblePadding * 2); - AddChildView(label2_); - - std::wstring question_str = l10n_util::GetStringF(IDS_FR_BUBBLE_QUESTION, - UTF16ToWideHack(GetDefaultSearchEngineName(profile))); - label3_ = new views::Label(question_str); - label3_->SetMultiLine(true); - label3_->SetFont(font); - label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label3_->SizeToFit(ps.width() - kBubblePadding * 2); - AddChildView(label3_); - - std::wstring keep_str = l10n_util::GetStringF(IDS_FR_BUBBLE_OK, - UTF16ToWideHack(GetDefaultSearchEngineName(profile))); - keep_button_ = new views::NativeButton(this, keep_str); - keep_button_->SetIsDefault(true); - AddChildView(keep_button_); - - std::wstring change_str = l10n_util::GetString(IDS_FR_BUBBLE_CHANGE); - change_button_ = new views::NativeButton(this, change_str); - AddChildView(change_button_); -} - -void FirstRunBubbleView::BubbleShown() { - keep_button_->RequestFocus(); -} - -void FirstRunBubbleView::ButtonPressed(views::Button* sender, - const views::Event& event) { - UserMetrics::RecordAction(UserMetricsAction("FirstRunBubbleView_Clicked"), - profile_); - bubble_window_->set_fade_away_on_close(true); - bubble_window_->Close(); - if (change_button_ == sender) { - UserMetrics::RecordAction( - UserMetricsAction("FirstRunBubbleView_ChangeButton"), - profile_); - - Browser* browser = BrowserList::GetLastActive(); - if (browser) { - browser->OpenSearchEngineOptionsDialog(); - } - } -} - -void FirstRunBubbleView::Layout() { - gfx::Size canvas = GetPreferredSize(); - - // The multiline business that follows is dirty hacks to get around - // bug 1325257. - label1_->SetMultiLine(false); - gfx::Size pref_size = label1_->GetPreferredSize(); - label1_->SetMultiLine(true); - label1_->SizeToFit(canvas.width() - kBubblePadding * 2); - label1_->SetBounds(kBubblePadding, kBubblePadding, - canvas.width() - kBubblePadding * 2, - pref_size.height()); - - int next_v_space = label1_->y() + pref_size.height() + - kRelatedControlSmallVerticalSpacing; - - pref_size = label2_->GetPreferredSize(); - label2_->SetBounds(kBubblePadding, next_v_space, - canvas.width() - kBubblePadding * 2, - pref_size.height()); - - next_v_space = label2_->y() + label2_->height() + - kPanelSubVerticalSpacing; - - pref_size = label3_->GetPreferredSize(); - label3_->SetBounds(kBubblePadding, next_v_space, - canvas.width() - kBubblePadding * 2, - pref_size.height()); - - pref_size = change_button_->GetPreferredSize(); - change_button_->SetBounds( - canvas.width() - pref_size.width() - kBubblePadding, - canvas.height() - pref_size.height() - kButtonVEdgeMargin, - pref_size.width(), pref_size.height()); - - pref_size = keep_button_->GetPreferredSize(); - keep_button_->SetBounds(change_button_->x() - pref_size.width() - - kRelatedButtonHSpacing, change_button_->y(), - pref_size.width(), pref_size.height()); -} - -gfx::Size FirstRunBubbleView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_FIRSTRUNBUBBLE_DIALOG_WIDTH_CHARS, - IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES)); -} - -void FirstRunBubbleView::FocusWillChange(View* focused_before, - View* focused_now) { - if (focused_before && - (focused_before->GetClassName() == views::NativeButton::kViewClassName)) { - views::NativeButton* before = - static_cast<views::NativeButton*>(focused_before); - before->SetIsDefault(false); - } - if (focused_now && - (focused_now->GetClassName() == views::NativeButton::kViewClassName)) { - views::NativeButton* after = static_cast<views::NativeButton*>(focused_now); - after->SetIsDefault(true); - } -} - -// FirstRunOEMBubbleView ------------------------------------------------------ - -class FirstRunOEMBubbleView : public FirstRunBubbleViewBase { - public: - FirstRunOEMBubbleView(FirstRunBubble* bubble_window, Profile* profile); - - private: - virtual ~FirstRunOEMBubbleView() { } - - // FirstRunBubbleViewBase: - virtual void BubbleShown(); - - // Overridden from View: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - // FocusChangeListener: - virtual void FocusWillChange(View* focused_before, View* focused_now); - - FirstRunBubble* bubble_window_; - views::Label* label1_; - views::Label* label2_; - views::Label* label3_; - views::ImageButton* close_button_; - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(FirstRunOEMBubbleView); -}; - -FirstRunOEMBubbleView::FirstRunOEMBubbleView(FirstRunBubble* bubble_window, - Profile* profile) - : bubble_window_(bubble_window), - label1_(NULL), - label2_(NULL), - label3_(NULL), - close_button_(NULL), - profile_(profile) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& font = rb.GetFont(ResourceBundle::MediumFont); - - label1_ = new views::Label(l10n_util::GetString(IDS_FR_OEM_BUBBLE_TITLE_1)); - label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); - label1_->SetColor(SK_ColorRED); - label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label1_); - - label2_ = new views::Label(l10n_util::GetString(IDS_FR_OEM_BUBBLE_TITLE_2)); - label2_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); - label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label2_); - - gfx::Size ps = GetPreferredSize(); - - label3_ = new views::Label(l10n_util::GetString(IDS_FR_OEM_BUBBLE_SUBTEXT)); - label3_->SetMultiLine(true); - label3_->SetFont(font); - label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label3_->SizeToFit(ps.width() - kOEMBubblePadding * 2); - AddChildView(label3_); - - close_button_ = new views::ImageButton(this); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_CLOSE_BAR)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); - - AddChildView(close_button_); -} - -void FirstRunOEMBubbleView::BubbleShown() { - RequestFocus(); - // No button in oem_bubble to request focus. -} - -void FirstRunOEMBubbleView::ButtonPressed(views::Button* sender, - const views::Event& event) { - UserMetrics::RecordAction(UserMetricsAction("FirstRunOEMBubbleView_Clicked"), - profile_); - bubble_window_->set_fade_away_on_close(true); - bubble_window_->Close(); -} - -void FirstRunOEMBubbleView::Layout() { - gfx::Size canvas = GetPreferredSize(); - - // First, draw the close button on the far right. - gfx::Size sz = close_button_->GetPreferredSize(); - close_button_->SetBounds( - canvas.width() - sz.width() - kMarginRightOfCloseButton, - kOEMBubblePadding, sz.width(), sz.height()); - - gfx::Size pref_size = label1_->GetPreferredSize(); - label1_->SetBounds(kOEMBubblePadding, kOEMBubblePadding, - pref_size.width() + kOEMBubblePadding * 2, - pref_size.height()); - - pref_size = label2_->GetPreferredSize(); - label2_->SetBounds( - kOEMBubblePadding * 2 + label1_->GetPreferredSize().width(), - kOEMBubblePadding, canvas.width() - kOEMBubblePadding * 2, - pref_size.height()); - - int next_v_space = - label1_->y() + pref_size.height() + kRelatedControlSmallVerticalSpacing; - - pref_size = label3_->GetPreferredSize(); - label3_->SetBounds(kOEMBubblePadding, next_v_space, - canvas.width() - kOEMBubblePadding * 2, - pref_size.height()); -} - -gfx::Size FirstRunOEMBubbleView::GetPreferredSize() { - // Calculate width based on font and text. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& font = rb.GetFont( - ResourceBundle::MediumFont).DeriveFont(3, gfx::Font::BOLD); - gfx::Size size = gfx::Size( - gfx::GetLocalizedContentsWidthForFont( - IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS, font), - gfx::GetLocalizedContentsHeightForFont( - IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES, font)); - - // WARNING: HACK. Vista and XP calculate font size differently; this means - // that a dialog box correctly proportioned for XP will appear too large in - // Vista. The correct thing to do is to change font size calculations in - // XP or Vista so that the length of a string is calculated properly. For - // now, we force Vista to show a correctly-sized box by taking account of - // the difference in font size calculation. The coefficient should not be - // stored in a variable because it's a hack and should go away. - if (win_util::ShouldUseVistaFrame()) { - size.set_width(static_cast<int>(size.width() * 0.85)); - size.set_height(static_cast<int>(size.height() * 0.85)); - } - return size; -} - -void FirstRunOEMBubbleView::FocusWillChange(View* focused_before, - View* focused_now) { - // No buttons in oem_bubble to register focus changes. -} - -// FirstRunMinimalBubbleView -------------------------------------------------- -// TODO(mirandac): combine FRBubbles more elegantly. http://crbug.com/41353 - -class FirstRunMinimalBubbleView : public FirstRunBubbleViewBase { - public: - FirstRunMinimalBubbleView(FirstRunBubble* bubble_window, Profile* profile); - - private: - virtual ~FirstRunMinimalBubbleView() { } - - // FirstRunBubbleViewBase: - virtual void BubbleShown(); - - // Overridden from View: - virtual void ButtonPressed(views::Button* sender, - const views::Event& event) { } - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - // FocusChangeListener: - virtual void FocusWillChange(View* focused_before, View* focused_now); - - FirstRunBubble* bubble_window_; - Profile* profile_; - views::Label* label1_; - views::Label* label2_; - - DISALLOW_COPY_AND_ASSIGN(FirstRunMinimalBubbleView); -}; - -FirstRunMinimalBubbleView::FirstRunMinimalBubbleView( - FirstRunBubble* bubble_window, - Profile* profile) - : bubble_window_(bubble_window), - profile_(profile), - label1_(NULL), - label2_(NULL) { - const gfx::Font& font = - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont); - - label1_ = new views::Label(l10n_util::GetStringF(IDS_FR_SE_BUBBLE_TITLE, - UTF16ToWideHack(GetDefaultSearchEngineName(profile_)))); - label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); - label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label1_); - - gfx::Size ps = GetPreferredSize(); - - label2_ = new views::Label(l10n_util::GetString(IDS_FR_BUBBLE_SUBTEXT)); - label2_->SetMultiLine(true); - label2_->SetFont(font); - label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label2_->SizeToFit(ps.width() - kBubblePadding * 2); - AddChildView(label2_); -} - -void FirstRunMinimalBubbleView::BubbleShown() { - RequestFocus(); -} - -void FirstRunMinimalBubbleView::Layout() { - gfx::Size canvas = GetPreferredSize(); - - // See comments in FirstRunOEMBubbleView::Layout explaining this hack. - label1_->SetMultiLine(false); - gfx::Size pref_size = label1_->GetPreferredSize(); - label1_->SetMultiLine(true); - label1_->SizeToFit(canvas.width() - kBubblePadding * 2); - label1_->SetBounds(kBubblePadding, kBubblePadding, - canvas.width() - kBubblePadding * 2, - pref_size.height()); - - int next_v_space = label1_->y() + pref_size.height() + - kRelatedControlSmallVerticalSpacing; - - pref_size = label2_->GetPreferredSize(); - label2_->SetBounds(kBubblePadding, next_v_space, - canvas.width() - kBubblePadding * 2, - pref_size.height()); -} - -gfx::Size FirstRunMinimalBubbleView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_FIRSTRUN_MINIMAL_BUBBLE_DIALOG_WIDTH_CHARS, - IDS_FIRSTRUN_MINIMAL_BUBBLE_DIALOG_HEIGHT_LINES)); -} - -void FirstRunMinimalBubbleView::FocusWillChange(View* focused_before, - View* focused_now) { - // No buttons in minimal bubble to register focus changes. -} - - -// FirstRunBubble ------------------------------------------------------------- - -// static -FirstRunBubble* FirstRunBubble::Show(Profile* profile, - views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - FirstRun::BubbleType bubble_type) { - FirstRunBubble* window = new FirstRunBubble(); - FirstRunBubbleViewBase* view = NULL; - - switch (bubble_type) { - case FirstRun::OEM_BUBBLE: - view = new FirstRunOEMBubbleView(window, profile); - break; - case FirstRun::LARGE_BUBBLE: - view = new FirstRunBubbleView(window, profile); - break; - case FirstRun::MINIMAL_BUBBLE: - view = new FirstRunMinimalBubbleView(window, profile); - break; - default: - NOTREACHED(); - } - window->set_view(view); - window->Init(parent, position_relative_to, arrow_location, view, window); - window->GetFocusManager()->AddFocusChangeListener(view); - view->BubbleShown(); - return window; -} - -FirstRunBubble::FirstRunBubble() - : has_been_activated_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(enable_window_method_factory_(this)), - view_(NULL) { -} - -FirstRunBubble::~FirstRunBubble() { - enable_window_method_factory_.RevokeAll(); - GetFocusManager()->RemoveFocusChangeListener(view_); -} - -void FirstRunBubble::EnableParent() { - ::EnableWindow(GetParent(), true); - // Reactivate the FirstRunBubble so it responds to OnActivate messages. - SetWindowPos(GetParent(), 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_SHOWWINDOW); -} - -void FirstRunBubble::OnActivate(UINT action, BOOL minimized, HWND window) { - // Keep the bubble around for kLingerTime milliseconds, to prevent accidental - // closure. - const int kLingerTime = 3000; - - // We might get re-enabled right before we are closed (sequence is: we get - // deactivated, we call close, before we are actually closed we get - // reactivated). Don't do the disabling of the parent in such cases. - if (action == WA_ACTIVE && !has_been_activated_) { - has_been_activated_ = true; - - ::EnableWindow(GetParent(), false); - - MessageLoop::current()->PostDelayedTask(FROM_HERE, - enable_window_method_factory_.NewRunnableMethod( - &FirstRunBubble::EnableParent), - kLingerTime); - return; - } - - // Keep window from automatically closing until kLingerTime has passed. - if (::IsWindowEnabled(GetParent())) - InfoBubble::OnActivate(action, minimized, window); -} - -void FirstRunBubble::InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape) { - // Make sure our parent window is re-enabled. - if (!IsWindowEnabled(GetParent())) - ::EnableWindow(GetParent(), true); -} diff --git a/chrome/browser/views/first_run_bubble.h b/chrome/browser/views/first_run_bubble.h index 7de3969..235e004 100644 --- a/chrome/browser/views/first_run_bubble.h +++ b/chrome/browser/views/first_run_bubble.h @@ -6,51 +6,8 @@ #define CHROME_BROWSER_VIEWS_FIRST_RUN_BUBBLE_H_ #pragma once -#include "base/compiler_specific.h" -#include "base/task.h" -#include "chrome/browser/first_run/first_run.h" -#include "chrome/browser/views/info_bubble.h" - -class FirstRunBubbleViewBase; -class Profile; - -class FirstRunBubble : public InfoBubble, - public InfoBubbleDelegate { - public: - static FirstRunBubble* Show(Profile* profile, views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - FirstRun::BubbleType bubble_type); - - private: - FirstRunBubble(); - virtual ~FirstRunBubble(); - - void set_view(FirstRunBubbleViewBase* view) { view_ = view; } - - // Re-enable the parent window. - void EnableParent(); - -#if defined(OS_WIN) - // Overridden from InfoBubble: - virtual void OnActivate(UINT action, BOOL minimized, HWND window); -#endif - - // InfoBubbleDelegate. - virtual void InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape); - virtual bool CloseOnEscape() { return true; } - virtual bool FadeInOnShow() { return true; } - - // Whether we have already been activated. - bool has_been_activated_; - - ScopedRunnableMethodFactory<FirstRunBubble> enable_window_method_factory_; - - // The view inside the FirstRunBubble. - FirstRunBubbleViewBase* view_; - - DISALLOW_COPY_AND_ASSIGN(FirstRunBubble); -}; +#include "chrome/browser/ui/views/first_run_bubble.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FIRST_RUN_BUBBLE_H_ + diff --git a/chrome/browser/views/first_run_search_engine_view.cc b/chrome/browser/views/first_run_search_engine_view.cc deleted file mode 100644 index 6688d9e..0000000 --- a/chrome/browser/views/first_run_search_engine_view.cc +++ /dev/null @@ -1,430 +0,0 @@ -// 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/first_run_search_engine_view.h" - -#include <algorithm> -#include <map> -#include <vector> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/i18n/rtl.h" -#include "base/rand_util.h" -#include "base/time.h" -#include "chrome/browser/options_window.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/search_engine_type.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "gfx/canvas.h" -#include "gfx/font.h" -#include "grit/browser_resources.h" -#include "grit/chromium_strings.h" -#include "grit/google_chrome_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "views/controls/button/button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/standard_layout.h" -#include "views/view_text_utils.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -using base::Time; - -namespace { - -// Size to scale logos down to if showing 4 instead of 3 choices. Logo images -// are all originally sized at 180 x 120 pixels, with the logo text baseline -// located 74 pixels beneath the top of the image. -const int kSmallLogoWidth = 132; -const int kSmallLogoHeight = 88; - -// Used to pad text label height so it fits nicely in view. -const int kLabelPadding = 25; - -} // namespace - -SearchEngineChoice::SearchEngineChoice(views::ButtonListener* listener, - const TemplateURL* search_engine, - bool use_small_logos) - : NativeButton(listener, l10n_util::GetString(IDS_FR_SEARCH_CHOOSE)), - is_image_label_(false), - search_engine_(search_engine), - slot_(0) { - bool use_images = false; -#if defined(GOOGLE_CHROME_BUILD) - use_images = true; -#endif - int logo_id = search_engine_->logo_id(); - if (use_images && logo_id != kNoSearchEngineLogo) { - is_image_label_ = true; - views::ImageView* logo_image = new views::ImageView(); - SkBitmap* logo_bmp = - ResourceBundle::GetSharedInstance().GetBitmapNamed(logo_id); - logo_image->SetImage(logo_bmp); - if (use_small_logos) - logo_image->SetImageSize(gfx::Size(kSmallLogoWidth, kSmallLogoHeight)); - // Tooltip text provides accessibility for low-vision users. - logo_image->SetTooltipText(search_engine_->short_name()); - choice_view_ = logo_image; - } else { - // No logo -- we must show a text label. - views::Label* logo_label = new views::Label(search_engine_->short_name()); - logo_label->SetColor(SK_ColorDKGRAY); - logo_label->SetFont(logo_label->font().DeriveFont(3, gfx::Font::BOLD)); - logo_label->SetHorizontalAlignment(views::Label::ALIGN_CENTER); - logo_label->SetTooltipText(search_engine_->short_name()); - logo_label->SetMultiLine(true); - logo_label->SizeToFit(kSmallLogoWidth); - choice_view_ = logo_label; - } - - // The accessible name of the button provides accessibility for - // screenreaders. It uses the browser name rather than the text of the - // button "Choose", since it's not obvious to a screenreader user which - // browser each button corresponds to. - SetAccessibleName(search_engine_->short_name()); -} - -int SearchEngineChoice::GetChoiceViewWidth() { - if (is_image_label_) - return choice_view_->GetPreferredSize().width(); - else - return kSmallLogoWidth; -} - -int SearchEngineChoice::GetChoiceViewHeight() { - if (!is_image_label_) { - // Labels need to be padded to look nicer. - return choice_view_->GetPreferredSize().height() + kLabelPadding; - } else { - return choice_view_->GetPreferredSize().height(); - } -} - -void SearchEngineChoice::SetChoiceViewBounds(int x, int y, int width, - int height) { - choice_view_->SetBounds(x, y, width, height); -} - -FirstRunSearchEngineView::FirstRunSearchEngineView( - Profile* profile, bool randomize) - : background_image_(NULL), - profile_(profile), - text_direction_is_rtl_(base::i18n::IsRTL()), - randomize_(randomize) { - // Don't show ourselves until all the search engines have loaded from - // the profile -- otherwise we have nothing to show. - SetVisible(false); - - // Start loading the search engines for the given profile. - search_engines_model_ = profile_->GetTemplateURLModel(); - if (search_engines_model_) { - DCHECK(!search_engines_model_->loaded()); - search_engines_model_->AddObserver(this); - search_engines_model_->Load(); - } else { - NOTREACHED(); - } - SetupControls(); -} - -FirstRunSearchEngineView::~FirstRunSearchEngineView() { - search_engines_model_->RemoveObserver(this); -} - -void FirstRunSearchEngineView::ButtonPressed(views::Button* sender, - const views::Event& event) { - SearchEngineChoice* choice = static_cast<SearchEngineChoice*>(sender); - TemplateURLModel* template_url_model = profile_->GetTemplateURLModel(); - DCHECK(template_url_model); - template_url_model->SetSearchEngineDialogSlot(choice->slot()); - const TemplateURL* default_search = choice->GetSearchEngine(); - if (default_search) - template_url_model->SetDefaultSearchProvider(default_search); - - MessageLoop::current()->Quit(); -} - -void FirstRunSearchEngineView::Paint(gfx::Canvas* canvas) { - // Fill in behind the background image with the standard gray toolbar color. - canvas->FillRectInt(SkColorSetRGB(237, 238, 237), 0, 0, width(), - background_image_->height()); - // The rest of the dialog background should be white. - DCHECK(height() > background_image_->height()); - canvas->FillRectInt(SK_ColorWHITE, 0, background_image_->height(), width(), - height() - background_image_->height()); -} - -void FirstRunSearchEngineView::OnTemplateURLModelChanged() { - using views::ImageView; - - // We only watch the search engine model change once, on load. Remove - // observer so we don't try to redraw if engines change under us. - search_engines_model_->RemoveObserver(this); - - // Add search engines in search_engines_model_ to buttons list. The - // first three will always be from prepopulated data. - std::vector<const TemplateURL*> template_urls = - search_engines_model_->GetTemplateURLs(); - - // If we have fewer than two search engines, end search engine dialog - // immediately, leaving imported default search engine setting intact. - if (template_urls.size() < 2) { - MessageLoop::current()->Quit(); - return; - } - - std::vector<const TemplateURL*>::iterator search_engine_iter; - - // Is user's default search engine included in first three prepopulated - // set? If not, we need to expand the dialog to include a fourth engine. - const TemplateURL* default_search_engine = - search_engines_model_->GetDefaultSearchProvider(); - // If the user's default choice is not in the first three search engines - // in template_urls, store it in |default_choice| and provide it as a - // fourth option. - SearchEngineChoice* default_choice = NULL; - - // First, see if we have 4 logos to show (in which case we use small logos). - // We show 4 logos when the default search engine the user has chosen is - // not one of the first three prepopulated engines. - if (template_urls.size() > 3) { - for (search_engine_iter = template_urls.begin() + 3; - search_engine_iter != template_urls.end(); - ++search_engine_iter) { - if (default_search_engine == *search_engine_iter) { - default_choice = new SearchEngineChoice(this, *search_engine_iter, - true); - } - } - } - - // Now that we know what size the logos should be, create new search engine - // choices for the view. If there are 2 search engines, only show 2 - // choices; for 3 or more, show 3 (unless the default is not one of the - // top 3, in which case show 4). - for (search_engine_iter = template_urls.begin(); - search_engine_iter < template_urls.begin() + - (template_urls.size() < 3 ? 2 : 3); - ++search_engine_iter) { - // Push first three engines into buttons: - SearchEngineChoice* choice = new SearchEngineChoice(this, - *search_engine_iter, default_choice != NULL); - search_engine_choices_.push_back(choice); - AddChildView(choice->GetView()); // The logo or text view. - AddChildView(choice); // The button associated with the choice. - } - // Push the default choice to the fourth position. - if (default_choice) { - search_engine_choices_.push_back(default_choice); - AddChildView(default_choice->GetView()); // The logo or text view. - AddChildView(default_choice); // The button associated with the choice. - } - - // Randomize order of logos if option has been set. - if (randomize_) { - std::random_shuffle(search_engine_choices_.begin(), - search_engine_choices_.end(), - base::RandGenerator); - // Assign to each choice the position in which it is shown on the screen. - std::vector<SearchEngineChoice*>::iterator it; - int slot = 0; - for (it = search_engine_choices_.begin(); - it != search_engine_choices_.end(); - it++) { - (*it)->set_slot(slot++); - } - } - - // Now that we know how many logos to show, lay out and become visible. - SetVisible(true); - Layout(); - SchedulePaint(); - - // If the widget has detected that a screenreader is running, change the - // button names from "Choose" to the name of the search engine. This works - // around a bug that JAWS ignores the accessible name of a native button. - if (GetWidget() && GetWidget()->IsAccessibleWidget()) { - std::vector<SearchEngineChoice*>::iterator it; - for (it = search_engine_choices_.begin(); - it != search_engine_choices_.end(); - it++) { - (*it)->SetLabel((*it)->GetSearchEngine()->short_name()); - } - } - - // This will tell screenreaders that they should read the full text - // of this dialog to the user now (rather than waiting for the user - // to explore it). - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); -} - -gfx::Size FirstRunSearchEngineView::GetPreferredSize() { - return views::Window::GetLocalizedContentsSize( - IDS_FIRSTRUN_SEARCH_ENGINE_SELECTION_WIDTH_CHARS, - IDS_FIRSTRUN_SEARCH_ENGINE_SELECTION_HEIGHT_LINES); -} - -void FirstRunSearchEngineView::SetupControls() { - using views::Background; - using views::ImageView; - using views::Label; - using views::NativeButton; - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - background_image_ = new views::ImageView(); - background_image_->SetImage(rb.GetBitmapNamed(IDR_SEARCH_ENGINE_DIALOG_TOP)); - background_image_->EnableCanvasFlippingForRTLUI(true); - if (text_direction_is_rtl_) { - background_image_->SetHorizontalAlignment(ImageView::LEADING); - } else { - background_image_->SetHorizontalAlignment(ImageView::TRAILING); - } - - AddChildView(background_image_); - - int label_width = GetPreferredSize().width() - 2 * kPanelHorizMargin; - - // Add title and text asking the user to choose a search engine: - title_label_ = new Label(l10n_util::GetString( - IDS_FR_SEARCH_MAIN_LABEL)); - title_label_->SetColor(SK_ColorBLACK); - title_label_->SetFont(title_label_->font().DeriveFont(3, gfx::Font::BOLD)); - title_label_->SetMultiLine(true); - title_label_->SetHorizontalAlignment(Label::ALIGN_LEFT); - title_label_->SizeToFit(label_width); - AddChildView(title_label_); - - text_label_ = new Label(l10n_util::GetStringF(IDS_FR_SEARCH_TEXT, - l10n_util::GetString(IDS_PRODUCT_NAME))); - text_label_->SetColor(SK_ColorBLACK); - text_label_->SetFont(text_label_->font().DeriveFont(1, gfx::Font::NORMAL)); - text_label_->SetMultiLine(true); - text_label_->SetHorizontalAlignment(Label::ALIGN_LEFT); - text_label_->SizeToFit(label_width); - AddChildView(text_label_); -} - -void FirstRunSearchEngineView::Layout() { - // Disable the close button. - GetWindow()->EnableClose(false); - - gfx::Size pref_size = background_image_->GetPreferredSize(); - background_image_->SetBounds(0, 0, GetPreferredSize().width(), - pref_size.height()); - - // General vertical spacing between elements: - const int kVertSpacing = 8; - // Percentage of vertical space around logos to use for upper padding. - const double kUpperPaddingPercent = 0.4; - - int num_choices = search_engine_choices_.size(); - int label_width = GetPreferredSize().width() - 2 * kPanelHorizMargin; - int label_height = GetPreferredSize().height() - 2 * kPanelVertMargin; - - // Set title. - title_label_->SetBounds(kPanelHorizMargin, - pref_size.height() / 2 - title_label_->GetPreferredSize().height() / 2, - label_width, title_label_->GetPreferredSize().height()); - - int next_v_space = background_image_->height() + kVertSpacing * 2; - - // Set text describing search engine hooked into omnibox. - text_label_->SetBounds(kPanelHorizMargin, next_v_space, - label_width, - text_label_->GetPreferredSize().height()); - next_v_space = text_label_->y() + - text_label_->height() + kVertSpacing; - - // Logos and buttons - if (num_choices > 0) { - // All search engine logos are sized the same, so the size of the first is - // generally valid as the size of all. - int logo_width = search_engine_choices_[0]->GetChoiceViewWidth(); - int logo_height = search_engine_choices_[0]->GetChoiceViewHeight(); - int button_width = search_engine_choices_[0]->GetPreferredSize().width(); - int button_height = search_engine_choices_[0]->GetPreferredSize().height(); - - int logo_section_height = logo_height + kVertSpacing + button_height; - // Upper logo margin gives the amount of whitespace between the text label - // and the logo field. The total amount of whitespace available is equal - // to the height of the whole label subtracting the heights of the logo - // section itself, the top image, the text label, and vertical spacing - // between those elements. - int upper_logo_margin = - static_cast<int>((label_height - logo_section_height - - background_image_->height() - text_label_->height() - - kVertSpacing + kPanelVertMargin) * kUpperPaddingPercent); - - next_v_space = text_label_->y() + text_label_->height() + - upper_logo_margin; - - // The search engine logos (which all have equal size): - int logo_padding = - (label_width - (num_choices * logo_width)) / (num_choices + 1); - - search_engine_choices_[0]->SetChoiceViewBounds( - kPanelHorizMargin + logo_padding, next_v_space, logo_width, - logo_height); - - int next_h_space = search_engine_choices_[0]->GetView()->x() + - logo_width + logo_padding; - search_engine_choices_[1]->SetChoiceViewBounds( - next_h_space, next_v_space, logo_width, logo_height); - - next_h_space = search_engine_choices_[1]->GetView()->x() + logo_width + - logo_padding; - if (num_choices > 2) { - search_engine_choices_[2]->SetChoiceViewBounds( - next_h_space, next_v_space, logo_width, logo_height); - } - - if (num_choices > 3) { - next_h_space = search_engine_choices_[2]->GetView()->x() + logo_width + - logo_padding; - search_engine_choices_[3]->SetChoiceViewBounds( - next_h_space, next_v_space, logo_width, logo_height); - } - - next_v_space = search_engine_choices_[0]->GetView()->y() + logo_height + - kVertSpacing; - - // The buttons for search engine selection: - int button_padding = logo_padding + logo_width / 2 - button_width / 2; - - search_engine_choices_[0]->SetBounds(kPanelHorizMargin + button_padding, - next_v_space, button_width, - button_height); - - next_h_space = search_engine_choices_[0]->x() + logo_width + logo_padding; - search_engine_choices_[1]->SetBounds(next_h_space, next_v_space, - button_width, button_height); - next_h_space = search_engine_choices_[1]->x() + logo_width + logo_padding; - if (num_choices > 2) { - search_engine_choices_[2]->SetBounds(next_h_space, next_v_space, - button_width, button_height); - } - - if (num_choices > 3) { - next_h_space = search_engine_choices_[2]->x() + logo_width + - logo_padding; - search_engine_choices_[3]->SetBounds(next_h_space, next_v_space, - button_width, button_height); - } - } // if (search_engine_choices.size() > 0) -} - -AccessibilityTypes::Role FirstRunSearchEngineView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_ALERT; -} - -std::wstring FirstRunSearchEngineView::GetWindowTitle() const { - return l10n_util::GetString(IDS_FIRSTRUN_DLG_TITLE); -} diff --git a/chrome/browser/views/first_run_search_engine_view.h b/chrome/browser/views/first_run_search_engine_view.h index a29a7ba..7dffda0 100644 --- a/chrome/browser/views/first_run_search_engine_view.h +++ b/chrome/browser/views/first_run_search_engine_view.h @@ -6,139 +6,8 @@ #define CHROME_BROWSER_VIEWS_FIRST_RUN_SEARCH_ENGINE_VIEW_H_ #pragma once -#include <vector> - -#include "chrome/browser/search_engines/template_url_model_observer.h" -#include "gfx/size.h" -#include "views/controls/button/native_button.h" -#include "views/view.h" -#include "views/window/window_delegate.h" - -namespace views { -class ButtonListener; -class ImageView; -class Label; -class Separator; -class Window; -} - -class Profile; -class TemplateURL; -class TemplateURLModel; - -// This class holds the logo and TemplateURL for a search engine and serves -// as its button in the search engine selection view. -class SearchEngineChoice : public views::NativeButton { - public: - // |listener| is the FirstRunView that waits for the search engine selection - // to complete; |search_engine| holds the data for the particular search - // engine this button represents; |use_small_logos| is true if we're - // displaying more than three choices. - SearchEngineChoice(views::ButtonListener* listener, - const TemplateURL* search_engine, - bool use_small_logos); - - virtual ~SearchEngineChoice() {} - - // These methods return data about the logo or text view associated - // with this search engine choice. - views::View* GetView() { return choice_view_; } - int GetChoiceViewWidth(); - int GetChoiceViewHeight(); - - // Set the bounds for the search engine choice view; called in the - // Layout method, when we know what the new bounds should be. - void SetChoiceViewBounds(int x, int y, int width, int height); - - // Accessor for the search engine data this button represents. - const TemplateURL* GetSearchEngine() { return search_engine_; } - - // Used for UX testing. - void set_slot(int slot) { slot_ = slot; } - int slot() const { return slot_; } - - private: - // Either an ImageView of a logo, or a Label with text. Owned by - // FirstRunSearchEngineView. - views::View* choice_view_; - - // True if choice_view_ is holding an ImageView. - bool is_image_label_; - - // Data for the search engine held here. - const TemplateURL* search_engine_; - - // Used for UX testing. Gives slot in which search engine was shown. - int slot_; - - DISALLOW_COPY_AND_ASSIGN(SearchEngineChoice); -}; - -// This class displays a large search engine choice dialog view during -// initial first run import. -class FirstRunSearchEngineView - : public views::View, - public views::ButtonListener, - public views::WindowDelegate, - public TemplateURLModelObserver { - public: - // |profile| allows us to get the set of imported search engines. - // |randomize| is true if logos are to be displayed in random order. - FirstRunSearchEngineView(Profile* profile, bool randomize); - - virtual ~FirstRunSearchEngineView(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // Overridden from views::WindowDelegate: - virtual std::wstring GetWindowTitle() const; - views::View* GetContentsView() { return this; } - bool CanResize() const { return false; } - bool CanMaximize() const { return false; } - bool IsAlwaysOnTop() const { return true; } - bool HasAlwaysOnTopMenu() const { return false; } - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Override from View so we can draw the gray background at dialog top. - virtual void Paint(gfx::Canvas* canvas); - - // Overridden from TemplateURLModelObserver. When the search engines have - // loaded from the profile, we can populate the logos in the dialog box - // to present to the user. - virtual void OnTemplateURLModelChanged(); - - private: - // Initializes the labels and controls in the view. - void SetupControls(); - - // Owned by the profile_. - TemplateURLModel* search_engines_model_; - - // One for each search engine choice offered, either three or four. - std::vector<SearchEngineChoice*> search_engine_choices_; - - // If logos are to be displayed in random order. Used for UX testing. - bool randomize_; - - // The profile associated with this import process. - Profile* profile_; - - bool text_direction_is_rtl_; - - // Image of browser search box with grey background and bubble arrow. - views::ImageView* background_image_; - - // UI elements: - views::Label* title_label_; - views::Label* text_label_; - - DISALLOW_COPY_AND_ASSIGN(FirstRunSearchEngineView); -}; +#include "chrome/browser/ui/views/first_run_search_engine_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FIRST_RUN_SEARCH_ENGINE_VIEW_H_ diff --git a/chrome/browser/views/frame/app_panel_browser_frame_view.cc b/chrome/browser/views/frame/app_panel_browser_frame_view.cc deleted file mode 100644 index d7efbe9..0000000 --- a/chrome/browser/views/frame/app_panel_browser_frame_view.cc +++ /dev/null @@ -1,505 +0,0 @@ -// 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/app_panel_browser_frame_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/compiler_specific.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "gfx/canvas.h" -#include "gfx/font.h" -#include "gfx/path.h" -#include "grit/app_resources.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/image_button.h" -#include "views/window/window.h" -#include "views/window/window_resources.h" - -#if defined(OS_LINUX) -#include "views/window/hit_test.h" -#endif - -namespace { -// The frame border is only visible in restored mode and is hardcoded to 1 px on -// each side regardless of the system window border size. -const int kFrameBorderThickness = 1; -// In the window corners, the resize areas don't actually expand bigger, but the -// 16 px at the end of each edge triggers diagonal resizing. -const int kResizeAreaCornerSize = 16; -// The titlebar never shrinks too short to show the caption button plus some -// padding below it. -const int kCaptionButtonHeightWithPadding = 27; -// The titlebar has a 2 px 3D edge along the bottom, and we reserve 2 px (1 for -// border, 1 for padding) along the top. -const int kTitlebarTopAndBottomEdgeThickness = 2; -// The icon is inset 6 px from the left frame border. -const int kIconLeftSpacing = 6; -// The icon never shrinks below 16 px on a side. -const int kIconMinimumSize = 16; -// There is a 4 px gap between the icon and the title text. -const int kIconTitleSpacing = 4; -// There is a 5 px gap between the title text and the close button. -const int kTitleCloseButtonSpacing = 5; -// There is a 4 px gap between the close button and the frame border. -const int kCloseButtonFrameBorderSpacing = 4; -} - -/////////////////////////////////////////////////////////////////////////////// -// AppPanelBrowserFrameView, public: - -AppPanelBrowserFrameView::AppPanelBrowserFrameView(BrowserFrame* frame, - BrowserView* browser_view) - : BrowserNonClientFrameView(), - ALLOW_THIS_IN_INITIALIZER_LIST( - close_button_(new views::ImageButton(this))), - window_icon_(NULL), - frame_(frame), - browser_view_(browser_view) { - DCHECK(browser_view->ShouldShowWindowIcon()); - DCHECK(browser_view->ShouldShowWindowTitle()); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_CLOSE_BAR)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); - close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); - AddChildView(close_button_); - - window_icon_ = new TabIconView(this); - window_icon_->set_is_light(true); - AddChildView(window_icon_); - window_icon_->Update(); -} - -AppPanelBrowserFrameView::~AppPanelBrowserFrameView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// AppPanelBrowserFrameView, BrowserNonClientFrameView implementation: - -gfx::Rect AppPanelBrowserFrameView::GetBoundsForTabStrip( - BaseTabStrip* tabstrip) const { - // App panels never show a tab strip. - NOTREACHED(); - return gfx::Rect(); -} - -int AppPanelBrowserFrameView::GetHorizontalTabStripVerticalOffset( - bool restored) const { - // App panels are not themed and don't need this. - return 0; -} - -void AppPanelBrowserFrameView::UpdateThrobber(bool running) { - window_icon_->Update(); -} - -gfx::Size AppPanelBrowserFrameView::GetMinimumSize() { - gfx::Size min_size(browser_view_->GetMinimumSize()); - int border_thickness = NonClientBorderThickness(); - min_size.Enlarge(2 * border_thickness, - NonClientTopBorderHeight() + border_thickness); - - min_size.set_width(std::max(min_size.width(), - (2 * FrameBorderThickness()) + kIconLeftSpacing + IconSize() + - kTitleCloseButtonSpacing + kCloseButtonFrameBorderSpacing)); - return min_size; -} - -/////////////////////////////////////////////////////////////////////////////// -// AppPanelBrowserFrameView, views::NonClientFrameView implementation: - -gfx::Rect AppPanelBrowserFrameView::GetBoundsForClientView() const { - return client_view_bounds_; -} - -bool AppPanelBrowserFrameView::AlwaysUseCustomFrame() const { - return true; -} - -bool AppPanelBrowserFrameView::AlwaysUseNativeFrame() const { - return frame_->AlwaysUseNativeFrame(); -} - -gfx::Rect AppPanelBrowserFrameView::GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const { - int top_height = NonClientTopBorderHeight(); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), - std::max(0, client_bounds.y() - top_height), - client_bounds.width() + (2 * border_thickness), - client_bounds.height() + top_height + border_thickness); -} - -int AppPanelBrowserFrameView::NonClientHitTest(const gfx::Point& point) { - if (!bounds().Contains(point)) - return HTNOWHERE; - - int frame_component = - frame_->GetWindow()->GetClientView()->NonClientHitTest(point); - - // See if we're in the sysmenu region. (We check the ClientView first to be - // consistent with OpaqueBrowserFrameView; it's not really necessary here.) - gfx::Rect sysmenu_rect(IconBounds()); - // In maximized mode we extend the rect to the screen corner to take advantage - // of Fitts' Law. - if (frame_->GetWindow()->IsMaximized()) - sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom()); - sysmenu_rect.set_x(MirroredLeftPointForRect(sysmenu_rect)); - if (sysmenu_rect.Contains(point)) - return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; - - if (frame_component != HTNOWHERE) - return frame_component; - - // Then see if the point is within any of the window controls. - if (close_button_->IsVisible() && - close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) - return HTCLOSE; - - int window_component = GetHTComponentForFrame(point, - NonClientBorderThickness(), NonClientBorderThickness(), - kResizeAreaCornerSize, kResizeAreaCornerSize, - frame_->GetWindow()->GetDelegate()->CanResize()); - // Fall back to the caption if no other component matches. - return (window_component == HTNOWHERE) ? HTCAPTION : window_component; -} - -void AppPanelBrowserFrameView::GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) { - DCHECK(window_mask); - - if (frame_->GetWindow()->IsMaximized()) - return; - - // Redefine the window visible region for the new size. - window_mask->moveTo(0, 3); - window_mask->lineTo(1, 2); - window_mask->lineTo(1, 1); - window_mask->lineTo(2, 1); - window_mask->lineTo(3, 0); - - window_mask->lineTo(SkIntToScalar(size.width() - 3), 0); - window_mask->lineTo(SkIntToScalar(size.width() - 2), 1); - window_mask->lineTo(SkIntToScalar(size.width() - 1), 1); - window_mask->lineTo(SkIntToScalar(size.width() - 1), 2); - window_mask->lineTo(SkIntToScalar(size.width()), 3); - - window_mask->lineTo(SkIntToScalar(size.width()), - SkIntToScalar(size.height())); - window_mask->lineTo(0, SkIntToScalar(size.height())); - window_mask->close(); -} - -void AppPanelBrowserFrameView::EnableClose(bool enable) { - close_button_->SetEnabled(enable); -} - -void AppPanelBrowserFrameView::ResetWindowControls() { - // The close button isn't affected by this constraint. -} - -/////////////////////////////////////////////////////////////////////////////// -// AppPanelBrowserFrameView, views::View overrides: - -void AppPanelBrowserFrameView::Paint(gfx::Canvas* canvas) { - views::Window* window = frame_->GetWindow(); - if (window->IsMaximized()) - PaintMaximizedFrameBorder(canvas); - else - PaintRestoredFrameBorder(canvas); - PaintTitleBar(canvas); - if (!window->IsMaximized()) - PaintRestoredClientEdge(canvas); -} - -void AppPanelBrowserFrameView::Layout() { - LayoutWindowControls(); - LayoutTitleBar(); - client_view_bounds_ = CalculateClientAreaBounds(width(), height()); -} - -/////////////////////////////////////////////////////////////////////////////// -// AppPanelBrowserFrameView, views::ButtonListener implementation: - -void AppPanelBrowserFrameView::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == close_button_) - frame_->GetWindow()->Close(); -} - -/////////////////////////////////////////////////////////////////////////////// -// AppPanelBrowserFrameView, TabIconView::TabContentsProvider implementation: - -bool AppPanelBrowserFrameView::ShouldTabIconViewAnimate() const { - // This function is queried during the creation of the window as the - // TabIconView we host is initialized, so we need to NULL check the selected - // TabContents because in this condition there is not yet a selected tab. - TabContents* current_tab = browser_view_->GetSelectedTabContents(); - return current_tab ? current_tab->is_loading() : false; -} - -SkBitmap AppPanelBrowserFrameView::GetFavIconForTabIconView() { - return frame_->GetWindow()->GetDelegate()->GetWindowIcon(); -} - -/////////////////////////////////////////////////////////////////////////////// -// AppPanelBrowserFrameView, private: - -int AppPanelBrowserFrameView::FrameBorderThickness() const { - return frame_->GetWindow()->IsMaximized() ? 0 : kFrameBorderThickness; -} - -int AppPanelBrowserFrameView::NonClientBorderThickness() const { - return FrameBorderThickness() + - (frame_->GetWindow()->IsMaximized() ? 0 : kClientEdgeThickness); -} - -int AppPanelBrowserFrameView::NonClientTopBorderHeight() const { - return std::max(FrameBorderThickness() + IconSize(), - FrameBorderThickness() + kCaptionButtonHeightWithPadding) + - TitlebarBottomThickness(); -} - -int AppPanelBrowserFrameView::TitlebarBottomThickness() const { - return kTitlebarTopAndBottomEdgeThickness + - (frame_->GetWindow()->IsMaximized() ? 0 : kClientEdgeThickness); -} - -int AppPanelBrowserFrameView::IconSize() const { -#if defined(OS_WIN) - // This metric scales up if either the titlebar height or the titlebar font - // size are increased. - return GetSystemMetrics(SM_CYSMICON); -#else - return std::max(BrowserFrame::GetTitleFont().height(), kIconMinimumSize); -#endif -} - -gfx::Rect AppPanelBrowserFrameView::IconBounds() const { - int size = IconSize(); - int frame_thickness = FrameBorderThickness(); - // Our frame border has a different "3D look" than Windows'. Theirs has a - // more complex gradient on the top that they push their icon/title below; - // then the maximized window cuts this off and the icon/title are centered - // in the remaining space. Because the apparent shape of our border is - // simpler, using the same positioning makes things look slightly uncentered - // with restored windows, so when the window is restored, instead of - // calculating the remaining space from below the frame border, we calculate - // from below the top border-plus-padding. - int unavailable_px_at_top = frame_->GetWindow()->IsMaximized() ? - frame_thickness : kTitlebarTopAndBottomEdgeThickness; - // When the icon is shorter than the minimum space we reserve for the caption - // button, we vertically center it. We want to bias rounding to put extra - // space above the icon, since the 3D edge (+ client edge, for restored - // windows) below looks (to the eye) more like additional space than does the - // border + padding (or nothing at all, for maximized windows) above; hence - // the +1. - int y = unavailable_px_at_top + (NonClientTopBorderHeight() - - unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2; - return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size); -} - -void AppPanelBrowserFrameView::PaintRestoredFrameBorder(gfx::Canvas* canvas) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - SkBitmap* top_left_corner = rb.GetBitmapNamed(IDR_WINDOW_TOP_LEFT_CORNER); - SkBitmap* top_right_corner = - rb.GetBitmapNamed(IDR_WINDOW_TOP_RIGHT_CORNER); - SkBitmap* top_edge = rb.GetBitmapNamed(IDR_WINDOW_TOP_CENTER); - SkBitmap* right_edge = rb.GetBitmapNamed(IDR_WINDOW_RIGHT_SIDE); - SkBitmap* left_edge = rb.GetBitmapNamed(IDR_WINDOW_LEFT_SIDE); - SkBitmap* bottom_left_corner = - rb.GetBitmapNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER); - SkBitmap* bottom_right_corner = - rb.GetBitmapNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER); - SkBitmap* bottom_edge = rb.GetBitmapNamed(IDR_WINDOW_BOTTOM_CENTER); - - // Window frame mode and color. - SkBitmap* theme_frame; - SkColor frame_color; - if (ShouldPaintAsActive()) { - theme_frame = rb.GetBitmapNamed(IDR_FRAME_APP_PANEL); - frame_color = ResourceBundle::frame_color_app_panel; - } else { - theme_frame = rb.GetBitmapNamed(IDR_FRAME_APP_PANEL); // TODO - frame_color = ResourceBundle::frame_color_app_panel_inactive; - } - - // Fill with the frame color first so we have a constant background for - // areas not covered by the theme image. - canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height()); - // Now fill down the sides. - canvas->FillRectInt(frame_color, 0, theme_frame->height(), left_edge->width(), - height() - theme_frame->height()); - canvas->FillRectInt(frame_color, width() - right_edge->width(), - theme_frame->height(), right_edge->width(), - height() - theme_frame->height()); - // Now fill the bottom area. - canvas->FillRectInt(frame_color, left_edge->width(), - height() - bottom_edge->height(), - width() - left_edge->width() - right_edge->width(), - bottom_edge->height()); - - // Draw the theme frame. - canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height()); - - // Top. - canvas->DrawBitmapInt(*top_left_corner, 0, 0); - canvas->TileImageInt(*top_edge, top_left_corner->width(), 0, - width() - top_right_corner->width(), top_edge->height()); - canvas->DrawBitmapInt(*top_right_corner, - width() - top_right_corner->width(), 0); - - // Right. - canvas->TileImageInt(*right_edge, width() - right_edge->width(), - top_right_corner->height(), right_edge->width(), - height() - top_right_corner->height() - bottom_right_corner->height()); - - // Bottom. - canvas->DrawBitmapInt(*bottom_right_corner, - width() - bottom_right_corner->width(), - height() - bottom_right_corner->height()); - canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(), - height() - bottom_edge->height(), - width() - bottom_left_corner->width() - bottom_right_corner->width(), - bottom_edge->height()); - canvas->DrawBitmapInt(*bottom_left_corner, 0, - height() - bottom_left_corner->height()); - - // Left. - canvas->TileImageInt(*left_edge, 0, top_left_corner->height(), - left_edge->width(), - height() - top_left_corner->height() - bottom_left_corner->height()); -} - -void AppPanelBrowserFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - SkBitmap* frame_image = rb.GetBitmapNamed(IDR_FRAME_APP_PANEL); - canvas->TileImageInt(*frame_image, 0, FrameBorderThickness(), width(), - frame_image->height()); - - // The bottom of the titlebar actually comes from the top of the Client Edge - // graphic, with the actual client edge clipped off the bottom. - SkBitmap* titlebar_bottom = rb.GetBitmapNamed(IDR_APP_TOP_CENTER); - int edge_height = titlebar_bottom->height() - kClientEdgeThickness; - canvas->TileImageInt(*titlebar_bottom, 0, - frame_->GetWindow()->GetClientView()->y() - edge_height, - width(), edge_height); -} - -void AppPanelBrowserFrameView::PaintTitleBar(gfx::Canvas* canvas) { - // The window icon is painted by the TabIconView. - views::WindowDelegate* d = frame_->GetWindow()->GetDelegate(); - canvas->DrawStringInt(d->GetWindowTitle(), BrowserFrame::GetTitleFont(), - SK_ColorBLACK, MirroredLeftPointForRect(title_bounds_), title_bounds_.y(), - title_bounds_.width(), title_bounds_.height()); -} - -void AppPanelBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { - gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); - int client_area_top = client_area_bounds.y(); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - SkBitmap* top_left = rb.GetBitmapNamed(IDR_APP_TOP_LEFT); - SkBitmap* top = rb.GetBitmapNamed(IDR_APP_TOP_CENTER); - SkBitmap* top_right = rb.GetBitmapNamed(IDR_APP_TOP_RIGHT); - SkBitmap* right = rb.GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE); - SkBitmap* bottom_right = - rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER); - SkBitmap* bottom = rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER); - SkBitmap* bottom_left = - rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER); - SkBitmap* left = rb.GetBitmapNamed(IDR_CONTENT_LEFT_SIDE); - - // Top. - int top_edge_y = client_area_top - top->height(); - canvas->DrawBitmapInt(*top_left, client_area_bounds.x() - top_left->width(), - top_edge_y); - canvas->TileImageInt(*top, client_area_bounds.x(), top_edge_y, - client_area_bounds.width(), top->height()); - canvas->DrawBitmapInt(*top_right, client_area_bounds.right(), top_edge_y); - - // Right. - int client_area_bottom = - std::max(client_area_top, client_area_bounds.bottom()); - int client_area_height = client_area_bottom - client_area_top; - canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, - right->width(), client_area_height); - - // Bottom. - canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(), - client_area_bottom); - canvas->TileImageInt(*bottom, client_area_bounds.x(), client_area_bottom, - client_area_bounds.width(), bottom_right->height()); - canvas->DrawBitmapInt(*bottom_left, - client_area_bounds.x() - bottom_left->width(), client_area_bottom); - - // Left. - canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), - client_area_top, left->width(), client_area_height); - - // Draw the toolbar color to fill in the edges. - canvas->DrawRectInt(ResourceBundle::toolbar_color, - client_area_bounds.x() - kClientEdgeThickness, - client_area_top - kClientEdgeThickness, - client_area_bounds.width() + kClientEdgeThickness, - client_area_bottom - client_area_top + kClientEdgeThickness); -} - -void AppPanelBrowserFrameView::LayoutWindowControls() { - close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, - views::ImageButton::ALIGN_BOTTOM); - bool is_maximized = frame_->GetWindow()->IsMaximized(); - // There should always be the same number of non-border pixels visible to the - // side of the close button. In maximized mode we extend the button to the - // screen corner to obey Fitts' Law. - int right_extra_width = is_maximized ? kCloseButtonFrameBorderSpacing : 0; - gfx::Size close_button_size = close_button_->GetPreferredSize(); - int close_button_y = - (NonClientTopBorderHeight() - close_button_size.height()) / 2; - int top_extra_height = is_maximized ? close_button_y : 0; - close_button_->SetBounds(width() - FrameBorderThickness() - - kCloseButtonFrameBorderSpacing - close_button_size.width(), - close_button_y - top_extra_height, - close_button_size.width() + right_extra_width, - close_button_size.height() + top_extra_height); -} - -void AppPanelBrowserFrameView::LayoutTitleBar() { - // Size the icon first; the window title is based on the icon position. - gfx::Rect icon_bounds(IconBounds()); - window_icon_->SetBounds(icon_bounds); - - // Size the title. - int title_x = icon_bounds.right() + kIconTitleSpacing; - int title_height = BrowserFrame::GetTitleFont().GetHeight(); - // We bias the title position so that when the difference between the icon - // and title heights is odd, the extra pixel of the title is above the - // vertical midline rather than below. This compensates for how the icon is - // already biased downwards (see IconBounds()) and helps prevent descenders - // on the title from overlapping the 3D edge at the bottom of the titlebar. - title_bounds_.SetRect(title_x, - icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), - std::max(0, close_button_->x() - kTitleCloseButtonSpacing - title_x), - title_height); -} - -gfx::Rect AppPanelBrowserFrameView::CalculateClientAreaBounds(int width, - int height) const { - int top_height = NonClientTopBorderHeight(); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(border_thickness, top_height, - std::max(0, width - (2 * border_thickness)), - std::max(0, height - top_height - border_thickness)); -} diff --git a/chrome/browser/views/frame/app_panel_browser_frame_view.h b/chrome/browser/views/frame/app_panel_browser_frame_view.h index eae6d9b..cc93319 100644 --- a/chrome/browser/views/frame/app_panel_browser_frame_view.h +++ b/chrome/browser/views/frame/app_panel_browser_frame_view.h @@ -6,125 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_APP_PANEL_BROWSER_FRAME_VIEW_H_ #pragma once -#include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/browser/views/frame/browser_non_client_frame_view.h" -#include "chrome/browser/views/tab_icon_view.h" -#include "views/controls/button/button.h" -#include "views/window/non_client_view.h" - -class BaseTabStrip; -class BrowserView; -class TabContents; -namespace gfx { -class Font; -} -namespace views { -class ImageButton; -class ImageView; -} -// The frame view which is used for Application Panels. -// TODO(rafaelw): Refactor. This shares much duplicated code with -// OpaqueBrowserFrameView. -class AppPanelBrowserFrameView : public BrowserNonClientFrameView, - public views::ButtonListener, - public TabIconView::TabIconViewModel { - public: - // Constructs a non-client view for an BrowserFrame. - AppPanelBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view); - virtual ~AppPanelBrowserFrameView(); - - // Overridden from BrowserNonClientFrameView: - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const; - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const; - virtual void UpdateThrobber(bool running); - virtual gfx::Size GetMinimumSize(); - - protected: - // Overridden from views::NonClientFrameView: - virtual gfx::Rect GetBoundsForClientView() const; - virtual bool AlwaysUseCustomFrame() const; - virtual bool AlwaysUseNativeFrame() const; - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); - virtual void EnableClose(bool enable); - virtual void ResetWindowControls(); - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from TabIconView::TabIconViewModel: - virtual bool ShouldTabIconViewAnimate() const; - virtual SkBitmap GetFavIconForTabIconView(); - - private: - // Returns the thickness of the border that makes up the window frame edges. - // This does not include any client edge. - int FrameBorderThickness() const; - - // Returns the thickness of the entire nonclient left, right, and bottom - // borders, including both the window frame and any client edge. - int NonClientBorderThickness() const; - - // Returns the height of the entire nonclient top border, including the window - // frame, any title area, and any connected client edge. - int NonClientTopBorderHeight() const; - - // Returns the thickness of the nonclient portion of the 3D edge along the - // bottom of the titlebar. - int TitlebarBottomThickness() const; - - // Returns the size of the titlebar icon. - int IconSize() const; - - // Returns the bounds of the titlebar icon. - gfx::Rect IconBounds() const; - - // Paint various sub-components of this view. The *FrameBorder() function - // also paints the background of the titlebar area, since the top frame border - // and titlebar background are a contiguous component. - void PaintRestoredFrameBorder(gfx::Canvas* canvas); - void PaintMaximizedFrameBorder(gfx::Canvas* canvas); - void PaintTitleBar(gfx::Canvas* canvas); - void PaintRestoredClientEdge(gfx::Canvas* canvas); - - // Layout various sub-components of this view. - void LayoutWindowControls(); - void LayoutTitleBar(); - - // Returns the bounds of the client area for the specified view size. - gfx::Rect CalculateClientAreaBounds(int width, int height) const; - - // The layout rect of the title, if visible. - gfx::Rect title_bounds_; - - // Window controls. - views::ImageButton* close_button_; - - // The Window icon. - TabIconView* window_icon_; - - // The frame that hosts this view. - BrowserFrame* frame_; - - // The BrowserView hosted within this View. - BrowserView* browser_view_; - - // The bounds of the ClientView. - gfx::Rect client_view_bounds_; - - // The accessible name of this view. - std::wstring accessible_name_; - - static void InitAppWindowResources(); - static gfx::Font* title_font_; - - DISALLOW_COPY_AND_ASSIGN(AppPanelBrowserFrameView); -}; +#include "chrome/browser/ui/views/frame/app_panel_browser_frame_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_APP_PANEL_BROWSER_FRAME_VIEW_H_ + diff --git a/chrome/browser/views/frame/browser_bubble_host.cc b/chrome/browser/views/frame/browser_bubble_host.cc deleted file mode 100644 index 60809bf..0000000 --- a/chrome/browser/views/frame/browser_bubble_host.cc +++ /dev/null @@ -1,43 +0,0 @@ -// 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_bubble_host.h" - -#include "base/logging.h" -#include "chrome/browser/views/browser_bubble.h" - -void BrowserBubbleHost::WindowMoved() { - // Do safe iteration in case the bubble winds up closing as a result of this - // message. - for (BubbleSet::iterator i = browser_bubbles_.begin(); - i != browser_bubbles_.end();) { - BubbleSet::iterator bubble = i++; - (*bubble)->BrowserWindowMoved(); - } -} - -void BrowserBubbleHost::AttachBrowserBubble(BrowserBubble* bubble) { - DCHECK(browser_bubbles_.find(bubble) == browser_bubbles_.end()) << - "Attempt to register the same BrowserBubble multiple times."; - browser_bubbles_.insert(bubble); -} - -void BrowserBubbleHost::DetachBrowserBubble(BrowserBubble* bubble) { - BubbleSet::iterator it = browser_bubbles_.find(bubble); - DCHECK(it != browser_bubbles_.end()) << - "Attempt to detach an unrecognized BrowserBubble."; - if (it != browser_bubbles_.end()) - browser_bubbles_.erase(it); -} - -void BrowserBubbleHost::Close() { - // BrowserWindowClosing will usually cause the bubble to remove itself from - // the set, so we need to iterate in a way that's safe against deletion. - for (BubbleSet::iterator i = browser_bubbles_.begin(); - i != browser_bubbles_.end();) { - BubbleSet::iterator bubble = i++; - (*bubble)->BrowserWindowClosing(); - } -} - diff --git a/chrome/browser/views/frame/browser_bubble_host.h b/chrome/browser/views/frame/browser_bubble_host.h index 99b8058..f903d99 100644 --- a/chrome/browser/views/frame/browser_bubble_host.h +++ b/chrome/browser/views/frame/browser_bubble_host.h @@ -6,38 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_BUBBLE_HOST_H_ #pragma once -#include <set> - -#include "base/basictypes.h" - -class BrowserBubble; - -// A class providing a hosting environment for BrowserBubble instances. -// Allows for notification to attached BrowserBubbles of browser move, and -// close events. -class BrowserBubbleHost { - public: - BrowserBubbleHost() {} - - // Invoked when the window containing the attached browser-bubbles is moved. - // Calls BrowserBubble::BrowserWindowMoved on all attached bubbles. - void WindowMoved(); - - // To be called when the frame containing the BrowserBubbleHost is closing. - // Calls BrowserBubble::BrowserWindowClosing on all attached bubbles. - void Close(); - - // Registers/Unregisters |bubble| to receive notifications when the host moves - // or is closed. - void AttachBrowserBubble(BrowserBubble* bubble); - void DetachBrowserBubble(BrowserBubble* bubble); - - private: - // The set of bubbles associated with this host. - typedef std::set<BrowserBubble*> BubbleSet; - BubbleSet browser_bubbles_; - - DISALLOW_COPY_AND_ASSIGN(BrowserBubbleHost); -}; +#include "chrome/browser/ui/views/frame/browser_bubble_host.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_BUBBLE_HOST_H_ + diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h index 0e3b9b2..eaf9fe6 100644 --- a/chrome/browser/views/frame/browser_frame.h +++ b/chrome/browser/views/frame/browser_frame.h @@ -6,75 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_ #pragma once -#include "build/build_config.h" -#include "views/window/non_client_view.h" - -class BaseTabStrip; -class BrowserView; -class Profile; -class ThemeProvider; - -namespace gfx { -class Font; -class Rect; -} // namespace gfx - -namespace views { -class Window; - -#if defined(OS_WIN) -class WindowWin; -#endif -} // namespace views - -// This is a virtual interface that allows system specific browser frames. -class BrowserFrame { - public: - virtual ~BrowserFrame() {} - - // Creates the appropriate BrowserFrame for this platform. The returned - // object is owned by the caller. - static BrowserFrame* Create(BrowserView* browser_view, Profile* profile); - - static const gfx::Font& GetTitleFont(); - - // Returns the Window associated with this frame. Guraranteed non-NULL after - // construction. - virtual views::Window* GetWindow() = 0; - - // Determine the distance of the left edge of the minimize button from the - // left edge of the window. Used in our Non-Client View's Layout. - virtual int GetMinimizeButtonOffset() const = 0; - - // Retrieves the bounds, in non-client view coordinates for the specified - // TabStrip. - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const = 0; - - // Returns the y coordinate within the window at which the horizontal TabStrip - // begins (or would begin). If |restored| is true, this is calculated as if - // we were in restored mode regardless of the current mode. - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const = 0; - - // Tells the frame to update the throbber. - virtual void UpdateThrobber(bool running) = 0; - - // Tells the frame to continue a drag detached tab operation. - virtual void ContinueDraggingDetachedTab() = 0; - - // Returns the theme provider for this frame. - virtual ThemeProvider* GetThemeProviderForFrame() const = 0; - - // Returns true if the window should use the native frame view. This is true - // if there are no themes applied on Vista, or if there are themes applied and - // this browser window is an app or popup. - virtual bool AlwaysUseNativeFrame() const = 0; - - // Returns the NonClientFrameView of this frame. - virtual views::View* GetFrameView() const = 0; - - // Notifies the frame that the tab strip display mode changed so it can update - // its frame treatment if necessary. - virtual void TabStripDisplayModeChanged() = 0; -}; +#include "chrome/browser/ui/views/frame/browser_frame.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_ + diff --git a/chrome/browser/views/frame/browser_frame_gtk.cc b/chrome/browser/views/frame/browser_frame_gtk.cc deleted file mode 100644 index 83a6acb..0000000 --- a/chrome/browser/views/frame/browser_frame_gtk.cc +++ /dev/null @@ -1,154 +0,0 @@ -// 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_frame_gtk.h" - -#include "base/logging.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/status_bubble.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/views/frame/app_panel_browser_frame_view.h" -#include "chrome/browser/views/frame/browser_root_view.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/frame/opaque_browser_frame_view.h" -#include "chrome/browser/views/frame/popup_non_client_frame_view.h" -#include "gfx/font.h" -#include "views/widget/root_view.h" -#include "views/window/hit_test.h" - -#if !defined(OS_CHROMEOS) -// static (Factory method.) -BrowserFrame* BrowserFrame::Create(BrowserView* browser_view, - Profile* profile) { - BrowserFrameGtk* frame = new BrowserFrameGtk(browser_view, profile); - frame->Init(); - return frame; -} -#endif - -// static -const gfx::Font& BrowserFrame::GetTitleFont() { - static gfx::Font *title_font = new gfx::Font(); - return *title_font; -} - -BrowserFrameGtk::BrowserFrameGtk(BrowserView* browser_view, Profile* profile) - : WindowGtk(browser_view), - browser_view_(browser_view), - browser_frame_view_(NULL), - root_view_(NULL), - profile_(profile) { - browser_view_->set_frame(this); -} - -BrowserFrameGtk::~BrowserFrameGtk() { -} - -void BrowserFrameGtk::Init() { - if (browser_frame_view_ == NULL) { - if (browser_view_->browser()->type() & Browser::TYPE_POPUP) - browser_frame_view_ = new PopupNonClientFrameView(); - else - browser_frame_view_ = new OpaqueBrowserFrameView(this, browser_view_); - } - GetNonClientView()->SetFrameView(browser_frame_view_); - WindowGtk::Init(NULL, gfx::Rect()); - // Don't focus anything on creation, selecting a tab will set the focus. -} - -views::Window* BrowserFrameGtk::GetWindow() { - return this; -} - -int BrowserFrameGtk::GetMinimizeButtonOffset() const { - NOTIMPLEMENTED(); - return 0; -} - -gfx::Rect BrowserFrameGtk::GetBoundsForTabStrip(BaseTabStrip* tabstrip) const { - return browser_frame_view_->GetBoundsForTabStrip(tabstrip); -} - -int BrowserFrameGtk::GetHorizontalTabStripVerticalOffset(bool restored) const { - return browser_frame_view_->GetHorizontalTabStripVerticalOffset(restored); -} - -void BrowserFrameGtk::UpdateThrobber(bool running) { - browser_frame_view_->UpdateThrobber(running); -} - -void BrowserFrameGtk::ContinueDraggingDetachedTab() { - NOTIMPLEMENTED(); -} - -ThemeProvider* BrowserFrameGtk::GetThemeProviderForFrame() const { - // This is implemented for a different interface than GetThemeProvider is, - // but they mean the same things. - return GetThemeProvider(); -} - -bool BrowserFrameGtk::AlwaysUseNativeFrame() const { - return false; -} - -views::View* BrowserFrameGtk::GetFrameView() const { - return browser_frame_view_; -} - -void BrowserFrameGtk::TabStripDisplayModeChanged() { - if (GetRootView()->GetChildViewCount() > 0) { - // Make sure the child of the root view gets Layout again. - GetRootView()->GetChildViewAt(0)->InvalidateLayout(); - } - GetRootView()->Layout(); -} - -ThemeProvider* BrowserFrameGtk::GetThemeProvider() const { - return profile_->GetThemeProvider(); -} - -ThemeProvider* BrowserFrameGtk::GetDefaultThemeProvider() const { - return profile_->GetThemeProvider(); -} - -views::RootView* BrowserFrameGtk::CreateRootView() { - root_view_ = new BrowserRootView(browser_view_, this); - return root_view_; -} - -void BrowserFrameGtk::IsActiveChanged() { - GetRootView()->SchedulePaint(); - browser_view_->ActivationChanged(IsActive()); - views::WidgetGtk::IsActiveChanged(); -} - -void BrowserFrameGtk::SetInitialFocus() { - browser_view_->RestoreFocus(); -} - -bool BrowserFrameGtk::GetAccelerator(int cmd_id, - menus::Accelerator* accelerator) { - return browser_view_->GetAccelerator(cmd_id, accelerator); -} - -gboolean BrowserFrameGtk::OnWindowStateEvent(GtkWidget* widget, - GdkEventWindowState* event) { - bool was_full_screen = IsFullscreen(); - gboolean result = views::WindowGtk::OnWindowStateEvent(widget, event); - if ((!IsVisible() || IsMinimized()) && browser_view_->GetStatusBubble()) { - // The window is effectively hidden. We have to hide the status bubble as - // unlike windows gtk has no notion of child windows that are hidden along - // with the parent. - browser_view_->GetStatusBubble()->Hide(); - } - if (was_full_screen != IsFullscreen()) - browser_view_->FullScreenStateChanged(); - return result; -} - -gboolean BrowserFrameGtk::OnConfigureEvent(GtkWidget* widget, - GdkEventConfigure* event) { - browser_view_->WindowMoved(); - return views::WindowGtk::OnConfigureEvent(widget, event); -} diff --git a/chrome/browser/views/frame/browser_frame_gtk.h b/chrome/browser/views/frame/browser_frame_gtk.h index 742eea5..1b8977c 100644 --- a/chrome/browser/views/frame/browser_frame_gtk.h +++ b/chrome/browser/views/frame/browser_frame_gtk.h @@ -6,80 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_GTK_H_ #pragma once -#include "base/basictypes.h" -#include "chrome/browser/views/frame/browser_frame.h" -#include "views/window/window_gtk.h" - -class BrowserNonClientFrameView; -class BrowserRootView; - -class BrowserFrameGtk : public BrowserFrame, - public views::WindowGtk { - public: - // Normally you will create this class by calling BrowserFrame::Create. - // Init must be called before using this class, which Create will do for you. - BrowserFrameGtk(BrowserView* browser_view, Profile* profile); - virtual ~BrowserFrameGtk(); - - // Creates a frame view and initializes the window. This - // initialization function must be called after construction, it is - // separate to avoid recursive calling of the frame from its - // constructor. - virtual void Init(); - - // Overridden from BrowserFrame: - virtual views::Window* GetWindow(); - virtual int GetMinimizeButtonOffset() const; - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const; - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const; - virtual void UpdateThrobber(bool running); - virtual void ContinueDraggingDetachedTab(); - virtual ThemeProvider* GetThemeProviderForFrame() const; - virtual bool AlwaysUseNativeFrame() const; - virtual views::View* GetFrameView() const; - virtual void TabStripDisplayModeChanged(); - - // Overridden from views::Widget: - virtual ThemeProvider* GetThemeProvider() const; - virtual ThemeProvider* GetDefaultThemeProvider() const; - virtual void IsActiveChanged(); - virtual void SetInitialFocus(); - - protected: - void set_browser_frame_view(BrowserNonClientFrameView* browser_frame_view) { - browser_frame_view_ = browser_frame_view; - } - - // Overridden from views::WidgetGtk: - virtual views::RootView* CreateRootView(); - virtual bool GetAccelerator(int cmd_id, menus::Accelerator* accelerator); - - // Overriden from views::WindowGtk: - virtual gboolean OnWindowStateEvent(GtkWidget* widget, - GdkEventWindowState* event); - virtual gboolean OnConfigureEvent(GtkWidget* widget, - GdkEventConfigure* event); - - protected: - BrowserView* browser_view() const { - return browser_view_; - } - - private: - // The BrowserView is our ClientView. This is a pointer to it. - BrowserView* browser_view_; - - // A pointer to our NonClientFrameView as a BrowserNonClientFrameView. - BrowserNonClientFrameView* browser_frame_view_; - - // An unowning reference to the root view associated with the window. We save - // a copy as a BrowserRootView to avoid evil casting later, when we need to - // call functions that only exist on BrowserRootView (versus RootView). - BrowserRootView* root_view_; - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(BrowserFrameGtk); -}; +#include "chrome/browser/ui/views/frame/browser_frame_gtk.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_GTK_H_ + diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc deleted file mode 100644 index bd5ddca..0000000 --- a/chrome/browser/views/frame/browser_frame_win.cc +++ /dev/null @@ -1,324 +0,0 @@ -// 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_frame_win.h" - -#include <dwmapi.h> -#include <shellapi.h> - -#include <set> - -#include "app/win_util.h" -#include "base/win_util.h" -#include "chrome/browser/accessibility/browser_accessibility_state.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/views/frame/app_panel_browser_frame_view.h" -#include "chrome/browser/views/frame/browser_non_client_frame_view.h" -#include "chrome/browser/views/frame/browser_root_view.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/frame/glass_browser_frame_view.h" -#include "chrome/browser/views/frame/opaque_browser_frame_view.h" -#include "grit/theme_resources.h" -#include "views/screen.h" -#include "views/window/window_delegate.h" - -// static -static const int kClientEdgeThickness = 3; -static const int kTabDragWindowAlpha = 200; -// We need to offset the DWMFrame into the toolbar so that the blackness -// doesn't show up on our rounded corners. -static const int kDWMFrameTopOffset = 3; - -// static (Factory method.) -BrowserFrame* BrowserFrame::Create(BrowserView* browser_view, - Profile* profile) { - BrowserFrameWin* frame = new BrowserFrameWin(browser_view, profile); - frame->Init(); - return frame; -} - -// static -const gfx::Font& BrowserFrame::GetTitleFont() { - static gfx::Font* title_font = new gfx::Font(win_util::GetWindowTitleFont()); - return *title_font; -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserFrame, public: - -BrowserFrameWin::BrowserFrameWin(BrowserView* browser_view, Profile* profile) - : WindowWin(browser_view), - browser_view_(browser_view), - root_view_(NULL), - frame_initialized_(false), - profile_(profile) { - browser_view_->set_frame(this); - GetNonClientView()->SetFrameView(CreateFrameViewForWindow()); - // Don't focus anything on creation, selecting a tab will set the focus. - set_focus_on_creation(false); -} - -void BrowserFrameWin::Init() { - WindowWin::Init(NULL, gfx::Rect()); -} - -BrowserFrameWin::~BrowserFrameWin() { -} - -views::Window* BrowserFrameWin::GetWindow() { - return this; -} - -int BrowserFrameWin::GetMinimizeButtonOffset() const { - TITLEBARINFOEX titlebar_info; - titlebar_info.cbSize = sizeof(TITLEBARINFOEX); - SendMessage(GetNativeView(), WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info); - - CPoint minimize_button_corner(titlebar_info.rgrect[2].left, - titlebar_info.rgrect[2].top); - MapWindowPoints(HWND_DESKTOP, GetNativeView(), &minimize_button_corner, 1); - - return minimize_button_corner.x; -} - -gfx::Rect BrowserFrameWin::GetBoundsForTabStrip(BaseTabStrip* tabstrip) const { - return browser_frame_view_->GetBoundsForTabStrip(tabstrip); -} - -int BrowserFrameWin::GetHorizontalTabStripVerticalOffset(bool restored) const { - return browser_frame_view_->GetHorizontalTabStripVerticalOffset(restored); -} - -void BrowserFrameWin::UpdateThrobber(bool running) { - browser_frame_view_->UpdateThrobber(running); -} - -void BrowserFrameWin::ContinueDraggingDetachedTab() { - // Send the message directly, so that the window is positioned appropriately. - SendMessage(GetNativeWindow(), WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(0, 0)); -} - -ThemeProvider* BrowserFrameWin::GetThemeProviderForFrame() const { - // This is implemented for a different interface than GetThemeProvider is, - // but they mean the same things. - return GetThemeProvider(); -} - -bool BrowserFrameWin::AlwaysUseNativeFrame() const { - // App panel windows draw their own frame. - if (browser_view_->IsBrowserTypePanel()) - return false; - - if (browser_view_->browser()->type() == Browser::TYPE_EXTENSION_APP) - return false; - - // We don't theme popup or app windows, so regardless of whether or not a - // theme is active for normal browser windows, we don't want to use the custom - // frame for popups/apps. - if (!browser_view_->IsBrowserTypeNormal() && win_util::ShouldUseVistaFrame()) - return true; - - // Otherwise, we use the native frame when we're told we should by the theme - // provider (e.g. no custom theme is active). - return GetThemeProvider()->ShouldUseNativeFrame(); -} - -views::View* BrowserFrameWin::GetFrameView() const { - return browser_frame_view_; -} - -void BrowserFrameWin::TabStripDisplayModeChanged() { - if (GetRootView()->GetChildViewCount() > 0) { - // Make sure the child of the root view gets Layout again. - GetRootView()->GetChildViewAt(0)->InvalidateLayout(); - } - GetRootView()->Layout(); - - UpdateDWMFrame(); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserFrame, views::WindowWin overrides: - -gfx::Insets BrowserFrameWin::GetClientAreaInsets() const { - // Use the default client insets for an opaque frame or a glass popup/app - // frame. - if (!GetNonClientView()->UseNativeFrame() || - !browser_view_->IsBrowserTypeNormal()) { - return WindowWin::GetClientAreaInsets(); - } - - int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); - // In fullscreen mode, we have no frame. In restored mode, we draw our own - // client edge over part of the default frame. - if (IsFullscreen()) - border_thickness = 0; - else if (!IsMaximized()) - border_thickness -= kClientEdgeThickness; - return gfx::Insets(0, border_thickness, border_thickness, border_thickness); -} - -bool BrowserFrameWin::GetAccelerator(int cmd_id, - menus::Accelerator* accelerator) { - return browser_view_->GetAccelerator(cmd_id, accelerator); -} - -void BrowserFrameWin::OnEndSession(BOOL ending, UINT logoff) { - BrowserList::WindowsSessionEnding(); -} - -void BrowserFrameWin::OnEnterSizeMove() { - browser_view_->WindowMoveOrResizeStarted(); -} - -void BrowserFrameWin::OnExitSizeMove() { - WidgetWin::OnExitSizeMove(); -} - -void BrowserFrameWin::OnInitMenuPopup(HMENU menu, UINT position, - BOOL is_system_menu) { - browser_view_->PrepareToRunSystemMenu(menu); -} - -LRESULT BrowserFrameWin::OnMouseActivate(HWND window, UINT hittest_code, - UINT message) { - return browser_view_->ActivateAppModalDialog() ? MA_NOACTIVATEANDEAT - : MA_ACTIVATE; -} - -void BrowserFrameWin::OnMove(const CPoint& point) { - browser_view_->WindowMoved(); -} - -void BrowserFrameWin::OnMoving(UINT param, LPRECT new_bounds) { - browser_view_->WindowMoved(); -} - -LRESULT BrowserFrameWin::OnNCActivate(BOOL active) { - if (browser_view_->ActivateAppModalDialog()) - return TRUE; - - browser_view_->ActivationChanged(!!active); - return WindowWin::OnNCActivate(active); -} - -LRESULT BrowserFrameWin::OnNCHitTest(const CPoint& pt) { - // Only do DWM hit-testing when we are using the native frame. - if (GetNonClientView()->UseNativeFrame()) { - LRESULT result; - if (DwmDefWindowProc(GetNativeView(), WM_NCHITTEST, 0, - MAKELPARAM(pt.x, pt.y), &result)) { - return result; - } - } - return WindowWin::OnNCHitTest(pt); -} - -void BrowserFrameWin::OnWindowPosChanged(WINDOWPOS* window_pos) { - WindowWin::OnWindowPosChanged(window_pos); - UpdateDWMFrame(); - - // Windows lies to us about the position of the minimize button before a - // window is visible. We use this position to place the OTR avatar in RTL - // mode, so when the window is shown, we need to re-layout and schedule a - // paint for the non-client frame view so that the icon top has the correct - // position when the window becomes visible. This fixes bugs where the icon - // appears to overlay the minimize button. - // Note that we will call Layout every time SetWindowPos is called with - // SWP_SHOWWINDOW, however callers typically are careful about not specifying - // this flag unless necessary to avoid flicker. - if (window_pos->flags & SWP_SHOWWINDOW) { - GetNonClientView()->Layout(); - GetNonClientView()->SchedulePaint(); - } -} - -ThemeProvider* BrowserFrameWin::GetThemeProvider() const { - return profile_->GetThemeProvider(); -} - -ThemeProvider* BrowserFrameWin::GetDefaultThemeProvider() const { - return profile_->GetThemeProvider(); -} - -void BrowserFrameWin::OnScreenReaderDetected() { - Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected(); - WindowWin::OnScreenReaderDetected(); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserFrame, views::CustomFrameWindow overrides: - -int BrowserFrameWin::GetShowState() const { - return browser_view_->GetShowState(); -} - -void BrowserFrameWin::Activate() { - // When running under remote desktop, if the remote desktop client is not - // active on the users desktop, then none of the windows contained in the - // remote desktop will be activated. However, WindowWin::Activate will still - // bring this browser window to the foreground. We explicitly set ourselves - // as the last active browser window to ensure that we get treated as such by - // the rest of Chrome. - BrowserList::SetLastActive(browser_view_->browser()); - - WindowWin::Activate(); -} - -views::NonClientFrameView* BrowserFrameWin::CreateFrameViewForWindow() { - if (AlwaysUseNativeFrame()) - browser_frame_view_ = new GlassBrowserFrameView(this, browser_view_); - else if (browser_view_->IsBrowserTypePanel()) - browser_frame_view_ = new AppPanelBrowserFrameView(this, browser_view_); - else - browser_frame_view_ = new OpaqueBrowserFrameView(this, browser_view_); - return browser_frame_view_; -} - -void BrowserFrameWin::UpdateFrameAfterFrameChange() { - // We need to update the glass region on or off before the base class adjusts - // the window region. - UpdateDWMFrame(); - WindowWin::UpdateFrameAfterFrameChange(); -} - -views::RootView* BrowserFrameWin::CreateRootView() { - root_view_ = new BrowserRootView(browser_view_, this); - return root_view_; -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserFrame, private: - -void BrowserFrameWin::UpdateDWMFrame() { - // Nothing to do yet, or we're not showing a DWM frame. - if (!GetClientView() || !AlwaysUseNativeFrame()) - return; - - MARGINS margins = { 0 }; - if (browser_view_->IsBrowserTypeNormal()) { - // In fullscreen mode, we don't extend glass into the client area at all, - // because the GDI-drawn text in the web content composited over it will - // become semi-transparent over any glass area. - if (!IsMaximized() && !IsFullscreen()) { - margins.cxLeftWidth = kClientEdgeThickness + 1; - margins.cxRightWidth = kClientEdgeThickness + 1; - margins.cyBottomHeight = kClientEdgeThickness + 1; - margins.cyTopHeight = kClientEdgeThickness + 1; - } - // In maximized mode, we only have a titlebar strip of glass, no side/bottom - // borders. - if (!browser_view_->IsFullscreen()) { - gfx::Rect tabstrip_bounds( - GetBoundsForTabStrip(browser_view_->tabstrip())); - margins.cyTopHeight = (browser_view_->UseVerticalTabs() ? - tabstrip_bounds.y() : tabstrip_bounds.bottom()) + kDWMFrameTopOffset; - } - } else { - // For popup and app windows we want to use the default margins. - } - DwmExtendFrameIntoClientArea(GetNativeView(), &margins); -} diff --git a/chrome/browser/views/frame/browser_frame_win.h b/chrome/browser/views/frame/browser_frame_win.h index 1dbc4dd..b755e21 100644 --- a/chrome/browser/views/frame/browser_frame_win.h +++ b/chrome/browser/views/frame/browser_frame_win.h @@ -6,96 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_WIN_H_ #pragma once -#include "base/basictypes.h" -#include "chrome/browser/views/frame/browser_frame.h" -#include "views/window/window_win.h" - -class AeroGlassNonClientView; -class BrowserNonClientFrameView; -class BrowserRootView; -class BrowserView; -class NonClientFrameView; -class Profile; - -/////////////////////////////////////////////////////////////////////////////// -// BrowserFrameWin -// -// BrowserFrame is a WindowWin subclass that provides the window frame for the -// Chrome browser window. -// -class BrowserFrameWin : public BrowserFrame, public views::WindowWin { - public: - // Normally you will create this class by calling BrowserFrame::Create. - // Init must be called before using this class, which Create will do for you. - BrowserFrameWin(BrowserView* browser_view, Profile* profile); - virtual ~BrowserFrameWin(); - - // This initialization function must be called after construction, it is - // separate to avoid recursive calling of the frame from its constructor. - void Init(); - - BrowserView* browser_view() const { return browser_view_; } - - // BrowserFrame implementation. - virtual views::Window* GetWindow(); - virtual int GetMinimizeButtonOffset() const; - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const; - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const; - virtual void UpdateThrobber(bool running); - virtual void ContinueDraggingDetachedTab(); - virtual ThemeProvider* GetThemeProviderForFrame() const; - virtual bool AlwaysUseNativeFrame() const; - virtual views::View* GetFrameView() const; - virtual void TabStripDisplayModeChanged(); - - protected: - // Overridden from views::WindowWin: - virtual gfx::Insets GetClientAreaInsets() const; - virtual bool GetAccelerator(int cmd_id, menus::Accelerator* accelerator); - virtual void OnEndSession(BOOL ending, UINT logoff); - virtual void OnEnterSizeMove(); - virtual void OnExitSizeMove(); - virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu); - virtual LRESULT OnMouseActivate(HWND window, - UINT hittest_code, - UINT message); - virtual void OnMove(const CPoint& point); - virtual void OnMoving(UINT param, LPRECT new_bounds); - virtual LRESULT OnNCActivate(BOOL active); - virtual LRESULT OnNCHitTest(const CPoint& pt); - virtual void OnWindowPosChanged(WINDOWPOS* window_pos); - virtual ThemeProvider* GetThemeProvider() const; - virtual ThemeProvider* GetDefaultThemeProvider() const; - virtual void OnScreenReaderDetected(); - - // Overridden from views::Window: - virtual int GetShowState() const; - virtual void Activate(); - virtual bool IsAppWindow() const { return true; } - virtual views::NonClientFrameView* CreateFrameViewForWindow(); - virtual void UpdateFrameAfterFrameChange(); - virtual views::RootView* CreateRootView(); - - private: - // Updates the DWM with the frame bounds. - void UpdateDWMFrame(); - - // The BrowserView is our ClientView. This is a pointer to it. - BrowserView* browser_view_; - - // A pointer to our NonClientFrameView as a BrowserNonClientFrameView. - BrowserNonClientFrameView* browser_frame_view_; - - // An unowning reference to the root view associated with the window. We save - // a copy as a BrowserRootView to avoid evil casting later, when we need to - // call functions that only exist on BrowserRootView (versus RootView). - BrowserRootView* root_view_; - - bool frame_initialized_; - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(BrowserFrameWin); -}; +#include "chrome/browser/ui/views/frame/browser_frame_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_WIN_H_ + diff --git a/chrome/browser/views/frame/browser_non_client_frame_view.h b/chrome/browser/views/frame/browser_non_client_frame_view.h index ba8ba40..38b6cfd 100644 --- a/chrome/browser/views/frame/browser_non_client_frame_view.h +++ b/chrome/browser/views/frame/browser_non_client_frame_view.h @@ -6,28 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_NON_CLIENT_FRAME_VIEW_H_ #pragma once -#include "views/window/non_client_view.h" - -class BaseTabStrip; - -// A specialization of the NonClientFrameView object that provides additional -// Browser-specific methods. -class BrowserNonClientFrameView : public views::NonClientFrameView { - public: - BrowserNonClientFrameView() : NonClientFrameView() {} - virtual ~BrowserNonClientFrameView() {} - - // Returns the bounds within which the TabStrip should be laid out. - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const = 0; - - // Returns the y coordinate within the window at which the horizontal TabStrip - // begins, or (in vertical tabs mode) would begin. If |restored| is true, - // this is calculated as if we were in restored mode regardless of the current - // mode. This is used to correctly align theme images. - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const = 0; - - // Updates the throbber. - virtual void UpdateThrobber(bool running) = 0; -}; +#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_NON_CLIENT_FRAME_VIEW_H_ + diff --git a/chrome/browser/views/frame/browser_root_view.cc b/chrome/browser/views/frame/browser_root_view.cc deleted file mode 100644 index e423603..0000000 --- a/chrome/browser/views/frame/browser_root_view.cc +++ /dev/null @@ -1,155 +0,0 @@ -// 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/autocomplete/autocomplete_match.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; -} diff --git a/chrome/browser/views/frame/browser_root_view.h b/chrome/browser/views/frame/browser_root_view.h index 4ae382a..bf129da 100644 --- a/chrome/browser/views/frame/browser_root_view.h +++ b/chrome/browser/views/frame/browser_root_view.h @@ -1,63 +1,13 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. -#ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_ -#define CHROME_BROWSER_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_ +#ifndef CHROME_BROWSER_VIEWS_FRAME_POPUP_BROWSER_ROOT_VIEW_H_ +#define CHROME_BROWSER_VIEWS_FRAME_POPUP_BROWSER_ROOT_VIEW_H_ #pragma once -#include "views/widget/root_view.h" +#include "chrome/browser/ui/views/frame/browser_root_view.h" +// TODO(beng): remove this file once all includes have been updated. -class BrowserView; -class OSExchangeData; -class BaseTabStrip; +#endif // CHROME_BROWSER_VIEWS_FRAME_POPUP_BROWSER_ROOT_VIEW_H_ -// RootView implementation used by BrowserFrame. This forwards drop events to -// the TabStrip. Visually the tabstrip extends to the top of the frame, but in -// actually it doesn't. The tabstrip is only as high as a tab. To enable -// dropping above the tabstrip BrowserRootView forwards drop events to the -// TabStrip. -class BrowserRootView : public views::RootView { - public: - // You must call set_tabstrip before this class will accept drops. - BrowserRootView(BrowserView* browser_view, views::Widget* widget); - - virtual bool GetDropFormats( - int* formats, - std::set<OSExchangeData::CustomFormat>* custom_formats); - virtual bool AreDropTypesRequired(); - virtual bool CanDrop(const OSExchangeData& data); - virtual void OnDragEntered(const views::DropTargetEvent& event); - virtual int OnDragUpdated(const views::DropTargetEvent& event); - virtual void OnDragExited(); - virtual int OnPerformDrop(const views::DropTargetEvent& event); - - private: - // Returns true if the event should be forwarded to the tabstrip. - bool ShouldForwardToTabStrip(const views::DropTargetEvent& event); - - // Converts the event from the hosts coordinate system to the tabstrips - // coordinate system. - views::DropTargetEvent* MapEventToTabStrip( - const views::DropTargetEvent& event, - const OSExchangeData& data); - - inline BaseTabStrip* tabstrip() const; - - // Returns true if |data| has string contents and the user can "paste and go". - // If |url| is non-NULL and the user can "paste and go", |url| is set to the - // desired destination. - bool GetPasteAndGoURL(const OSExchangeData& data, GURL* url); - - // The BrowserView. - BrowserView* browser_view_; - - // If true, drag and drop events are being forwarded to the tab strip. - // This is used to determine when to send OnDragEntered and OnDragExited - // to the tab strip. - bool forwarding_to_tab_strip_; - - DISALLOW_COPY_AND_ASSIGN(BrowserRootView); -}; - -#endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_ diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc deleted file mode 100644 index 949b73b..0000000 --- a/chrome/browser/views/frame/browser_view.cc +++ /dev/null @@ -1,2472 +0,0 @@ -// 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_view.h" - -#if defined(OS_LINUX) -#include <gtk/gtk.h> -#endif - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/command_line.h" -#include "base/i18n/rtl.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/app_modal_dialog_queue.h" -#include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/autocomplete/autocomplete_popup_view.h" -#include "chrome/browser/automation/ui_controls.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/debugger/devtools_window.h" -#include "chrome/browser/dom_ui/bug_report_ui.h" -#include "chrome/browser/download/download_manager.h" -#include "chrome/browser/instant/instant_controller.h" -#include "chrome/browser/ntp_background_util.h" -#include "chrome/browser/page_info_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/sessions/tab_restore_service.h" -#include "chrome/browser/sidebar/sidebar_container.h" -#include "chrome/browser/sidebar/sidebar_manager.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/accessible_view_helper.h" -#include "chrome/browser/views/bookmark_bar_view.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "chrome/browser/views/default_search_view.h" -#include "chrome/browser/views/download_shelf_view.h" -#include "chrome/browser/views/frame/browser_view_layout.h" -#include "chrome/browser/views/frame/contents_container.h" -#include "chrome/browser/views/fullscreen_exit_bubble.h" -#include "chrome/browser/views/status_bubble_views.h" -#include "chrome/browser/views/tab_contents/tab_contents_container.h" -#include "chrome/browser/views/tabs/browser_tab_strip_controller.h" -#include "chrome/browser/views/tabs/side_tab_strip.h" -#include "chrome/browser/views/theme_install_bubble_view.h" -#include "chrome/browser/views/toolbar_view.h" -#include "chrome/browser/views/update_recommended_message_box.h" -#include "chrome/browser/views/window.h" -#include "chrome/browser/window_sizer.h" -#include "chrome/browser/wrench_menu_model.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/extension_resource.h" -#include "chrome/common/native_window_notification_source.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "gfx/canvas_skia.h" -#include "grit/app_resources.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "grit/webkit_resources.h" -#include "views/controls/single_split_view.h" -#include "views/focus/external_focus_tracker.h" -#include "views/focus/view_storage.h" -#include "views/grid_layout.h" -#include "views/widget/root_view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "app/win_util.h" -#include "chrome/browser/aeropeek_manager.h" -#include "chrome/browser/jumplist_win.h" -#elif defined(OS_LINUX) -#include "chrome/browser/views/accelerator_table_gtk.h" -#include "views/window/hit_test.h" -#include "views/window/window_gtk.h" -#endif - -using base::TimeDelta; -using views::ColumnSet; -using views::GridLayout; - -// The height of the status bubble. -static const int kStatusBubbleHeight = 20; -// The name of a key to store on the window handle so that other code can -// locate this object using just the handle. -#if defined(OS_WIN) -static const wchar_t* kBrowserViewKey = L"__BROWSER_VIEW__"; -#else -static const char* kBrowserViewKey = "__BROWSER_VIEW__"; -#endif -// How frequently we check for hung plugin windows. -static const int kDefaultHungPluginDetectFrequency = 2000; -// How long do we wait before we consider a window hung (in ms). -static const int kDefaultPluginMessageResponseTimeout = 30000; -// The number of milliseconds between loading animation frames. -static const int kLoadingAnimationFrameTimeMs = 30; -// The amount of space we expect the window border to take up. -static const int kWindowBorderWidth = 5; - -// If not -1, windows are shown with this state. -static int explicit_show_state = -1; - -// How round the 'new tab' style bookmarks bar is. -static const int kNewtabBarRoundness = 5; -// ------------ - -// Returned from BrowserView::GetClassName. -const char BrowserView::kViewClassName[] = "browser/views/BrowserView"; - -#if defined(OS_CHROMEOS) -// Get a normal browser window of given |profile| to use as dialog parent -// if given |browser| is not one. Otherwise, returns browser window of -// |browser|. If |profile| is NULL, |browser|'s profile is used to find the -// normal browser. -static gfx::NativeWindow GetNormalBrowserWindowForBrowser(Browser* browser, - Profile* profile) { - if (browser->type() != Browser::TYPE_NORMAL) { - Browser* normal_browser = BrowserList::FindBrowserWithType( - profile ? profile : browser->profile(), - Browser::TYPE_NORMAL, true); - if (normal_browser && normal_browser->window()) - return normal_browser->window()->GetNativeHandle(); - } - - return browser->window()->GetNativeHandle(); -} -#endif // defined(OS_CHROMEOS) - -/////////////////////////////////////////////////////////////////////////////// -// BookmarkExtensionBackground, private: -// This object serves as the views::Background object which is used to layout -// and paint the bookmark bar. -class BookmarkExtensionBackground : public views::Background { - public: - explicit BookmarkExtensionBackground(BrowserView* browser_view, - DetachableToolbarView* host_view, - Browser* browser); - - // View methods overridden from views:Background. - virtual void Paint(gfx::Canvas* canvas, views::View* view) const; - - private: - BrowserView* browser_view_; - - // The view hosting this background. - DetachableToolbarView* host_view_; - - Browser* browser_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkExtensionBackground); -}; - -BookmarkExtensionBackground::BookmarkExtensionBackground( - BrowserView* browser_view, - DetachableToolbarView* host_view, - Browser* browser) - : browser_view_(browser_view), - host_view_(host_view), - browser_(browser) { -} - -void BookmarkExtensionBackground::Paint(gfx::Canvas* canvas, - views::View* view) const { - ThemeProvider* tp = host_view_->GetThemeProvider(); - int toolbar_overlap = host_view_->GetToolbarOverlap(); - // The client edge is drawn below the toolbar bounds. - if (toolbar_overlap) - toolbar_overlap += views::NonClientFrameView::kClientEdgeThickness; - if (host_view_->IsDetached()) { - // Draw the background to match the new tab page. - int height = 0; - TabContents* contents = browser_->GetSelectedTabContents(); - if (contents && contents->view()) - height = contents->view()->GetContainerSize().height(); - NtpBackgroundUtil::PaintBackgroundDetachedMode( - host_view_->GetThemeProvider(), canvas, - gfx::Rect(0, toolbar_overlap, host_view_->width(), - host_view_->height() - toolbar_overlap), height); - - // As 'hidden' according to the animation is the full in-tab state, - // we invert the value - when current_state is at '0', we expect the - // bar to be docked. - double current_state = 1 - host_view_->GetAnimationValue(); - double h_padding = - static_cast<double>(BookmarkBarView::kNewtabHorizontalPadding) * - current_state; - double v_padding = - static_cast<double>(BookmarkBarView::kNewtabVerticalPadding) * - current_state; - - SkRect rect; - double roundness = 0; - DetachableToolbarView::CalculateContentArea(current_state, h_padding, - v_padding, &rect, &roundness, host_view_); - DetachableToolbarView::PaintContentAreaBackground(canvas, tp, rect, - roundness); - DetachableToolbarView::PaintContentAreaBorder(canvas, tp, rect, roundness); - if (!toolbar_overlap) - DetachableToolbarView::PaintHorizontalBorder(canvas, host_view_); - } else { - DetachableToolbarView::PaintBackgroundAttachedMode(canvas, host_view_, - browser_view_->OffsetPointForToolbarBackgroundImage( - gfx::Point(host_view_->MirroredX(), host_view_->y()))); - if (host_view_->height() >= toolbar_overlap) - DetachableToolbarView::PaintHorizontalBorder(canvas, host_view_); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// ResizeCorner, private: - -class ResizeCorner : public views::View { - public: - ResizeCorner() { - EnableCanvasFlippingForRTLUI(true); - } - - virtual void Paint(gfx::Canvas* canvas) { - views::Window* window = GetWindow(); - if (!window || (window->IsMaximized() || window->IsFullscreen())) - return; - - SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_TEXTAREA_RESIZER); - bitmap->buildMipMap(false); - canvas->DrawBitmapInt(*bitmap, width() - bitmap->width(), - height() - bitmap->height()); - } - - static gfx::Size GetSize() { - // This is disabled until we find what makes us slower when we let - // WebKit know that we have a resizer rect... - // int scrollbar_thickness = gfx::scrollbar_size(); - // return gfx::Size(scrollbar_thickness, scrollbar_thickness); - return gfx::Size(); - } - - virtual gfx::Size GetPreferredSize() { - views::Window* window = GetWindow(); - return (!window || window->IsMaximized() || window->IsFullscreen()) ? - gfx::Size() : GetSize(); - } - - virtual void Layout() { - views::View* parent_view = GetParent(); - if (parent_view) { - gfx::Size ps = GetPreferredSize(); - // No need to handle Right to left text direction here, - // our parent must take care of it for us... - SetBounds(parent_view->width() - ps.width(), - parent_view->height() - ps.height(), ps.width(), ps.height()); - } - } - - private: - // Returns the WindowWin we're displayed in. Returns NULL if we're not - // currently in a window. - views::Window* GetWindow() { - views::Widget* widget = GetWidget(); - return widget ? widget->GetWindow() : NULL; - } - - DISALLOW_COPY_AND_ASSIGN(ResizeCorner); -}; - -//////////////////////////////////////////////////////////////////////////////// -// DownloadInProgressConfirmDialogDelegate - -class DownloadInProgressConfirmDialogDelegate : public views::DialogDelegate, - public views::View { - public: - explicit DownloadInProgressConfirmDialogDelegate(Browser* browser) - : browser_(browser), - product_name_(l10n_util::GetString(IDS_PRODUCT_NAME)) { - int download_count = browser->profile()->GetDownloadManager()-> - in_progress_count(); - - std::wstring warning_text; - std::wstring explanation_text; - if (download_count == 1) { - warning_text = - l10n_util::GetStringF(IDS_SINGLE_DOWNLOAD_REMOVE_CONFIRM_WARNING, - product_name_); - explanation_text = - l10n_util::GetStringF(IDS_SINGLE_DOWNLOAD_REMOVE_CONFIRM_EXPLANATION, - product_name_); - ok_button_text_ = l10n_util::GetString( - IDS_SINGLE_DOWNLOAD_REMOVE_CONFIRM_OK_BUTTON_LABEL); - cancel_button_text_ = l10n_util::GetString( - IDS_SINGLE_DOWNLOAD_REMOVE_CONFIRM_CANCEL_BUTTON_LABEL); - } else { - warning_text = - l10n_util::GetStringF(IDS_MULTIPLE_DOWNLOADS_REMOVE_CONFIRM_WARNING, - product_name_, - UTF8ToWide(base::IntToString(download_count))); - explanation_text = - l10n_util::GetStringF( - IDS_MULTIPLE_DOWNLOADS_REMOVE_CONFIRM_EXPLANATION, product_name_); - ok_button_text_ = l10n_util::GetString( - IDS_MULTIPLE_DOWNLOADS_REMOVE_CONFIRM_OK_BUTTON_LABEL); - cancel_button_text_ = l10n_util::GetString( - IDS_MULTIPLE_DOWNLOADS_REMOVE_CONFIRM_CANCEL_BUTTON_LABEL); - } - - // There are two lines of text: the bold warning label and the text - // explanation label. - GridLayout* layout = new GridLayout(this); - SetLayoutManager(layout); - const int columnset_id = 0; - ColumnSet* column_set = layout->AddColumnSet(columnset_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1, - GridLayout::USE_PREF, 0, 0); - - gfx::Font bold_font = - ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); - warning_ = new views::Label(warning_text, bold_font); - warning_->SetMultiLine(true); - warning_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - warning_->set_border(views::Border::CreateEmptyBorder(10, 10, 10, 10)); - layout->StartRow(0, columnset_id); - layout->AddView(warning_); - - explanation_ = new views::Label(explanation_text); - explanation_->SetMultiLine(true); - explanation_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - explanation_->set_border(views::Border::CreateEmptyBorder(10, 10, 10, 10)); - layout->StartRow(0, columnset_id); - layout->AddView(explanation_); - - dialog_dimensions_ = views::Window::GetLocalizedContentsSize( - IDS_DOWNLOAD_IN_PROGRESS_WIDTH_CHARS, - IDS_DOWNLOAD_IN_PROGRESS_MINIMUM_HEIGHT_LINES); - const int height = - warning_->GetHeightForWidth(dialog_dimensions_.width()) + - explanation_->GetHeightForWidth(dialog_dimensions_.width()); - dialog_dimensions_.set_height(std::max(height, - dialog_dimensions_.height())); - } - - ~DownloadInProgressConfirmDialogDelegate() { - } - - // View implementation: - virtual gfx::Size GetPreferredSize() { - return dialog_dimensions_; - } - - // DialogDelegate implementation: - virtual int GetDefaultDialogButton() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - return ok_button_text_; - - DCHECK_EQ(MessageBoxFlags::DIALOGBUTTON_CANCEL, button); - return cancel_button_text_; - } - - virtual bool Accept() { - browser_->InProgressDownloadResponse(true); - return true; - } - - virtual bool Cancel() { - browser_->InProgressDownloadResponse(false); - return true; - } - - // WindowDelegate implementation: - virtual bool IsModal() const { return true; } - - virtual views::View* GetContentsView() { - return this; - } - - virtual std::wstring GetWindowTitle() const { - return product_name_; - } - - private: - Browser* browser_; - views::Label* warning_; - views::Label* explanation_; - - std::wstring ok_button_text_; - std::wstring cancel_button_text_; - - std::wstring product_name_; - - gfx::Size dialog_dimensions_; - - DISALLOW_COPY_AND_ASSIGN(DownloadInProgressConfirmDialogDelegate); -}; - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, public: - -// static -void BrowserView::SetShowState(int state) { - explicit_show_state = state; -} - -BrowserView::BrowserView(Browser* browser) - : views::ClientView(NULL, NULL), - last_focused_view_storage_id_( - views::ViewStorage::GetSharedInstance()->CreateStorageID()), - frame_(NULL), - browser_(browser), - active_bookmark_bar_(NULL), - tabstrip_(NULL), - toolbar_(NULL), - infobar_container_(NULL), - sidebar_container_(NULL), - sidebar_split_(NULL), - contents_container_(NULL), - devtools_container_(NULL), - preview_container_(NULL), - contents_(NULL), - contents_split_(NULL), - initialized_(false), - ignore_layout_(true) -#if defined(OS_WIN) - , hung_window_detector_(&hung_plugin_action_), - ticker_(0) -#endif - { - browser_->tabstrip_model()->AddObserver(this); - - registrar_.Add(this, - NotificationType::SIDEBAR_CHANGED, - Source<SidebarManager>(SidebarManager::GetInstance())); -} - -BrowserView::~BrowserView() { - browser_->tabstrip_model()->RemoveObserver(this); - -#if defined(OS_WIN) - // Remove this observer. - if (aeropeek_manager_.get()) - browser_->tabstrip_model()->RemoveObserver(aeropeek_manager_.get()); - - // Stop hung plugin monitoring. - ticker_.Stop(); - ticker_.UnregisterTickHandler(&hung_window_detector_); -#endif - - // We destroy the download shelf before |browser_| to remove its child - // download views from the set of download observers (since the observed - // downloads can be destroyed along with |browser_| and the observer - // notifications will call back into deleted objects). - download_shelf_.reset(); - - // The TabStrip attaches a listener to the model. Make sure we shut down the - // TabStrip first so that it can cleanly remove the listener. - tabstrip_->GetParent()->RemoveChildView(tabstrip_); - delete tabstrip_; - tabstrip_ = NULL; - - // Explicitly set browser_ to NULL. - browser_.reset(); -} - -// static -BrowserView* BrowserView::GetBrowserViewForNativeWindow( - gfx::NativeWindow window) { -#if defined(OS_WIN) - if (IsWindow(window)) { - HANDLE data = GetProp(window, kBrowserViewKey); - if (data) - return reinterpret_cast<BrowserView*>(data); - } -#else - if (window) { - return static_cast<BrowserView*>( - g_object_get_data(G_OBJECT(window), kBrowserViewKey)); - } -#endif - return NULL; -} - -int BrowserView::GetShowState() const { - if (explicit_show_state != -1) - return explicit_show_state; - -#if defined(OS_WIN) - STARTUPINFO si = {0}; - si.cb = sizeof(si); - si.dwFlags = STARTF_USESHOWWINDOW; - GetStartupInfo(&si); - return si.wShowWindow; -#else - NOTIMPLEMENTED(); - return 0; -#endif -} - -void BrowserView::WindowMoved() { - // Cancel any tabstrip animations, some of them may be invalidated by the - // window being repositioned. - // Comment out for one cycle to see if this fixes dist tests. - // tabstrip_->DestroyDragController(); - - status_bubble_->Reposition(); - - BrowserBubbleHost::WindowMoved(); - - browser::HideBookmarkBubbleView(); - - // Close the omnibox popup, if any. - if (toolbar_->location_bar()) - toolbar_->location_bar()->location_entry()->ClosePopup(); -} - -void BrowserView::WindowMoveOrResizeStarted() { - TabContents* tab_contents = GetSelectedTabContents(); - if (tab_contents) - tab_contents->WindowMoveOrResizeStarted(); -} - -gfx::Rect BrowserView::GetToolbarBounds() const { - gfx::Rect toolbar_bounds(toolbar_->bounds()); - if (toolbar_bounds.IsEmpty()) - return toolbar_bounds; - // When using vertical tabs, the toolbar appears to extend behind the tab - // column. - if (UseVerticalTabs()) - toolbar_bounds.Inset(tabstrip_->x() - toolbar_bounds.x(), 0, 0, 0); - // The apparent toolbar edges are outside the "real" toolbar edges. - toolbar_bounds.Inset(-views::NonClientFrameView::kClientEdgeThickness, 0); - return toolbar_bounds; -} - -gfx::Rect BrowserView::GetClientAreaBounds() const { - gfx::Rect container_bounds = contents_->bounds(); - gfx::Point container_origin = container_bounds.origin(); - ConvertPointToView(this, GetParent(), &container_origin); - container_bounds.set_origin(container_origin); - return container_bounds; -} - -gfx::Rect BrowserView::GetFindBarBoundingBox() const { - return GetBrowserViewLayout()->GetFindBarBoundingBox(); -} - -int BrowserView::GetTabStripHeight() const { - // We want to return tabstrip_->height(), but we might be called in the midst - // of layout, when that hasn't yet been updated to reflect the current state. - // So return what the tabstrip height _ought_ to be right now. - return IsTabStripVisible() ? tabstrip_->GetPreferredSize().height() : 0; -} - -gfx::Point BrowserView::OffsetPointForToolbarBackgroundImage( - const gfx::Point& point) const { - // The background image starts tiling horizontally at the window left edge and - // vertically at the top edge of the horizontal tab strip (or where it would - // be). We expect our parent's origin to be the window origin. - gfx::Point window_point(point.Add(gfx::Point(MirroredX(), y()))); - window_point.Offset(0, -frame_->GetHorizontalTabStripVerticalOffset(false)); - return window_point; -} - -int BrowserView::GetSidebarWidth() const { - if (!sidebar_container_ || !sidebar_container_->IsVisible()) - return 0; - return sidebar_split_->divider_offset(); -} - -bool BrowserView::IsTabStripVisible() const { - return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); -} - -bool BrowserView::UseVerticalTabs() const { - return browser_->tabstrip_model()->delegate()->UseVerticalTabs(); -} - -bool BrowserView::IsOffTheRecord() const { - return browser_->profile()->IsOffTheRecord(); -} - -bool BrowserView::ShouldShowOffTheRecordAvatar() const { - return IsOffTheRecord() && IsBrowserTypeNormal(); -} - -bool BrowserView::AcceleratorPressed(const views::Accelerator& accelerator) { - std::map<views::Accelerator, int>::const_iterator iter = - accelerator_table_.find(accelerator); - DCHECK(iter != accelerator_table_.end()); - - int command_id = iter->second; - if (browser_->command_updater()->SupportsCommand(command_id) && - browser_->command_updater()->IsCommandEnabled(command_id)) { - browser_->ExecuteCommand(command_id); - return true; - } - return false; -} - -bool BrowserView::GetAccelerator(int cmd_id, menus::Accelerator* accelerator) { - // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators - // anywhere so we need to check for them explicitly here. - switch (cmd_id) { - case IDC_CUT: - *accelerator = views::Accelerator(app::VKEY_X, false, true, false); - return true; - case IDC_COPY: - *accelerator = views::Accelerator(app::VKEY_C, false, true, false); - return true; - case IDC_PASTE: - *accelerator = views::Accelerator(app::VKEY_V, false, true, false); - return true; - } - // Else, we retrieve the accelerator information from the accelerator table. - std::map<views::Accelerator, int>::iterator it = - accelerator_table_.begin(); - for (; it != accelerator_table_.end(); ++it) { - if (it->second == cmd_id) { - *accelerator = it->first; - return true; - } - } - return false; -} - -bool BrowserView::ActivateAppModalDialog() const { - // If another browser is app modal, flash and activate the modal browser. - if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) { - Browser* active_browser = BrowserList::GetLastActive(); - if (active_browser && (browser_ != active_browser)) { - active_browser->window()->FlashFrame(); - active_browser->window()->Activate(); - } - Singleton<AppModalDialogQueue>()->ActivateModalDialog(); - return true; - } - return false; -} - -void BrowserView::ActivationChanged(bool activated) { - if (activated) - BrowserList::SetLastActive(browser_.get()); -} - -TabContents* BrowserView::GetSelectedTabContents() const { - return browser_->GetSelectedTabContents(); -} - -SkBitmap BrowserView::GetOTRAvatarIcon() { - static SkBitmap* otr_avatar_ = new SkBitmap(); - - if (otr_avatar_->isNull()) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - *otr_avatar_ = *rb.GetBitmapNamed(IDR_OTR_ICON); - } - return *otr_avatar_; -} - -#if defined(OS_WIN) -void BrowserView::PrepareToRunSystemMenu(HMENU menu) { - system_menu_->UpdateStates(); -} -#endif - -// static -void BrowserView::RegisterBrowserViewPrefs(PrefService* prefs) { - prefs->RegisterIntegerPref(prefs::kPluginMessageResponseTimeout, - kDefaultPluginMessageResponseTimeout); - prefs->RegisterIntegerPref(prefs::kHungPluginDetectFrequency, - kDefaultHungPluginDetectFrequency); -} - -bool BrowserView::IsPositionInWindowCaption(const gfx::Point& point) { - return GetBrowserViewLayout()->IsPositionInWindowCaption(point); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, BrowserWindow implementation: - -void BrowserView::Show() { - // If the window is already visible, just activate it. - if (frame_->GetWindow()->IsVisible()) { - frame_->GetWindow()->Activate(); - return; - } - - // Setting the focus doesn't work when the window is invisible, so any focus - // initialization that happened before this will be lost. - // - // We really "should" restore the focus whenever the window becomes unhidden, - // but I think initializing is the only time where this can happen where - // there is some focus change we need to pick up, and this is easier than - // plumbing through an un-hide message all the way from the frame. - // - // If we do find there are cases where we need to restore the focus on show, - // that should be added and this should be removed. - RestoreFocus(); - - frame_->GetWindow()->Show(); -} - -void BrowserView::SetBounds(const gfx::Rect& bounds) { - GetWidget()->SetBounds(bounds); -} - -void BrowserView::Close() { - BrowserBubbleHost::Close(); - - frame_->GetWindow()->Close(); -} - -void BrowserView::Activate() { - frame_->GetWindow()->Activate(); -} - -void BrowserView::Deactivate() { - frame_->GetWindow()->Deactivate(); -} - -bool BrowserView::IsActive() const { - return frame_->GetWindow()->IsActive(); -} - -void BrowserView::FlashFrame() { -#if defined(OS_WIN) - FLASHWINFO fwi; - fwi.cbSize = sizeof(fwi); - fwi.hwnd = frame_->GetWindow()->GetNativeWindow(); - fwi.dwFlags = FLASHW_ALL; - fwi.uCount = 4; - fwi.dwTimeout = 0; - FlashWindowEx(&fwi); -#else - // Doesn't matter for chrome os. -#endif -} - -gfx::NativeWindow BrowserView::GetNativeHandle() { - return GetWidget()->GetWindow()->GetNativeWindow(); -} - -BrowserWindowTesting* BrowserView::GetBrowserWindowTesting() { - return this; -} - -StatusBubble* BrowserView::GetStatusBubble() { - return status_bubble_.get(); -} - -void BrowserView::SelectedTabToolbarSizeChanged(bool is_animating) { - if (is_animating) { - contents_container_->SetFastResize(true); - UpdateUIForContents(browser_->GetSelectedTabContents()); - contents_container_->SetFastResize(false); - } else { - UpdateUIForContents(browser_->GetSelectedTabContents()); - // When transitioning from animating to not animating we need to make sure - // the contents_container_ gets layed out. If we don't do this and the - // bounds haven't changed contents_container_ won't get a Layout out and - // we'll end up with a gray rect because the clip wasn't updated. - contents_container_->InvalidateLayout(); - contents_split_->Layout(); - } -} - -void BrowserView::UpdateTitleBar() { - frame_->GetWindow()->UpdateWindowTitle(); - if (ShouldShowWindowIcon() && !loading_animation_timer_.IsRunning()) - frame_->GetWindow()->UpdateWindowIcon(); -} - -void BrowserView::ShelfVisibilityChanged() { - Layout(); -} - -void BrowserView::UpdateDevTools() { - UpdateDevToolsForContents(GetSelectedTabContents()); - Layout(); -} - -void BrowserView::UpdateLoadingAnimations(bool should_animate) { - if (should_animate) { - if (!loading_animation_timer_.IsRunning()) { - // Loads are happening, and the timer isn't running, so start it. - loading_animation_timer_.Start( - TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this, - &BrowserView::LoadingAnimationCallback); - } - } else { - if (loading_animation_timer_.IsRunning()) { - loading_animation_timer_.Stop(); - // Loads are now complete, update the state if a task was scheduled. - LoadingAnimationCallback(); - } - } -} - -void BrowserView::SetStarredState(bool is_starred) { - toolbar_->location_bar()->SetStarToggled(is_starred); -} - -gfx::Rect BrowserView::GetRestoredBounds() const { - return frame_->GetWindow()->GetNormalBounds(); -} - -bool BrowserView::IsMaximized() const { - return frame_->GetWindow()->IsMaximized(); -} - -void BrowserView::SetFullscreen(bool fullscreen) { - if (IsFullscreen() == fullscreen) - return; // Nothing to do. - -#if defined(OS_WIN) - ProcessFullscreen(fullscreen); -#else - // On Linux changing fullscreen is async. Ask the window to change it's - // fullscreen state, and when done invoke ProcessFullscreen. - frame_->GetWindow()->SetFullscreen(fullscreen); -#endif -} - -bool BrowserView::IsFullscreen() const { - return frame_->GetWindow()->IsFullscreen(); -} - -bool BrowserView::IsFullscreenBubbleVisible() const { - return fullscreen_bubble_.get() ? true : false; -} - -void BrowserView::FullScreenStateChanged() { - ProcessFullscreen(IsFullscreen()); -} - -void BrowserView::RestoreFocus() { - TabContents* selected_tab_contents = GetSelectedTabContents(); - if (selected_tab_contents) - selected_tab_contents->view()->RestoreFocus(); -} - -LocationBar* BrowserView::GetLocationBar() const { - return toolbar_->location_bar(); -} - -void BrowserView::SetFocusToLocationBar(bool select_all) { - LocationBarView* location_bar = toolbar_->location_bar(); - if (location_bar->IsFocusableInRootView()) { - // Location bar got focus. - location_bar->FocusLocation(select_all); - } else { - // If none of location bar/compact navigation bar got focus, - // then clear focus. - views::FocusManager* focus_manager = GetFocusManager(); - DCHECK(focus_manager); - focus_manager->ClearFocus(); - } -} - -void BrowserView::UpdateReloadStopState(bool is_loading, bool force) { - toolbar_->reload_button()->ChangeMode( - is_loading ? ReloadButton::MODE_STOP : ReloadButton::MODE_RELOAD, force); -} - -void BrowserView::UpdateToolbar(TabContents* contents, - bool should_restore_state) { - toolbar_->Update(contents, should_restore_state); -} - -void BrowserView::FocusToolbar() { - // Start the traversal within the main toolbar, passing it the storage id - // of the view where focus should be returned if the user exits the toolbar. - SaveFocusedView(); - toolbar_->SetPaneFocus(last_focused_view_storage_id_, NULL); -} - -void BrowserView::FocusBookmarksToolbar() { - if (active_bookmark_bar_ && bookmark_bar_view_->IsVisible()) { - SaveFocusedView(); - bookmark_bar_view_->SetPaneFocus(last_focused_view_storage_id_, NULL); - } -} - -void BrowserView::FocusAppMenu() { - // Chrome doesn't have a traditional menu bar, but it has a menu button in the - // main toolbar that plays the same role. If the user presses a key that - // would typically focus the menu bar, tell the toolbar to focus the menu - // button. If the user presses the key again, return focus to the previous - // location. - // - // Not used on the Mac, which has a normal menu bar. - if (toolbar_->IsAppMenuFocused()) { - RestoreFocus(); - } else { - SaveFocusedView(); - toolbar_->SetPaneFocusAndFocusAppMenu(last_focused_view_storage_id_); - } -} - -void BrowserView::RotatePaneFocus(bool forwards) { - // This gets called when the user presses F6 (forwards) or Shift+F6 - // (backwards) to rotate to the next pane. Here, our "panes" are the - // tab contents and each of our accessible toolbars, infobars, downloads - // shelf, etc. When a pane has focus, all of its controls are accessible - // in the tab traversal, and the tab traversal is "trapped" within that pane. - // - // Get a vector of all panes in the order we want them to be focused, - // with NULL to represent the tab contents getting focus. If one of these - // is currently invisible or has no focusable children it will be - // automatically skipped. - std::vector<AccessiblePaneView*> accessible_panes; - GetAccessiblePanes(&accessible_panes); - int pane_count = static_cast<int>(accessible_panes.size()); - - std::vector<views::View*> accessible_views( - accessible_panes.begin(), accessible_panes.end()); - accessible_views.push_back(GetTabContentsContainerView()); - if (sidebar_container_ && sidebar_container_->IsVisible()) - accessible_views.push_back(GetSidebarContainerView()); - if (devtools_container_->IsVisible()) - accessible_views.push_back(devtools_container_->GetFocusView()); - int count = static_cast<int>(accessible_views.size()); - - // Figure out which view (if any) currently has the focus. - views::View* focused_view = GetRootView()->GetFocusedView(); - int index = -1; - if (focused_view) { - for (int i = 0; i < count; ++i) { - if (accessible_views[i] == focused_view || - accessible_views[i]->IsParentOf(focused_view)) { - index = i; - break; - } - } - } - - // If the focus isn't currently in a pane, save the focus so we - // can restore it if the user presses Escape. - if (focused_view && index >= pane_count) - SaveFocusedView(); - - // Try to focus the next pane; if SetPaneFocusAndFocusDefault returns - // false it means the pane didn't have any focusable controls, so skip - // it and try the next one. - for (;;) { - if (forwards) - index = (index + 1) % count; - else - index = ((index - 1) + count) % count; - - if (index < pane_count) { - if (accessible_panes[index]->SetPaneFocusAndFocusDefault( - last_focused_view_storage_id_)) { - break; - } - } else { - accessible_views[index]->RequestFocus(); - break; - } - } -} - -void BrowserView::SaveFocusedView() { - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - if (view_storage->RetrieveView(last_focused_view_storage_id_)) - view_storage->RemoveView(last_focused_view_storage_id_); - views::View* focused_view = GetRootView()->GetFocusedView(); - if (focused_view) - view_storage->StoreView(last_focused_view_storage_id_, focused_view); -} - -void BrowserView::DestroyBrowser() { - // Explicitly delete the BookmarkBarView now. That way we don't have to - // worry about the BookmarkBarView potentially outliving the Browser & - // Profile. - bookmark_bar_view_.reset(); - browser_.reset(); -} - -bool BrowserView::IsBookmarkBarVisible() const { - return browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR) && - active_bookmark_bar_ && - (active_bookmark_bar_->GetPreferredSize().height() != 0); -} - -bool BrowserView::IsBookmarkBarAnimating() const { - return bookmark_bar_view_.get() && bookmark_bar_view_->is_animating(); -} - -bool BrowserView::IsToolbarVisible() const { - return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || - browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); -} - -gfx::Rect BrowserView::GetRootWindowResizerRect() const { - if (frame_->GetWindow()->IsMaximized() || frame_->GetWindow()->IsFullscreen()) - return gfx::Rect(); - - // We don't specify a resize corner size if we have a bottom shelf either. - // This is because we take care of drawing the resize corner on top of that - // shelf, so we don't want others to do it for us in this case. - // Currently, the only visible bottom shelf is the download shelf. - // Other tests should be added here if we add more bottom shelves. - if (download_shelf_.get() && download_shelf_->IsShowing()) { - return gfx::Rect(); - } - - gfx::Rect client_rect = contents_split_->bounds(); - gfx::Size resize_corner_size = ResizeCorner::GetSize(); - int x = client_rect.width() - resize_corner_size.width(); - if (base::i18n::IsRTL()) - x = 0; - return gfx::Rect(x, client_rect.height() - resize_corner_size.height(), - resize_corner_size.width(), resize_corner_size.height()); -} - -void BrowserView::DisableInactiveFrame() { -#if defined(OS_WIN) - frame_->GetWindow()->DisableInactiveRendering(); -#endif // No tricks are needed to get the right behavior on Linux. -} - -void BrowserView::ConfirmSetDefaultSearchProvider( - TabContents* tab_contents, - TemplateURL* template_url, - TemplateURLModel* template_url_model) { -#if defined(OS_WIN) - DefaultSearchView::Show(tab_contents, template_url, template_url_model); -#else - // TODO(levin): Implement for other platforms. Right now this is behind - // a command line flag which is off. -#endif -} - -void BrowserView::ConfirmAddSearchProvider(const TemplateURL* template_url, - Profile* profile) { - browser::EditSearchEngine(GetWindow()->GetNativeWindow(), template_url, NULL, - profile); -} - -void BrowserView::ToggleBookmarkBar() { - bookmark_utils::ToggleWhenVisible(browser_->profile()); -} - -views::Window* BrowserView::ShowAboutChromeDialog() { - return browser::ShowAboutChromeView(GetWindow()->GetNativeWindow(), - browser_->profile()); -} - -void BrowserView::ShowUpdateChromeDialog() { - UpdateRecommendedMessageBox::ShowMessageBox(GetWindow()->GetNativeWindow()); -} - -void BrowserView::ShowTaskManager() { - browser::ShowTaskManager(); -} - -void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) { - toolbar_->location_bar()->ShowStarBubble(url, !already_bookmarked); -} - -void BrowserView::SetDownloadShelfVisible(bool visible) { - // This can be called from the superclass destructor, when it destroys our - // child views. At that point, browser_ is already gone. - if (browser_ == NULL) - return; - - if (visible && IsDownloadShelfVisible() != visible) { - // Invoke GetDownloadShelf to force the shelf to be created. - GetDownloadShelf(); - } - - if (browser_ != NULL) - browser_->UpdateDownloadShelfVisibility(visible); - - // SetDownloadShelfVisible can force-close the shelf, so make sure we lay out - // everything correctly, as if the animation had finished. This doesn't - // matter for showing the shelf, as the show animation will do it. - SelectedTabToolbarSizeChanged(false); -} - -bool BrowserView::IsDownloadShelfVisible() const { - return download_shelf_.get() && download_shelf_->IsShowing(); -} - -DownloadShelf* BrowserView::GetDownloadShelf() { - if (!download_shelf_.get()) { - download_shelf_.reset(new DownloadShelfView(browser_.get(), this)); - download_shelf_->set_parent_owned(false); - } - return download_shelf_.get(); -} - -void BrowserView::ShowReportBugDialog() { - browser::ShowHtmlBugReportView(GetWindow(), browser_.get()); -} - -void BrowserView::ShowClearBrowsingDataDialog() { - browser::ShowClearBrowsingDataView(GetWindow()->GetNativeWindow(), - browser_->profile()); -} - -void BrowserView::ShowImportDialog() { - browser::ShowImporterView(GetWidget(), browser_->profile()); -} - -void BrowserView::ShowSearchEnginesDialog() { - browser::ShowKeywordEditorView(browser_->profile()); -} - -void BrowserView::ShowPasswordManager() { - browser::ShowPasswordsExceptionsWindowView(browser_->profile()); -} - -void BrowserView::ShowRepostFormWarningDialog(TabContents* tab_contents) { - browser::ShowRepostFormWarningDialog(GetNativeHandle(), tab_contents); -} - -void BrowserView::ShowContentSettingsWindow(ContentSettingsType content_type, - Profile* profile) { - browser::ShowContentSettingsWindow(GetNativeHandle(), content_type, profile); -} - -void BrowserView::ShowCollectedCookiesDialog(TabContents* tab_contents) { - browser::ShowCollectedCookiesDialog(GetNativeHandle(), tab_contents); -} - -void BrowserView::ShowProfileErrorDialog(int message_id) { -#if defined(OS_WIN) - std::wstring title = l10n_util::GetString(IDS_PRODUCT_NAME); - std::wstring message = l10n_util::GetString(message_id); - win_util::MessageBox(GetNativeHandle(), message, title, - MB_OK | MB_ICONWARNING | MB_TOPMOST); -#elif defined(OS_LINUX) - std::string title = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME); - std::string message = l10n_util::GetStringUTF8(message_id); - GtkWidget* dialog = gtk_message_dialog_new(GetNativeHandle(), - static_cast<GtkDialogFlags>(0), GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, - "%s", message.c_str()); - gtk_window_set_title(GTK_WINDOW(dialog), title.c_str()); - g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); - gtk_widget_show_all(dialog); -#else - NOTIMPLEMENTED(); -#endif -} - -void BrowserView::ShowThemeInstallBubble() { - TabContents* tab_contents = browser_->GetSelectedTabContents(); - if (!tab_contents) - return; - ThemeInstallBubbleView::Show(tab_contents); -} - -void BrowserView::ConfirmBrowserCloseWithPendingDownloads() { - DownloadInProgressConfirmDialogDelegate* delegate = - new DownloadInProgressConfirmDialogDelegate(browser_.get()); - browser::CreateViewsWindow(GetNativeHandle(), gfx::Rect(), - delegate)->Show(); -} - -void BrowserView::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, - gfx::NativeWindow parent_window) { - // Default to using our window as the parent if the argument is not specified. - gfx::NativeWindow parent = parent_window ? parent_window - : GetNativeHandle(); -#if defined(OS_CHROMEOS) - parent = GetNormalBrowserWindowForBrowser(browser(), NULL); -#endif // defined(OS_CHROMEOS) - - browser::ShowHtmlDialogView(parent, browser_.get()->profile(), delegate); -} - -void BrowserView::ShowCreateShortcutsDialog(TabContents* tab_contents) { - browser::ShowCreateShortcutsDialog(GetNativeHandle(), tab_contents); -} - -void BrowserView::ContinueDraggingDetachedTab(const gfx::Rect& tab_bounds) { - tabstrip_->SetDraggedTabBounds(0, tab_bounds); - frame_->ContinueDraggingDetachedTab(); -} - -void BrowserView::UserChangedTheme() { - frame_->GetWindow()->FrameTypeChanged(); -} - -int BrowserView::GetExtraRenderViewHeight() const { - // Currently this is only used on linux. - return 0; -} - -void BrowserView::TabContentsFocused(TabContents* tab_contents) { - contents_container_->TabContentsFocused(tab_contents); -} - -void BrowserView::ShowPageInfo(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - bool show_history) { - gfx::NativeWindow parent = GetWindow()->GetNativeWindow(); - -#if defined(OS_CHROMEOS) - parent = GetNormalBrowserWindowForBrowser(browser(), profile); -#endif // defined(OS_CHROMEOS) - - browser::ShowPageInfoBubble(parent, profile, url, ssl, show_history); -} - -void BrowserView::ShowAppMenu() { - toolbar_->app_menu()->Activate(); -} - -bool BrowserView::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, - bool* is_keyboard_shortcut) { - if (event.type != WebKit::WebInputEvent::RawKeyDown) - return false; - -#if defined(OS_WIN) - // As Alt+F4 is the close-app keyboard shortcut, it needs processing - // immediately. - if (event.windowsKeyCode == app::VKEY_F4 && - event.modifiers == NativeWebKeyboardEvent::AltKey) { - DefWindowProc(event.os_event.hwnd, event.os_event.message, - event.os_event.wParam, event.os_event.lParam); - return true; - } -#endif - - views::FocusManager* focus_manager = GetFocusManager(); - DCHECK(focus_manager); - -#if defined(OS_LINUX) - // Views and WebKit use different tables for GdkEventKey -> views::KeyEvent - // conversion. We need to use View's conversion table here to keep consistent - // behavior with views::FocusManager::OnKeyEvent() method. - // TODO(suzhe): We need to check if Windows code also has this issue, and - // it'll be best if we can unify these conversion tables. - // See http://crbug.com/54315 - views::KeyEvent views_event(event.os_event); - views::Accelerator accelerator(views_event.GetKeyCode(), - views_event.IsShiftDown(), - views_event.IsControlDown(), - views_event.IsAltDown()); -#else - views::Accelerator accelerator( - static_cast<app::KeyboardCode>(event.windowsKeyCode), - (event.modifiers & NativeWebKeyboardEvent::ShiftKey) == - NativeWebKeyboardEvent::ShiftKey, - (event.modifiers & NativeWebKeyboardEvent::ControlKey) == - NativeWebKeyboardEvent::ControlKey, - (event.modifiers & NativeWebKeyboardEvent::AltKey) == - NativeWebKeyboardEvent::AltKey); -#endif - - // We first find out the browser command associated to the |event|. - // Then if the command is a reserved one, and should be processed - // immediately according to the |event|, the command will be executed - // immediately. Otherwise we just set |*is_keyboard_shortcut| properly and - // return false. - - // This piece of code is based on the fact that accelerators registered - // into the |focus_manager| may only trigger a browser command execution. - // - // Here we need to retrieve the command id (if any) associated to the - // keyboard event. Instead of looking up the command id in the - // |accelerator_table_| by ourselves, we block the command execution of - // the |browser_| object then send the keyboard event to the - // |focus_manager| as if we are activating an accelerator key. - // Then we can retrieve the command id from the |browser_| object. - browser_->SetBlockCommandExecution(true); - focus_manager->ProcessAccelerator(accelerator); - int id = browser_->GetLastBlockedCommand(NULL); - browser_->SetBlockCommandExecution(false); - - if (id == -1) - return false; - - if (browser_->IsReservedCommand(id)) { - // TODO(suzhe): For Linux, should we send things like Ctrl+w, Ctrl+n - // to the renderer first, just like what - // BrowserWindowGtk::HandleKeyboardEvent() does? - // Executing the command may cause |this| object to be destroyed. - browser_->ExecuteCommand(id); - return true; - } - - DCHECK(is_keyboard_shortcut != NULL); - *is_keyboard_shortcut = true; - - return false; -} - -void BrowserView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { -#if defined(OS_LINUX) - views::Window* window = GetWidget()->GetWindow(); - if (window && event.os_event && !event.skip_in_browser) - static_cast<views::WindowGtk*>(window)->HandleKeyboardEvent(event.os_event); -#else - unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, - GetFocusManager()); -#endif -} - -// TODO(devint): http://b/issue?id=1117225 Cut, Copy, and Paste are always -// enabled in the page menu regardless of whether the command will do -// anything. When someone selects the menu item, we just act as if they hit -// the keyboard shortcut for the command by sending the associated key press -// to windows. The real fix to this bug is to disable the commands when they -// won't do anything. We'll need something like an overall clipboard command -// manager to do that. -#if !defined(OS_MACOSX) -void BrowserView::Cut() { - ui_controls::SendKeyPress(GetNativeHandle(), app::VKEY_X, - true, false, false, false); -} - -void BrowserView::Copy() { - ui_controls::SendKeyPress(GetNativeHandle(), app::VKEY_C, - true, false, false, false); -} - -void BrowserView::Paste() { - ui_controls::SendKeyPress(GetNativeHandle(), app::VKEY_V, - true, false, false, false); -} -#else -// Mac versions. Not tested by antyhing yet; -// don't assume written == works. -void BrowserView::Cut() { - ui_controls::SendKeyPress(GetNativeHandle(), app::VKEY_X, - false, false, false, true); -} - -void BrowserView::Copy() { - ui_controls::SendKeyPress(GetNativeHandle(), app::VKEY_C, - false, false, false, true); -} - -void BrowserView::Paste() { - ui_controls::SendKeyPress(GetNativeHandle(), app::VKEY_V, - false, false, false, true); -} -#endif - -void BrowserView::ToggleTabStripMode() { - InitTabStrip(browser_->tabstrip_model()); - frame_->TabStripDisplayModeChanged(); -} - -void BrowserView::ShowInstant(TabContents* preview_contents) { - if (!preview_container_) - preview_container_ = new TabContentsContainer(); - contents_->SetPreview(preview_container_, preview_contents); - preview_container_->ChangeTabContents(preview_contents); -} - -void BrowserView::HideInstant() { - if (!preview_container_) - return; - - // The contents must be changed before SetPreview is invoked. - preview_container_->ChangeTabContents(NULL); - contents_->SetPreview(NULL, NULL); - delete preview_container_; - preview_container_ = NULL; -} - -gfx::Rect BrowserView::GetInstantBounds() { - return contents_->GetPreviewBounds(); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, BrowserWindowTesting implementation: - -BookmarkBarView* BrowserView::GetBookmarkBarView() const { - return bookmark_bar_view_.get(); -} - -LocationBarView* BrowserView::GetLocationBarView() const { - return toolbar_->location_bar(); -} - -views::View* BrowserView::GetTabContentsContainerView() const { - return contents_container_->GetFocusView(); -} - -views::View* BrowserView::GetSidebarContainerView() const { - if (!sidebar_container_) - return NULL; - return sidebar_container_->GetFocusView(); -} - -ToolbarView* BrowserView::GetToolbarView() const { - return toolbar_; -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, NotificationObserver implementation: - -void BrowserView::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - switch (type.value) { - case NotificationType::PREF_CHANGED: - if (*Details<std::string>(details).ptr() == prefs::kShowBookmarkBar && - MaybeShowBookmarkBar(browser_->GetSelectedTabContents())) { - Layout(); - } - break; - - case NotificationType::SIDEBAR_CHANGED: - if (Details<SidebarContainer>(details)->tab_contents() == - browser_->GetSelectedTabContents()) { - UpdateSidebar(); - } - break; - - default: - NOTREACHED() << "Got a notification we didn't register for!"; - break; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, TabStripModelObserver implementation: - -void BrowserView::TabDetachedAt(TabContents* contents, int index) { - // We use index here rather than comparing |contents| because by this time - // the model has already removed |contents| from its list, so - // browser_->GetSelectedTabContents() will return NULL or something else. - if (index == browser_->tabstrip_model()->selected_index()) { - // We need to reset the current tab contents to NULL before it gets - // freed. This is because the focus manager performs some operations - // on the selected TabContents when it is removed. - contents_container_->ChangeTabContents(NULL); - infobar_container_->ChangeTabContents(NULL); - UpdateSidebarForContents(NULL); - UpdateDevToolsForContents(NULL); - } -} - -void BrowserView::TabDeselectedAt(TabContents* contents, int index) { - // We do not store the focus when closing the tab to work-around bug 4633. - // Some reports seem to show that the focus manager and/or focused view can - // be garbage at that point, it is not clear why. - if (!contents->is_being_destroyed()) - contents->view()->StoreFocus(); -} - -void BrowserView::TabSelectedAt(TabContents* old_contents, - TabContents* new_contents, - int index, - bool user_gesture) { - DCHECK(old_contents != new_contents); - - ProcessTabSelected(new_contents, true); -} - -void BrowserView::TabReplacedAt(TabContents* old_contents, - TabContents* new_contents, - int index) { - if (index != browser_->tabstrip_model()->selected_index()) - return; - - // Swap the 'active' and 'preview' and delete what was the active. - contents_->MakePreviewContentsActiveContents(); - TabContentsContainer* old_container = contents_container_; - contents_container_ = preview_container_; - old_container->ChangeTabContents(NULL); - delete old_container; - preview_container_ = NULL; - - // Update the UI for what was the preview contents and is now active. Pass in - // false to ProcessTabSelected as new_contents is already parented correctly. - ProcessTabSelected(new_contents, false); -} - -void BrowserView::TabStripEmpty() { - // Make sure all optional UI is removed before we are destroyed, otherwise - // there will be consequences (since our view hierarchy will still have - // references to freed views). - UpdateUIForContents(NULL); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, menus::SimpleMenuModel::Delegate implementation: - -bool BrowserView::IsCommandIdChecked(int command_id) const { - // TODO(beng): encoding menu. - // No items in our system menu are check-able. - return false; -} - -bool BrowserView::IsCommandIdEnabled(int command_id) const { - return browser_->command_updater()->IsCommandEnabled(command_id); -} - -bool BrowserView::GetAcceleratorForCommandId(int command_id, - menus::Accelerator* accelerator) { - // Let's let the ToolbarView own the canonical implementation of this method. - return toolbar_->GetAcceleratorForCommandId(command_id, accelerator); -} - -bool BrowserView::IsLabelForCommandIdDynamic(int command_id) const { - return command_id == IDC_RESTORE_TAB; -} - -string16 BrowserView::GetLabelForCommandId(int command_id) const { - DCHECK(command_id == IDC_RESTORE_TAB); - - int string_id = IDS_RESTORE_TAB; - if (IsCommandIdEnabled(command_id)) { - TabRestoreService* trs = browser_->profile()->GetTabRestoreService(); - if (trs && trs->entries().front()->type == TabRestoreService::WINDOW) - string_id = IDS_RESTORE_WINDOW; - } - return l10n_util::GetStringUTF16(string_id); -} - -void BrowserView::ExecuteCommand(int command_id) { - browser_->ExecuteCommand(command_id); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, views::WindowDelegate implementation: - -bool BrowserView::CanResize() const { - return true; -} - -bool BrowserView::CanMaximize() const { - return true; -} - -bool BrowserView::IsModal() const { - return false; -} - -std::wstring BrowserView::GetWindowTitle() const { - return UTF16ToWideHack(browser_->GetWindowTitleForCurrentTab()); -} - -std::wstring BrowserView::GetAccessibleWindowTitle() const { - if (IsOffTheRecord()) { - return l10n_util::GetStringF( - IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT, GetWindowTitle()); - } - return GetWindowTitle(); -} - -views::View* BrowserView::GetInitiallyFocusedView() { - // We set the frame not focus on creation so this should never be called. - NOTREACHED(); - return NULL; -} - -bool BrowserView::ShouldShowWindowTitle() const { - return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); -} - -SkBitmap BrowserView::GetWindowAppIcon() { - if (browser_->type() & Browser::TYPE_APP) { - TabContents* contents = browser_->GetSelectedTabContents(); - if (contents && !contents->app_icon().isNull()) - return contents->app_icon(); - } - - return GetWindowIcon(); -} - -SkBitmap BrowserView::GetWindowIcon() { - if (browser_->type() & Browser::TYPE_APP) - return browser_->GetCurrentPageIcon(); - return SkBitmap(); -} - -bool BrowserView::ShouldShowWindowIcon() const { - return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); -} - -bool BrowserView::ExecuteWindowsCommand(int command_id) { - // This function handles WM_SYSCOMMAND, WM_APPCOMMAND, and WM_COMMAND. - - // Translate WM_APPCOMMAND command ids into a command id that the browser - // knows how to handle. - int command_id_from_app_command = GetCommandIDForAppCommandID(command_id); - if (command_id_from_app_command != -1) - command_id = command_id_from_app_command; - - if (browser_->command_updater()->SupportsCommand(command_id)) { - if (browser_->command_updater()->IsCommandEnabled(command_id)) - browser_->ExecuteCommand(command_id); - return true; - } - return false; -} - -std::wstring BrowserView::GetWindowName() const { - return UTF8ToWide(browser_->GetWindowPlacementKey()); -} - -void BrowserView::SaveWindowPlacement(const gfx::Rect& bounds, - bool maximized) { - // If IsFullscreen() is true, we've just changed into fullscreen mode, and - // we're catching the going-into-fullscreen sizing and positioning calls, - // which we want to ignore. - if (!IsFullscreen() && browser_->ShouldSaveWindowPlacement()) { - WindowDelegate::SaveWindowPlacement(bounds, maximized); - browser_->SaveWindowPlacement(bounds, maximized); - } -} - -bool BrowserView::GetSavedWindowBounds(gfx::Rect* bounds) const { - *bounds = browser_->GetSavedWindowBounds(); - if (browser_->type() & Browser::TYPE_POPUP) { - // We are a popup window. The value passed in |bounds| represents two - // pieces of information: - // - the position of the window, in screen coordinates (outer position). - // - the size of the content area (inner size). - // We need to use these values to determine the appropriate size and - // position of the resulting window. - if (IsToolbarVisible()) { - // If we're showing the toolbar, we need to adjust |*bounds| to include - // its desired height, since the toolbar is considered part of the - // window's client area as far as GetWindowBoundsForClientBounds is - // concerned... - bounds->set_height( - bounds->height() + toolbar_->GetPreferredSize().height()); - } - - gfx::Rect window_rect = frame_->GetWindow()->GetNonClientView()-> - GetWindowBoundsForClientBounds(*bounds); - window_rect.set_origin(bounds->origin()); - - // When we are given x/y coordinates of 0 on a created popup window, - // assume none were given by the window.open() command. - if (window_rect.x() == 0 && window_rect.y() == 0) { - gfx::Size size = window_rect.size(); - window_rect.set_origin(WindowSizer::GetDefaultPopupOrigin(size)); - } - - *bounds = window_rect; - } - - // We return true because we can _always_ locate reasonable bounds using the - // WindowSizer, and we don't want to trigger the Window's built-in "size to - // default" handling because the browser window has no default preferred - // size. - return true; -} - -bool BrowserView::GetSavedMaximizedState(bool* maximized) const { - *maximized = browser_->GetSavedMaximizedState(); - return true; -} - -views::View* BrowserView::GetContentsView() { - return contents_container_; -} - -views::ClientView* BrowserView::CreateClientView(views::Window* window) { - set_window(window); - return this; -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, views::ClientView overrides: - -bool BrowserView::CanClose() const { - // You cannot close a frame for which there is an active originating drag - // session. - if (tabstrip_->IsDragSessionActive()) - return false; - - // Give beforeunload handlers the chance to cancel the close before we hide - // the window below. - if (!browser_->ShouldCloseWindow()) - return false; - - if (!browser_->tabstrip_model()->empty()) { - // Tab strip isn't empty. Hide the frame (so it appears to have closed - // immediately) and close all the tabs, allowing the renderers to shut - // down. When the tab strip is empty we'll be called back again. - frame_->GetWindow()->HideWindow(); - browser_->OnWindowClosing(); - return false; - } - - // Empty TabStripModel, it's now safe to allow the Window to be closed. - NotificationService::current()->Notify( - NotificationType::WINDOW_CLOSED, - Source<gfx::NativeWindow>(frame_->GetWindow()->GetNativeWindow()), - NotificationService::NoDetails()); - return true; -} - -int BrowserView::NonClientHitTest(const gfx::Point& point) { -#if defined(OS_WIN) - // The following code is not in the LayoutManager because it's - // independent of layout and also depends on the ResizeCorner which - // is private. - if (!frame_->GetWindow()->IsMaximized() && - !frame_->GetWindow()->IsFullscreen()) { - CRect client_rect; - ::GetClientRect(frame_->GetWindow()->GetNativeWindow(), &client_rect); - gfx::Size resize_corner_size = ResizeCorner::GetSize(); - gfx::Rect resize_corner_rect(client_rect.right - resize_corner_size.width(), - client_rect.bottom - resize_corner_size.height(), - resize_corner_size.width(), resize_corner_size.height()); - bool rtl_dir = base::i18n::IsRTL(); - if (rtl_dir) - resize_corner_rect.set_x(0); - if (resize_corner_rect.Contains(point)) { - if (rtl_dir) - return HTBOTTOMLEFT; - return HTBOTTOMRIGHT; - } - } -#endif - - return GetBrowserViewLayout()->NonClientHitTest(point); -} - -gfx::Size BrowserView::GetMinimumSize() { - return GetBrowserViewLayout()->GetMinimumSize(); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, protected - -void BrowserView::GetAccessiblePanes( - std::vector<AccessiblePaneView*>* panes) { - // This should be in the order of pane traversal of the panes using F6. - // If one of these is invisible or has no focusable children, it will be - // automatically skipped. - panes->push_back(toolbar_); - if (bookmark_bar_view_.get()) - panes->push_back(bookmark_bar_view_.get()); - if (infobar_container_) - panes->push_back(infobar_container_); - if (download_shelf_.get()) - panes->push_back(download_shelf_.get()); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, views::View overrides: - -std::string BrowserView::GetClassName() const { - return kViewClassName; -} - -void BrowserView::Layout() { - if (ignore_layout_) - return; - views::View::Layout(); - - // The status bubble position requires that all other layout finish first. - LayoutStatusBubble(); - -#if defined(OS_WIN) - // Send the margins of the "user-perceived content area" of this - // browser window so AeroPeekManager can render a background-tab image in - // the area. - // TODO(pkasting) correct content inset?? - if (aeropeek_manager_.get()) { - gfx::Insets insets(GetFindBarBoundingBox().y() + 1, - 0, - 0, - 0); - aeropeek_manager_->SetContentInsets(insets); - } -#endif -} - -void BrowserView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this && GetWidget() && !initialized_) { - Init(); - initialized_ = true; - } -} - -void BrowserView::ChildPreferredSizeChanged(View* child) { - Layout(); -} - -AccessibilityTypes::Role BrowserView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_CLIENT; -} - -void BrowserView::InfoBarSizeChanged(bool is_animating) { - SelectedTabToolbarSizeChanged(is_animating); -} - -views::LayoutManager* BrowserView::CreateLayoutManager() const { - return new BrowserViewLayout; -} - -void BrowserView::InitTabStrip(TabStripModel* model) { - // Throw away the existing tabstrip if we're switching display modes. - if (tabstrip_) { - tabstrip_->GetParent()->RemoveChildView(tabstrip_); - delete tabstrip_; - } - - BrowserTabStripController* tabstrip_controller = - new BrowserTabStripController(browser_.get(), model); - - if (UseVerticalTabs()) - tabstrip_ = new SideTabStrip(tabstrip_controller); - else - tabstrip_ = new TabStrip(tabstrip_controller); - - tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP)); - AddChildView(tabstrip_); - - tabstrip_controller->InitFromModel(tabstrip_); -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView, private: - -void BrowserView::Init() { - accessible_view_helper_.reset(new AccessibleViewHelper( - this, browser_->profile())); - - SetLayoutManager(CreateLayoutManager()); - // Stow a pointer to this object onto the window handle so that we can get - // at it later when all we have is a native view. -#if defined(OS_WIN) - GetWidget()->SetNativeWindowProperty(kBrowserViewKey, this); -#else - g_object_set_data(G_OBJECT(GetWidget()->GetNativeView()), - kBrowserViewKey, this); -#endif - - // Start a hung plugin window detector for this browser object (as long as - // hang detection is not disabled). - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableHangMonitor)) { - InitHangMonitor(); - } - - LoadAccelerators(); - SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME)); - - InitTabStrip(browser_->tabstrip_model()); - - toolbar_ = new ToolbarView(browser_.get()); - AddChildView(toolbar_); - toolbar_->Init(browser_->profile()); - toolbar_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TOOLBAR)); - - infobar_container_ = new InfoBarContainer(this); - AddChildView(infobar_container_); - - contents_container_ = new TabContentsContainer; - contents_ = new ContentsContainer(this, contents_container_); - - SkColor bg_color = GetWidget()->GetThemeProvider()-> - GetColor(BrowserThemeProvider::COLOR_TOOLBAR); - - bool sidebar_allowed = SidebarManager::IsSidebarAllowed(); - if (sidebar_allowed) { - sidebar_container_ = new TabContentsContainer; - sidebar_container_->SetID(VIEW_ID_SIDE_BAR_CONTAINER); - sidebar_container_->SetVisible(false); - - sidebar_split_ = new views::SingleSplitView( - contents_, - sidebar_container_, - views::SingleSplitView::HORIZONTAL_SPLIT); - sidebar_split_->SetID(VIEW_ID_SIDE_BAR_SPLIT); - sidebar_split_-> - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SIDE_BAR)); - sidebar_split_->set_background( - views::Background::CreateSolidBackground(bg_color)); - } - - devtools_container_ = new TabContentsContainer; - devtools_container_->SetID(VIEW_ID_DEV_TOOLS_DOCKED); - devtools_container_->SetVisible(false); - - views::View* contents_view = contents_; - if (sidebar_allowed) - contents_view = sidebar_split_; - - contents_split_ = new views::SingleSplitView( - contents_view, - devtools_container_, - views::SingleSplitView::VERTICAL_SPLIT); - contents_split_->SetID(VIEW_ID_CONTENTS_SPLIT); - contents_split_-> - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_WEB_CONTENTS)); - contents_split_->set_background( - views::Background::CreateSolidBackground(bg_color)); - AddChildView(contents_split_); - set_contents_view(contents_split_); - - status_bubble_.reset(new StatusBubbleViews(contents_)); - -#if defined(OS_WIN) - InitSystemMenu(); - - // Create a custom JumpList and add it to an observer of TabRestoreService - // so we can update the custom JumpList when a tab is added or removed. - if (JumpList::Enabled()) { - jumplist_.reset(new JumpList); - jumplist_->AddObserver(browser_->profile()); - } - - if (AeroPeekManager::Enabled()) { - aeropeek_manager_.reset(new AeroPeekManager( - frame_->GetWindow()->GetNativeWindow())); - browser_->tabstrip_model()->AddObserver(aeropeek_manager_.get()); - } -#endif - - // We're now initialized and ready to process Layout requests. - ignore_layout_ = false; -} - -#if defined(OS_WIN) -void BrowserView::InitSystemMenu() { - system_menu_contents_.reset(new views::SystemMenuModel(this)); - // We add the menu items in reverse order so that insertion_index never needs - // to change. - if (IsBrowserTypeNormal()) - BuildSystemMenuForBrowserWindow(); - else - BuildSystemMenuForAppOrPopupWindow(browser_->type() == Browser::TYPE_APP); - system_menu_.reset( - new views::NativeMenuWin(system_menu_contents_.get(), - frame_->GetWindow()->GetNativeWindow())); - system_menu_->Rebuild(); -} -#endif - -BrowserViewLayout* BrowserView::GetBrowserViewLayout() const { - return static_cast<BrowserViewLayout*>(GetLayoutManager()); -} - -void BrowserView::LayoutStatusBubble() { - // In restored mode, the client area has a client edge between it and the - // frame. - int overlap = StatusBubbleViews::kShadowThickness + - (IsMaximized() ? 0 : views::NonClientFrameView::kClientEdgeThickness); - int x = -overlap; - if (UseVerticalTabs() && IsTabStripVisible()) - x += tabstrip_->bounds().right(); - int height = status_bubble_->GetPreferredSize().height(); - int contents_height = status_bubble_->base_view()->bounds().height(); - gfx::Point origin(-overlap, contents_height - height + overlap); - status_bubble_->SetBounds(origin.x(), origin.y(), width() / 3, height); -} - -bool BrowserView::MaybeShowBookmarkBar(TabContents* contents) { - views::View* new_bookmark_bar_view = NULL; - if (browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR) - && contents) { - if (!bookmark_bar_view_.get()) { - bookmark_bar_view_.reset(new BookmarkBarView(contents->profile(), - browser_.get())); - bookmark_bar_view_->set_parent_owned(false); - bookmark_bar_view_->set_background( - new BookmarkExtensionBackground(this, bookmark_bar_view_.get(), - browser_.get())); - } else { - bookmark_bar_view_->SetProfile(contents->profile()); - } - bookmark_bar_view_->SetPageNavigator(contents); - bookmark_bar_view_-> - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_BOOKMARKS)); - new_bookmark_bar_view = bookmark_bar_view_.get(); - } - return UpdateChildViewAndLayout(new_bookmark_bar_view, &active_bookmark_bar_); -} - -bool BrowserView::MaybeShowInfoBar(TabContents* contents) { - // TODO(beng): Remove this function once the interface between - // InfoBarContainer, DownloadShelfView and TabContents and this - // view is sorted out. - return true; -} - -void BrowserView::UpdateSidebar() { - UpdateSidebarForContents(GetSelectedTabContents()); - Layout(); -} - -void BrowserView::UpdateSidebarForContents(TabContents* tab_contents) { - if (!sidebar_container_) - return; // Happens when sidebar is not allowed. - if (!SidebarManager::GetInstance()) - return; // Happens only in tests. - - TabContents* sidebar_contents = NULL; - if (tab_contents) { - SidebarContainer* client_host = SidebarManager::GetInstance()-> - GetActiveSidebarContainerFor(tab_contents); - if (client_host) - sidebar_contents = client_host->sidebar_contents(); - } - - bool visible = NULL != sidebar_contents && - browser_->SupportsWindowFeature(Browser::FEATURE_SIDEBAR); - - bool should_show = visible && !sidebar_container_->IsVisible(); - bool should_hide = !visible && sidebar_container_->IsVisible(); - - // Update sidebar content. - TabContents* old_contents = sidebar_container_->tab_contents(); - sidebar_container_->ChangeTabContents(sidebar_contents); - SidebarManager::GetInstance()-> - NotifyStateChanges(old_contents, sidebar_contents); - - // Update sidebar UI width. - if (should_show) { - // Restore split offset. - int sidebar_width = g_browser_process->local_state()->GetInteger( - prefs::kExtensionSidebarWidth); - if (sidebar_width < 0) { - // Initial load, set to default value. - sidebar_width = sidebar_split_->width() / 7; - } - // Make sure user can see both panes. - int min_sidebar_width = sidebar_split_->GetMinimumSize().width(); - sidebar_width = std::min(sidebar_split_->width() - min_sidebar_width, - std::max(min_sidebar_width, sidebar_width)); - - sidebar_split_->set_divider_offset( - sidebar_split_->width() - sidebar_width); - - sidebar_container_->SetVisible(true); - sidebar_split_->Layout(); - } else if (should_hide) { - // Store split offset when hiding sidebar only. - g_browser_process->local_state()->SetInteger( - prefs::kExtensionSidebarWidth, - sidebar_split_->width() - sidebar_split_->divider_offset()); - - sidebar_container_->SetVisible(false); - sidebar_split_->Layout(); - } -} - -void BrowserView::UpdateDevToolsForContents(TabContents* tab_contents) { - TabContents* devtools_contents = - DevToolsWindow::GetDevToolsContents(tab_contents); - - bool should_show = devtools_contents && !devtools_container_->IsVisible(); - bool should_hide = !devtools_contents && devtools_container_->IsVisible(); - - devtools_container_->ChangeTabContents(devtools_contents); - - if (should_show) { - if (!devtools_focus_tracker_.get()) { - // Install devtools focus tracker when dev tools window is shown for the - // first time. - devtools_focus_tracker_.reset( - new views::ExternalFocusTracker(devtools_container_, - GetFocusManager())); - } - - // Restore split offset. - int split_offset = g_browser_process->local_state()->GetInteger( - prefs::kDevToolsSplitLocation); - if (split_offset == -1) { - // Initial load, set to default value. - split_offset = 2 * contents_split_->height() / 3; - } - // Make sure user can see both panes. - int min_split_size = contents_split_->height() / 10; - split_offset = std::min(contents_split_->height() - min_split_size, - std::max(min_split_size, split_offset)); - contents_split_->set_divider_offset(split_offset); - - devtools_container_->SetVisible(true); - contents_split_->Layout(); - } else if (should_hide) { - // Store split offset when hiding devtools window only. - g_browser_process->local_state()->SetInteger( - prefs::kDevToolsSplitLocation, contents_split_->divider_offset()); - - // Restore focus to the last focused view when hiding devtools window. - devtools_focus_tracker_->FocusLastFocusedExternalView(); - - devtools_container_->SetVisible(false); - contents_split_->Layout(); - } -} - -void BrowserView::UpdateUIForContents(TabContents* contents) { - bool needs_layout = MaybeShowBookmarkBar(contents); - needs_layout |= MaybeShowInfoBar(contents); - if (needs_layout) - Layout(); -} - -bool BrowserView::UpdateChildViewAndLayout(views::View* new_view, - views::View** old_view) { - DCHECK(old_view); - if (*old_view == new_view) { - // The views haven't changed, if the views pref changed schedule a layout. - if (new_view) { - if (new_view->GetPreferredSize().height() != new_view->height()) - return true; - } - return false; - } - - // The views differ, and one may be null (but not both). Remove the old - // view (if it non-null), and add the new one (if it is non-null). If the - // height has changed, schedule a layout, otherwise reuse the existing - // bounds to avoid scheduling a layout. - - int current_height = 0; - if (*old_view) { - current_height = (*old_view)->height(); - RemoveChildView(*old_view); - } - - int new_height = 0; - if (new_view) { - new_height = new_view->GetPreferredSize().height(); - AddChildView(new_view); - } - bool changed = false; - if (new_height != current_height) { - changed = true; - } else if (new_view && *old_view) { - // The view changed, but the new view wants the same size, give it the - // bounds of the last view and have it repaint. - new_view->SetBounds((*old_view)->bounds()); - new_view->SchedulePaint(); - } else if (new_view) { - DCHECK_EQ(0, new_height); - // The heights are the same, but the old view is null. This only happens - // when the height is zero. Zero out the bounds. - new_view->SetBounds(0, 0, 0, 0); - } - *old_view = new_view; - return changed; -} - -void BrowserView::ProcessFullscreen(bool fullscreen) { - // Reduce jankiness during the following position changes by: - // * Hiding the window until it's in the final position - // * Ignoring all intervening Layout() calls, which resize the webpage and - // thus are slow and look ugly - ignore_layout_ = true; - LocationBarView* location_bar = toolbar_->location_bar(); -#if defined(OS_WIN) - AutocompleteEditViewWin* edit_view = - static_cast<AutocompleteEditViewWin*>(location_bar->location_entry()); -#endif - if (!fullscreen) { - // Hide the fullscreen bubble as soon as possible, since the mode toggle can - // take enough time for the user to notice. - fullscreen_bubble_.reset(); - } else { - // Move focus out of the location bar if necessary. - views::FocusManager* focus_manager = GetFocusManager(); - DCHECK(focus_manager); - if (focus_manager->GetFocusedView() == location_bar) - focus_manager->ClearFocus(); - -#if defined(OS_WIN) - // If we don't hide the edit and force it to not show until we come out of - // fullscreen, then if the user was on the New Tab Page, the edit contents - // will appear atop the web contents once we go into fullscreen mode. This - // has something to do with how we move the main window while it's hidden; - // if we don't hide the main window below, we don't get this problem. - edit_view->set_force_hidden(true); - ShowWindow(edit_view->m_hWnd, SW_HIDE); -#endif - } -#if defined(OS_WIN) - frame_->GetWindow()->PushForceHidden(); -#endif - - // Notify bookmark bar, so it can set itself to the appropriate drawing state. - if (bookmark_bar_view_.get()) - bookmark_bar_view_->OnFullscreenToggled(fullscreen); - - // Toggle fullscreen mode. -#if defined(OS_WIN) - frame_->GetWindow()->SetFullscreen(fullscreen); -#endif // No need to invoke SetFullscreen for linux as this code is executed - // once we're already fullscreen on linux. - -#if defined(OS_LINUX) - // Updating of commands for fullscreen mode is called from SetFullScreen on - // Wndows (see just above), but for ChromeOS, this method (ProcessFullScreen) - // is called after full screen has happened successfully (via GTK's - // window-state-change event), so we have to update commands here. - browser_->UpdateCommandsForFullscreenMode(fullscreen); -#endif - - if (fullscreen) { - bool is_kiosk = - CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode); - if (!is_kiosk) { - fullscreen_bubble_.reset(new FullscreenExitBubble(GetWidget(), - browser_.get())); - } - } else { -#if defined(OS_WIN) - // Show the edit again since we're no longer in fullscreen mode. - edit_view->set_force_hidden(false); - ShowWindow(edit_view->m_hWnd, SW_SHOW); -#endif - } - - // Undo our anti-jankiness hacks and force the window to relayout now that - // it's in its final position. - ignore_layout_ = false; - Layout(); -#if defined(OS_WIN) - frame_->GetWindow()->PopForceHidden(); -#endif -} - - -void BrowserView::LoadAccelerators() { -#if defined(OS_WIN) - HACCEL accelerator_table = AtlLoadAccelerators(IDR_MAINFRAME); - DCHECK(accelerator_table); - - // We have to copy the table to access its contents. - int count = CopyAcceleratorTable(accelerator_table, 0, 0); - if (count == 0) { - // Nothing to do in that case. - return; - } - - ACCEL* accelerators = static_cast<ACCEL*>(malloc(sizeof(ACCEL) * count)); - CopyAcceleratorTable(accelerator_table, accelerators, count); - - views::FocusManager* focus_manager = GetFocusManager(); - DCHECK(focus_manager); - - // Let's fill our own accelerator table. - for (int i = 0; i < count; ++i) { - bool alt_down = (accelerators[i].fVirt & FALT) == FALT; - bool ctrl_down = (accelerators[i].fVirt & FCONTROL) == FCONTROL; - bool shift_down = (accelerators[i].fVirt & FSHIFT) == FSHIFT; - views::Accelerator accelerator( - static_cast<app::KeyboardCode>(accelerators[i].key), - shift_down, ctrl_down, alt_down); - accelerator_table_[accelerator] = accelerators[i].cmd; - - // Also register with the focus manager. - focus_manager->RegisterAccelerator(accelerator, this); - } - - // We don't need the Windows accelerator table anymore. - free(accelerators); -#else - views::FocusManager* focus_manager = GetFocusManager(); - DCHECK(focus_manager); - // Let's fill our own accelerator table. - for (size_t i = 0; i < browser::kAcceleratorMapLength; ++i) { - views::Accelerator accelerator(browser::kAcceleratorMap[i].keycode, - browser::kAcceleratorMap[i].shift_pressed, - browser::kAcceleratorMap[i].ctrl_pressed, - browser::kAcceleratorMap[i].alt_pressed); - accelerator_table_[accelerator] = browser::kAcceleratorMap[i].command_id; - - // Also register with the focus manager. - focus_manager->RegisterAccelerator(accelerator, this); - } -#endif -} - -#if defined(OS_WIN) -void BrowserView::BuildSystemMenuForBrowserWindow() { - system_menu_contents_->AddSeparator(); - system_menu_contents_->AddItemWithStringId(IDC_TASK_MANAGER, - IDS_TASK_MANAGER); - system_menu_contents_->AddSeparator(); - system_menu_contents_->AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB); - system_menu_contents_->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); - // If it's a regular browser window with tabs, we don't add any more items, - // since it already has menus (Page, Chrome). -} - -void BrowserView::BuildSystemMenuForAppOrPopupWindow(bool is_app) { - if (is_app) { - system_menu_contents_->AddSeparator(); - system_menu_contents_->AddItemWithStringId(IDC_TASK_MANAGER, - IDS_TASK_MANAGER); - } - system_menu_contents_->AddSeparator(); - encoding_menu_contents_.reset(new EncodingMenuModel(browser_.get())); - system_menu_contents_->AddSubMenuWithStringId(IDC_ENCODING_MENU, - IDS_ENCODING_MENU, - encoding_menu_contents_.get()); - zoom_menu_contents_.reset(new ZoomMenuModel(this)); - system_menu_contents_->AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, - zoom_menu_contents_.get()); - system_menu_contents_->AddItemWithStringId(IDC_PRINT, IDS_PRINT); - system_menu_contents_->AddItemWithStringId(IDC_FIND, IDS_FIND); - system_menu_contents_->AddSeparator(); - system_menu_contents_->AddItemWithStringId(IDC_PASTE, IDS_PASTE); - system_menu_contents_->AddItemWithStringId(IDC_COPY, IDS_COPY); - system_menu_contents_->AddItemWithStringId(IDC_CUT, IDS_CUT); - system_menu_contents_->AddSeparator(); - if (is_app) { - system_menu_contents_->AddItemWithStringId(IDC_NEW_TAB, - IDS_APP_MENU_NEW_WEB_PAGE); - } else { - system_menu_contents_->AddItemWithStringId(IDC_SHOW_AS_TAB, - IDS_SHOW_AS_TAB); - } - system_menu_contents_->AddItemWithStringId(IDC_COPY_URL, - IDS_APP_MENU_COPY_URL); - system_menu_contents_->AddSeparator(); - system_menu_contents_->AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD); - system_menu_contents_->AddItemWithStringId(IDC_FORWARD, - IDS_CONTENT_CONTEXT_FORWARD); - system_menu_contents_->AddItemWithStringId(IDC_BACK, - IDS_CONTENT_CONTEXT_BACK); -} -#endif - -int BrowserView::GetCommandIDForAppCommandID(int app_command_id) const { -#if defined(OS_WIN) - switch (app_command_id) { - // NOTE: The order here matches the APPCOMMAND declaration order in the - // Windows headers. - case APPCOMMAND_BROWSER_BACKWARD: return IDC_BACK; - case APPCOMMAND_BROWSER_FORWARD: return IDC_FORWARD; - case APPCOMMAND_BROWSER_REFRESH: return IDC_RELOAD; - case APPCOMMAND_BROWSER_HOME: return IDC_HOME; - case APPCOMMAND_BROWSER_STOP: return IDC_STOP; - case APPCOMMAND_BROWSER_SEARCH: return IDC_FOCUS_SEARCH; - case APPCOMMAND_HELP: return IDC_HELP_PAGE; - case APPCOMMAND_NEW: return IDC_NEW_TAB; - case APPCOMMAND_OPEN: return IDC_OPEN_FILE; - case APPCOMMAND_CLOSE: return IDC_CLOSE_TAB; - case APPCOMMAND_SAVE: return IDC_SAVE_PAGE; - case APPCOMMAND_PRINT: return IDC_PRINT; - case APPCOMMAND_COPY: return IDC_COPY; - case APPCOMMAND_CUT: return IDC_CUT; - case APPCOMMAND_PASTE: return IDC_PASTE; - - // TODO(pkasting): http://b/1113069 Handle these. - case APPCOMMAND_UNDO: - case APPCOMMAND_REDO: - case APPCOMMAND_SPELL_CHECK: - default: return -1; - } -#else - // App commands are Windows-specific so there's nothing to do here. - return -1; -#endif -} - -void BrowserView::LoadingAnimationCallback() { - if (browser_->type() == Browser::TYPE_NORMAL) { - // Loading animations are shown in the tab for tabbed windows. We check the - // browser type instead of calling IsTabStripVisible() because the latter - // will return false for fullscreen windows, but we still need to update - // their animations (so that when they come out of fullscreen mode they'll - // be correct). - tabstrip_->UpdateLoadingAnimations(); - } else if (ShouldShowWindowIcon()) { - // ... or in the window icon area for popups and app windows. - TabContents* tab_contents = browser_->GetSelectedTabContents(); - // GetSelectedTabContents can return NULL for example under Purify when - // the animations are running slowly and this function is called on a timer - // through LoadingAnimationCallback. - frame_->UpdateThrobber(tab_contents && tab_contents->is_loading()); - } -} - -void BrowserView::InitHangMonitor() { -#if defined(OS_WIN) - PrefService* pref_service = g_browser_process->local_state(); - if (!pref_service) - return; - - int plugin_message_response_timeout = - pref_service->GetInteger(prefs::kPluginMessageResponseTimeout); - int hung_plugin_detect_freq = - pref_service->GetInteger(prefs::kHungPluginDetectFrequency); - if ((hung_plugin_detect_freq > 0) && - hung_window_detector_.Initialize(GetWidget()->GetNativeView(), - plugin_message_response_timeout)) { - ticker_.set_tick_interval(hung_plugin_detect_freq); - ticker_.RegisterTickHandler(&hung_window_detector_); - ticker_.Start(); - - pref_service->SetInteger(prefs::kPluginMessageResponseTimeout, - plugin_message_response_timeout); - pref_service->SetInteger(prefs::kHungPluginDetectFrequency, - hung_plugin_detect_freq); - } -#endif -} - -void BrowserView::ProcessTabSelected(TabContents* new_contents, - bool change_tab_contents) { - // Update various elements that are interested in knowing the current - // TabContents. - - // When we toggle the NTP floating bookmarks bar and/or the info bar, - // we don't want any TabContents to be attached, so that we - // avoid an unnecessary resize and re-layout of a TabContents. - if (change_tab_contents) - contents_container_->ChangeTabContents(NULL); - infobar_container_->ChangeTabContents(new_contents); - UpdateUIForContents(new_contents); - if (change_tab_contents) - contents_container_->ChangeTabContents(new_contents); - UpdateSidebarForContents(new_contents); - - UpdateDevToolsForContents(new_contents); - // TODO(beng): This should be called automatically by ChangeTabContents, but I - // am striving for parity now rather than cleanliness. This is - // required to make features like Duplicate Tab, Undo Close Tab, - // etc not result in sad tab. - new_contents->DidBecomeSelected(); - if (BrowserList::GetLastActive() == browser_ && - !browser_->tabstrip_model()->closing_all() && GetWindow()->IsVisible()) { - // We only restore focus if our window is visible, to avoid invoking blur - // handlers when we are eventually shown. - new_contents->view()->RestoreFocus(); - } - - // Update all the UI bits. - UpdateTitleBar(); - UpdateToolbar(new_contents, true); - UpdateUIForContents(new_contents); -} - -#if !defined(OS_CHROMEOS) -// static -BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { - // Create the view and the frame. The frame will attach itself via the view - // so we don't need to do anything with the pointer. - BrowserView* view = new BrowserView(browser); - BrowserFrame::Create(view, browser->profile()); - - view->GetWindow()->GetNonClientView()-> - SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME)); - - return view; -} -#endif - -// static -FindBar* BrowserWindow::CreateFindBar(Browser* browser) { - return browser::CreateFindBar(static_cast<BrowserView*>(browser->window())); -} diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index d113525..4e90f82 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -2,653 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_H_ -#define CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_H_ +#ifndef CHROME_BROWSER_VIEWS_FRAME_POPUP_BROWSER_VIEW_H_ +#define CHROME_BROWSER_VIEWS_FRAME_POPUP_BROWSER_VIEW_H_ #pragma once -#include <map> -#include <string> -#include <vector> +#include "chrome/browser/ui/views/frame/browser_view.h" +// TODO(beng): remove this file once all includes have been updated. -#include "app/menus/simple_menu_model.h" -#include "base/scoped_ptr.h" -#include "base/timer.h" -#include "build/build_config.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/tabs/tab_strip_model_observer.h" -#include "chrome/browser/views/frame/browser_bubble_host.h" -#include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/browser/views/infobars/infobar_container.h" -#include "chrome/browser/views/tabs/tab_strip.h" -#include "chrome/browser/views/tabs/base_tab_strip.h" -#include "chrome/browser/views/unhandled_keyboard_event_handler.h" -#include "chrome/common/notification_registrar.h" -#include "gfx/native_widget_types.h" -#include "views/window/client_view.h" -#include "views/window/window_delegate.h" +#endif // CHROME_BROWSER_VIEWS_FRAME_POPUP_BROWSER_VIEW_H_ -#if defined(OS_WIN) -#include "chrome/browser/hang_monitor/hung_plugin_action.h" -#include "chrome/browser/hang_monitor/hung_window_detector.h" -#include "views/controls/menu/native_menu_win.h" -#endif - -// NOTE: For more information about the objects and files in this directory, -// view: http://dev.chromium.org/developers/design-documents/browser-window - -class AccessiblePaneView; -class AccessibleViewHelper; -class BookmarkBarView; -class Browser; -class BrowserBubble; -class BrowserViewLayout; -class ContentsContainer; -class DownloadShelfView; -class EncodingMenuModel; -class FullscreenExitBubble; -class HtmlDialogUIDelegate; -class InfoBarContainer; -class LocationBarView; -class SideTabStrip; -class StatusBubbleViews; -class TabContentsContainer; -class TabStripModel; -class ToolbarView; -class ZoomMenuModel; - -#if defined(OS_WIN) -class AeroPeekManager; -class JumpList; -#endif - -namespace views { -class ExternalFocusTracker; -class Menu; -class SingleSplitView; -} - -/////////////////////////////////////////////////////////////////////////////// -// BrowserView -// -// A ClientView subclass that provides the contents of a browser window, -// including the TabStrip, toolbars, download shelves, the content area etc. -// -class BrowserView : public BrowserBubbleHost, - public BrowserWindow, - public BrowserWindowTesting, - public NotificationObserver, - public TabStripModelObserver, - public menus::SimpleMenuModel::Delegate, - public views::WindowDelegate, - public views::ClientView, - public InfoBarContainer::Delegate { - public: - // The browser view's class name. - static const char kViewClassName[]; - - // Explicitly sets how windows are shown. Use a value of -1 to give the - // default behavior. This is used during testing and not generally useful - // otherwise. - static void SetShowState(int state); - - explicit BrowserView(Browser* browser); - virtual ~BrowserView(); - - void set_frame(BrowserFrame* frame) { frame_ = frame; } - BrowserFrame* frame() const { return frame_; } - - // Returns a pointer to the BrowserView* interface implementation (an - // instance of this object, typically) for a given native window, or NULL if - // there is no such association. - static BrowserView* GetBrowserViewForNativeWindow(gfx::NativeWindow window); - - // Returns a Browser instance of this view. - Browser* browser() const { return browser_.get(); } - - // Returns the show flag that should be used to show the frame containing - // this view. - int GetShowState() const; - - // Called by the frame to notify the BrowserView that it was moved, and that - // any dependent popup windows should be repositioned. - void WindowMoved(); - - // Called by the frame to notify the BrowserView that a move or resize was - // initiated. - void WindowMoveOrResizeStarted(); - - // Returns the apparent bounds of the toolbar, in BrowserView coordinates. - // These differ from |toolbar_.bounds()| in that they match where the toolbar - // background image is drawn -- slightly outside the "true" bounds - // horizontally, and, when using vertical tabs, behind the tab column. - gfx::Rect GetToolbarBounds() const; - - // Returns the bounds of the content area, in the coordinates of the - // BrowserView's parent. - gfx::Rect GetClientAreaBounds() const; - - // Returns the constraining bounding box that should be used to lay out the - // FindBar within. This is _not_ the size of the find bar, just the bounding - // box it should be laid out within. The coordinate system of the returned - // rect is in the coordinate system of the frame, since the FindBar is a child - // window. - gfx::Rect GetFindBarBoundingBox() const; - - // Returns the preferred height of the TabStrip. Used to position the OTR - // avatar icon. - int GetTabStripHeight() const; - - // Takes some view's origin (relative to this BrowserView) and offsets it such - // that it can be used as the source origin for seamlessly tiling the toolbar - // background image over that view. - gfx::Point OffsetPointForToolbarBackgroundImage( - const gfx::Point& point) const; - - // Returns the width of the currently displayed sidebar or 0. - int GetSidebarWidth() const; - - // Accessor for the TabStrip. - BaseTabStrip* tabstrip() const { return tabstrip_; } - - // Accessor for the Toolbar. - ToolbarView* toolbar() const { return toolbar_; } - - // Returns true if various window components are visible. - bool IsTabStripVisible() const; - - // Returns true if the vertical tabstrip is in use. - bool UseVerticalTabs() const; - - // Returns true if the profile associated with this Browser window is - // off the record. - bool IsOffTheRecord() const; - - // Returns true if the non-client view should render the Off-The-Record - // avatar icon if the window is off the record. - bool ShouldShowOffTheRecordAvatar() const; - - // Handle the specified |accelerator| being pressed. - bool AcceleratorPressed(const views::Accelerator& accelerator); - - // Provides the containing frame with the accelerator for the specified - // command id. This can be used to provide menu item shortcut hints etc. - // Returns true if an accelerator was found for the specified |cmd_id|, false - // otherwise. - bool GetAccelerator(int cmd_id, menus::Accelerator* accelerator); - - // Shows the next app-modal dialog box, if there is one to be shown, or moves - // an existing showing one to the front. Returns true if one was shown or - // activated, false if none was shown. - bool ActivateAppModalDialog() const; - - // Returns the selected TabContents. Used by our NonClientView's - // TabIconView::TabContentsProvider implementations. - // TODO(beng): exposing this here is a bit bogus, since it's only used to - // determine loading state. It'd be nicer if we could change this to be - // bool IsSelectedTabLoading() const; or something like that. We could even - // move it to a WindowDelegate subclass. - TabContents* GetSelectedTabContents() const; - - // Retrieves the icon to use in the frame to indicate an OTR window. - SkBitmap GetOTRAvatarIcon(); - -#if defined(OS_WIN) - // Called right before displaying the system menu to allow the BrowserView - // to add or delete entries. - void PrepareToRunSystemMenu(HMENU menu); -#endif - - // Returns true if the Browser object associated with this BrowserView is a - // normal-type window (i.e. a browser window, not an app or popup). - bool IsBrowserTypeNormal() const { - return browser_->type() == Browser::TYPE_NORMAL; - } - - // Returns true if the Browser object associated with this BrowserView is a - // app panel window. - bool IsBrowserTypePanel() const { - return browser_->type() == Browser::TYPE_APP_PANEL; - } - - // Returns true if the Browser object associated with this BrowserView is a - // popup window. - bool IsBrowserTypePopup() const { - return (browser_->type() & Browser::TYPE_POPUP) != 0; - } - - // Register preferences specific to this view. - static void RegisterBrowserViewPrefs(PrefService* prefs); - - // Returns true if the specified point(BrowserView coordinates) is in - // in the window caption area of the browser window. - bool IsPositionInWindowCaption(const gfx::Point& point); - - // Returns whether the fullscreen bubble is visible or not. - bool IsFullscreenBubbleVisible() const; - - // Invoked from the frame when the full screen state changes. This is only - // used on Linux. - void FullScreenStateChanged(); - - // Restores the focused view. This is also used to set the initial focus - // when a new browser window is created. - void RestoreFocus(); - - // Called when the activation of the frame changes. - virtual void ActivationChanged(bool activated); - - // Overridden from BrowserWindow: - virtual void Show(); - virtual void SetBounds(const gfx::Rect& bounds); - virtual void Close(); - virtual void Activate(); - virtual void Deactivate(); - virtual bool IsActive() const; - virtual void FlashFrame(); - virtual gfx::NativeWindow GetNativeHandle(); - virtual BrowserWindowTesting* GetBrowserWindowTesting(); - virtual StatusBubble* GetStatusBubble(); - virtual void SelectedTabToolbarSizeChanged(bool is_animating); - virtual void UpdateTitleBar(); - virtual void ShelfVisibilityChanged(); - virtual void UpdateDevTools(); - virtual void UpdateLoadingAnimations(bool should_animate); - virtual void SetStarredState(bool is_starred); - virtual gfx::Rect GetRestoredBounds() const; - virtual bool IsMaximized() const; - virtual void SetFullscreen(bool fullscreen); - virtual bool IsFullscreen() const; - virtual LocationBar* GetLocationBar() const; - virtual void SetFocusToLocationBar(bool select_all); - virtual void UpdateReloadStopState(bool is_loading, bool force); - virtual void UpdateToolbar(TabContents* contents, bool should_restore_state); - virtual void FocusToolbar(); - virtual void FocusAppMenu(); - virtual void FocusBookmarksToolbar(); - virtual void FocusChromeOSStatus() {} - virtual void RotatePaneFocus(bool forwards); - virtual void DestroyBrowser(); - virtual bool IsBookmarkBarVisible() const; - virtual bool IsBookmarkBarAnimating() const; - virtual bool IsToolbarVisible() const; - virtual gfx::Rect GetRootWindowResizerRect() const; - virtual void DisableInactiveFrame(); - virtual void ConfirmSetDefaultSearchProvider( - TabContents* tab_contents, - TemplateURL* template_url, - TemplateURLModel* template_url_model); - virtual void ConfirmAddSearchProvider(const TemplateURL* template_url, - Profile* profile); - virtual void ToggleBookmarkBar(); - virtual views::Window* ShowAboutChromeDialog(); - virtual void ShowUpdateChromeDialog(); - virtual void ShowTaskManager(); - virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked); - virtual void SetDownloadShelfVisible(bool visible); - virtual bool IsDownloadShelfVisible() const; - virtual DownloadShelf* GetDownloadShelf(); - virtual void ShowReportBugDialog(); - virtual void ShowClearBrowsingDataDialog(); - virtual void ShowImportDialog(); - virtual void ShowSearchEnginesDialog(); - virtual void ShowPasswordManager(); - virtual void ShowRepostFormWarningDialog(TabContents* tab_contents); - virtual void ShowContentSettingsWindow(ContentSettingsType content_type, - Profile* profile); - virtual void ShowCollectedCookiesDialog(TabContents* tab_contents); - virtual void ShowProfileErrorDialog(int message_id); - virtual void ShowThemeInstallBubble(); - virtual void ConfirmBrowserCloseWithPendingDownloads(); - virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, - gfx::NativeWindow parent_window); - virtual void ContinueDraggingDetachedTab(const gfx::Rect& tab_bounds); - virtual void UserChangedTheme(); - virtual int GetExtraRenderViewHeight() const; - virtual void TabContentsFocused(TabContents* source); - virtual void ShowPageInfo(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - bool show_history); - virtual void ShowAppMenu(); - virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, - bool* is_keyboard_shortcut); - virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); - virtual void ShowCreateShortcutsDialog(TabContents* tab_contents); - virtual void Cut(); - virtual void Copy(); - virtual void Paste(); - virtual void ToggleTabStripMode(); - virtual void ShowInstant(TabContents* preview_contents); - virtual void HideInstant(); - virtual gfx::Rect GetInstantBounds(); - - // Overridden from BrowserWindowTesting: - virtual BookmarkBarView* GetBookmarkBarView() const; - virtual LocationBarView* GetLocationBarView() const; - virtual views::View* GetTabContentsContainerView() const; - virtual views::View* GetSidebarContainerView() const; - virtual ToolbarView* GetToolbarView() const; - - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Overridden from TabStripModelObserver: - virtual void TabDetachedAt(TabContents* contents, int index); - virtual void TabDeselectedAt(TabContents* contents, int index); - virtual void TabSelectedAt(TabContents* old_contents, - TabContents* new_contents, - int index, - bool user_gesture); - virtual void TabReplacedAt(TabContents* old_contents, - TabContents* new_contents, - int index); - virtual void TabStripEmpty(); - - // Overridden from menus::SimpleMenuModel::Delegate: - virtual bool IsCommandIdChecked(int command_id) const; - virtual bool IsCommandIdEnabled(int command_id) const; - virtual bool GetAcceleratorForCommandId(int command_id, - menus::Accelerator* accelerator); - virtual bool IsLabelForCommandIdDynamic(int command_id) const; - virtual string16 GetLabelForCommandId(int command_id) const; - virtual void ExecuteCommand(int command_id); - - // Overridden from views::WindowDelegate: - virtual bool CanResize() const; - virtual bool CanMaximize() const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual std::wstring GetAccessibleWindowTitle() const; - virtual views::View* GetInitiallyFocusedView(); - virtual bool ShouldShowWindowTitle() const; - virtual SkBitmap GetWindowAppIcon(); - virtual SkBitmap GetWindowIcon(); - virtual bool ShouldShowWindowIcon() const; - virtual bool ExecuteWindowsCommand(int command_id); - virtual std::wstring GetWindowName() const; - virtual void SaveWindowPlacement(const gfx::Rect& bounds, - bool maximized); - virtual bool GetSavedWindowBounds(gfx::Rect* bounds) const; - virtual bool GetSavedMaximizedState(bool* maximized) const; - virtual views::View* GetContentsView(); - virtual views::ClientView* CreateClientView(views::Window* window); - - // Overridden from views::ClientView: - virtual bool CanClose() const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual gfx::Size GetMinimumSize(); - - // InfoBarContainer::Delegate overrides - virtual void InfoBarSizeChanged(bool is_animating); - - protected: - // Appends to |toolbars| a pointer to each AccessiblePaneView that - // can be traversed using F6, in the order they should be traversed. - // Abstracted here so that it can be extended for Chrome OS. - virtual void GetAccessiblePanes( - std::vector<AccessiblePaneView*>* panes); - - // Save the current focused view to view storage - void SaveFocusedView(); - - int last_focused_view_storage_id() const { - return last_focused_view_storage_id_; - } - - // Overridden from views::View: - virtual std::string GetClassName() const; - virtual void Layout(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - virtual void ChildPreferredSizeChanged(View* child); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // Factory Methods. - // Returns a new LayoutManager for this browser view. A subclass may - // override to implemnet different layout pocily. - virtual views::LayoutManager* CreateLayoutManager() const; - - // Initializes a new TabStrip for the browser view. This can be performed - // multiple times over the life of the browser, and is run when the display - // mode for the tabstrip changes from horizontal to vertical. - virtual void InitTabStrip(TabStripModel* tab_strip_model); - - // Browser window related initializations. - virtual void Init(); - - private: - friend class BrowserViewLayout; - -#if defined(OS_WIN) - // Creates the system menu. - void InitSystemMenu(); -#endif - - // Returns the BrowserViewLayout. - BrowserViewLayout* GetBrowserViewLayout() const; - - // Layout the Status Bubble. - void LayoutStatusBubble(); - - // Prepare to show the Bookmark Bar for the specified TabContents. Returns - // true if the Bookmark Bar can be shown (i.e. it's supported for this - // Browser type) and there should be a subsequent re-layout to show it. - // |contents| can be NULL. - bool MaybeShowBookmarkBar(TabContents* contents); - - // Prepare to show an Info Bar for the specified TabContents. Returns true - // if there is an Info Bar to show and one is supported for this Browser - // type, and there should be a subsequent re-layout to show it. - // |contents| can be NULL. - bool MaybeShowInfoBar(TabContents* contents); - - // Updates sidebar UI according to the current tab and sidebar state. - void UpdateSidebar(); - // Displays active sidebar linked to the |tab_contents| or hides sidebar UI, - // if there's no such sidebar. - void UpdateSidebarForContents(TabContents* tab_contents); - - // Updated devtools window for given contents. - void UpdateDevToolsForContents(TabContents* tab_contents); - - // Updates various optional child Views, e.g. Bookmarks Bar, Info Bar or the - // Download Shelf in response to a change notification from the specified - // |contents|. |contents| can be NULL. In this case, all optional UI will be - // removed. - void UpdateUIForContents(TabContents* contents); - - // Updates an optional child View, e.g. Bookmarks Bar, Info Bar, Download - // Shelf. If |*old_view| differs from new_view, the old_view is removed and - // the new_view is added. This is intended to be used when swapping in/out - // child views that are referenced via a field. - // Returns true if anything was changed, and a re-Layout is now required. - bool UpdateChildViewAndLayout(views::View* new_view, views::View** old_view); - - // Invoked to update the necessary things when our fullscreen state changes - // to |fullscreen|. On Windows this is invoked immediately when we toggle the - // full screen state. On Linux changing the fullscreen state is async, so we - // ask the window to change it's fullscreen state, then when we get - // notification that it succeeded this method is invoked. - void ProcessFullscreen(bool fullscreen); - - // Copy the accelerator table from the app resources into something we can - // use. - void LoadAccelerators(); - -#if defined(OS_WIN) - // Builds the correct menu for when we have minimal chrome. - void BuildSystemMenuForBrowserWindow(); - void BuildSystemMenuForAppOrPopupWindow(bool is_app); -#endif - - // Retrieves the command id for the specified Windows app command. - int GetCommandIDForAppCommandID(int app_command_id) const; - - // Callback for the loading animation(s) associated with this view. - void LoadingAnimationCallback(); - - // Initialize the hung plugin detector. - void InitHangMonitor(); - - // Invoked from TabSelectedAt or when instant is made active. Is - // |change_tab_contents| is true, |new_contents| is added to the view - // hierarchy, if |change_tab_contents| is false, it's assumed |new_contents| - // has already been added to the view hierarchy. - void ProcessTabSelected(TabContents* new_contents, bool change_tab_contents); - - // Last focused view that issued a tab traversal. - int last_focused_view_storage_id_; - - // The BrowserFrame that hosts this view. - BrowserFrame* frame_; - - // The Browser object we are associated with. - scoped_ptr<Browser> browser_; - - // BrowserView layout (LTR one is pictured here). - // - // -------------------------------------------------------------------------- - // | | Tabs (1) | - // | |--------------------------------------------------------------| - // | | Navigation buttons, menus and the address bar (toolbar_) | - // | |--------------------------------------------------------------| - // | | All infobars (infobar_container_) * | - // | |--------------------------------------------------------------| - // | | Bookmarks (bookmark_bar_view_) * | - // | |--------------------------------------------------------------| - // | |Page content (contents_) || | - // | |--------------------------------------|| Sidebar content | - // | || contents_container_ and/or ||| (sidebar_container_) | - // | || preview_container_ ||| | - // | || |(3) | - // | Tabs (2)|| ||| | - // | || ||| | - // | || ||| | - // | || ||| | - // | |--------------------------------------|| | - // | |==(4)=========================================================| - // | | | - // | | | - // | | Debugger (devtools_container_) | - // | | | - // | | | - // | |--------------------------------------------------------------| - // | | Active downloads (download_shelf_) | - // -------------------------------------------------------------------------- - // - // (1) - tabstrip_, default position - // (2) - tabstrip_, position when side tabs are enabled - // (3) - sidebar_split_ - // (4) - contents_split_ - // - // * - The bookmark bar and info bar are swapped when on the new tab page. - // Additionally contents_ is positioned on top of the bookmark bar when - // the bookmark bar is detached. This is done to allow the - // preview_container_ to appear over the bookmark bar. - - // Tool/Info bars that we are currently showing. Used for layout. - // active_bookmark_bar_ is either NULL, if the bookmark bar isn't showing, - // or is bookmark_bar_view_ if the bookmark bar is showing. - views::View* active_bookmark_bar_; - - // The TabStrip. - BaseTabStrip* tabstrip_; - - // The Toolbar containing the navigation buttons, menus and the address bar. - ToolbarView* toolbar_; - - // The Bookmark Bar View for this window. Lazily created. - scoped_ptr<BookmarkBarView> bookmark_bar_view_; - - // The download shelf view (view at the bottom of the page). - scoped_ptr<DownloadShelfView> download_shelf_; - - // The InfoBarContainer that contains InfoBars for the current tab. - InfoBarContainer* infobar_container_; - - // The view that contains sidebar for the current tab. - TabContentsContainer* sidebar_container_; - - // Split view containing the contents container and sidebar container. - views::SingleSplitView* sidebar_split_; - - // The view that contains the selected TabContents. - TabContentsContainer* contents_container_; - - // The view that contains devtools window for the selected TabContents. - TabContentsContainer* devtools_container_; - - // The view that contains instant's TabContents. - TabContentsContainer* preview_container_; - - // The view managing both the contents_container_ and preview_container_. - ContentsContainer* contents_; - - // Split view containing the contents container and devtools container. - views::SingleSplitView* contents_split_; - - // Tracks and stores the last focused view which is not the - // devtools_container_ or any of its children. Used to restore focus once - // the devtools_container_ is hidden. - scoped_ptr<views::ExternalFocusTracker> devtools_focus_tracker_; - - // The Status information bubble that appears at the bottom of the window. - scoped_ptr<StatusBubbleViews> status_bubble_; - - // A mapping between accelerators and commands. - std::map<views::Accelerator, int> accelerator_table_; - - // True if we have already been initialized. - bool initialized_; - - // True if we should ignore requests to layout. This is set while toggling - // fullscreen mode on and off to reduce jankiness. - bool ignore_layout_; - - scoped_ptr<FullscreenExitBubble> fullscreen_bubble_; - -#if defined(OS_WIN) - // The additional items we insert into the system menu. - scoped_ptr<views::SystemMenuModel> system_menu_contents_; - scoped_ptr<ZoomMenuModel> zoom_menu_contents_; - scoped_ptr<EncodingMenuModel> encoding_menu_contents_; - // The wrapped system menu itself. - scoped_ptr<views::NativeMenuWin> system_menu_; - - // This object is used to perform periodic actions in a worker - // thread. It is currently used to monitor hung plugin windows. - WorkerThreadTicker ticker_; - - // This object is initialized with the frame window HWND. This - // object is also passed as a tick handler with the ticker_ object. - // It is used to periodically monitor for hung plugin windows - HungWindowDetector hung_window_detector_; - - // This object is invoked by hung_window_detector_ when it detects a hung - // plugin window. - HungPluginAction hung_plugin_action_; - - // The custom JumpList for Windows 7. - scoped_ptr<JumpList> jumplist_; - - // The custom AeroPeek manager for Windows 7. - scoped_ptr<AeroPeekManager> aeropeek_manager_; -#endif - - // The timer used to update frames for the Loading Animation. - base::RepeatingTimer<BrowserView> loading_animation_timer_; - - UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; - - scoped_ptr<AccessibleViewHelper> accessible_view_helper_; - - NotificationRegistrar registrar_; - - DISALLOW_COPY_AND_ASSIGN(BrowserView); -}; - -#endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_H_ diff --git a/chrome/browser/views/frame/browser_view_layout.cc b/chrome/browser/views/frame/browser_view_layout.cc deleted file mode 100644 index 5b7dc66..0000000 --- a/chrome/browser/views/frame/browser_view_layout.cc +++ /dev/null @@ -1,414 +0,0 @@ -// 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_view_layout.h" - -#include "chrome/browser/find_bar.h" -#include "chrome/browser/find_bar_controller.h" -#include "chrome/browser/sidebar/sidebar_manager.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/bookmark_bar_view.h" -#include "chrome/browser/views/download_shelf_view.h" -#include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/frame/contents_container.h" -#include "chrome/browser/views/tabs/side_tab_strip.h" -#include "chrome/browser/views/tabs/tab_strip.h" -#include "chrome/browser/views/toolbar_view.h" -#include "gfx/scrollbar_size.h" -#include "views/window/window.h" - -#if defined(OS_LINUX) -#include "views/window/hit_test.h" -#endif - -namespace { - -// The visible height of the shadow above the tabs. Clicks in this area are -// treated as clicks to the frame, rather than clicks to the tab. -const int kTabShadowSize = 2; -// The vertical overlap between the TabStrip and the Toolbar. -const int kToolbarTabStripVerticalOverlap = 3; -// An offset distance between certain toolbars and the toolbar that preceded -// them in layout. -const int kSeparationLineHeight = 1; - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// BrowserViewLayout, public: - -BrowserViewLayout::BrowserViewLayout() - : tabstrip_(NULL), - toolbar_(NULL), - contents_split_(NULL), - contents_container_(NULL), - infobar_container_(NULL), - download_shelf_(NULL), - active_bookmark_bar_(NULL), - browser_view_(NULL), - find_bar_y_(0) { -} - -gfx::Size BrowserViewLayout::GetMinimumSize() { - // TODO(noname): In theory the tabstrip width should probably be - // (OTR + tabstrip + caption buttons) width. - gfx::Size tabstrip_size( - browser()->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ? - tabstrip_->GetMinimumSize() : gfx::Size()); - gfx::Size toolbar_size( - (browser()->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || - browser()->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)) ? - toolbar_->GetMinimumSize() : gfx::Size()); - if (tabstrip_size.height() && toolbar_size.height()) - toolbar_size.Enlarge(0, -kToolbarTabStripVerticalOverlap); - gfx::Size bookmark_bar_size; - if (active_bookmark_bar_ && - browser()->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR)) { - bookmark_bar_size = active_bookmark_bar_->GetMinimumSize(); - bookmark_bar_size.Enlarge(0, -(kSeparationLineHeight + - active_bookmark_bar_->GetToolbarOverlap(true))); - } - gfx::Size contents_size(contents_split_->GetMinimumSize()); - - int min_height = tabstrip_size.height() + toolbar_size.height() + - bookmark_bar_size.height() + contents_size.height(); - int widths[] = { tabstrip_size.width(), toolbar_size.width(), - bookmark_bar_size.width(), contents_size.width() }; - int min_width = *std::max_element(&widths[0], &widths[arraysize(widths)]); - return gfx::Size(min_width, min_height); -} - -gfx::Rect BrowserViewLayout::GetFindBarBoundingBox() const { - // This function returns the area the Find Bar can be laid out - // within. This basically implies the "user-perceived content - // area" of the browser window excluding the vertical - // scrollbar. This is not quite so straightforward as positioning - // based on the TabContentsContainer since the BookmarkBarView may - // be visible but not persistent (in the New Tab case) and we - // position the Find Bar over the top of it in that case since the - // BookmarkBarView is not _visually_ connected to the Toolbar. - - // First determine the bounding box of the content area in Widget - // coordinates. - gfx::Rect bounding_box(contents_container_->bounds()); - - gfx::Point topleft; - views::View::ConvertPointToWidget(contents_container_, &topleft); - bounding_box.set_origin(topleft); - - // Adjust the position and size of the bounding box by the find bar offset - // calculated during the last Layout. - int height_delta = find_bar_y_ - bounding_box.y(); - bounding_box.set_y(find_bar_y_); - bounding_box.set_height(std::max(0, bounding_box.height() + height_delta)); - - // Finally decrease the width of the bounding box by the width of - // the vertical scroll bar. - int scrollbar_width = gfx::scrollbar_size(); - bounding_box.set_width(std::max(0, bounding_box.width() - scrollbar_width)); - if (base::i18n::IsRTL()) - bounding_box.set_x(bounding_box.x() + scrollbar_width); - - return bounding_box; -} - -bool BrowserViewLayout::IsPositionInWindowCaption( - const gfx::Point& point) { - gfx::Point tabstrip_point(point); - views::View::ConvertPointToView(browser_view_, tabstrip_, &tabstrip_point); - return tabstrip_->IsPositionInWindowCaption(tabstrip_point); -} - -int BrowserViewLayout::NonClientHitTest( - const gfx::Point& point) { - // Since the TabStrip only renders in some parts of the top of the window, - // the un-obscured area is considered to be part of the non-client caption - // area of the window. So we need to treat hit-tests in these regions as - // hit-tests of the titlebar. - - views::View* parent = browser_view_->GetParent(); - - gfx::Point point_in_browser_view_coords(point); - views::View::ConvertPointToView( - parent, browser_view_, &point_in_browser_view_coords); - - // Determine if the TabStrip exists and is capable of being clicked on. We - // might be a popup window without a TabStrip. - if (browser_view_->IsTabStripVisible()) { - // See if the mouse pointer is within the bounds of the TabStrip. - gfx::Point point_in_tabstrip_coords(point); - views::View::ConvertPointToView(parent, tabstrip_, - &point_in_tabstrip_coords); - if (tabstrip_->HitTest(point_in_tabstrip_coords)) { - if (tabstrip_->IsPositionInWindowCaption(point_in_tabstrip_coords)) - return HTCAPTION; - return HTCLIENT; - } - - // The top few pixels of the TabStrip are a drop-shadow - as we're pretty - // starved of dragable area, let's give it to window dragging (this also - // makes sense visually). - if (!browser_view_->IsMaximized() && - (point_in_browser_view_coords.y() < - (tabstrip_->y() + kTabShadowSize))) { - // We return HTNOWHERE as this is a signal to our containing - // NonClientView that it should figure out what the correct hit-test - // code is given the mouse position... - return HTNOWHERE; - } - } - - // If the point's y coordinate is below the top of the toolbar and otherwise - // within the bounds of this view, the point is considered to be within the - // client area. - gfx::Rect bv_bounds = browser_view_->bounds(); - bv_bounds.Offset(0, toolbar_->y()); - bv_bounds.set_height(bv_bounds.height() - toolbar_->y()); - if (bv_bounds.Contains(point)) - return HTCLIENT; - - // If the point's y coordinate is above the top of the toolbar, but not in - // the tabstrip (per previous checking in this function), then we consider it - // in the window caption (e.g. the area to the right of the tabstrip - // underneath the window controls). However, note that we DO NOT return - // HTCAPTION here, because when the window is maximized the window controls - // will fall into this space (since the BrowserView is sized to entire size - // of the window at that point), and the HTCAPTION value will cause the - // window controls not to work. So we return HTNOWHERE so that the caller - // will hit-test the window controls before finally falling back to - // HTCAPTION. - bv_bounds = browser_view_->bounds(); - bv_bounds.set_height(toolbar_->y()); - if (bv_bounds.Contains(point)) - return HTNOWHERE; - - // If the point is somewhere else, delegate to the default implementation. - return browser_view_->views::ClientView::NonClientHitTest(point); -} - -////////////////////////////////////////////////////////////////////////////// -// BrowserViewLayout, views::LayoutManager implementation: - -void BrowserViewLayout::Installed(views::View* host) { - toolbar_ = NULL; - contents_split_ = NULL; - contents_container_ = NULL; - infobar_container_ = NULL; - download_shelf_ = NULL; - active_bookmark_bar_ = NULL; - tabstrip_ = NULL; - browser_view_ = static_cast<BrowserView*>(host); -} - -void BrowserViewLayout::Uninstalled(views::View* host) {} - -void BrowserViewLayout::ViewAdded(views::View* host, views::View* view) { - switch (view->GetID()) { - case VIEW_ID_CONTENTS_SPLIT: { - contents_split_ = view; - // We're installed as the LayoutManager before BrowserView creates the - // contents, so we have to set contents_container_ here rather than - // Installed. - contents_container_ = browser_view_->contents_; - break; - } - case VIEW_ID_INFO_BAR_CONTAINER: - infobar_container_ = view; - break; - case VIEW_ID_DOWNLOAD_SHELF: - download_shelf_ = static_cast<DownloadShelfView*>(view); - break; - case VIEW_ID_BOOKMARK_BAR: - active_bookmark_bar_ = static_cast<BookmarkBarView*>(view); - break; - case VIEW_ID_TOOLBAR: - toolbar_ = static_cast<ToolbarView*>(view); - break; - case VIEW_ID_TAB_STRIP: - tabstrip_ = static_cast<BaseTabStrip*>(view); - break; - } -} - -void BrowserViewLayout::ViewRemoved(views::View* host, views::View* view) { - switch (view->GetID()) { - case VIEW_ID_BOOKMARK_BAR: - active_bookmark_bar_ = NULL; - break; - } -} - -void BrowserViewLayout::Layout(views::View* host) { - vertical_layout_rect_ = browser_view_->GetLocalBounds(true); - int top = LayoutTabStrip(); - if (browser_view_->IsTabStripVisible() && !browser_view_->UseVerticalTabs()) { - tabstrip_->SetBackgroundOffset(gfx::Point( - tabstrip_->MirroredX() + browser_view_->MirroredX(), - browser_view_->frame()->GetHorizontalTabStripVerticalOffset(false))); - } - top = LayoutToolbar(top); - top = LayoutBookmarkAndInfoBars(top); - int bottom = LayoutDownloadShelf(browser_view_->height()); - int active_top_margin = GetTopMarginForActiveContent(); - top -= active_top_margin; - contents_container_->SetActiveTopMargin(active_top_margin); - LayoutTabContents(top, bottom); - // This must be done _after_ we lay out the TabContents since this - // code calls back into us to find the bounding box the find bar - // must be laid out within, and that code depends on the - // TabContentsContainer's bounds being up to date. - if (browser()->HasFindBarController()) { - browser()->GetFindBarController()->find_bar()->MoveWindowIfNecessary( - gfx::Rect(), true); - } -} - -// Return the preferred size which is the size required to give each -// children their respective preferred size. -gfx::Size BrowserViewLayout::GetPreferredSize(views::View* host) { - return gfx::Size(); -} - -////////////////////////////////////////////////////////////////////////////// -// BrowserViewLayout, private: - -Browser* BrowserViewLayout::browser() { - return browser_view_->browser(); -} - -const Browser* BrowserViewLayout::browser() const { - return browser_view_->browser(); -} - -int BrowserViewLayout::LayoutTabStrip() { - if (!browser_view_->IsTabStripVisible()) { - tabstrip_->SetVisible(false); - tabstrip_->SetBounds(0, 0, 0, 0); - return 0; - } - - gfx::Rect tabstrip_bounds( - browser_view_->frame()->GetBoundsForTabStrip(tabstrip_)); - gfx::Point tabstrip_origin(tabstrip_bounds.origin()); - views::View::ConvertPointToView(browser_view_->GetParent(), browser_view_, - &tabstrip_origin); - tabstrip_bounds.set_origin(tabstrip_origin); - - if (browser_view_->UseVerticalTabs()) - vertical_layout_rect_.Inset(tabstrip_bounds.width(), 0, 0, 0); - - tabstrip_->SetVisible(true); - tabstrip_->SetBounds(tabstrip_bounds); - return browser_view_->UseVerticalTabs() ? - tabstrip_bounds.y() : tabstrip_bounds.bottom(); -} - -int BrowserViewLayout::LayoutToolbar(int top) { - int browser_view_width = vertical_layout_rect_.width(); - bool visible = browser_view_->IsToolbarVisible(); - toolbar_->location_bar()->SetFocusable(visible); - int y = top; - if (!browser_view_->UseVerticalTabs()) { - y -= ((visible && browser_view_->IsTabStripVisible()) ? - kToolbarTabStripVerticalOverlap : 0); - } - int height = visible ? toolbar_->GetPreferredSize().height() : 0; - toolbar_->SetVisible(visible); - toolbar_->SetBounds(vertical_layout_rect_.x(), y, browser_view_width, height); - return y + height; -} - -int BrowserViewLayout::LayoutBookmarkAndInfoBars(int top) { - find_bar_y_ = top + browser_view_->y() - 1; - if (active_bookmark_bar_) { - // If we're showing the Bookmark bar in detached style, then we - // need to show any Info bar _above_ the Bookmark bar, since the - // Bookmark bar is styled to look like it's part of the page. - if (active_bookmark_bar_->IsDetached()) - return LayoutBookmarkBar(LayoutInfoBar(top)); - // Otherwise, Bookmark bar first, Info bar second. - top = std::max(toolbar_->bounds().bottom(), LayoutBookmarkBar(top)); - } - find_bar_y_ = top + browser_view_->y() - 1; - return LayoutInfoBar(top); -} - -int BrowserViewLayout::LayoutBookmarkBar(int top) { - DCHECK(active_bookmark_bar_); - int y = top; - if (!browser_view_->IsBookmarkBarVisible()) { - active_bookmark_bar_->SetVisible(false); - active_bookmark_bar_->SetBounds(0, y, browser_view_->width(), 0); - return y; - } - - active_bookmark_bar_->set_infobar_visible(InfobarVisible()); - int bookmark_bar_height = active_bookmark_bar_->GetPreferredSize().height(); - y -= kSeparationLineHeight + active_bookmark_bar_->GetToolbarOverlap(false); - active_bookmark_bar_->SetVisible(true); - active_bookmark_bar_->SetBounds(vertical_layout_rect_.x(), y, - vertical_layout_rect_.width(), - bookmark_bar_height); - return y + bookmark_bar_height; -} - -int BrowserViewLayout::LayoutInfoBar(int top) { - bool visible = InfobarVisible(); - int height = visible ? infobar_container_->GetPreferredSize().height() : 0; - infobar_container_->SetVisible(visible); - infobar_container_->SetBounds(vertical_layout_rect_.x(), top, - vertical_layout_rect_.width(), height); - return top + height; -} - -void BrowserViewLayout::LayoutTabContents(int top, int bottom) { - contents_split_->SetBounds(vertical_layout_rect_.x(), top, - vertical_layout_rect_.width(), bottom - top); -} - -int BrowserViewLayout::GetTopMarginForActiveContent() { - if (!active_bookmark_bar_ || !browser_view_->IsBookmarkBarVisible() || - !active_bookmark_bar_->IsDetached()) { - return 0; - } - - if (contents_split_->GetChildViewAt(1) && - contents_split_->GetChildViewAt(1)->IsVisible()) - return 0; - - if (SidebarManager::IsSidebarAllowed()) { - views::View* sidebar_split = contents_split_->GetChildViewAt(0); - if (sidebar_split->GetChildViewAt(1) && - sidebar_split->GetChildViewAt(1)->IsVisible()) - return 0; - } - - // Adjust for separator. - return active_bookmark_bar_->height() - kSeparationLineHeight; -} - -int BrowserViewLayout::LayoutDownloadShelf(int bottom) { - // Re-layout the shelf either if it is visible or if it's close animation - // is currently running. - if (browser_view_->IsDownloadShelfVisible() || - (download_shelf_ && download_shelf_->IsClosing())) { - bool visible = browser()->SupportsWindowFeature( - Browser::FEATURE_DOWNLOADSHELF); - DCHECK(download_shelf_); - int height = visible ? download_shelf_->GetPreferredSize().height() : 0; - download_shelf_->SetVisible(visible); - download_shelf_->SetBounds(vertical_layout_rect_.x(), bottom - height, - vertical_layout_rect_.width(), height); - download_shelf_->Layout(); - bottom -= height; - } - return bottom; -} - -bool BrowserViewLayout::InfobarVisible() const { - // NOTE: Can't check if the size IsEmpty() since it's always 0-width. - return browser()->SupportsWindowFeature(Browser::FEATURE_INFOBAR) && - (infobar_container_->GetPreferredSize().height() != 0); -} diff --git a/chrome/browser/views/frame/browser_view_layout.h b/chrome/browser/views/frame/browser_view_layout.h index 42652ef..a96fa8e 100644 --- a/chrome/browser/views/frame/browser_view_layout.h +++ b/chrome/browser/views/frame/browser_view_layout.h @@ -6,107 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ #pragma once -#include "views/layout_manager.h" - -class BaseTabStrip; -class BookmarkBarView; -class Browser; -class BrowserView; -class ContentsContainer; -class DownloadShelfView; -class ToolbarView; - -// The layout manager used in chrome browser. -class BrowserViewLayout : public views::LayoutManager { - public: - BrowserViewLayout(); - virtual ~BrowserViewLayout() {} - - // Returns the minimum size of the browser view. - virtual gfx::Size GetMinimumSize(); - - // Returns the bounding box for the find bar. - virtual gfx::Rect GetFindBarBoundingBox() const; - - // Returns true if the specified point(BrowserView coordinates) is in - // in the window caption area of the browser window. - virtual bool IsPositionInWindowCaption(const gfx::Point& point); - - // Tests to see if the specified |point| (in nonclient view's coordinates) - // is within the views managed by the laymanager. Returns one of - // HitTestCompat enum defined in views/window/hit_test.h. - // See also ClientView::NonClientHitTest. - virtual int NonClientHitTest(const gfx::Point& point); - - // views::LayoutManager overrides: - virtual void Installed(views::View* host); - virtual void Uninstalled(views::View* host); - virtual void ViewAdded(views::View* host, views::View* view); - virtual void ViewRemoved(views::View* host, views::View* view); - virtual void Layout(views::View* host); - virtual gfx::Size GetPreferredSize(views::View* host); - - protected: - Browser* browser(); - const Browser* browser() const; - - // Layout the TabStrip, returns the coordinate of the bottom of the TabStrip, - // for laying out subsequent controls. - virtual int LayoutTabStrip(); - - // Layout the following controls, starting at |top|, returns the coordinate - // of the bottom of the control, for laying out the next control. - virtual int LayoutToolbar(int top); - int LayoutBookmarkAndInfoBars(int top); - int LayoutBookmarkBar(int top); - int LayoutInfoBar(int top); - - // Layout the TabContents container, between the coordinates |top| and - // |bottom|. - void LayoutTabContents(int top, int bottom); - - // Returns the top margin to adjust the contents_container_ by. This is used - // to make the bookmark bar and contents_container_ overlap so that the - // preview contents hides the bookmark bar. - int GetTopMarginForActiveContent(); - - // Layout the Download Shelf, returns the coordinate of the top of the - // control, for laying out the previous control. - int LayoutDownloadShelf(int bottom); - - // Returns true if an infobar is showing. - bool InfobarVisible() const; - - // See description above vertical_layout_rect_ for details. - void set_vertical_layout_rect(const gfx::Rect& bounds) { - vertical_layout_rect_ = bounds; - } - const gfx::Rect& vertical_layout_rect() const { - return vertical_layout_rect_; - } - - // Child views that the layout manager manages. - BaseTabStrip* tabstrip_; - ToolbarView* toolbar_; - views::View* contents_split_; - ContentsContainer* contents_container_; - views::View* infobar_container_; - DownloadShelfView* download_shelf_; - BookmarkBarView* active_bookmark_bar_; - - BrowserView* browser_view_; - - // The bounds within which the vertically-stacked contents of the BrowserView - // should be laid out within. When the SideTabstrip is not visible, this is - // just the local bounds of the BrowserView, otherwise it's the local bounds - // of the BrowserView less the width of the SideTabstrip. - gfx::Rect vertical_layout_rect_; - - // The distance the FindBar is from the top of the window, in pixels. - int find_bar_y_; - - DISALLOW_COPY_AND_ASSIGN(BrowserViewLayout); -}; +#include "chrome/browser/ui/views/frame/browser_view_layout.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ diff --git a/chrome/browser/views/frame/contents_container.cc b/chrome/browser/views/frame/contents_container.cc deleted file mode 100644 index fd80e3b..0000000 --- a/chrome/browser/views/frame/contents_container.cc +++ /dev/null @@ -1,200 +0,0 @@ -// 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/contents_container.h" - -#include "app/resource_bundle.h" -#include "chrome/browser/location_bar.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "grit/theme_resources.h" -#include "views/controls/image_view.h" -#include "views/widget/root_view.h" - -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#elif defined(OS_LINUX) -#include "chrome/browser/gtk/gtk_util.h" -#include "views/window/window_gtk.h" -#endif - -#if defined(OS_WIN) - -class ContentsContainer::TearWindow : public views::WidgetWin { - public: - explicit TearWindow(ContentsContainer* contents_container) - : contents_container_(contents_container) { - set_window_style(WS_POPUP | WS_CLIPCHILDREN); - set_window_ex_style(WS_EX_TOOLWINDOW | WS_EX_LAYERED); - } - - virtual ~TearWindow() { - // On windows it's possible for us to be deleted before the - // ContentsContainer. If this happens make sure contents_container_ doesn't - // attempt to delete us too. - if (contents_container_) - contents_container_->TearWindowDestroyed(); - } - - void set_contents_container(ContentsContainer* contents_container) { - contents_container_ = contents_container; - } - - virtual LRESULT OnMouseActivate(HWND window, - UINT hit_test, - UINT mouse_message) { - // Don't activate the window when the user clicks it. - contents_container_->browser_view_->GetLocationBar()->Revert(); - return MA_NOACTIVATE; - } - - private: - ContentsContainer* contents_container_; - - DISALLOW_COPY_AND_ASSIGN(TearWindow); -}; - -#endif - -ContentsContainer::ContentsContainer(BrowserView* browser_view, - views::View* active) - : browser_view_(browser_view), - active_(active), - preview_(NULL), - preview_tab_contents_(NULL), - tear_window_(NULL), - active_top_margin_(0) { - AddChildView(active_); -} - -ContentsContainer::~ContentsContainer() { - DeleteTearWindow(); -} - -void ContentsContainer::MakePreviewContentsActiveContents() { - active_ = preview_; - preview_ = NULL; - DeleteTearWindow(); - Layout(); -} - -void ContentsContainer::SetPreview(views::View* preview, - TabContents* preview_tab_contents) { - if (preview == preview_) - return; - - if (preview_) { - RemoveChildView(preview_); - DeleteTearWindow(); - } - preview_ = preview; - preview_tab_contents_ = preview_tab_contents; - if (preview_) { - AddChildView(preview_); - CreateTearWindow(); - } - - Layout(); - - if (preview_) - tear_window_->Show(); // Show after we'ved positioned it in Layout. -} - -void ContentsContainer::SetActiveTopMargin(int margin) { - if (active_top_margin_ == margin) - return; - - active_top_margin_ = margin; - // Make sure we layout next time around. We need this in case our bounds - // haven't changed. - InvalidateLayout(); -} - -gfx::Rect ContentsContainer::GetPreviewBounds() { - gfx::Point screen_loc; - ConvertPointToScreen(this, &screen_loc); - return gfx::Rect(screen_loc, size()); -} - -void ContentsContainer::Layout() { - // The active view always gets the full bounds. - active_->SetBounds(0, active_top_margin_, width(), - std::max(0, height() - active_top_margin_)); - - if (preview_) { - preview_->SetBounds(0, 0, width(), height()); - PositionTearWindow(); - } - - // Need to invoke views::View in case any views whose bounds didn't change - // still need a layout. - views::View::Layout(); -} - -void ContentsContainer::CreateTearWindow() { - DCHECK(preview_); - tear_window_ = CreateTearWindowImpl(); - - views::ImageView* image_view = new views::ImageView(); - image_view->SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_MATCH_PREVIEW_TEAR)); - tear_window_->SetContentsView(image_view); -} - -#if defined(OS_WIN) - -ContentsContainer::TearWindow* ContentsContainer::CreateTearWindowImpl() { - TearWindow* widget = new TearWindow(this); - widget->Init(browser_view_->GetNativeHandle(), gfx::Rect()); - return widget; -} - -#elif defined(OS_LINUX) - -ContentsContainer::TearWindow* ContentsContainer::CreateTearWindowImpl() { - views::WidgetGtk* widget = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); - widget->MakeTransparent(); - widget->Init(NULL, gfx::Rect()); - gtk_util::StackPopupWindow(widget->GetNativeView(), - GTK_WIDGET(browser_view_->GetNativeHandle())); - return widget; -} - -#endif - -void ContentsContainer::PositionTearWindow() { - if (!tear_window_) - return; - - gfx::Rect vis_bounds = GetVisibleBounds(); - - gfx::Size pref = tear_window_->GetRootView()->GetPreferredSize(); - // Constrain to the the visible bounds as we may be given a different size - // than is actually visible. - pref.SetSize(std::min(pref.width(), vis_bounds.width()), - std::min(pref.height(), vis_bounds.height())); - - gfx::Rect bounds(0, 0, pref.width(), pref.height()); - bounds.set_x(MirroredLeftPointForRect(bounds)); - - gfx::Point origin(bounds.origin()); - views::View::ConvertPointToScreen(this, &origin); - - tear_window_->SetBounds(gfx::Rect(origin, pref)); -} - -void ContentsContainer::DeleteTearWindow() { - if (!tear_window_) - return; - - tear_window_->Close(); -#if defined(OS_WIN) - tear_window_->set_contents_container(NULL); -#endif - // Close deletes the tear window. - tear_window_ = NULL; -} - -void ContentsContainer::TearWindowDestroyed() { - tear_window_ = NULL; -} diff --git a/chrome/browser/views/frame/contents_container.h b/chrome/browser/views/frame/contents_container.h index fe22d47..07b7983 100644 --- a/chrome/browser/views/frame/contents_container.h +++ b/chrome/browser/views/frame/contents_container.h @@ -6,81 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_CONTENTS_CONTAINER_H_ #pragma once -#include "views/view.h" - -class BrowserView; -class TabContents; - -namespace views { -class Widget; -} - -// ContentsContainer is responsible for managing the TabContents views. -// ContentsContainer has up to two children: one for the currently active -// TabContents and one for instant's TabContents. -class ContentsContainer : public views::View { - public: - ContentsContainer(BrowserView* browser_view, views::View* active); - virtual ~ContentsContainer(); - - // Makes the preview view the active view and nulls out the old active view. - // It's assumed the caller will delete or remove the old active view - // separately. - void MakePreviewContentsActiveContents(); - - // Sets the preview view. This does not delete the old. - void SetPreview(views::View* preview, TabContents* preview_tab_contents); - - TabContents* preview_tab_contents() const { return preview_tab_contents_; } - - // Sets the active top margin. - void SetActiveTopMargin(int margin); - - // Returns the bounds of the preview. If the preview isn't active this - // retuns the bounds the preview would be shown at. - gfx::Rect GetPreviewBounds(); - - // View overrides: - virtual void Layout(); - - private: -#if defined(OS_WIN) - class TearWindow; -#else - typedef views::Widget TearWindow; -#endif - - // Creates and configures the tear window. - void CreateTearWindow(); - - // Creates and returns a new TearWindow. - TearWindow* CreateTearWindowImpl(); - - // Resets the bounds of the tear window. - void PositionTearWindow(); - - // Closes and deletes the tear window. - void DeleteTearWindow(); - - // Invoked when the tear window is destroyed. - void TearWindowDestroyed(); - - BrowserView* browser_view_; - - views::View* active_; - - views::View* preview_; - - TabContents* preview_tab_contents_; - - // Window used to show the page tear. - TearWindow* tear_window_; - - // The margin between the top and the active view. This is used to make the - // preview overlap the bookmark bar on the new tab page. - int active_top_margin_; - - DISALLOW_COPY_AND_ASSIGN(ContentsContainer); -}; +#include "chrome/browser/ui/views/frame/contents_container.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_CONTENTS_CONTAINER_H_ + diff --git a/chrome/browser/views/frame/glass_browser_frame_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc deleted file mode 100644 index fdc1956..0000000 --- a/chrome/browser/views/frame/glass_browser_frame_view.cc +++ /dev/null @@ -1,511 +0,0 @@ -// 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/glass_browser_frame_view.h" - -#include "app/resource_bundle.h" -#include "app/theme_provider.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/tabs/side_tab_strip.h" -#include "chrome/browser/views/tabs/tab.h" -#include "chrome/browser/views/tabs/tab_strip.h" -#include "gfx/canvas_skia.h" -#include "gfx/icon_util.h" -#include "grit/app_resources.h" -#include "grit/theme_resources.h" -#include "views/window/client_view.h" -#include "views/window/window_resources.h" - -HICON GlassBrowserFrameView::throbber_icons_[ - GlassBrowserFrameView::kThrobberIconCount]; - -namespace { -// There are 3 px of client edge drawn inside the outer frame borders. -const int kNonClientBorderThickness = 3; -// Vertical tabs have 4 px border. -const int kNonClientVerticalTabStripBorderThickness = 4; -// Besides the frame border, there's another 11 px of empty space atop the -// window in restored mode, to use to drag the window around. -const int kNonClientRestoredExtraThickness = 11; -// In the window corners, the resize areas don't actually expand bigger, but the -// 16 px at the end of the top and bottom edges triggers diagonal resizing. -const int kResizeAreaCornerSize = 16; -// The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the -// way the tabstrip draws its bottom edge, will appear like a 1 px gap to the -// user). -const int kOTRBottomSpacing = 2; -// There are 2 px on each side of the OTR avatar (between the frame border and -// it on the left, and between it and the tabstrip on the right). -const int kOTRSideSpacing = 2; -// The content left/right images have a shadow built into them. -const int kContentEdgeShadowThickness = 2; -// The top 1 px of the tabstrip is shadow; in maximized mode we push this off -// the top of the screen so the tabs appear flush against the screen edge. -const int kTabstripTopShadowThickness = 1; -// In restored mode, the New Tab button isn't at the same height as the caption -// buttons, but the space will look cluttered if it actually slides under them, -// so we stop it when the gap between the two is down to 5 px. -const int kNewTabCaptionRestoredSpacing = 5; -// In maximized mode, where the New Tab button and the caption buttons are at -// similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid -// looking too cluttered. -const int kNewTabCaptionMaximizedSpacing = 16; -} - -/////////////////////////////////////////////////////////////////////////////// -// GlassBrowserFrameView, public: - -GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, - BrowserView* browser_view) - : BrowserNonClientFrameView(), - frame_(frame), - browser_view_(browser_view), - throbber_running_(false), - throbber_frame_(0) { - if (frame_->GetWindow()->GetDelegate()->ShouldShowWindowIcon()) - InitThrobberIcons(); -} - -GlassBrowserFrameView::~GlassBrowserFrameView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// GlassBrowserFrameView, BrowserNonClientFrameView implementation: - -gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( - BaseTabStrip* tabstrip) const { - if (browser_view_->UseVerticalTabs()) { - gfx::Size ps = tabstrip->GetPreferredSize(); - return gfx::Rect(NonClientBorderThickness(), - NonClientTopBorderHeight(false, false), ps.width(), - browser_view_->height()); - } - int minimize_button_offset = frame_->GetMinimizeButtonOffset(); - int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? - (otr_avatar_bounds_.right() + kOTRSideSpacing) : - NonClientBorderThickness(); - // In RTL languages, we have moved an avatar icon left by the size of window - // controls to prevent it from being rendered over them. So, we use its x - // position to move this tab strip left when maximized. Also, we can render - // a tab strip until the left end of this window without considering the size - // of window controls in RTL languages. - if (base::i18n::IsRTL()) { - if (!browser_view_->ShouldShowOffTheRecordAvatar() && - frame_->GetWindow()->IsMaximized()) - tabstrip_x += otr_avatar_bounds_.x(); - minimize_button_offset = width(); - } - int tabstrip_width = minimize_button_offset - tabstrip_x - - (frame_->GetWindow()->IsMaximized() ? - kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); - return gfx::Rect(tabstrip_x, GetHorizontalTabStripVerticalOffset(false), - std::max(0, tabstrip_width), - tabstrip->GetPreferredHeight()); -} - -int GlassBrowserFrameView::GetHorizontalTabStripVerticalOffset( - bool restored) const { - return NonClientTopBorderHeight(restored, true); -} - -void GlassBrowserFrameView::UpdateThrobber(bool running) { - if (throbber_running_) { - if (running) { - DisplayNextThrobberFrame(); - } else { - StopThrobber(); - } - } else if (running) { - StartThrobber(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// GlassBrowserFrameView, views::NonClientFrameView implementation: - -gfx::Rect GlassBrowserFrameView::GetBoundsForClientView() const { - return client_view_bounds_; -} - -bool GlassBrowserFrameView::AlwaysUseNativeFrame() const { - return frame_->AlwaysUseNativeFrame(); -} - -gfx::Rect GlassBrowserFrameView::GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const { - HWND hwnd = frame_->GetWindow()->GetNativeWindow(); - if (!browser_view_->IsTabStripVisible() && hwnd) { - // If we don't have a tabstrip, we're either a popup or an app window, in - // which case we have a standard size non-client area and can just use - // AdjustWindowRectEx to obtain it. We check for a non-NULL window handle in - // case this gets called before the window is actually created. - RECT rect = client_bounds.ToRECT(); - AdjustWindowRectEx(&rect, GetWindowLong(hwnd, GWL_STYLE), FALSE, - GetWindowLong(hwnd, GWL_EXSTYLE)); - return gfx::Rect(rect); - } - - int top_height = NonClientTopBorderHeight(false, false); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), - std::max(0, client_bounds.y() - top_height), - client_bounds.width() + (2 * border_thickness), - client_bounds.height() + top_height + border_thickness); -} - -int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { - // If the browser isn't in normal mode, we haven't customized the frame, so - // Windows can figure this out. If the point isn't within our bounds, then - // it's in the native portion of the frame, so again Windows can figure it - // out. - if (!browser_view_->IsBrowserTypeNormal() || !bounds().Contains(point)) - return HTNOWHERE; - - int frame_component = - frame_->GetWindow()->GetClientView()->NonClientHitTest(point); - - // See if we're in the sysmenu region. We still have to check the tabstrip - // first so that clicks in a tab don't get treated as sysmenu clicks. - int nonclient_border_thickness = NonClientBorderThickness(); - if (gfx::Rect(nonclient_border_thickness, GetSystemMetrics(SM_CXSIZEFRAME), - GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON)).Contains(point)) - return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; - - if (frame_component != HTNOWHERE) - return frame_component; - - int frame_border_thickness = FrameBorderThickness(); - int window_component = GetHTComponentForFrame(point, frame_border_thickness, - nonclient_border_thickness, frame_border_thickness, - kResizeAreaCornerSize - frame_border_thickness, - frame_->GetWindow()->GetDelegate()->CanResize()); - // Fall back to the caption if no other component matches. - return (window_component == HTNOWHERE) ? HTCAPTION : window_component; -} - -/////////////////////////////////////////////////////////////////////////////// -// GlassBrowserFrameView, views::View overrides: - -void GlassBrowserFrameView::Paint(gfx::Canvas* canvas) { - if (!browser_view_->IsTabStripVisible()) - return; // Nothing is visible, so don't bother to paint. - - PaintToolbarBackground(canvas); - if (browser_view_->ShouldShowOffTheRecordAvatar()) - PaintOTRAvatar(canvas); - if (!frame_->GetWindow()->IsMaximized()) - PaintRestoredClientEdge(canvas); -} - -void GlassBrowserFrameView::Layout() { - LayoutOTRAvatar(); - LayoutClientView(); -} - -/////////////////////////////////////////////////////////////////////////////// -// GlassBrowserFrameView, private: - -int GlassBrowserFrameView::FrameBorderThickness() const { - views::Window* window = frame_->GetWindow(); - return (window->IsMaximized() || window->IsFullscreen()) ? - 0 : GetSystemMetrics(SM_CXSIZEFRAME); -} - -int GlassBrowserFrameView::NonClientBorderThickness() const { - views::Window* window = frame_->GetWindow(); - if (window->IsMaximized() || window->IsFullscreen()) - return 0; - - return browser_view_->UseVerticalTabs() ? - kNonClientVerticalTabStripBorderThickness : - kNonClientBorderThickness; -} - -int GlassBrowserFrameView::NonClientTopBorderHeight( - bool restored, - bool ignore_vertical_tabs) const { - if (!restored && frame_->GetWindow()->IsFullscreen()) - return 0; - // We'd like to use FrameBorderThickness() here, but the maximized Aero glass - // frame has a 0 frame border around most edges and a CYSIZEFRAME-thick border - // at the top (see AeroGlassFrame::OnGetMinMaxInfo()). - if (browser_view_->IsTabStripVisible() && !ignore_vertical_tabs && - browser_view_->UseVerticalTabs()) - return GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION); - return GetSystemMetrics(SM_CYSIZEFRAME) + - ((!restored && browser_view_->IsMaximized()) ? - -kTabstripTopShadowThickness : kNonClientRestoredExtraThickness); -} - -void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { - ThemeProvider* tp = GetThemeProvider(); - - gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds()); - gfx::Point toolbar_origin(toolbar_bounds.origin()); - View::ConvertPointToView(browser_view_, this, &toolbar_origin); - toolbar_bounds.set_origin(toolbar_origin); - int x = toolbar_bounds.x(); - int w = toolbar_bounds.width(); - int left_x = x - kContentEdgeShadowThickness; - - SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR); - SkBitmap* toolbar_left = tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER); - SkBitmap* toolbar_center = tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER); - - if (browser_view_->UseVerticalTabs()) { - gfx::Point tabstrip_origin(browser_view_->tabstrip()->bounds().origin()); - View::ConvertPointToView(browser_view_, this, &tabstrip_origin); - int y = tabstrip_origin.y(); - - // Tile the toolbar image starting at the frame edge on the left and where - // the horizontal tabstrip would be on the top. - canvas->TileImageInt(*theme_toolbar, x, - y - GetHorizontalTabStripVerticalOffset(false), x, y, - w, theme_toolbar->height()); - - // Draw left edge. - int dest_y = y - kNonClientBorderThickness; - canvas->DrawBitmapInt(*toolbar_left, 0, 0, kNonClientBorderThickness, - kNonClientBorderThickness, left_x, dest_y, - kNonClientBorderThickness, kNonClientBorderThickness, - false); - - // Draw center edge. We need to draw a while line above the toolbar for the - // image to overlay nicely. - int center_offset = - -kContentEdgeShadowThickness + kNonClientBorderThickness; - canvas->FillRectInt(SK_ColorWHITE, x + center_offset, y - 1, - w - (2 * center_offset), 1); - canvas->TileImageInt(*toolbar_center, x + center_offset, dest_y, - w - (2 * center_offset), toolbar_center->height()); - - // Right edge. - SkBitmap* toolbar_right = tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER); - canvas->DrawBitmapInt(*toolbar_right, - toolbar_right->width() - kNonClientBorderThickness, 0, - kNonClientBorderThickness, kNonClientBorderThickness, - x + w - center_offset, dest_y, kNonClientBorderThickness, - kNonClientBorderThickness, false); - } else { - // Tile the toolbar image starting at the frame edge on the left and where - // the tabstrip is on the top. - int y = toolbar_bounds.y(); - int dest_y = y + (kFrameShadowThickness * 2); - canvas->TileImageInt(*theme_toolbar, x, - dest_y - GetHorizontalTabStripVerticalOffset(false), x, - dest_y, w, theme_toolbar->height()); - - // Draw rounded corners for the tab. - SkBitmap* toolbar_left_mask = - tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK); - SkBitmap* toolbar_right_mask = - tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK); - - // We mask out the corners by using the DestinationIn transfer mode, - // which keeps the RGB pixels from the destination and the alpha from - // the source. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kDstIn_Mode); - - // Mask out the top left corner. - canvas->DrawBitmapInt(*toolbar_left_mask, left_x, y, paint); - - // Mask out the top right corner. - int right_x = - x + w + kContentEdgeShadowThickness - toolbar_right_mask->width(); - canvas->DrawBitmapInt(*toolbar_right_mask, right_x, y, paint); - - // Draw left edge. - canvas->DrawBitmapInt(*toolbar_left, left_x, y); - - // Draw center edge. - canvas->TileImageInt(*toolbar_center, left_x + toolbar_left->width(), y, - right_x - (left_x + toolbar_left->width()), toolbar_center->height()); - - // Right edge. - canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER), - right_x, y); - } - - // Draw the content/toolbar separator. - canvas->FillRectInt(ResourceBundle::toolbar_separator_color, - x + kClientEdgeThickness, toolbar_bounds.bottom() - kClientEdgeThickness, - w - (2 * kClientEdgeThickness), kClientEdgeThickness); -} - -void GlassBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { - // In RTL mode, the avatar icon should be looking the opposite direction. - canvas->Save(); - if (base::i18n::IsRTL()) { - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } - - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int w = otr_avatar_bounds_.width(); - int h = otr_avatar_bounds_.height(); - canvas->DrawBitmapInt(otr_avatar_icon, 0, - // Bias the rounding to select a region that's lower rather than higher, - // as the shadows at the image top mean the apparent center is below the - // real center. - ((otr_avatar_icon.height() - otr_avatar_bounds_.height()) + 1) / 2, w, h, - otr_avatar_bounds_.x(), otr_avatar_bounds_.y(), w, h, false); - - canvas->Restore(); -} - -void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { - ThemeProvider* tp = GetThemeProvider(); - gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); - - // The client edges start below the toolbar upper corner images regardless - // of how tall the toolbar itself is. - int client_area_top = browser_view_->UseVerticalTabs() ? - client_area_bounds.y() : - (frame_->GetWindow()->GetClientView()->y() + - browser_view_->GetToolbarBounds().y() + - tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height()); - int client_area_bottom = - std::max(client_area_top, height() - NonClientBorderThickness()); - int client_area_height = client_area_bottom - client_area_top; - - // Draw the client edge images. - SkBitmap* right = tp->GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE); - canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, - right->width(), client_area_height); - canvas->DrawBitmapInt( - *tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER), - client_area_bounds.right(), client_area_bottom); - SkBitmap* bottom = tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER); - canvas->TileImageInt(*bottom, client_area_bounds.x(), - client_area_bottom, client_area_bounds.width(), - bottom->height()); - SkBitmap* bottom_left = - tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER); - canvas->DrawBitmapInt(*bottom_left, - client_area_bounds.x() - bottom_left->width(), client_area_bottom); - SkBitmap* left = tp->GetBitmapNamed(IDR_CONTENT_LEFT_SIDE); - canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), - client_area_top, left->width(), client_area_height); - - // Draw the toolbar color so that the client edges show the right color even - // where not covered by the toolbar image. NOTE: We do this after drawing the - // images because the images are meant to alpha-blend atop the frame whereas - // these rects are meant to be fully opaque, without anything overlaid. - SkColor toolbar_color = tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); - canvas->FillRectInt(toolbar_color, - client_area_bounds.x() - kClientEdgeThickness, client_area_top, - kClientEdgeThickness, - client_area_bottom + kClientEdgeThickness - client_area_top); - canvas->FillRectInt(toolbar_color, client_area_bounds.x(), client_area_bottom, - client_area_bounds.width(), kClientEdgeThickness); - canvas->FillRectInt(toolbar_color, client_area_bounds.right(), - client_area_top, kClientEdgeThickness, - client_area_bottom + kClientEdgeThickness - client_area_top); -} - -void GlassBrowserFrameView::LayoutOTRAvatar() { - int otr_x = NonClientBorderThickness() + kOTRSideSpacing; - // Move this avatar icon by the size of window controls to prevent it from - // being rendered over them in RTL languages. This code also needs to adjust - // the width of a tab strip to avoid decreasing this size twice. (See the - // comment in GetBoundsForTabStrip().) - if (base::i18n::IsRTL()) - otr_x += width() - frame_->GetMinimizeButtonOffset(); - - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int otr_bottom, otr_restored_y; - if (browser_view_->UseVerticalTabs()) { - otr_bottom = NonClientTopBorderHeight(false, false) - kOTRBottomSpacing; - otr_restored_y = kFrameShadowThickness; - } else { - otr_bottom = GetHorizontalTabStripVerticalOffset(false) + - browser_view_->GetTabStripHeight() - kOTRBottomSpacing; - otr_restored_y = otr_bottom - otr_avatar_icon.height(); - } - int otr_y = frame_->GetWindow()->IsMaximized() ? - (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : - otr_restored_y; - otr_avatar_bounds_.SetRect(otr_x, otr_y, otr_avatar_icon.width(), - browser_view_->ShouldShowOffTheRecordAvatar() ? (otr_bottom - otr_y) : 0); -} - -void GlassBrowserFrameView::LayoutClientView() { - client_view_bounds_ = CalculateClientAreaBounds(width(), height()); -} - -gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds(int width, - int height) const { - if (!browser_view_->IsTabStripVisible()) - return gfx::Rect(0, 0, this->width(), this->height()); - - int top_height = NonClientTopBorderHeight(false, false); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(border_thickness, top_height, - std::max(0, width - (2 * border_thickness)), - std::max(0, height - top_height - border_thickness)); -} - -void GlassBrowserFrameView::StartThrobber() { - if (!throbber_running_) { - throbber_running_ = true; - throbber_frame_ = 0; - InitThrobberIcons(); - SendMessage(frame_->GetWindow()->GetNativeWindow(), WM_SETICON, - static_cast<WPARAM>(ICON_SMALL), - reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); - } -} - -void GlassBrowserFrameView::StopThrobber() { - if (throbber_running_) { - throbber_running_ = false; - - HICON frame_icon = NULL; - - // Check if hosted BrowserView has a window icon to use. - if (browser_view_->ShouldShowWindowIcon()) { - SkBitmap icon = browser_view_->GetWindowIcon(); - if (!icon.isNull()) - frame_icon = IconUtil::CreateHICONFromSkBitmap(icon); - } - - // Fallback to class icon. - if (!frame_icon) { - frame_icon = reinterpret_cast<HICON>(GetClassLongPtr( - frame_->GetWindow()->GetNativeWindow(), GCLP_HICONSM)); - } - - // This will reset the small icon which we set in the throbber code. - // WM_SETICON with NULL icon restores the icon for title bar but not - // for taskbar. See http://crbug.com/29996 - SendMessage(frame_->GetWindow()->GetNativeWindow(), WM_SETICON, - static_cast<WPARAM>(ICON_SMALL), - reinterpret_cast<LPARAM>(frame_icon)); - } -} - -void GlassBrowserFrameView::DisplayNextThrobberFrame() { - throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; - SendMessage(frame_->GetWindow()->GetNativeWindow(), WM_SETICON, - static_cast<WPARAM>(ICON_SMALL), - reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); -} - -// static -void GlassBrowserFrameView::InitThrobberIcons() { - static bool initialized = false; - if (!initialized) { - ResourceBundle &rb = ResourceBundle::GetSharedInstance(); - for (int i = 0; i < kThrobberIconCount; ++i) { - throbber_icons_[i] = rb.LoadThemeIcon(IDI_THROBBER_01 + i); - DCHECK(throbber_icons_[i]); - } - initialized = true; - } -} diff --git a/chrome/browser/views/frame/glass_browser_frame_view.h b/chrome/browser/views/frame/glass_browser_frame_view.h index 0a39da1..397ef26 100644 --- a/chrome/browser/views/frame/glass_browser_frame_view.h +++ b/chrome/browser/views/frame/glass_browser_frame_view.h @@ -6,98 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_GLASS_BROWSER_FRAME_VIEW_H_ #pragma once -#include "chrome/browser/views/frame/browser_frame_win.h" -#include "chrome/browser/views/frame/browser_non_client_frame_view.h" -#include "views/controls/button/button.h" -#include "views/window/non_client_view.h" - -class BrowserView; -class SkBitmap; - -class GlassBrowserFrameView : public BrowserNonClientFrameView { - public: - // Constructs a non-client view for an BrowserFrame. - GlassBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view); - virtual ~GlassBrowserFrameView(); - - // Overridden from BrowserNonClientFrameView: - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const; - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const; - virtual void UpdateThrobber(bool running); - - // Overridden from views::NonClientFrameView: - virtual gfx::Rect GetBoundsForClientView() const; - virtual bool AlwaysUseNativeFrame() const; - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) { } - virtual void EnableClose(bool enable) { } - virtual void ResetWindowControls() { } - - protected: - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - - private: - // Returns the thickness of the border that makes up the window frame edges. - // This does not include any client edge. - int FrameBorderThickness() const; - - // Returns the thickness of the entire nonclient left, right, and bottom - // borders, including both the window frame and any client edge. - int NonClientBorderThickness() const; - - // Returns the height of the entire nonclient top border, including the window - // frame, any title area, and any connected client edge. If |restored| is - // true, acts as if the window is restored regardless of the real mode. If - // |ignore_vertical_tabs| is true, acts as if vertical tabs are off regardless - // of the real state. - int NonClientTopBorderHeight(bool restored, bool ignore_vertical_tabs) const; - - // Paint various sub-components of this view. - void PaintToolbarBackground(gfx::Canvas* canvas); - void PaintOTRAvatar(gfx::Canvas* canvas); - void PaintRestoredClientEdge(gfx::Canvas* canvas); - - // Layout various sub-components of this view. - void LayoutOTRAvatar(); - void LayoutClientView(); - - // Returns the bounds of the client area for the specified view size. - gfx::Rect CalculateClientAreaBounds(int width, int height) const; - - // Starts/Stops the window throbber running. - void StartThrobber(); - void StopThrobber(); - - // Displays the next throbber frame. - void DisplayNextThrobberFrame(); - - // The layout rect of the OTR avatar icon, if visible. - gfx::Rect otr_avatar_bounds_; - - // The frame that hosts this view. - BrowserFrame* frame_; - - // The BrowserView hosted within this View. - BrowserView* browser_view_; - - // The bounds of the ClientView. - gfx::Rect client_view_bounds_; - - // Whether or not the window throbber is currently animating. - bool throbber_running_; - - // The index of the current frame of the throbber animation. - int throbber_frame_; - - static const int kThrobberIconCount = 24; - static HICON throbber_icons_[kThrobberIconCount]; - static void InitThrobberIcons(); - - DISALLOW_COPY_AND_ASSIGN(GlassBrowserFrameView); -}; +#include "chrome/browser/ui/views/frame/glass_browser_frame_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_GLASS_BROWSER_FRAME_VIEW_H_ + diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc deleted file mode 100644 index 94d0ffa..0000000 --- a/chrome/browser/views/frame/opaque_browser_frame_view.cc +++ /dev/null @@ -1,1031 +0,0 @@ -// 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/opaque_browser_frame_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/theme_provider.h" -#include "base/compiler_specific.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/tabs/tab_strip.h" -#include "chrome/browser/views/toolbar_view.h" -#include "gfx/canvas_skia.h" -#include "gfx/font.h" -#include "gfx/path.h" -#include "grit/app_resources.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/image_button.h" -#include "views/controls/image_view.h" -#include "views/widget/root_view.h" -#include "views/window/window.h" -#include "views/window/window_resources.h" -#include "views/window/window_shape.h" - -#if defined(OS_LINUX) -#include "views/window/hit_test.h" -#endif - -namespace { -// The frame border is only visible in restored mode and is hardcoded to 4 px on -// each side regardless of the system window border size. -const int kFrameBorderThickness = 4; -// Besides the frame border, there's another 11 px of empty space atop the -// window in restored mode, to use to drag the window around. -const int kNonClientRestoredExtraThickness = 11; -// While resize areas on Windows are normally the same size as the window -// borders, our top area is shrunk by 1 px to make it easier to move the window -// around with our thinner top grabbable strip. (Incidentally, our side and -// bottom resize areas don't match the frame border thickness either -- they -// span the whole nonclient area, so there's no "dead zone" for the mouse.) -const int kTopResizeAdjust = 1; -// In the window corners, the resize areas don't actually expand bigger, but the -// 16 px at the end of each edge triggers diagonal resizing. -const int kResizeAreaCornerSize = 16; -// The titlebar never shrinks too short to show the caption button plus some -// padding below it. -const int kCaptionButtonHeightWithPadding = 19; -// The content left/right images have a shadow built into them. -const int kContentEdgeShadowThickness = 2; -// The titlebar has a 2 px 3D edge along the top and bottom. -const int kTitlebarTopAndBottomEdgeThickness = 2; -// The icon is inset 2 px from the left frame border. -const int kIconLeftSpacing = 2; -// The icon never shrinks below 16 px on a side. -const int kIconMinimumSize = 16; -// There is a 4 px gap between the icon and the title text. -const int kIconTitleSpacing = 4; -// There is a 5 px gap between the title text and the caption buttons. -const int kTitleLogoSpacing = 5; -// The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the -// way the tabstrip draws its bottom edge, will appear like a 1 px gap to the -// user). -const int kOTRBottomSpacing = 2; -// There are 2 px on each side of the OTR avatar (between the frame border and -// it on the left, and between it and the tabstrip on the right). -const int kOTRSideSpacing = 2; -// The top 1 px of the tabstrip is shadow; in maximized mode we push this off -// the top of the screen so the tabs appear flush against the screen edge. -const int kTabstripTopShadowThickness = 1; -// In restored mode, the New Tab button isn't at the same height as the caption -// buttons, but the space will look cluttered if it actually slides under them, -// so we stop it when the gap between the two is down to 5 px. -const int kNewTabCaptionRestoredSpacing = 5; -// In maximized mode, where the New Tab button and the caption buttons are at -// similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid -// looking too cluttered. -const int kNewTabCaptionMaximizedSpacing = 16; -// How far to indent the tabstrip from the left side of the screen when there -// is no OTR icon. -const int kTabStripIndent = 1; -// Inset from the top of the toolbar/tabstrip to the shadow. Used only for -// vertical tabs. -const int kVerticalTabBorderInset = 3; -} - -/////////////////////////////////////////////////////////////////////////////// -// OpaqueBrowserFrameView, public: - -OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame, - BrowserView* browser_view) - : BrowserNonClientFrameView(), - ALLOW_THIS_IN_INITIALIZER_LIST( - minimize_button_(new views::ImageButton(this))), - ALLOW_THIS_IN_INITIALIZER_LIST( - maximize_button_(new views::ImageButton(this))), - ALLOW_THIS_IN_INITIALIZER_LIST( - restore_button_(new views::ImageButton(this))), - ALLOW_THIS_IN_INITIALIZER_LIST( - close_button_(new views::ImageButton(this))), - window_icon_(NULL), - frame_(frame), - browser_view_(browser_view) { - ThemeProvider* tp = frame_->GetThemeProviderForFrame(); - SkColor color = tp->GetColor(BrowserThemeProvider::COLOR_BUTTON_BACKGROUND); - SkBitmap* background = - tp->GetBitmapNamed(IDR_THEME_WINDOW_CONTROL_BACKGROUND); - minimize_button_->SetImage(views::CustomButton::BS_NORMAL, - tp->GetBitmapNamed(IDR_MINIMIZE)); - minimize_button_->SetImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_MINIMIZE_H)); - minimize_button_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_MINIMIZE_P)); - if (browser_view_->IsBrowserTypeNormal()) { - minimize_button_->SetBackground(color, background, - tp->GetBitmapNamed(IDR_MINIMIZE_BUTTON_MASK)); - } - minimize_button_->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_MINIMIZE)); - AddChildView(minimize_button_); - - maximize_button_->SetImage(views::CustomButton::BS_NORMAL, - tp->GetBitmapNamed(IDR_MAXIMIZE)); - maximize_button_->SetImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_MAXIMIZE_H)); - maximize_button_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_MAXIMIZE_P)); - if (browser_view_->IsBrowserTypeNormal()) { - maximize_button_->SetBackground(color, background, - tp->GetBitmapNamed(IDR_MAXIMIZE_BUTTON_MASK)); - } - maximize_button_->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_MAXIMIZE)); - AddChildView(maximize_button_); - - restore_button_->SetImage(views::CustomButton::BS_NORMAL, - tp->GetBitmapNamed(IDR_RESTORE)); - restore_button_->SetImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_RESTORE_H)); - restore_button_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_RESTORE_P)); - if (browser_view_->IsBrowserTypeNormal()) { - restore_button_->SetBackground(color, background, - tp->GetBitmapNamed(IDR_RESTORE_BUTTON_MASK)); - } - restore_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_RESTORE)); - AddChildView(restore_button_); - - close_button_->SetImage(views::CustomButton::BS_NORMAL, - tp->GetBitmapNamed(IDR_CLOSE)); - close_button_->SetImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_CLOSE_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_CLOSE_P)); - if (browser_view_->IsBrowserTypeNormal()) { - close_button_->SetBackground(color, background, - tp->GetBitmapNamed(IDR_CLOSE_BUTTON_MASK)); - } - close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); - AddChildView(close_button_); - - // Initializing the TabIconView is expensive, so only do it if we need to. - if (browser_view_->ShouldShowWindowIcon()) { - window_icon_ = new TabIconView(this); - window_icon_->set_is_light(true); - AddChildView(window_icon_); - window_icon_->Update(); - } -} - -OpaqueBrowserFrameView::~OpaqueBrowserFrameView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// OpaqueBrowserFrameView, BrowserNonClientFrameView implementation: - -gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip( - BaseTabStrip* tabstrip) const { - if (browser_view_->UseVerticalTabs()) { - gfx::Size ps = tabstrip->GetPreferredSize(); - return gfx::Rect(NonClientBorderThickness(), - NonClientTopBorderHeight(false, false), ps.width(), - browser_view_->height()); - } - - int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? - (otr_avatar_bounds_.right() + kOTRSideSpacing) : - NonClientBorderThickness() + kTabStripIndent; - - int tabstrip_width = minimize_button_->x() - tabstrip_x - - (frame_->GetWindow()->IsMaximized() ? - kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); - return gfx::Rect(tabstrip_x, GetHorizontalTabStripVerticalOffset(false), - std::max(0, tabstrip_width), tabstrip->GetPreferredHeight()); -} - -int OpaqueBrowserFrameView::GetHorizontalTabStripVerticalOffset( - bool restored) const { - return NonClientTopBorderHeight(restored, true) + ((!restored && - (frame_->GetWindow()->IsMaximized() || - frame_->GetWindow()->IsFullscreen())) ? - 0 : kNonClientRestoredExtraThickness); -} - -void OpaqueBrowserFrameView::UpdateThrobber(bool running) { - if (window_icon_) - window_icon_->Update(); -} - -gfx::Size OpaqueBrowserFrameView::GetMinimumSize() { - gfx::Size min_size(browser_view_->GetMinimumSize()); - int border_thickness = NonClientBorderThickness(); - min_size.Enlarge(2 * border_thickness, - NonClientTopBorderHeight(false, false) + border_thickness); - - views::WindowDelegate* d = frame_->GetWindow()->GetDelegate(); - int min_titlebar_width = (2 * FrameBorderThickness(false)) + - kIconLeftSpacing + - (d->ShouldShowWindowIcon() ? (IconSize() + kTitleLogoSpacing) : 0); -#if !defined(OS_CHROMEOS) - min_titlebar_width += - minimize_button_->GetMinimumSize().width() + - restore_button_->GetMinimumSize().width() + - close_button_->GetMinimumSize().width(); -#endif - min_size.set_width(std::max(min_size.width(), min_titlebar_width)); - return min_size; -} - -/////////////////////////////////////////////////////////////////////////////// -// OpaqueBrowserFrameView, views::NonClientFrameView implementation: - -gfx::Rect OpaqueBrowserFrameView::GetBoundsForClientView() const { - return client_view_bounds_; -} - -bool OpaqueBrowserFrameView::AlwaysUseNativeFrame() const { - return frame_->AlwaysUseNativeFrame(); -} - -bool OpaqueBrowserFrameView::AlwaysUseCustomFrame() const { - return true; -} - -gfx::Rect OpaqueBrowserFrameView::GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const { - int top_height = NonClientTopBorderHeight(false, false); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), - std::max(0, client_bounds.y() - top_height), - client_bounds.width() + (2 * border_thickness), - client_bounds.height() + top_height + border_thickness); -} - -int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) { - if (!bounds().Contains(point)) - return HTNOWHERE; - - int frame_component = - frame_->GetWindow()->GetClientView()->NonClientHitTest(point); - - // See if we're in the sysmenu region. We still have to check the tabstrip - // first so that clicks in a tab don't get treated as sysmenu clicks. - gfx::Rect sysmenu_rect(IconBounds()); - // In maximized mode we extend the rect to the screen corner to take advantage - // of Fitts' Law. - if (frame_->GetWindow()->IsMaximized()) - sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom()); - sysmenu_rect.set_x(MirroredLeftPointForRect(sysmenu_rect)); - if (sysmenu_rect.Contains(point)) - return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; - - if (frame_component != HTNOWHERE) - return frame_component; - - // Then see if the point is within any of the window controls. - if (close_button_->IsVisible() && - close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) - return HTCLOSE; - if (restore_button_->IsVisible() && - restore_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( - point)) - return HTMAXBUTTON; - if (maximize_button_->IsVisible() && - maximize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( - point)) - return HTMAXBUTTON; - if (minimize_button_->IsVisible() && - minimize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( - point)) - return HTMINBUTTON; - - int window_component = GetHTComponentForFrame(point, TopResizeHeight(), - NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, - frame_->GetWindow()->GetDelegate()->CanResize()); - // Fall back to the caption if no other component matches. - return (window_component == HTNOWHERE) ? HTCAPTION : window_component; -} - -void OpaqueBrowserFrameView::GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) { - DCHECK(window_mask); - - if (frame_->GetWindow()->IsMaximized() || frame_->GetWindow()->IsFullscreen()) - return; - - views::GetDefaultWindowMask(size, window_mask); -} - -void OpaqueBrowserFrameView::EnableClose(bool enable) { - close_button_->SetEnabled(enable); -} - -void OpaqueBrowserFrameView::ResetWindowControls() { - restore_button_->SetState(views::CustomButton::BS_NORMAL); - minimize_button_->SetState(views::CustomButton::BS_NORMAL); - maximize_button_->SetState(views::CustomButton::BS_NORMAL); - // The close button isn't affected by this constraint. -} - -/////////////////////////////////////////////////////////////////////////////// -// OpaqueBrowserFrameView, views::View overrides: - -void OpaqueBrowserFrameView::Paint(gfx::Canvas* canvas) { - views::Window* window = frame_->GetWindow(); - if (window->IsFullscreen()) - return; // Nothing is visible, so don't bother to paint. - - if (window->IsMaximized()) - PaintMaximizedFrameBorder(canvas); - else - PaintRestoredFrameBorder(canvas); - PaintTitleBar(canvas); - if (browser_view_->IsToolbarVisible()) - PaintToolbarBackground(canvas); - if (browser_view_->ShouldShowOffTheRecordAvatar()) - PaintOTRAvatar(canvas); - if (!window->IsMaximized()) - PaintRestoredClientEdge(canvas); -} - -void OpaqueBrowserFrameView::Layout() { - LayoutWindowControls(); - LayoutTitleBar(); - LayoutOTRAvatar(); - client_view_bounds_ = CalculateClientAreaBounds(width(), height()); -} - -bool OpaqueBrowserFrameView::HitTest(const gfx::Point& l) const { - // If the point is outside the bounds of the client area, claim it. - bool in_nonclient = NonClientFrameView::HitTest(l); - if (in_nonclient) - return in_nonclient; - - // Otherwise claim it only if it's in a non-tab portion of the tabstrip. - bool vertical_tabs = browser_view_->UseVerticalTabs(); - gfx::Rect tabstrip_bounds = browser_view_->tabstrip()->bounds(); - gfx::Point tabstrip_origin(tabstrip_bounds.origin()); - View::ConvertPointToView(frame_->GetWindow()->GetClientView(), - this, &tabstrip_origin); - tabstrip_bounds.set_origin(tabstrip_origin); - if ((!vertical_tabs && l.y() > tabstrip_bounds.bottom()) || - (vertical_tabs && l.x() > tabstrip_bounds.right())) { - return false; - } - - // We convert from our parent's coordinates since we assume we fill its bounds - // completely. We need to do this since we're not a parent of the tabstrip, - // meaning ConvertPointToView would otherwise return something bogus. - gfx::Point browser_view_point(l); - View::ConvertPointToView(GetParent(), browser_view_, &browser_view_point); - return browser_view_->IsPositionInWindowCaption(browser_view_point); -} - -AccessibilityTypes::Role OpaqueBrowserFrameView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_TITLEBAR; -} - -/////////////////////////////////////////////////////////////////////////////// -// OpaqueBrowserFrameView, views::ButtonListener implementation: - -void OpaqueBrowserFrameView::ButtonPressed(views::Button* sender, - const views::Event& event) { - views::Window* window = frame_->GetWindow(); - if (sender == minimize_button_) - window->Minimize(); - else if (sender == maximize_button_) - window->Maximize(); - else if (sender == restore_button_) - window->Restore(); - else if (sender == close_button_) - window->Close(); -} - -/////////////////////////////////////////////////////////////////////////////// -// OpaqueBrowserFrameView, TabIconView::TabContentsProvider implementation: - -bool OpaqueBrowserFrameView::ShouldTabIconViewAnimate() const { - // This function is queried during the creation of the window as the - // TabIconView we host is initialized, so we need to NULL check the selected - // TabContents because in this condition there is not yet a selected tab. - TabContents* current_tab = browser_view_->GetSelectedTabContents(); - return current_tab ? current_tab->is_loading() : false; -} - -SkBitmap OpaqueBrowserFrameView::GetFavIconForTabIconView() { - return frame_->GetWindow()->GetDelegate()->GetWindowIcon(); -} - -/////////////////////////////////////////////////////////////////////////////// -// OpaqueBrowserFrameView, private: - -int OpaqueBrowserFrameView::FrameBorderThickness(bool restored) const { - views::Window* window = frame_->GetWindow(); - return (!restored && (window->IsMaximized() || window->IsFullscreen())) ? - 0 : kFrameBorderThickness; -} - -int OpaqueBrowserFrameView::TopResizeHeight() const { - return FrameBorderThickness(false) - kTopResizeAdjust; -} - -int OpaqueBrowserFrameView::NonClientBorderThickness() const { - // When we fill the screen, we don't show a client edge. - views::Window* window = frame_->GetWindow(); - return FrameBorderThickness(false) + - ((window->IsMaximized() || window->IsFullscreen()) ? - 0 : kClientEdgeThickness); -} - -int OpaqueBrowserFrameView::NonClientTopBorderHeight( - bool restored, - bool ignore_vertical_tabs) const { - views::Window* window = frame_->GetWindow(); - if (window->GetDelegate()->ShouldShowWindowTitle() || - (browser_view_->IsTabStripVisible() && !ignore_vertical_tabs && - browser_view_->UseVerticalTabs())) { - return std::max(FrameBorderThickness(restored) + IconSize(), - CaptionButtonY(restored) + kCaptionButtonHeightWithPadding) + - TitlebarBottomThickness(restored); - } - - return FrameBorderThickness(restored) - - ((browser_view_->IsTabStripVisible() && !restored && - window->IsMaximized()) ? kTabstripTopShadowThickness : 0); -} - -int OpaqueBrowserFrameView::CaptionButtonY(bool restored) const { - // Maximized buttons start at window top so that even if their images aren't - // drawn flush with the screen edge, they still obey Fitts' Law. - return (!restored && frame_->GetWindow()->IsMaximized()) ? - FrameBorderThickness(false) : kFrameShadowThickness; -} - -int OpaqueBrowserFrameView::TitlebarBottomThickness(bool restored) const { - return kTitlebarTopAndBottomEdgeThickness + - ((!restored && frame_->GetWindow()->IsMaximized()) ? - 0 : kClientEdgeThickness); -} - -int OpaqueBrowserFrameView::IconSize() const { -#if defined(OS_WIN) - // This metric scales up if either the titlebar height or the titlebar font - // size are increased. - return GetSystemMetrics(SM_CYSMICON); -#else - return std::max(BrowserFrame::GetTitleFont().GetHeight(), kIconMinimumSize); -#endif -} - -gfx::Rect OpaqueBrowserFrameView::IconBounds() const { - int size = IconSize(); - int frame_thickness = FrameBorderThickness(false); - int y; - views::WindowDelegate* d = frame_->GetWindow()->GetDelegate(); - if (d->ShouldShowWindowIcon() || d->ShouldShowWindowTitle()) { - // Our frame border has a different "3D look" than Windows'. Theirs has a - // more complex gradient on the top that they push their icon/title below; - // then the maximized window cuts this off and the icon/title are centered - // in the remaining space. Because the apparent shape of our border is - // simpler, using the same positioning makes things look slightly uncentered - // with restored windows, so when the window is restored, instead of - // calculating the remaining space from below the frame border, we calculate - // from below the 3D edge. - int unavailable_px_at_top = frame_->GetWindow()->IsMaximized() ? - frame_thickness : kTitlebarTopAndBottomEdgeThickness; - // When the icon is shorter than the minimum space we reserve for the - // caption button, we vertically center it. We want to bias rounding to put - // extra space above the icon, since the 3D edge (+ client edge, for - // restored windows) below looks (to the eye) more like additional space - // than does the 3D edge (or nothing at all, for maximized windows) above; - // hence the +1. - y = unavailable_px_at_top + (NonClientTopBorderHeight(false, false) - - unavailable_px_at_top - size - TitlebarBottomThickness(false) + 1) / 2; - } else { - // For "browser mode" windows, we use the native positioning, which is just - // below the top frame border. - y = frame_thickness; - } - return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size); -} - -void OpaqueBrowserFrameView::PaintRestoredFrameBorder(gfx::Canvas* canvas) { - ThemeProvider* tp = GetThemeProvider(); - - SkBitmap* top_left_corner = tp->GetBitmapNamed(IDR_WINDOW_TOP_LEFT_CORNER); - SkBitmap* top_right_corner = - tp->GetBitmapNamed(IDR_WINDOW_TOP_RIGHT_CORNER); - SkBitmap* top_edge = tp->GetBitmapNamed(IDR_WINDOW_TOP_CENTER); - SkBitmap* right_edge = tp->GetBitmapNamed(IDR_WINDOW_RIGHT_SIDE); - SkBitmap* left_edge = tp->GetBitmapNamed(IDR_WINDOW_LEFT_SIDE); - SkBitmap* bottom_left_corner = - tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER); - SkBitmap* bottom_right_corner = - tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER); - SkBitmap* bottom_edge = tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_CENTER); - - // Window frame mode and color. - SkBitmap* theme_frame; - SkColor frame_color; - if (!browser_view_->IsBrowserTypeNormal()) { - // Never theme app and popup windows. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - bool is_off_the_record = browser_view_->IsOffTheRecord(); - if (ShouldPaintAsActive()) { - theme_frame = rb.GetBitmapNamed(is_off_the_record ? - IDR_THEME_FRAME_INCOGNITO : IDR_FRAME); - frame_color = is_off_the_record ? - ResourceBundle::frame_color_incognito : - ResourceBundle::frame_color; - } else { - theme_frame = rb.GetBitmapNamed(is_off_the_record ? - IDR_THEME_FRAME_INCOGNITO_INACTIVE : - IDR_THEME_FRAME_INACTIVE); - frame_color = is_off_the_record ? - ResourceBundle::frame_color_incognito_inactive : - ResourceBundle::frame_color_inactive; - } - } else if (!browser_view_->IsOffTheRecord()) { - if (ShouldPaintAsActive()) { - theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME); - frame_color = tp->GetColor(BrowserThemeProvider::COLOR_FRAME); - } else { - theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME_INACTIVE); - frame_color = tp->GetColor(BrowserThemeProvider::COLOR_FRAME_INACTIVE); - } - } else if (ShouldPaintAsActive()) { - theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME_INCOGNITO); - frame_color = tp->GetColor(BrowserThemeProvider::COLOR_FRAME_INCOGNITO); - } else { - theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME_INCOGNITO_INACTIVE); - frame_color = tp->GetColor( - BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE); - } - - // Fill with the frame color first so we have a constant background for - // areas not covered by the theme image. - canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height()); - // Now fill down the sides. - canvas->FillRectInt(frame_color, 0, theme_frame->height(), left_edge->width(), - height() - theme_frame->height()); - canvas->FillRectInt(frame_color, width() - right_edge->width(), - theme_frame->height(), right_edge->width(), - height() - theme_frame->height()); - // Now fill the bottom area. - canvas->FillRectInt(frame_color, left_edge->width(), - height() - bottom_edge->height(), - width() - left_edge->width() - right_edge->width(), - bottom_edge->height()); - - // Draw the theme frame. - canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height()); - - // Draw the theme frame overlay. - if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && - browser_view_->IsBrowserTypeNormal() && - !browser_view_->IsOffTheRecord()) { - canvas->DrawBitmapInt(*tp->GetBitmapNamed(ShouldPaintAsActive() ? - IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE), 0, 0); - } - - // Top. - int top_left_height = std::min(top_left_corner->height(), - height() - bottom_left_corner->height()); - canvas->DrawBitmapInt(*top_left_corner, 0, 0, top_left_corner->width(), - top_left_height, 0, 0, top_left_corner->width(), top_left_height, false); - canvas->TileImageInt(*top_edge, top_left_corner->width(), 0, - width() - top_right_corner->width(), top_edge->height()); - int top_right_height = std::min(top_right_corner->height(), - height() - bottom_right_corner->height()); - canvas->DrawBitmapInt(*top_right_corner, 0, 0, top_right_corner->width(), - top_right_height, width() - top_right_corner->width(), 0, - top_right_corner->width(), top_right_height, false); - // Note: When we don't have a toolbar, we need to draw some kind of bottom - // edge here. Because the App Window graphics we use for this have an - // attached client edge and their sizing algorithm is a little involved, we do - // all this in PaintRestoredClientEdge(). - - // Right. - canvas->TileImageInt(*right_edge, width() - right_edge->width(), - top_right_height, right_edge->width(), - height() - top_right_height - bottom_right_corner->height()); - - // Bottom. - canvas->DrawBitmapInt(*bottom_right_corner, - width() - bottom_right_corner->width(), - height() - bottom_right_corner->height()); - canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(), - height() - bottom_edge->height(), - width() - bottom_left_corner->width() - bottom_right_corner->width(), - bottom_edge->height()); - canvas->DrawBitmapInt(*bottom_left_corner, 0, - height() - bottom_left_corner->height()); - - // Left. - canvas->TileImageInt(*left_edge, 0, top_left_height, left_edge->width(), - height() - top_left_height - bottom_left_corner->height()); -} - - -void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { - ThemeProvider* tp = GetThemeProvider(); - views::Window* window = frame_->GetWindow(); - - // Window frame mode and color - SkBitmap* theme_frame; - // Never theme app and popup windows. - if (!browser_view_->IsBrowserTypeNormal()) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - theme_frame = rb.GetBitmapNamed(ShouldPaintAsActive() ? - IDR_FRAME : IDR_FRAME_INACTIVE); - } else if (!browser_view_->IsOffTheRecord()) { - theme_frame = tp->GetBitmapNamed(ShouldPaintAsActive() ? - IDR_THEME_FRAME : IDR_THEME_FRAME_INACTIVE); - } else { - theme_frame = tp->GetBitmapNamed(ShouldPaintAsActive() ? - IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME_INCOGNITO_INACTIVE); - } - // Draw the theme frame. It must be aligned with the tabstrip as if we were - // in restored mode. Note that the top of the tabstrip is - // kTabstripTopShadowThickness px off the top of the screen. - int theme_background_y = -(GetHorizontalTabStripVerticalOffset(true) + - kTabstripTopShadowThickness); - canvas->TileImageInt(*theme_frame, 0, theme_background_y, width(), - theme_frame->height()); - - // Draw the theme frame overlay - if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && - browser_view_->IsBrowserTypeNormal()) { - SkBitmap* theme_overlay = tp->GetBitmapNamed(ShouldPaintAsActive() ? - IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE); - canvas->DrawBitmapInt(*theme_overlay, 0, theme_background_y); - } - - if (!browser_view_->IsToolbarVisible()) { - // There's no toolbar to edge the frame border, so we need to draw a bottom - // edge. The graphic we use for this has a built in client edge, so we clip - // it off the bottom. - SkBitmap* top_center = - tp->GetBitmapNamed(IDR_APP_TOP_CENTER); - int edge_height = top_center->height() - kClientEdgeThickness; - canvas->TileImageInt(*top_center, 0, - window->GetClientView()->y() - edge_height, width(), edge_height); - } -} - -void OpaqueBrowserFrameView::PaintTitleBar(gfx::Canvas* canvas) { - // The window icon is painted by the TabIconView. - views::WindowDelegate* d = frame_->GetWindow()->GetDelegate(); - if (d->ShouldShowWindowTitle()) { - canvas->DrawStringInt(d->GetWindowTitle(), BrowserFrame::GetTitleFont(), - SK_ColorWHITE, MirroredLeftPointForRect(title_bounds_), - title_bounds_.y(), title_bounds_.width(), title_bounds_.height()); - /* TODO(pkasting): If this window is active, we should also draw a drop - * shadow on the title. This is tricky, because we don't want to hardcode a - * shadow color (since we want to work with various themes), but we can't - * alpha-blend either (since the Windows text APIs don't really do this). - * So we'd need to sample the background color at the right location and - * synthesize a good shadow color. */ - } -} - -void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { - gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds()); - if (toolbar_bounds.IsEmpty()) - return; - gfx::Point toolbar_origin(toolbar_bounds.origin()); - ConvertPointToView(browser_view_, this, &toolbar_origin); - toolbar_bounds.set_origin(toolbar_origin); - - int x = toolbar_bounds.x(); - int w = toolbar_bounds.width(); - int y, h; - if (browser_view_->UseVerticalTabs()) { - gfx::Point tabstrip_origin(browser_view_->tabstrip()->bounds().origin()); - ConvertPointToView(browser_view_, this, &tabstrip_origin); - y = tabstrip_origin.y() - kVerticalTabBorderInset; - h = toolbar_bounds.bottom() - y; - } else { - y = toolbar_bounds.y(); - h = toolbar_bounds.bottom(); - } - - // Gross hack: We split the toolbar images into two pieces, since sometimes - // (popup mode) the toolbar isn't tall enough to show the whole image. The - // split happens between the top shadow section and the bottom gradient - // section so that we never break the gradient. - int split_point = kFrameShadowThickness * 2; - int bottom_y = y + split_point; - ThemeProvider* tp = GetThemeProvider(); - SkBitmap* toolbar_left = tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER); - int bottom_edge_height = std::min(toolbar_left->height(), h) - split_point; - - // Split our canvas out so we can mask out the corners of the toolbar - // without masking out the frame. - canvas->SaveLayerAlpha( - 255, gfx::Rect(x - kClientEdgeThickness, y, w + kClientEdgeThickness * 3, - h)); - canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); - - SkColor theme_toolbar_color = - tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); - canvas->FillRectInt(theme_toolbar_color, x, bottom_y, w, bottom_edge_height); - - // Tile the toolbar image starting at the frame edge on the left and where the - // horizontal tabstrip is (or would be) on the top. - SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR); - canvas->TileImageInt(*theme_toolbar, x, - bottom_y - GetHorizontalTabStripVerticalOffset(false), x, - bottom_y, w, theme_toolbar->height()); - - // Draw rounded corners for the tab. - SkBitmap* toolbar_left_mask = - tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK); - SkBitmap* toolbar_right_mask = - tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK); - - // We mask out the corners by using the DestinationIn transfer mode, - // which keeps the RGB pixels from the destination and the alpha from - // the source. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kDstIn_Mode); - - // Mask the left edge. - int left_x = x - kContentEdgeShadowThickness; - canvas->DrawBitmapInt(*toolbar_left_mask, 0, 0, toolbar_left_mask->width(), - split_point, left_x, y, toolbar_left_mask->width(), - split_point, false, paint); - canvas->DrawBitmapInt(*toolbar_left_mask, 0, - toolbar_left_mask->height() - bottom_edge_height, - toolbar_left_mask->width(), bottom_edge_height, left_x, bottom_y, - toolbar_left_mask->width(), bottom_edge_height, false, paint); - - // Mask the right edge. - int right_x = - x + w - toolbar_right_mask->width() + kContentEdgeShadowThickness; - canvas->DrawBitmapInt(*toolbar_right_mask, 0, 0, toolbar_right_mask->width(), - split_point, right_x, y, toolbar_right_mask->width(), - split_point, false, paint); - canvas->DrawBitmapInt(*toolbar_right_mask, 0, - toolbar_right_mask->height() - bottom_edge_height, - toolbar_right_mask->width(), bottom_edge_height, right_x, bottom_y, - toolbar_right_mask->width(), bottom_edge_height, false, paint); - canvas->Restore(); - - canvas->DrawBitmapInt(*toolbar_left, 0, 0, toolbar_left->width(), split_point, - left_x, y, toolbar_left->width(), split_point, false); - canvas->DrawBitmapInt(*toolbar_left, 0, - toolbar_left->height() - bottom_edge_height, toolbar_left->width(), - bottom_edge_height, left_x, bottom_y, toolbar_left->width(), - bottom_edge_height, false); - - SkBitmap* toolbar_center = - tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER); - canvas->TileImageInt(*toolbar_center, 0, 0, left_x + toolbar_left->width(), - y, right_x - (left_x + toolbar_left->width()), - split_point); - - SkBitmap* toolbar_right = tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER); - canvas->DrawBitmapInt(*toolbar_right, 0, 0, toolbar_right->width(), - split_point, right_x, y, toolbar_right->width(), split_point, false); - canvas->DrawBitmapInt(*toolbar_right, 0, - toolbar_right->height() - bottom_edge_height, toolbar_right->width(), - bottom_edge_height, right_x, bottom_y, toolbar_right->width(), - bottom_edge_height, false); - - // Draw the content/toolbar separator. - canvas->FillRectInt(ResourceBundle::toolbar_separator_color, - x + kClientEdgeThickness, toolbar_bounds.bottom() - kClientEdgeThickness, - w - (2 * kClientEdgeThickness), kClientEdgeThickness); -} - -void OpaqueBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { - // In RTL mode, the avatar icon should be looking the opposite direction. - canvas->Save(); - if (base::i18n::IsRTL()) { - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } - - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int w = otr_avatar_bounds_.width(); - int h = otr_avatar_bounds_.height(); - canvas->DrawBitmapInt(otr_avatar_icon, 0, - // Bias the rounding to select a region that's lower rather than higher, - // as the shadows at the image top mean the apparent center is below the - // real center. - ((otr_avatar_icon.height() - otr_avatar_bounds_.height()) + 1) / 2, w, h, - otr_avatar_bounds_.x(), otr_avatar_bounds_.y(), w, h, false); - - canvas->Restore(); -} - -void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { - ThemeProvider* tp = GetThemeProvider(); - int client_area_top = frame_->GetWindow()->GetClientView()->y(); - int image_top = client_area_top; - - gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); - SkColor toolbar_color = tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); - - if (browser_view_->IsToolbarVisible()) { - // The client edge images always start below the toolbar corner images. The - // client edge filled rects start there or at the bottom of the tooolbar, - // whichever is shorter. - gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds()); - image_top += toolbar_bounds.y() + - tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height(); - client_area_top = std::min(image_top, - client_area_top + toolbar_bounds.bottom() - kClientEdgeThickness); - if (browser_view_->UseVerticalTabs()) { - client_area_top -= kVerticalTabBorderInset; - image_top -= kVerticalTabBorderInset; - } - } else if (!browser_view_->IsTabStripVisible()) { - // The toolbar isn't going to draw a client edge for us, so draw one - // ourselves. - SkBitmap* top_left = tp->GetBitmapNamed(IDR_APP_TOP_LEFT); - SkBitmap* top_center = tp->GetBitmapNamed(IDR_APP_TOP_CENTER); - SkBitmap* top_right = tp->GetBitmapNamed(IDR_APP_TOP_RIGHT); - int top_edge_y = client_area_top - top_center->height(); - int height = client_area_top - top_edge_y; - - canvas->DrawBitmapInt(*top_left, 0, 0, top_left->width(), height, - client_area_bounds.x() - top_left->width(), top_edge_y, - top_left->width(), height, false); - canvas->TileImageInt(*top_center, 0, 0, client_area_bounds.x(), top_edge_y, - client_area_bounds.width(), std::min(height, top_center->height())); - canvas->DrawBitmapInt(*top_right, 0, 0, top_right->width(), height, - client_area_bounds.right(), top_edge_y, - top_right->width(), height, false); - - // Draw the toolbar color across the top edge. - canvas->FillRectInt(toolbar_color, - client_area_bounds.x() - kClientEdgeThickness, - client_area_top - kClientEdgeThickness, - client_area_bounds.width() + (2 * kClientEdgeThickness), - kClientEdgeThickness); - } - - int client_area_bottom = - std::max(client_area_top, height() - NonClientBorderThickness()); - int image_height = client_area_bottom - image_top; - - // Draw the client edge images. - // Draw the client edge images. - SkBitmap* right = tp->GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE); - canvas->TileImageInt(*right, client_area_bounds.right(), image_top, - right->width(), image_height); - canvas->DrawBitmapInt( - *tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER), - client_area_bounds.right(), client_area_bottom); - SkBitmap* bottom = tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER); - canvas->TileImageInt(*bottom, client_area_bounds.x(), - client_area_bottom, client_area_bounds.width(), - bottom->height()); - SkBitmap* bottom_left = - tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER); - canvas->DrawBitmapInt(*bottom_left, - client_area_bounds.x() - bottom_left->width(), client_area_bottom); - SkBitmap* left = tp->GetBitmapNamed(IDR_CONTENT_LEFT_SIDE); - canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), - image_top, left->width(), image_height); - - // Draw the toolbar color so that the client edges show the right color even - // where not covered by the toolbar image. NOTE: We do this after drawing the - // images because the images are meant to alpha-blend atop the frame whereas - // these rects are meant to be fully opaque, without anything overlaid. - canvas->FillRectInt(toolbar_color, - client_area_bounds.x() - kClientEdgeThickness, client_area_top, - kClientEdgeThickness, - client_area_bottom + kClientEdgeThickness - client_area_top); - canvas->FillRectInt(toolbar_color, client_area_bounds.x(), client_area_bottom, - client_area_bounds.width(), kClientEdgeThickness); - canvas->FillRectInt(toolbar_color, client_area_bounds.right(), - client_area_top, kClientEdgeThickness, - client_area_bottom + kClientEdgeThickness - client_area_top); -} - -void OpaqueBrowserFrameView::LayoutWindowControls() { - bool is_maximized = frame_->GetWindow()->IsMaximized(); - close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, - views::ImageButton::ALIGN_BOTTOM); - int caption_y = CaptionButtonY(false); - // There should always be the same number of non-shadow pixels visible to the - // side of the caption buttons. In maximized mode we extend the rightmost - // button to the screen corner to obey Fitts' Law. - int right_extra_width = is_maximized ? - (kFrameBorderThickness - kFrameShadowThickness) : 0; - gfx::Size close_button_size = close_button_->GetPreferredSize(); - close_button_->SetBounds(width() - FrameBorderThickness(false) - - right_extra_width - close_button_size.width(), caption_y, - close_button_size.width() + right_extra_width, - close_button_size.height()); - -#if defined(OS_CHROMEOS) - // LayoutWindowControls could be triggered from WindowGtk::UpdateWindowTitle, - // which could happen when user navigates in fullscreen mode. And because - // BrowserFrameChromeos::IsMaximized return false for fullscreen mode, we - // explicitly test fullscreen mode here and make it use the same code path - // as maximized mode. - // TODO(oshima): Optimize the relayout logic to defer the frame view's - // relayout until it is necessary, i.e when it becomes visible. - if (is_maximized || frame_->GetWindow()->IsFullscreen()) { - minimize_button_->SetVisible(false); - restore_button_->SetVisible(false); - maximize_button_->SetVisible(false); - - if (browser_view_->browser()->type() == Browser::TYPE_DEVTOOLS) { - close_button_->SetVisible(true); - minimize_button_->SetBounds(close_button_->bounds().x(), 0, 0, 0); - } else { - close_button_->SetVisible(false); - // Set the bounds of the minimize button so that we don't have to change - // other places that rely on the bounds. Put it slightly to the right - // of the edge of the view, so that when we remove the spacing it lines - // up with the edge. - minimize_button_->SetBounds(width() - FrameBorderThickness(false) + - kNewTabCaptionMaximizedSpacing, 0, 0, 0); - } - - return; - } else { - close_button_->SetVisible(true); - } -#endif - - // When the window is restored, we show a maximized button; otherwise, we show - // a restore button. - bool is_restored = !is_maximized && !frame_->GetWindow()->IsMinimized(); - views::ImageButton* invisible_button = is_restored ? - restore_button_ : maximize_button_; - invisible_button->SetVisible(false); - - views::ImageButton* visible_button = is_restored ? - maximize_button_ : restore_button_; - visible_button->SetVisible(true); - visible_button->SetImageAlignment(views::ImageButton::ALIGN_LEFT, - views::ImageButton::ALIGN_BOTTOM); - gfx::Size visible_button_size = visible_button->GetPreferredSize(); - visible_button->SetBounds(close_button_->x() - visible_button_size.width(), - caption_y, visible_button_size.width(), - visible_button_size.height()); - - minimize_button_->SetVisible(true); - minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, - views::ImageButton::ALIGN_BOTTOM); - gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); - minimize_button_->SetBounds( - visible_button->x() - minimize_button_size.width(), caption_y, - minimize_button_size.width(), - minimize_button_size.height()); -} - -void OpaqueBrowserFrameView::LayoutTitleBar() { - // The window title is based on the calculated icon position, even when there - // is no icon. - gfx::Rect icon_bounds(IconBounds()); - views::WindowDelegate* d = frame_->GetWindow()->GetDelegate(); - if (d->ShouldShowWindowIcon()) - window_icon_->SetBounds(icon_bounds); - - // Size the title, if visible. - if (d->ShouldShowWindowTitle()) { - int title_x = d->ShouldShowWindowIcon() ? - icon_bounds.right() + kIconTitleSpacing : icon_bounds.x(); - int title_height = BrowserFrame::GetTitleFont().GetHeight(); - // We bias the title position so that when the difference between the icon - // and title heights is odd, the extra pixel of the title is above the - // vertical midline rather than below. This compensates for how the icon is - // already biased downwards (see IconBounds()) and helps prevent descenders - // on the title from overlapping the 3D edge at the bottom of the titlebar. - title_bounds_.SetRect(title_x, - icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), - std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), - title_height); - } -} - -void OpaqueBrowserFrameView::LayoutOTRAvatar() { - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int otr_bottom, otr_restored_y; - if (browser_view_->UseVerticalTabs()) { - otr_bottom = NonClientTopBorderHeight(false, false) - kOTRBottomSpacing; - otr_restored_y = kFrameShadowThickness; - } else { - otr_bottom = GetHorizontalTabStripVerticalOffset(false) + - browser_view_->GetTabStripHeight() - kOTRBottomSpacing; - otr_restored_y = otr_bottom - otr_avatar_icon.height(); - } - int otr_y = frame_->GetWindow()->IsMaximized() ? - (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : - otr_restored_y; - otr_avatar_bounds_.SetRect(NonClientBorderThickness() + kOTRSideSpacing, - otr_y, otr_avatar_icon.width(), - browser_view_->ShouldShowOffTheRecordAvatar() ? (otr_bottom - otr_y) : 0); -} - -gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, - int height) const { - int top_height = NonClientTopBorderHeight(false, false); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(border_thickness, top_height, - std::max(0, width - (2 * border_thickness)), - std::max(0, height - top_height - border_thickness)); -} diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.h b/chrome/browser/views/frame/opaque_browser_frame_view.h index 483693e..3e11721 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.h +++ b/chrome/browser/views/frame/opaque_browser_frame_view.h @@ -6,143 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_H_ #pragma once -#include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/browser/views/frame/browser_non_client_frame_view.h" -#include "chrome/browser/views/tab_icon_view.h" -#include "views/controls/button/button.h" -#include "views/window/non_client_view.h" - -class BaseTabStrip; -class BrowserView; -namespace gfx { -class Font; -} -class TabContents; -namespace views { -class ImageButton; -class ImageView; -} - -class OpaqueBrowserFrameView : public BrowserNonClientFrameView, - public views::ButtonListener, - public TabIconView::TabIconViewModel { - public: - // Constructs a non-client view for an BrowserFrame. - OpaqueBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view); - virtual ~OpaqueBrowserFrameView(); - - // Overridden from BrowserNonClientFrameView: - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const; - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const; - virtual void UpdateThrobber(bool running); - virtual gfx::Size GetMinimumSize(); - - protected: - // Overridden from views::NonClientFrameView: - virtual gfx::Rect GetBoundsForClientView() const; - virtual bool AlwaysUseNativeFrame() const; - virtual bool AlwaysUseCustomFrame() const; - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); - virtual void EnableClose(bool enable); - virtual void ResetWindowControls(); - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual bool HitTest(const gfx::Point& l) const; - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from TabIconView::TabIconViewModel: - virtual bool ShouldTabIconViewAnimate() const; - virtual SkBitmap GetFavIconForTabIconView(); - - private: - // Returns the thickness of the border that makes up the window frame edges. - // This does not include any client edge. If |restored| is true, acts as if - // the window is restored regardless of the real mode. - int FrameBorderThickness(bool restored) const; - - // Returns the height of the top resize area. This is smaller than the frame - // border height in order to increase the window draggable area. - int TopResizeHeight() const; - - // Returns the thickness of the entire nonclient left, right, and bottom - // borders, including both the window frame and any client edge. - int NonClientBorderThickness() const; - - // Returns the height of the entire nonclient top border, including the window - // frame, any title area, and any connected client edge. If |restored| is - // true, acts as if the window is restored regardless of the real mode. If - // |ignore_vertical_tabs| is true, acts as if vertical tabs are off regardless - // of the real state. - int NonClientTopBorderHeight(bool restored, bool ignore_vertical_tabs) const; - - // Returns the y-coordinate of the caption buttons. If |restored| is true, - // acts as if the window is restored regardless of the real mode. - int CaptionButtonY(bool restored) const; - - // Returns the thickness of the 3D edge along the bottom of the titlebar. If - // |restored| is true, acts as if the window is restored regardless of the - // real mode. - int TitlebarBottomThickness(bool restored) const; - - // Returns the size of the titlebar icon. This is used even when the icon is - // not shown, e.g. to set the titlebar height. - int IconSize() const; - - // Returns the bounds of the titlebar icon (or where the icon would be if - // there was one). - gfx::Rect IconBounds() const; - - // Paint various sub-components of this view. The *FrameBorder() functions - // also paint the background of the titlebar area, since the top frame border - // and titlebar background are a contiguous component. - void PaintRestoredFrameBorder(gfx::Canvas* canvas); - void PaintMaximizedFrameBorder(gfx::Canvas* canvas); - void PaintTitleBar(gfx::Canvas* canvas); - void PaintToolbarBackground(gfx::Canvas* canvas); - void PaintOTRAvatar(gfx::Canvas* canvas); - void PaintRestoredClientEdge(gfx::Canvas* canvas); - - // Layout various sub-components of this view. - void LayoutWindowControls(); - void LayoutTitleBar(); - void LayoutOTRAvatar(); - - // Returns the bounds of the client area for the specified view size. - gfx::Rect CalculateClientAreaBounds(int width, int height) const; - - // The layout rect of the title, if visible. - gfx::Rect title_bounds_; - - // The layout rect of the OTR avatar icon, if visible. - gfx::Rect otr_avatar_bounds_; - - // Window controls. - views::ImageButton* minimize_button_; - views::ImageButton* maximize_button_; - views::ImageButton* restore_button_; - views::ImageButton* close_button_; - - // The Window icon. - TabIconView* window_icon_; - - // The frame that hosts this view. - BrowserFrame* frame_; - - // The BrowserView hosted within this View. - BrowserView* browser_view_; - - // The bounds of the ClientView. - gfx::Rect client_view_bounds_; - - DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameView); -}; +#include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_H_ + diff --git a/chrome/browser/views/frame/popup_non_client_frame_view.cc b/chrome/browser/views/frame/popup_non_client_frame_view.cc deleted file mode 100644 index dd76c86..0000000 --- a/chrome/browser/views/frame/popup_non_client_frame_view.cc +++ /dev/null @@ -1,58 +0,0 @@ -// 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/popup_non_client_frame_view.h" - -#include "chrome/browser/views/tabs/base_tab_strip.h" -#include "gfx/point.h" -#include "gfx/rect.h" -#include "gfx/size.h" - -#if defined(OS_LINUX) -#include "views/window/hit_test.h" -#endif - -gfx::Rect PopupNonClientFrameView::GetBoundsForClientView() const { - return gfx::Rect(0, 0, width(), height()); -} - -bool PopupNonClientFrameView::AlwaysUseCustomFrame() const { - return false; -} - -bool PopupNonClientFrameView::AlwaysUseNativeFrame() const { - return true; -} - -gfx::Rect PopupNonClientFrameView::GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const { - return client_bounds; -} - -int PopupNonClientFrameView::NonClientHitTest(const gfx::Point& point) { - return bounds().Contains(point) ? HTCLIENT : HTNOWHERE; -} - -void PopupNonClientFrameView::GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) { -} - -void PopupNonClientFrameView::EnableClose(bool enable) { -} - -void PopupNonClientFrameView::ResetWindowControls() { -} - -gfx::Rect PopupNonClientFrameView::GetBoundsForTabStrip( - BaseTabStrip* tabstrip) const { - return gfx::Rect(0, 0, width(), tabstrip->GetPreferredHeight()); -} - -int PopupNonClientFrameView::GetHorizontalTabStripVerticalOffset( - bool restored) const { - return 0; -} - -void PopupNonClientFrameView::UpdateThrobber(bool running) { -} diff --git a/chrome/browser/views/frame/popup_non_client_frame_view.h b/chrome/browser/views/frame/popup_non_client_frame_view.h index 12982c9..4866d34 100644 --- a/chrome/browser/views/frame/popup_non_client_frame_view.h +++ b/chrome/browser/views/frame/popup_non_client_frame_view.h @@ -6,35 +6,8 @@ #define CHROME_BROWSER_VIEWS_FRAME_POPUP_NON_CLIENT_FRAME_VIEW_H_ #pragma once -#include "chrome/browser/views/frame/browser_non_client_frame_view.h" - -class BaseTabStrip; - -// BrowserNonClientFrameView implementation for popups. We let the window -// manager implementation render the decorations for popups, so this draws -// nothing. -class PopupNonClientFrameView : public BrowserNonClientFrameView { - public: - PopupNonClientFrameView() {} - - // NonClientFrameView: - virtual gfx::Rect GetBoundsForClientView() const; - virtual bool AlwaysUseCustomFrame() const; - virtual bool AlwaysUseNativeFrame() const; - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); - virtual void EnableClose(bool enable); - virtual void ResetWindowControls(); - - // BrowserNonClientFrameView: - virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const; - virtual int GetHorizontalTabStripVerticalOffset(bool restored) const; - virtual void UpdateThrobber(bool running); - - private: - DISALLOW_COPY_AND_ASSIGN(PopupNonClientFrameView); -}; +#include "chrome/browser/ui/views/frame/popup_non_client_frame_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_FRAME_POPUP_NON_CLIENT_FRAME_VIEW_H_ + diff --git a/chrome/browser/views/fullscreen_exit_bubble.cc b/chrome/browser/views/fullscreen_exit_bubble.cc deleted file mode 100644 index 635e9d2..0000000 --- a/chrome/browser/views/fullscreen_exit_bubble.cc +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright (c) 2009 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/fullscreen_exit_bubble.h" - -#include "app/keyboard_codes.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/app/chrome_command_ids.h" -#include "gfx/canvas_skia.h" -#include "grit/generated_resources.h" -#include "views/screen.h" -#include "views/widget/root_view.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "app/l10n_util_win.h" -#include "views/widget/widget_win.h" -#elif defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -// FullscreenExitView ---------------------------------------------------------- - -class FullscreenExitBubble::FullscreenExitView : public views::View { - public: - FullscreenExitView(FullscreenExitBubble* bubble, - const std::wstring& accelerator); - virtual ~FullscreenExitView(); - - // views::View - virtual gfx::Size GetPreferredSize(); - - private: - static const int kPaddingPixels; // Number of pixels around all sides of link - - // views::View - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - - // Clickable hint text to show in the bubble. - views::Link link_; -}; - -const int FullscreenExitBubble::FullscreenExitView::kPaddingPixels = 8; - -FullscreenExitBubble::FullscreenExitView::FullscreenExitView( - FullscreenExitBubble* bubble, - const std::wstring& accelerator) { - link_.set_parent_owned(false); -#if !defined(OS_CHROMEOS) - link_.SetText(l10n_util::GetStringF(IDS_EXIT_FULLSCREEN_MODE, accelerator)); -#else - link_.SetText(l10n_util::GetString(IDS_EXIT_FULLSCREEN_MODE)); -#endif - link_.SetController(bubble); - link_.SetFont(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::LargeFont)); - link_.SetNormalColor(SK_ColorWHITE); - link_.SetHighlightedColor(SK_ColorWHITE); - AddChildView(&link_); -} - -FullscreenExitBubble::FullscreenExitView::~FullscreenExitView() { -} - -gfx::Size FullscreenExitBubble::FullscreenExitView::GetPreferredSize() { - gfx::Size preferred_size(link_.GetPreferredSize()); - preferred_size.Enlarge(kPaddingPixels * 2, kPaddingPixels * 2); - return preferred_size; -} - -void FullscreenExitBubble::FullscreenExitView::Layout() { - gfx::Size link_preferred_size(link_.GetPreferredSize()); - link_.SetBounds(kPaddingPixels, - height() - kPaddingPixels - link_preferred_size.height(), - link_preferred_size.width(), link_preferred_size.height()); -} - -void FullscreenExitBubble::FullscreenExitView::Paint(gfx::Canvas* canvas) { - // Create a round-bottomed rect to fill the whole View. - SkRect rect; - SkScalar padding = SkIntToScalar(kPaddingPixels); - // The "-padding" top coordinate ensures that the rect is always tall enough - // to contain the complete rounded corner radius. If we set this to 0, as the - // popup slides offscreen (in reality, squishes to 0 height), the corners will - // flatten out as the height becomes less than the corner radius. - rect.set(0, -padding, SkIntToScalar(width()), SkIntToScalar(height())); - SkScalar rad[8] = { 0, 0, 0, 0, padding, padding, padding, padding }; - SkPath path; - path.addRoundRect(rect, rad, SkPath::kCW_Direction); - - // Fill it black. - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setFlags(SkPaint::kAntiAlias_Flag); - paint.setColor(SK_ColorBLACK); - canvas->AsCanvasSkia()->drawPath(path, paint); -} - - -// FullscreenExitPopup --------------------------------------------------------- - -#if defined(OS_WIN) -class FullscreenExitBubble::FullscreenExitPopup : public views::WidgetWin { - public: - FullscreenExitPopup() : views::WidgetWin() {} - virtual ~FullscreenExitPopup() {} - - // views::WidgetWin: - virtual LRESULT OnMouseActivate(HWND window, - UINT hittest_code, - UINT message) { - // Prevent the popup from being activated, so it won't steal focus from the - // rest of the browser, and doesn't cause problems with the FocusManager's - // "RestoreFocusedView()" functionality. - return MA_NOACTIVATE; - } -}; -#elif defined(OS_LINUX) -// TODO: figure out the equivalent of MA_NOACTIVATE for gtk. -#endif - -// FullscreenExitBubble -------------------------------------------------------- - -const double FullscreenExitBubble::kOpacity = 0.7; -const int FullscreenExitBubble::kInitialDelayMs = 2300; -const int FullscreenExitBubble::kIdleTimeMs = 2300; -const int FullscreenExitBubble::kPositionCheckHz = 10; -const int FullscreenExitBubble::kSlideInRegionHeightPx = 4; -const int FullscreenExitBubble::kSlideInDurationMs = 350; -const int FullscreenExitBubble::kSlideOutDurationMs = 700; - -FullscreenExitBubble::FullscreenExitBubble( - views::Widget* frame, - CommandUpdater::CommandUpdaterDelegate* delegate) - : root_view_(frame->GetRootView()), - delegate_(delegate), - popup_(NULL), - size_animation_(new SlideAnimation(this)) { - size_animation_->Reset(1); - - // Create the contents view. - views::Accelerator accelerator(app::VKEY_UNKNOWN, false, false, false); - bool got_accelerator = frame->GetAccelerator(IDC_FULLSCREEN, &accelerator); - DCHECK(got_accelerator); - view_ = new FullscreenExitView(this, accelerator.GetShortcutText()); - - // Initialize the popup. -#if defined(OS_WIN) - popup_ = new FullscreenExitPopup(); - popup_->set_window_style(WS_POPUP); - popup_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | - l10n_util::GetExtendedTooltipStyles()); -#elif defined(OS_LINUX) - popup_ = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); - popup_->MakeTransparent(); -#endif - popup_->SetOpacity(static_cast<unsigned char>(0xff * kOpacity)); - popup_->Init(frame->GetNativeView(), GetPopupRect(false)); - popup_->set_delete_on_destroy(false); - popup_->SetContentsView(view_); - popup_->Show(); // This does not activate the popup. - - // Start the initial delay timer and begin watching the mouse. - initial_delay_.Start(base::TimeDelta::FromMilliseconds(kInitialDelayMs), this, - &FullscreenExitBubble::CheckMousePosition); - gfx::Point cursor_pos = views::Screen::GetCursorScreenPoint(); - last_mouse_pos_ = cursor_pos; - views::View::ConvertPointToView(NULL, root_view_, &last_mouse_pos_); - mouse_position_checker_.Start( - base::TimeDelta::FromMilliseconds(1000 / kPositionCheckHz), this, - &FullscreenExitBubble::CheckMousePosition); -} - -FullscreenExitBubble::~FullscreenExitBubble() { - // This is tricky. We may be in an ATL message handler stack, in which case - // the popup cannot be deleted yet. We also can't blindly use - // set_delete_on_destroy(true) on the popup to delete it when it closes, - // because if the user closed the last tab while in fullscreen mode, Windows - // has already destroyed the popup HWND by the time we get here, and thus - // either the popup will already have been deleted (if we set this in our - // constructor) or the popup will never get another OnFinalMessage() call (if - // not, as currently). So instead, we tell the popup to synchronously hide, - // and then asynchronously close and delete itself. - popup_->Close(); - MessageLoop::current()->DeleteSoon(FROM_HERE, popup_); -} - -void FullscreenExitBubble::LinkActivated(views::Link* source, int event_flags) { - delegate_->ExecuteCommand(IDC_FULLSCREEN); -} - -void FullscreenExitBubble::AnimationProgressed( - const Animation* animation) { - gfx::Rect popup_rect(GetPopupRect(false)); - if (popup_rect.IsEmpty()) { - popup_->Hide(); - } else { -#if defined(OS_WIN) - popup_->MoveWindow(popup_rect.x(), popup_rect.y(), popup_rect.width(), - popup_rect.height()); -#elif defined(OS_LINUX) - popup_->SetBounds(popup_rect); -#endif - popup_->Show(); - } -} -void FullscreenExitBubble::AnimationEnded( - const Animation* animation) { - AnimationProgressed(animation); -} - -void FullscreenExitBubble::CheckMousePosition() { - // Desired behavior: - // - // +------------+-----------------------------+------------+ - // | _ _ _ _ | Exit full screen mode (F11) | _ _ _ _ | Slide-in region - // | _ _ _ _ \_____________________________/ _ _ _ _ | Neutral region - // | | Slide-out region - // : : - // - // * If app is not active, we hide the popup. - // * If the mouse is offscreen or in the slide-out region, we hide the popup. - // * If the mouse goes idle, we hide the popup. - // * If the mouse is in the slide-in-region and not idle, we show the popup. - // * If the mouse is in the neutral region and not idle, and the popup is - // currently sliding out, we show it again. This facilitates users - // correcting us if they try to mouse horizontally towards the popup and - // unintentionally drop too low. - // * Otherwise, we do nothing, because the mouse is in the neutral region and - // either the popup is hidden or the mouse is not idle, so we don't want to - // change anything's state. - - gfx::Point cursor_pos = views::Screen::GetCursorScreenPoint(); - gfx::Point transformed_pos(cursor_pos); - views::View::ConvertPointToView(NULL, root_view_, &transformed_pos); - - // Check to see whether the mouse is idle. - if (transformed_pos != last_mouse_pos_) { - // The mouse moved; reset the idle timer. - idle_timeout_.Stop(); // If the timer isn't running, this is a no-op. - idle_timeout_.Start(base::TimeDelta::FromMilliseconds(kIdleTimeMs), this, - &FullscreenExitBubble::CheckMousePosition); - } - last_mouse_pos_ = transformed_pos; - - if ((!root_view_->GetWidget()->IsActive()) || - !root_view_->HitTest(transformed_pos) || - (cursor_pos.y() >= GetPopupRect(true).bottom()) || - !idle_timeout_.IsRunning()) { - // The cursor is offscreen, in the slide-out region, or idle. - Hide(); - } else if ((cursor_pos.y() < kSlideInRegionHeightPx) || - (size_animation_->GetCurrentValue() != 0)) { - // The cursor is not idle, and either it's in the slide-in region or it's in - // the neutral region and we're sliding out. - size_animation_->SetSlideDuration(kSlideInDurationMs); - size_animation_->Show(); - } -} - -void FullscreenExitBubble::Hide() { - // Allow the bubble to hide if the window is deactivated or our initial delay - // finishes. - if ((!root_view_->GetWidget()->IsActive()) || !initial_delay_.IsRunning()) { - size_animation_->SetSlideDuration(kSlideOutDurationMs); - size_animation_->Hide(); - } -} - -gfx::Rect FullscreenExitBubble::GetPopupRect( - bool ignore_animation_state) const { - gfx::Size size(view_->GetPreferredSize()); - if (!ignore_animation_state) { - size.set_height(static_cast<int>(static_cast<double>(size.height()) * - size_animation_->GetCurrentValue())); - } - // NOTE: don't use the bounds of the root_view_. On linux changing window - // size is async. Instead we use the size of the screen. - gfx::Rect screen_bounds = views::Screen::GetMonitorAreaNearestWindow( - root_view_->GetWidget()->GetNativeView()); - gfx::Point origin(screen_bounds.x() + - (screen_bounds.width() - size.width()) / 2, - screen_bounds.y()); - return gfx::Rect(origin, size); -} diff --git a/chrome/browser/views/fullscreen_exit_bubble.h b/chrome/browser/views/fullscreen_exit_bubble.h index c2ebd5a..fc71d5c 100644 --- a/chrome/browser/views/fullscreen_exit_bubble.h +++ b/chrome/browser/views/fullscreen_exit_bubble.h @@ -1,107 +1,13 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. -#ifndef CHROME_BROWSER_VIEWS_FULLSCREEN_EXIT_BUBBLE_H__ -#define CHROME_BROWSER_VIEWS_FULLSCREEN_EXIT_BUBBLE_H__ +#ifndef CHROME_BROWSER_VIEWS_FULLSCREEN_EXIT_BUBBLE_H_ +#define CHROME_BROWSER_VIEWS_FULLSCREEN_EXIT_BUBBLE_H_ #pragma once -#include "app/slide_animation.h" -#include "base/scoped_ptr.h" -#include "base/timer.h" -#include "chrome/browser/command_updater.h" -#include "views/controls/link.h" +#include "chrome/browser/ui/views/fullscreen_exit_bubble.h" +// TODO(beng): remove this file once all includes have been updated. -#if defined(OS_LINUX) -namespace views { -class WidgetGtk; -} -#endif +#endif // CHROME_BROWSER_VIEWS_FULLSCREEN_EXIT_BUBBLE_H_ -// FullscreenExitBubble is responsible for showing a bubble atop the screen in -// fullscreen mode, telling users how to exit and providing a click target. -// The bubble auto-hides, and re-shows when the user moves to the screen top. - -class FullscreenExitBubble : public views::LinkController, - public AnimationDelegate { - public: - explicit FullscreenExitBubble( - views::Widget* frame, - CommandUpdater::CommandUpdaterDelegate* delegate); - virtual ~FullscreenExitBubble(); - - private: - class FullscreenExitView; - class FullscreenExitPopup; - - static const double kOpacity; // Opacity of the bubble, 0.0 - 1.0 - static const int kInitialDelayMs; // Initial time bubble remains onscreen - static const int kIdleTimeMs; // Time before mouse idle triggers hide - static const int kPositionCheckHz; // How fast to check the mouse position - static const int kSlideInRegionHeightPx; - // Height of region triggering slide-in - static const int kSlideInDurationMs; // Duration of slide-in animation - static const int kSlideOutDurationMs; // Duration of slide-out animation - - // views::LinkController - virtual void LinkActivated(views::Link* source, int event_flags); - - // AnimationDelegate - virtual void AnimationProgressed(const Animation* animation); - virtual void AnimationEnded(const Animation* animation); - - // Called repeatedly to get the current mouse position and animate the bubble - // on or off the screen as appropriate. - void CheckMousePosition(); - - // Hides the bubble. This is a separate function so it can be called by a - // timer. - void Hide(); - - // Returns the current desirable rect for the popup window. If - // |ignore_animation_state| is true this returns the rect assuming the popup - // is fully onscreen. - gfx::Rect GetPopupRect(bool ignore_animation_state) const; - - // The root view containing us. - views::View* root_view_; - - // Someone who can toggle fullscreen mode on and off when the user requests - // it. - CommandUpdater::CommandUpdaterDelegate* delegate_; - -#if defined(OS_WIN) - // The popup itself, which is a slightly modified WidgetWin. We need to use - // a WidgetWin (and thus an HWND) to make the popup float over other HWNDs. - FullscreenExitPopup* popup_; -#elif defined(OS_LINUX) - views::WidgetGtk* popup_; -#endif - - // The contents of the popup. - FullscreenExitView* view_; - - // Animation controlling sliding into/out of the top of the screen. - scoped_ptr<SlideAnimation> size_animation_; - - // Timer to delay before allowing the bubble to hide after it's initially - // shown. - base::OneShotTimer<FullscreenExitBubble> initial_delay_; - - // Timer to see how long the mouse has been idle. - base::OneShotTimer<FullscreenExitBubble> idle_timeout_; - - // Timer to poll the current mouse position. We can't just listen for mouse - // events without putting a non-empty HWND onscreen (or hooking Windows, which - // has other problems), so instead we run a low-frequency poller to see if the - // user has moved in or out of our show/hide regions. - base::RepeatingTimer<FullscreenExitBubble> mouse_position_checker_; - - // The most recently seen mouse position, in screen coordinates. Used to see - // if the mouse has moved since our last check. - gfx::Point last_mouse_pos_; - - DISALLOW_COPY_AND_ASSIGN(FullscreenExitBubble); -}; - -#endif // CHROME_BROWSER_VIEWS_FULLSCREEN_EXIT_BUBBLE_H__ diff --git a/chrome/browser/views/generic_info_view.cc b/chrome/browser/views/generic_info_view.cc deleted file mode 100644 index 81ebb4a..0000000 --- a/chrome/browser/views/generic_info_view.cc +++ /dev/null @@ -1,105 +0,0 @@ -// 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/generic_info_view.h" - -#include "app/l10n_util.h" -#include "gfx/color_utils.h" -#include "base/logging.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" - -GenericInfoView::GenericInfoView(int number_of_rows) - : number_of_rows_(number_of_rows), name_string_ids_(NULL) { - DCHECK(number_of_rows_ > 0); -} - -GenericInfoView::GenericInfoView( - int number_of_rows, const int name_string_ids[]) - : number_of_rows_(number_of_rows), name_string_ids_(name_string_ids) { - DCHECK(number_of_rows_ > 0); -} - -void GenericInfoView::SetNameByStringId(int row, int name_string_id) { - SetName(row, l10n_util::GetString(name_string_id)); -} - -void GenericInfoView::SetName(int row, const string16& name) { - DCHECK(name_views_.get()); // Can only be called after Init time. - DCHECK(row >= 0 && row < number_of_rows_); - name_views_[row]->SetText(name); -} - -void GenericInfoView::SetValue(int row, const string16& name) { - DCHECK(value_views_.get()); // Can only be called after Init time. - DCHECK(row >= 0 && row < number_of_rows_); - value_views_[row]->SetText(name); -} - -void GenericInfoView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) { - InitGenericInfoView(); - if (name_string_ids_) { - for (int i = 0; i < number_of_rows_; ++i) - SetNameByStringId(i, name_string_ids_[i]); - } - } -} - -void GenericInfoView::InitGenericInfoView() { - const int kInfoViewBorderSize = 1; - const int kInfoViewInsetSize = 3; - const int kLayoutId = 0; - - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kInfoViewBorderSize, border_color); - set_border(border); - - using views::GridLayout; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kInfoViewInsetSize, kInfoViewInsetSize, - kInfoViewInsetSize, kInfoViewInsetSize); - SetLayoutManager(layout); - - views::ColumnSet* column_set = layout->AddColumnSet(kLayoutId); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - name_views_.reset(new views::Label* [number_of_rows_]); - value_views_.reset(new views::Textfield* [number_of_rows_]); - - for (int i = 0; i < number_of_rows_; ++i) { - if (i) - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - name_views_[i] = new views::Label; - value_views_[i] = new views::Textfield; - AddRow(kLayoutId, layout, name_views_[i], value_views_[i]); - } -} - -void GenericInfoView::AddRow( - int layout_id, views::GridLayout* layout, views::Label* name, - views::Textfield* value) { - // Add to the view hierarchy. - layout->StartRow(0, layout_id); - layout->AddView(name); - layout->AddView(value); - - // Color these borderless text areas the same as the containing dialog. - SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); - - // Init them now that they're in the view hierarchy. - value->SetReadOnly(true); - value->RemoveBorder(); - value->SetBackgroundColor(text_area_background); -} diff --git a/chrome/browser/views/generic_info_view.h b/chrome/browser/views/generic_info_view.h index 4c0318c..014ae18 100644 --- a/chrome/browser/views/generic_info_view.h +++ b/chrome/browser/views/generic_info_view.h @@ -6,62 +6,8 @@ #define CHROME_BROWSER_VIEWS_GENERIC_INFO_VIEW_H_ #pragma once -#include "base/gtest_prod_util.h" -#include "base/scoped_ptr.h" -#include "base/string16.h" -#include "views/view.h" - -namespace views { -class GridLayout; -class Label; -class Textfield; -} - -// GenericInfoView, displays a tabular grid of read-only textual information, -// <name, value> pairs. The fixed number of rows must be known at the time of -// construction. -class GenericInfoView : public views::View { - public: - // Constructs a info view with |number_of_rows| and populated with - // empty strings. - explicit GenericInfoView(int number_of_rows); - - // Constructs a info view with |number_of_rows|, and populates - // the name column with localized strings having the given - // |name_string_ids|. The array of ids should contain |number_of_rows| - // values and should remain valid for the life of the view. - GenericInfoView(int number_of_rows, const int name_string_ids[]); - - // The following methods should only be called after - // the view has been added to a view hierarchy. - void SetNameByStringId(int row, int id); - void SetName(int row, const string16& name); - void SetValue(int row, const string16& value); - void ClearValues() { - const string16 kEmptyString; - for (int i = 0; i < number_of_rows_; ++i) - SetValue(i, kEmptyString); - } - - protected: - // views::View override - virtual void ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child); - - private: - FRIEND_TEST_ALL_PREFIXES(GenericInfoViewTest, GenericInfoView); - - void InitGenericInfoView(); - void AddRow(int layout_id, views::GridLayout* layout, - views::Label* name, views::Textfield* value); - - const int number_of_rows_; - const int* name_string_ids_; - scoped_array<views::Label*> name_views_; - scoped_array<views::Textfield*> value_views_; - - DISALLOW_COPY_AND_ASSIGN(GenericInfoView); -}; +#include "chrome/browser/ui/views/generic_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_GENERIC_INFO_VIEW_H_ diff --git a/chrome/browser/views/generic_info_view_unittest.cc b/chrome/browser/views/generic_info_view_unittest.cc deleted file mode 100644 index 6c26603..0000000 --- a/chrome/browser/views/generic_info_view_unittest.cc +++ /dev/null @@ -1,65 +0,0 @@ -// 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 "app/l10n_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/views/generic_info_view.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/widget/root_view.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#endif - -// This class is only used on windows for now. -#if defined(OS_WIN) - -using namespace views; - -class GenericInfoViewTest : public testing::Test { - public: - Widget* CreateWidget() { - return new WidgetWin(); - } - private: - MessageLoopForUI message_loop_; -}; - -TEST_F(GenericInfoViewTest, GenericInfoView) { - const string16 kName = ASCIIToUTF16("Name"); - const string16 kValue = ASCIIToUTF16("Value"); - - Widget* window = CreateWidget(); - static_cast<WidgetWin*>(window)->Init(NULL, gfx::Rect(0, 0, 100, 100)); - RootView* root_view = window->GetRootView(); - - GenericInfoView* view1 = new GenericInfoView(1); - root_view->AddChildView(view1); - view1->SetName(0, kName); - view1->SetValue(0, kValue); - EXPECT_EQ(kName, view1->name_views_[0]->GetText()); - EXPECT_EQ(kValue, view1->value_views_[0]->text()); - view1->ClearValues(); - EXPECT_TRUE(view1->value_views_[0]->text().empty()); - - // Test setting values by localized string id. - static int kNameIds[] = { - IDS_PRODUCT_NAME, - IDS_PRODUCT_DESCRIPTION - }; - GenericInfoView* view2 = new GenericInfoView(ARRAYSIZE(kNameIds), kNameIds); - root_view->AddChildView(view2); - - string16 product_name = l10n_util::GetString(IDS_PRODUCT_NAME); - string16 product_desc = l10n_util::GetString(IDS_PRODUCT_DESCRIPTION); - EXPECT_EQ(product_name, view2->name_views_[0]->GetText()); - EXPECT_EQ(product_desc, view2->name_views_[1]->GetText()); - window->CloseNow(); -} -#endif // OS_WIN diff --git a/chrome/browser/views/html_dialog_view.cc b/chrome/browser/views/html_dialog_view.cc deleted file mode 100644 index f28e609..0000000 --- a/chrome/browser/views/html_dialog_view.cc +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright (c) 2006-2008 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/html_dialog_view.h" - -#include "app/keyboard_codes.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/window.h" -#include "chrome/common/native_web_keyboard_event.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -#if defined(OS_LINUX) -#include "views/window/window_gtk.h" -#endif - -namespace browser { - -// Declared in browser_dialogs.h so that others don't need to depend on our .h. -void ShowHtmlDialogView(gfx::NativeWindow parent, Profile* profile, - HtmlDialogUIDelegate* delegate) { - HtmlDialogView* html_view = - new HtmlDialogView(profile, delegate); - browser::CreateViewsWindow(parent, gfx::Rect(), html_view); - html_view->InitDialog(); - html_view->window()->Show(); -} - -} // namespace browser - -//////////////////////////////////////////////////////////////////////////////// -// HtmlDialogView, public: - -HtmlDialogView::HtmlDialogView(Profile* profile, - HtmlDialogUIDelegate* delegate) - : DOMView(), - HtmlDialogTabContentsDelegate(profile), - delegate_(delegate) { -} - -HtmlDialogView::~HtmlDialogView() { -} - -//////////////////////////////////////////////////////////////////////////////// -// HtmlDialogView, views::View implementation: - -gfx::Size HtmlDialogView::GetPreferredSize() { - gfx::Size out; - if (delegate_) - delegate_->GetDialogSize(&out); - return out; -} - -bool HtmlDialogView::AcceleratorPressed(const views::Accelerator& accelerator) { - // Pressing ESC closes the dialog. - DCHECK_EQ(app::VKEY_ESCAPE, accelerator.GetKeyCode()); - OnDialogClosed(std::string()); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// HtmlDialogView, views::WindowDelegate implementation: - -bool HtmlDialogView::CanResize() const { - return true; -} - -bool HtmlDialogView::IsModal() const { - if (delegate_) - return delegate_->IsDialogModal(); - else - return false; -} - -std::wstring HtmlDialogView::GetWindowTitle() const { - if (delegate_) - return delegate_->GetDialogTitle(); - else - return std::wstring(); -} - -void HtmlDialogView::WindowClosing() { - // If we still have a delegate that means we haven't notified it of the - // dialog closing. This happens if the user clicks the Close button on the - // dialog. - if (delegate_) - OnDialogClosed(""); -} - -views::View* HtmlDialogView::GetContentsView() { - return this; -} - -views::View* HtmlDialogView::GetInitiallyFocusedView() { - return this; -} - -bool HtmlDialogView::ShouldShowWindowTitle() const { - return ShouldShowDialogTitle(); -} - -//////////////////////////////////////////////////////////////////////////////// -// HtmlDialogUIDelegate implementation: - -bool HtmlDialogView::IsDialogModal() const { - return IsModal(); -} - -std::wstring HtmlDialogView::GetDialogTitle() const { - return GetWindowTitle(); -} - -GURL HtmlDialogView::GetDialogContentURL() const { - if (delegate_) - return delegate_->GetDialogContentURL(); - else - return GURL(); -} - -void HtmlDialogView::GetDOMMessageHandlers( - std::vector<DOMMessageHandler*>* handlers) const { - if (delegate_) - delegate_->GetDOMMessageHandlers(handlers); -} - -void HtmlDialogView::GetDialogSize(gfx::Size* size) const { - if (delegate_) - delegate_->GetDialogSize(size); -} - -std::string HtmlDialogView::GetDialogArgs() const { - if (delegate_) - return delegate_->GetDialogArgs(); - else - return std::string(); -} - -void HtmlDialogView::OnDialogClosed(const std::string& json_retval) { - HtmlDialogTabContentsDelegate::Detach(); - if (delegate_) { - HtmlDialogUIDelegate* dialog_delegate = delegate_; - delegate_ = NULL; // We will not communicate further with the delegate. - dialog_delegate->OnDialogClosed(json_retval); - } - window()->Close(); -} - -void HtmlDialogView::OnCloseContents(TabContents* source, - bool* out_close_dialog) { - if (delegate_) - delegate_->OnCloseContents(source, out_close_dialog); -} - -bool HtmlDialogView::ShouldShowDialogTitle() const { - if (delegate_) - return delegate_->ShouldShowDialogTitle(); - else - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// TabContentsDelegate implementation: - -void HtmlDialogView::MoveContents(TabContents* source, const gfx::Rect& pos) { - // The contained web page wishes to resize itself. We let it do this because - // if it's a dialog we know about, we trust it not to be mean to the user. - GetWidget()->SetBounds(pos); -} - -void HtmlDialogView::ToolbarSizeChanged(TabContents* source, - bool is_animating) { - Layout(); -} - -// A simplified version of BrowserView::HandleKeyboardEvent(). -// We don't handle global keyboard shortcuts here, but that's fine since -// they're all browser-specific. (This may change in the future.) -void HtmlDialogView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { -#if defined(OS_WIN) - // Any unhandled keyboard/character messages should be defproced. - // This allows stuff like F10, etc to work correctly. - DefWindowProc(event.os_event.hwnd, event.os_event.message, - event.os_event.wParam, event.os_event.lParam); -#elif defined(OS_LINUX) - views::WindowGtk* window_gtk = static_cast<views::WindowGtk*>(window()); - if (event.os_event && !event.skip_in_browser) - window_gtk->HandleKeyboardEvent(event.os_event); -#endif -} - -void HtmlDialogView::CloseContents(TabContents* source) { - bool close_dialog = false; - OnCloseContents(source, &close_dialog); - if (close_dialog) - OnDialogClosed(std::string()); -} - -//////////////////////////////////////////////////////////////////////////////// -// HtmlDialogView: - -void HtmlDialogView::InitDialog() { - // Now Init the DOMView. This view runs in its own process to render the html. - DOMView::Init(profile(), NULL); - - tab_contents_->set_delegate(this); - - // Set the delegate. This must be done before loading the page. See - // the comment above HtmlDialogUI in its header file for why. - HtmlDialogUI::GetPropertyAccessor().SetProperty(tab_contents_->property_bag(), - this); - - // Pressing the ESC key will close the dialog. - AddAccelerator(views::Accelerator(app::VKEY_ESCAPE, false, false, false)); - - DOMView::LoadURL(GetDialogContentURL()); -} diff --git a/chrome/browser/views/html_dialog_view.h b/chrome/browser/views/html_dialog_view.h index 1d42b6f..c26c76a 100644 --- a/chrome/browser/views/html_dialog_view.h +++ b/chrome/browser/views/html_dialog_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,83 +6,8 @@ #define CHROME_BROWSER_VIEWS_HTML_DIALOG_VIEW_H_ #pragma once -#include <string> - -#include "chrome/browser/dom_ui/html_dialog_ui.h" -#include "chrome/browser/dom_ui/html_dialog_tab_contents_delegate.h" -#include "chrome/browser/views/dom_view.h" -#include "gfx/size.h" -#include "views/window/window_delegate.h" - -class Browser; -namespace views { -class Window; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// HtmlDialogView is a view used to display an HTML dialog to the user. The -// content of the dialogs is determined by the delegate -// (HtmlDialogUIDelegate), but is basically a file URL along with a -// JSON input string. The HTML is supposed to show a UI to the user and is -// expected to send back a JSON file as a return value. -// -//////////////////////////////////////////////////////////////////////////////// -// -// TODO(akalin): Make HtmlDialogView contain an HtmlDialogTabContentsDelegate -// instead of inheriting from it to avoid violating the "no multiple -// inheritance" rule. -class HtmlDialogView - : public DOMView, - public HtmlDialogTabContentsDelegate, - public HtmlDialogUIDelegate, - public views::WindowDelegate { - public: - HtmlDialogView(Profile* profile, HtmlDialogUIDelegate* delegate); - virtual ~HtmlDialogView(); - - // Initializes the contents of the dialog (the DOMView and the callbacks). - void InitDialog(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual bool AcceleratorPressed(const views::Accelerator& accelerator); - - // Overridden from views::WindowDelegate: - virtual bool CanResize() const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual views::View* GetContentsView(); - virtual views::View* GetInitiallyFocusedView(); - virtual bool ShouldShowWindowTitle() const; - - // Overridden from HtmlDialogUIDelegate: - virtual bool IsDialogModal() const; - virtual std::wstring GetDialogTitle() const; - virtual GURL GetDialogContentURL() const; - virtual void GetDOMMessageHandlers( - std::vector<DOMMessageHandler*>* handlers) const; - virtual void GetDialogSize(gfx::Size* size) const; - virtual std::string GetDialogArgs() const; - virtual void OnDialogClosed(const std::string& json_retval); - virtual void OnCloseContents(TabContents* source, bool* out_close_dialog); - virtual bool ShouldShowDialogTitle() const; - - // Overridden from TabContentsDelegate: - virtual void MoveContents(TabContents* source, const gfx::Rect& pos); - virtual void ToolbarSizeChanged(TabContents* source, bool is_animating); - virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); - virtual void CloseContents(TabContents* source); - - private: - // This view is a delegate to the HTML content since it needs to get notified - // about when the dialog is closing. For all other actions (besides dialog - // closing) we delegate to the creator of this view, which we keep track of - // using this variable. - HtmlDialogUIDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(HtmlDialogView); -}; +#include "chrome/browser/ui/views/html_dialog_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_HTML_DIALOG_VIEW_H_ + diff --git a/chrome/browser/views/html_dialog_view_browsertest.cc b/chrome/browser/views/html_dialog_view_browsertest.cc deleted file mode 100644 index a2bcd35..0000000 --- a/chrome/browser/views/html_dialog_view_browsertest.cc +++ /dev/null @@ -1,205 +0,0 @@ -// 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/test/ui/ui_test.h" - -#include "base/file_path.h" -#include "base/message_loop.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/dom_ui/html_dialog_ui.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/views/html_dialog_view.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/in_process_browser_test.h" -#include "chrome/test/ui_test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -using testing::Eq; - -namespace { - -// Window non-client-area means that the minimum size for the window -// won't be the actual minimum size - our layout and resizing code -// makes sure the chrome is always visible. -const int kMinimumWidthToTestFor = 20; -const int kMinimumHeightToTestFor = 30; - -class TestHtmlDialogUIDelegate : public HtmlDialogUIDelegate { - public: - TestHtmlDialogUIDelegate() {} - virtual ~TestHtmlDialogUIDelegate() {} - - // HTMLDialogUIDelegate implementation: - virtual bool IsDialogModal() const { - return true; - } - virtual std::wstring GetDialogTitle() const { - return std::wstring(L"Test"); - } - virtual GURL GetDialogContentURL() const { - return GURL(chrome::kAboutBlankURL); - } - virtual void GetDOMMessageHandlers( - std::vector<DOMMessageHandler*>* handlers) const { } - virtual void GetDialogSize(gfx::Size* size) const { - size->set_width(40); - size->set_height(40); - } - virtual std::string GetDialogArgs() const { - return std::string(); - } - virtual void OnDialogClosed(const std::string& json_retval) { } - virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) { - if (out_close_dialog) - *out_close_dialog = true; - } - virtual bool ShouldShowDialogTitle() const { return true; } -}; - -} // namespace - -class HtmlDialogBrowserTest : public InProcessBrowserTest { - public: - HtmlDialogBrowserTest() {} - -#if defined(OS_WIN) - class WindowChangedObserver : public base::MessagePumpForUI::Observer { - public: - WindowChangedObserver() {} - - static WindowChangedObserver* Get() { - return Singleton<WindowChangedObserver>::get(); - } - - // This method is called before processing a message. - virtual void WillProcessMessage(const MSG& msg) {} - - // This method is called after processing a message. - virtual void DidProcessMessage(const MSG& msg) { - // Either WM_PAINT or WM_TIMER indicates the actual work of - // pushing through the window resizing messages is done since - // they are lower priority (we don't get to see the - // WM_WINDOWPOSCHANGED message here). - if (msg.message == WM_PAINT || msg.message == WM_TIMER) - MessageLoop::current()->Quit(); - } - }; -#elif !defined(OS_MACOSX) - class WindowChangedObserver : public base::MessagePumpForUI::Observer { - public: - WindowChangedObserver() {} - - static WindowChangedObserver* Get() { - return Singleton<WindowChangedObserver>::get(); - } - - // This method is called before processing a message. - virtual void WillProcessEvent(GdkEvent* event) {} - - // This method is called after processing a message. - virtual void DidProcessEvent(GdkEvent* event) { - // Quit once the GDK_CONFIGURE event has been processed - seeing - // this means the window sizing request that was made actually - // happened. - if (event->type == GDK_CONFIGURE) - MessageLoop::current()->Quit(); - } - }; -#endif -}; - -#if defined(OS_LINUX) -#define MAYBE_SizeWindow SizeWindow -#else -// http://code.google.com/p/chromium/issues/detail?id=52602 -// Windows has some issues resizing windows- an off by one problem, -// and a minimum size that seems too big. This file isn't included in -// Mac builds yet. -#define MAYBE_SizeWindow DISABLED_SizeWindow -#endif - -IN_PROC_BROWSER_TEST_F(HtmlDialogBrowserTest, MAYBE_SizeWindow) { - HtmlDialogUIDelegate* delegate = new TestHtmlDialogUIDelegate(); - - HtmlDialogView* html_view = - new HtmlDialogView(browser()->profile(), delegate); - TabContents* tab_contents = browser()->GetSelectedTabContents(); - ASSERT_TRUE(tab_contents != NULL); - views::Window::CreateChromeWindow(tab_contents->GetMessageBoxRootWindow(), - gfx::Rect(), html_view); - html_view->InitDialog(); - html_view->window()->Show(); - - MessageLoopForUI::current()->AddObserver(WindowChangedObserver::Get()); - - gfx::Rect bounds; - html_view->GetWidget()->GetBounds(&bounds, false); - - gfx::Rect set_bounds = bounds; - gfx::Rect actual_bounds, rwhv_bounds; - - // Bigger than the default in both dimensions. - set_bounds.set_width(400); - set_bounds.set_height(300); - - html_view->MoveContents(tab_contents, set_bounds); - ui_test_utils::RunMessageLoop(); - html_view->GetWidget()->GetBounds(&actual_bounds, false); - EXPECT_EQ(set_bounds, actual_bounds); - - rwhv_bounds = - html_view->tab_contents()->GetRenderWidgetHostView()->GetViewBounds(); - EXPECT_LT(0, rwhv_bounds.width()); - EXPECT_LT(0, rwhv_bounds.height()); - EXPECT_GE(set_bounds.width(), rwhv_bounds.width()); - EXPECT_GE(set_bounds.height(), rwhv_bounds.height()); - - // Larger in one dimension and smaller in the other. - set_bounds.set_width(550); - set_bounds.set_height(250); - - html_view->MoveContents(tab_contents, set_bounds); - ui_test_utils::RunMessageLoop(); - html_view->GetWidget()->GetBounds(&actual_bounds, false); - EXPECT_EQ(set_bounds, actual_bounds); - - rwhv_bounds = - html_view->tab_contents()->GetRenderWidgetHostView()->GetViewBounds(); - EXPECT_LT(0, rwhv_bounds.width()); - EXPECT_LT(0, rwhv_bounds.height()); - EXPECT_GE(set_bounds.width(), rwhv_bounds.width()); - EXPECT_GE(set_bounds.height(), rwhv_bounds.height()); - - // Get very small. - set_bounds.set_width(kMinimumWidthToTestFor); - set_bounds.set_height(kMinimumHeightToTestFor); - - html_view->MoveContents(tab_contents, set_bounds); - ui_test_utils::RunMessageLoop(); - html_view->GetWidget()->GetBounds(&actual_bounds, false); - EXPECT_EQ(set_bounds, actual_bounds); - - rwhv_bounds = - html_view->tab_contents()->GetRenderWidgetHostView()->GetViewBounds(); - EXPECT_LT(0, rwhv_bounds.width()); - EXPECT_LT(0, rwhv_bounds.height()); - EXPECT_GE(set_bounds.width(), rwhv_bounds.width()); - EXPECT_GE(set_bounds.height(), rwhv_bounds.height()); - - // Check to make sure we can't get to 0x0 - set_bounds.set_width(0); - set_bounds.set_height(0); - - html_view->MoveContents(tab_contents, set_bounds); - ui_test_utils::RunMessageLoop(); - html_view->GetWidget()->GetBounds(&actual_bounds, false); - EXPECT_LT(0, actual_bounds.width()); - EXPECT_LT(0, actual_bounds.height()); - - MessageLoopForUI::current()->RemoveObserver(WindowChangedObserver::Get()); -} diff --git a/chrome/browser/views/hung_renderer_view.cc b/chrome/browser/views/hung_renderer_view.cc deleted file mode 100644 index 775623e..0000000 --- a/chrome/browser/views/hung_renderer_view.cc +++ /dev/null @@ -1,464 +0,0 @@ -// 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/hung_renderer_dialog.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/i18n/rtl.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/logging_chrome.h" -#include "chrome/common/result_codes.h" -#include "gfx/canvas.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/grid_layout.h" -#include "views/controls/button/native_button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/table/group_table_view.h" -#include "views/standard_layout.h" -#include "views/window/client_view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -class HungRendererDialogView; - -namespace { -// We only support showing one of these at a time per app. -HungRendererDialogView* g_instance = NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -// HungPagesTableModel - -class HungPagesTableModel : public views::GroupTableModel { - public: - HungPagesTableModel(); - virtual ~HungPagesTableModel(); - - void InitForTabContents(TabContents* hung_contents); - - // Overridden from views::GroupTableModel: - virtual int RowCount(); - virtual std::wstring GetText(int row, int column_id); - virtual SkBitmap GetIcon(int row); - virtual void SetObserver(TableModelObserver* observer); - virtual void GetGroupRangeForItem(int item, views::GroupRange* range); - - private: - typedef std::vector<TabContents*> TabContentsVector; - TabContentsVector tab_contentses_; - - TableModelObserver* observer_; - - DISALLOW_COPY_AND_ASSIGN(HungPagesTableModel); -}; - -/////////////////////////////////////////////////////////////////////////////// -// HungPagesTableModel, public: - -HungPagesTableModel::HungPagesTableModel() : observer_(NULL) { -} - -HungPagesTableModel::~HungPagesTableModel() { -} - -void HungPagesTableModel::InitForTabContents(TabContents* hung_contents) { - tab_contentses_.clear(); - for (TabContentsIterator it; !it.done(); ++it) { - if (it->GetRenderProcessHost() == hung_contents->GetRenderProcessHost()) - tab_contentses_.push_back(*it); - } - // The world is different. - if (observer_) - observer_->OnModelChanged(); -} - -/////////////////////////////////////////////////////////////////////////////// -// HungPagesTableModel, views::GroupTableModel implementation: - -int HungPagesTableModel::RowCount() { - return static_cast<int>(tab_contentses_.size()); -} - -std::wstring HungPagesTableModel::GetText(int row, int column_id) { - DCHECK(row >= 0 && row < RowCount()); - std::wstring title = UTF16ToWideHack(tab_contentses_[row]->GetTitle()); - if (title.empty()) - title = UTF16ToWideHack(TabContents::GetDefaultTitle()); - // TODO(xji): Consider adding a special case if the title text is a URL, - // since those should always have LTR directionality. Please refer to - // http://crbug.com/6726 for more information. - base::i18n::AdjustStringForLocaleDirection(title, &title); - return title; -} - -SkBitmap HungPagesTableModel::GetIcon(int row) { - DCHECK(row >= 0 && row < RowCount()); - return tab_contentses_.at(row)->GetFavIcon(); -} - -void HungPagesTableModel::SetObserver(TableModelObserver* observer) { - observer_ = observer; -} - -void HungPagesTableModel::GetGroupRangeForItem(int item, - views::GroupRange* range) { - DCHECK(range); - range->start = 0; - range->length = RowCount(); -} - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView - -class HungRendererDialogView : public views::View, - public views::DialogDelegate, - public views::ButtonListener { - public: - HungRendererDialogView(); - ~HungRendererDialogView(); - - void ShowForTabContents(TabContents* contents); - void EndForTabContents(TabContents* contents); - - // views::WindowDelegate overrides: - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual int GetDialogButtons() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual views::View* GetExtraView(); - virtual bool Accept(bool window_closing); - virtual views::View* GetContentsView(); - - // views::ButtonListener overrides: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - private: - // Initialize the controls in this dialog. - void Init(); - void CreateKillButtonView(); - - // Returns the bounds the dialog should be displayed at to be meaningfully - // associated with the specified TabContents. - gfx::Rect GetDisplayBounds(TabContents* contents); - - static void InitClass(); - - // Controls within the dialog box. - views::ImageView* frozen_icon_view_; - views::Label* info_label_; - views::GroupTableView* hung_pages_table_; - - // The button we insert into the ClientView to kill the errant process. This - // is parented to a container view that uses a grid layout to align it - // properly. - views::NativeButton* kill_button_; - class ButtonContainer : public views::View { - public: - ButtonContainer() {} - virtual ~ButtonContainer() {} - private: - DISALLOW_COPY_AND_ASSIGN(ButtonContainer); - }; - ButtonContainer* kill_button_container_; - - // The model that provides the contents of the table that shows a list of - // pages affected by the hang. - scoped_ptr<HungPagesTableModel> hung_pages_table_model_; - - // The TabContents that we detected had hung in the first place resulting in - // the display of this view. - TabContents* contents_; - - // Whether or not we've created controls for ourself. - bool initialized_; - - // An amusing icon image. - static SkBitmap* frozen_icon_; - - DISALLOW_COPY_AND_ASSIGN(HungRendererDialogView); -}; - -// static -SkBitmap* HungRendererDialogView::frozen_icon_ = NULL; - -// The distance in pixels from the top of the relevant contents to place the -// warning window. -static const int kOverlayContentsOffsetY = 50; - -// The dimensions of the hung pages list table view, in pixels. -static const int kTableViewWidth = 300; -static const int kTableViewHeight = 100; - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, public: - -HungRendererDialogView::HungRendererDialogView() - : frozen_icon_view_(NULL), - info_label_(NULL), - hung_pages_table_(NULL), - kill_button_(NULL), - kill_button_container_(NULL), - contents_(NULL), - initialized_(false) { - InitClass(); -} - -HungRendererDialogView::~HungRendererDialogView() { - hung_pages_table_->SetModel(NULL); -} - -void HungRendererDialogView::ShowForTabContents(TabContents* contents) { - DCHECK(contents && window()); - contents_ = contents; - - // Don't show the warning unless the foreground window is the frame, or this - // window (but still invisible). If the user has another window or - // application selected, activating ourselves is rude. - HWND frame_hwnd = GetAncestor(contents->GetNativeView(), GA_ROOT); - HWND foreground_window = GetForegroundWindow(); - if (foreground_window != frame_hwnd && - foreground_window != window()->GetNativeWindow()) { - return; - } - - if (!window()->IsActive()) { - gfx::Rect bounds = GetDisplayBounds(contents); - window()->SetBounds(bounds, frame_hwnd); - - // We only do this if the window isn't active (i.e. hasn't been shown yet, - // or is currently shown but deactivated for another TabContents). This is - // because this window is a singleton, and it's possible another active - // renderer may hang while this one is showing, and we don't want to reset - // the list of hung pages for a potentially unrelated renderer while this - // one is showing. - hung_pages_table_model_->InitForTabContents(contents); - window()->Show(); - } -} - -void HungRendererDialogView::EndForTabContents(TabContents* contents) { - DCHECK(contents); - if (contents_ && contents_->GetRenderProcessHost() == - contents->GetRenderProcessHost()) { - window()->Close(); - // Since we're closing, we no longer need this TabContents. - contents_ = NULL; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, views::DialogDelegate implementation: - -std::wstring HungRendererDialogView::GetWindowTitle() const { - return l10n_util::GetString(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE); -} - -void HungRendererDialogView::WindowClosing() { - // We are going to be deleted soon, so make sure our instance is destroyed. - g_instance = NULL; -} - -int HungRendererDialogView::GetDialogButtons() const { - // We specifically don't want a CANCEL button here because that code path is - // also called when the window is closed by the user clicking the X button in - // the window's titlebar, and also if we call Window::Close. Rather, we want - // the OK button to wait for responsiveness (and close the dialog) and our - // additional button (which we create) to kill the process (which will result - // in the dialog being destroyed). - return MessageBoxFlags::DIALOGBUTTON_OK; -} - -std::wstring HungRendererDialogView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - return l10n_util::GetString(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT); - return std::wstring(); -} - -views::View* HungRendererDialogView::GetExtraView() { - return kill_button_container_; -} - -bool HungRendererDialogView::Accept(bool window_closing) { - // Don't do anything if we're being called only because the dialog is being - // destroyed and we don't supply a Cancel function... - if (window_closing) - return true; - - // Start waiting again for responsiveness. - if (contents_ && contents_->render_view_host()) - contents_->render_view_host()->RestartHangMonitorTimeout(); - return true; -} - -views::View* HungRendererDialogView::GetContentsView() { - return this; -} - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, views::ButtonListener implementation: - -void HungRendererDialogView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == kill_button_) { - if (contents_ && contents_->GetRenderProcessHost()) { - // Kill the process. - TerminateProcess(contents_->GetRenderProcessHost()->GetHandle(), - ResultCodes::HUNG); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, views::View overrides: - -void HungRendererDialogView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (!initialized_ && is_add && child == this && GetWidget()) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, private: - -void HungRendererDialogView::Init() { - frozen_icon_view_ = new views::ImageView; - frozen_icon_view_->SetImage(frozen_icon_); - - info_label_ = new views::Label( - l10n_util::GetString(IDS_BROWSER_HANGMONITOR_RENDERER)); - info_label_->SetMultiLine(true); - info_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - hung_pages_table_model_.reset(new HungPagesTableModel); - std::vector<TableColumn> columns; - columns.push_back(TableColumn()); - hung_pages_table_ = new views::GroupTableView( - hung_pages_table_model_.get(), columns, views::ICON_AND_TEXT, true, - false, true); - hung_pages_table_->SetPreferredSize( - gfx::Size(kTableViewWidth, kTableViewHeight)); - - CreateKillButtonView(); - - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int double_column_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(double_column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, - GridLayout::FIXED, frozen_icon_->width(), 0); - column_set->AddPaddingColumn(0, kUnrelatedControlLargeHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, double_column_set_id); - layout->AddView(frozen_icon_view_, 1, 3); - layout->AddView(info_label_); - - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - layout->StartRow(0, double_column_set_id); - layout->SkipColumns(1); - layout->AddView(hung_pages_table_); - - initialized_ = true; -} - -void HungRendererDialogView::CreateKillButtonView() { - kill_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_BROWSER_HANGMONITOR_RENDERER_END)); - - kill_button_container_ = new ButtonContainer; - - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = new GridLayout(kill_button_container_); - kill_button_container_->SetLayoutManager(layout); - - const int single_column_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_set_id); - column_set->AddPaddingColumn(0, frozen_icon_->width() + - kPanelHorizMargin + kUnrelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_set_id); - layout->AddView(kill_button_); -} - -gfx::Rect HungRendererDialogView::GetDisplayBounds( - TabContents* contents) { - HWND contents_hwnd = contents->GetNativeView(); - RECT contents_bounds_rect; - GetWindowRect(contents_hwnd, &contents_bounds_rect); - gfx::Rect contents_bounds(contents_bounds_rect); - gfx::Rect window_bounds = window()->GetBounds(); - - int window_x = contents_bounds.x() + - (contents_bounds.width() - window_bounds.width()) / 2; - int window_y = contents_bounds.y() + kOverlayContentsOffsetY; - return gfx::Rect(window_x, window_y, window_bounds.width(), - window_bounds.height()); -} - -// static -void HungRendererDialogView::InitClass() { - static bool initialized = false; - if (!initialized) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - frozen_icon_ = rb.GetBitmapNamed(IDR_FROZEN_TAB_ICON); - initialized = true; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialog - - -static HungRendererDialogView* CreateHungRendererDialogView() { - HungRendererDialogView* cv = new HungRendererDialogView; - views::Window::CreateChromeWindow(NULL, gfx::Rect(), cv); - return cv; -} - -namespace hung_renderer_dialog { - -void ShowForTabContents(TabContents* contents) { - if (!logging::DialogsAreSuppressed()) { - if (!g_instance) - g_instance = CreateHungRendererDialogView(); - g_instance->ShowForTabContents(contents); - } -} - -// static -void HideForTabContents(TabContents* contents) { - if (!logging::DialogsAreSuppressed() && g_instance) - g_instance->EndForTabContents(contents); -} - -} // namespace hung_renderer_dialog - diff --git a/chrome/browser/views/importer_lock_view.cc b/chrome/browser/views/importer_lock_view.cc deleted file mode 100644 index 8fc1c9a..0000000 --- a/chrome/browser/views/importer_lock_view.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2006-2008 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/importer_lock_view.h" - -#include "app/l10n_util.h" -#include "base/message_loop.h" -#include "chrome/browser/importer/importer.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/label.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -// Default size of the dialog window. -static const int kDefaultWindowWidth = 320; -static const int kDefaultWindowHeight = 100; - -ImporterLockView::ImporterLockView(ImporterHost* host) - : description_label_(NULL), - importer_host_(host) { - description_label_ = new views::Label( - l10n_util::GetString(IDS_IMPORTER_LOCK_TEXT)); - description_label_->SetMultiLine(true); - description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(description_label_); -} - -ImporterLockView::~ImporterLockView() { -} - -gfx::Size ImporterLockView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_IMPORTLOCK_DIALOG_WIDTH_CHARS, - IDS_IMPORTLOCK_DIALOG_HEIGHT_LINES)); -} - -void ImporterLockView::Layout() { - description_label_->SetBounds(kPanelHorizMargin, kPanelVertMargin, - width() - 2 * kPanelHorizMargin, - height() - 2 * kPanelVertMargin); -} - -std::wstring ImporterLockView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return l10n_util::GetString(IDS_IMPORTER_LOCK_OK); - } else if (button == MessageBoxFlags::DIALOGBUTTON_CANCEL) { - return l10n_util::GetString(IDS_IMPORTER_LOCK_CANCEL); - } - return std::wstring(); -} - -bool ImporterLockView::IsModal() const { - return false; -} - -std::wstring ImporterLockView::GetWindowTitle() const { - return l10n_util::GetString(IDS_IMPORTER_LOCK_TITLE); -} - -bool ImporterLockView::Accept() { - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - importer_host_, &ImporterHost::OnLockViewEnd, true)); - return true; -} - -bool ImporterLockView::Cancel() { - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - importer_host_, &ImporterHost::OnLockViewEnd, false)); - return true; -} - -views::View* ImporterLockView::GetContentsView() { - return this; -} diff --git a/chrome/browser/views/importer_lock_view.h b/chrome/browser/views/importer_lock_view.h index d974f38..1c64d40 100644 --- a/chrome/browser/views/importer_lock_view.h +++ b/chrome/browser/views/importer_lock_view.h @@ -2,47 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_IMPORTER_LOCK_VIEW_H__ -#define CHROME_BROWSER_VIEWS_IMPORTER_LOCK_VIEW_H__ +#ifndef CHROME_BROWSER_IMPORTER_LOCK_VIEW_H_ +#define CHROME_BROWSER_IMPORTER_LOCK_VIEW_H_ #pragma once -#include "views/view.h" -#include "views/window/dialog_delegate.h" +#include "chrome/browser/ui/views/importer_lock_view.h" +// TODO(beng): remove this file once all includes have been updated. -namespace views { -class Label; -class Window; -} +#endif // CHROME_BROWSER_IMPORTER_LOCK_VIEW_H_ -class ImporterHost; - -// ImporterLockView draws the dialog, and asks the user to shut Firefox -// down before starting the import. -class ImporterLockView : public views::View, - public views::DialogDelegate { - public: - explicit ImporterLockView(ImporterHost* host); - virtual ~ImporterLockView(); - - // Overridden from views::View. - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - // Overridden from views::DialogDelegate: - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool Accept(); - virtual bool Cancel(); - virtual views::View* GetContentsView(); - - private: - views::Label* description_label_; - - ImporterHost* importer_host_; - - DISALLOW_COPY_AND_ASSIGN(ImporterLockView); -}; - -#endif // CHROME_BROWSER_VIEWS_IMPORTER_LOCK_VIEW_H__ diff --git a/chrome/browser/views/importer_view.cc b/chrome/browser/views/importer_view.cc deleted file mode 100644 index 4ef686f..0000000 --- a/chrome/browser/views/importer_view.cc +++ /dev/null @@ -1,287 +0,0 @@ -// 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/importer_view.h" - -#include "app/l10n_util.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/importer/importer_data_types.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/label.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -using views::ColumnSet; -using views::GridLayout; - -namespace browser { - -// Declared in browser_dialogs.h so caller's don't have to depend on our header. -void ShowImporterView(views::Widget* parent, - Profile* profile) { - views::Window::CreateChromeWindow(parent->GetNativeView(), gfx::Rect(), - new ImporterView(profile, importer::ALL))->Show(); -} - -} // namespace browser - -ImporterView::ImporterView(Profile* profile, int initial_state) - : import_from_label_(NULL), - profile_combobox_(NULL), - import_items_label_(NULL), - history_checkbox_(NULL), - favorites_checkbox_(NULL), - passwords_checkbox_(NULL), - search_engines_checkbox_(NULL), - profile_(profile), - importer_host_(new ImporterHost()), - initial_state_(initial_state) { - DCHECK(profile); - SetupControl(); -} - -ImporterView::~ImporterView() { -} - -void ImporterView::SetupControl() { - // Adds all controls. - import_from_label_ = - new views::Label(l10n_util::GetString(IDS_IMPORT_FROM_LABEL)); - - profile_combobox_ = new views::Combobox(this); - profile_combobox_->set_listener(this); - profile_combobox_->SetAccessibleName(import_from_label_->GetText()); - - import_items_label_ = - new views::Label(l10n_util::GetString(IDS_IMPORT_ITEMS_LABEL)); - - history_checkbox_ = - InitCheckbox(l10n_util::GetString(IDS_IMPORT_HISTORY_CHKBOX), - (initial_state_ & importer::HISTORY) != 0); - favorites_checkbox_ = - InitCheckbox(l10n_util::GetString(IDS_IMPORT_FAVORITES_CHKBOX), - (initial_state_ & importer::FAVORITES) != 0); - passwords_checkbox_ = - InitCheckbox(l10n_util::GetString(IDS_IMPORT_PASSWORDS_CHKBOX), - (initial_state_ & importer::PASSWORDS) != 0); - search_engines_checkbox_ = - InitCheckbox(l10n_util::GetString(IDS_IMPORT_SEARCH_ENGINES_CHKBOX), - (initial_state_ & importer::SEARCH_ENGINES) != 0); - - // Arranges controls by using GridLayout. - const int column_set_id = 0; - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - ColumnSet* column_set = layout->AddColumnSet(column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::FIXED, 200, 0); - - layout->StartRow(0, column_set_id); - layout->AddView(import_from_label_); - layout->AddView(profile_combobox_); - - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - layout->StartRow(0, column_set_id); - layout->AddView(import_items_label_, 3, 1); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, column_set_id); - layout->AddView(favorites_checkbox_, 3, 1); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, column_set_id); - layout->AddView(search_engines_checkbox_, 3, 1); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, column_set_id); - layout->AddView(passwords_checkbox_, 3, 1); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, column_set_id); - layout->AddView(history_checkbox_, 3, 1); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); -} - -gfx::Size ImporterView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_IMPORT_DIALOG_WIDTH_CHARS, - IDS_IMPORT_DIALOG_HEIGHT_LINES)); -} - -void ImporterView::Layout() { - GetLayoutManager()->Layout(this); -} - -std::wstring ImporterView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return l10n_util::GetString(IDS_IMPORT_COMMIT); - } else { - return std::wstring(); - } -} - -bool ImporterView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return history_checkbox_->checked() || - favorites_checkbox_->checked() || - passwords_checkbox_->checked() || - search_engines_checkbox_->checked(); - } - - return true; -} - -bool ImporterView::IsModal() const { - return true; -} - -std::wstring ImporterView::GetWindowTitle() const { - return l10n_util::GetString(IDS_IMPORT_SETTINGS_TITLE); -} - -bool ImporterView::Accept() { - if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) { - return false; - } - - uint16 items = GetCheckedItems(); - - int selected_index = profile_combobox_->selected_item(); - StartImportingWithUI(GetWidget()->GetNativeView(), items, - importer_host_.get(), - importer_host_->GetSourceProfileInfoAt(selected_index), - profile_, this, false); - // We return false here to prevent the window from being closed. We will be - // notified back by our implementation of ImportObserver when the import is - // complete so that we can close ourselves. - return false; -} - -views::View* ImporterView::GetContentsView() { - return this; -} - -void ImporterView::ButtonPressed( - views::Button* sender, const views::Event& event) { - // When no checkbox is checked we should disable the "Import" button. - // This forces the button to evaluate what state they should be in. - GetDialogClientView()->UpdateDialogButtons(); -} - -int ImporterView::GetItemCount() { - DCHECK(importer_host_.get()); - int item_count = importer_host_->GetAvailableProfileCount(); - if (checkbox_items_.size() < static_cast<size_t>(item_count)) - checkbox_items_.resize(item_count, initial_state_); - return item_count; -} - -string16 ImporterView::GetItemAt(int index) { - DCHECK(importer_host_.get()); - return WideToUTF16Hack(importer_host_->GetSourceProfileNameAt(index)); -} - -void ImporterView::ItemChanged(views::Combobox* combobox, - int prev_index, int new_index) { - DCHECK(combobox); - DCHECK(checkbox_items_.size() >= - static_cast<size_t>(importer_host_->GetAvailableProfileCount())); - - if (prev_index == new_index) - return; - - // Save the current state - uint16 prev_items = GetCheckedItems(); - checkbox_items_[prev_index] = prev_items; - - // Enable/Disable the checkboxes for this Item - uint16 new_enabled_items = importer_host_->GetSourceProfileInfoAt( - new_index).services_supported; - SetCheckedItemsState(new_enabled_items); - - // Set the checked items for this Item - uint16 new_items = checkbox_items_[new_index]; - SetCheckedItems(new_items); -} - -void ImporterView::ImportCanceled() { - ImportComplete(); -} - -void ImporterView::ImportComplete() { - // Now close this window since the import completed or was canceled. - window()->Close(); -} - -views::Checkbox* ImporterView::InitCheckbox(const std::wstring& text, - bool checked) { - views::Checkbox* checkbox = new views::Checkbox(text); - checkbox->SetChecked(checked); - checkbox->set_listener(this); - return checkbox; -} - -uint16 ImporterView::GetCheckedItems() { - uint16 items = importer::NONE; - if (history_checkbox_->IsEnabled() && history_checkbox_->checked()) - items |= importer::HISTORY; - if (favorites_checkbox_->IsEnabled() && favorites_checkbox_->checked()) - items |= importer::FAVORITES; - if (passwords_checkbox_->IsEnabled() && passwords_checkbox_->checked()) - items |= importer::PASSWORDS; - if (search_engines_checkbox_->IsEnabled() && - search_engines_checkbox_->checked()) - items |= importer::SEARCH_ENGINES; - return items; -} - -void ImporterView::SetCheckedItemsState(uint16 items) { - if (items & importer::HISTORY) { - history_checkbox_->SetEnabled(true); - } else { - history_checkbox_->SetEnabled(false); - history_checkbox_->SetChecked(false); - } - if (items & importer::FAVORITES) { - favorites_checkbox_->SetEnabled(true); - } else { - favorites_checkbox_->SetEnabled(false); - favorites_checkbox_->SetChecked(false); - } - if (items & importer::PASSWORDS) { - passwords_checkbox_->SetEnabled(true); - } else { - passwords_checkbox_->SetEnabled(false); - passwords_checkbox_->SetChecked(false); - } - if (items & importer::SEARCH_ENGINES) { - search_engines_checkbox_->SetEnabled(true); - } else { - search_engines_checkbox_->SetEnabled(false); - search_engines_checkbox_->SetChecked(false); - } -} - -void ImporterView::SetCheckedItems(uint16 items) { - if (history_checkbox_->IsEnabled()) - history_checkbox_->SetChecked(!!(items & importer::HISTORY)); - - if (favorites_checkbox_->IsEnabled()) - favorites_checkbox_->SetChecked(!!(items & importer::FAVORITES)); - - if (passwords_checkbox_->IsEnabled()) - passwords_checkbox_->SetChecked(!!(items & importer::PASSWORDS)); - - if (search_engines_checkbox_->IsEnabled()) - search_engines_checkbox_->SetChecked(!!(items & - importer::SEARCH_ENGINES)); -} diff --git a/chrome/browser/views/importer_view.h b/chrome/browser/views/importer_view.h index 51044e5..44afa36 100644 --- a/chrome/browser/views/importer_view.h +++ b/chrome/browser/views/importer_view.h @@ -6,104 +6,8 @@ #define CHROME_BROWSER_VIEWS_IMPORTER_VIEW_H_ #pragma once -#include "app/combobox_model.h" -#include "base/string16.h" -#include "chrome/browser/importer/importer.h" -#include "views/controls/button/native_button.h" -#include "views/controls/combobox/combobox.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Checkbox; -class Label; -class Window; -} - -class Profile; - -// ImporterView draws the dialog that allows the user to select what to -// import from other browsers. -// Note: The UI team hasn't defined yet how the import UI will look like. -// So now use dialog as a placeholder. -class ImporterView : public views::View, - public views::DialogDelegate, - public views::ButtonListener, - public ComboboxModel, - public views::Combobox::Listener, - public ImportObserver { - public: - // Creates a new ImporterView. |initial_state| is a bitmask of ImportItems. - // Each checkbox for the bits in |initial_state| is checked. - ImporterView(Profile* profile, int initial_state); - virtual ~ImporterView(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - // Overridden from views::DialogDelegate: - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool Accept(); - virtual views::View* GetContentsView(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from ComboboxModel: - virtual int GetItemCount(); - virtual string16 GetItemAt(int index); - - // Overridden from ChromeViews::Combobox::Listener: - virtual void ItemChanged(views::Combobox* combobox, - int prev_index, - int new_index); - - // Overridden from ImportObserver: - virtual void ImportCanceled(); - virtual void ImportComplete(); - - private: - // Initializes the controls on the dialog. - void SetupControl(); - - // Creates and initializes a new check-box. - views::Checkbox* InitCheckbox(const std::wstring& text, bool checked); - - // Create a bitmap from the checkboxes of the view. - uint16 GetCheckedItems(); - - // Enables/Disables all the checked items for the given state. - void SetCheckedItemsState(uint16 items); - - // Sets all checked items in the given state. - void SetCheckedItems(uint16 items); - - views::Label* import_from_label_; - views::Combobox* profile_combobox_; - views::Label* import_items_label_; - views::Checkbox* history_checkbox_; - views::Checkbox* favorites_checkbox_; - views::Checkbox* passwords_checkbox_; - views::Checkbox* search_engines_checkbox_; - - scoped_refptr<ImporterHost> importer_host_; - - // Stores the state of the checked items associated with the position of the - // selected item in the combo-box. - std::vector<uint16> checkbox_items_; - - // Initial state of the |checkbox_items_|. - uint16 initial_state_; - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(ImporterView); -}; +#include "chrome/browser/ui/views/importer_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_IMPORTER_VIEW_H_ + diff --git a/chrome/browser/views/importing_progress_view.cc b/chrome/browser/views/importing_progress_view.cc deleted file mode 100644 index ae3135e..0000000 --- a/chrome/browser/views/importing_progress_view.cc +++ /dev/null @@ -1,312 +0,0 @@ -// 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/importing_progress_view.h" - -#include "app/l10n_util.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/throbber.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -//////////////////////////////////////////////////////////////////////////////// -// ImportingProgressView, public: - -ImportingProgressView::ImportingProgressView(const std::wstring& source_name, - int16 items, - ImporterHost* coordinator, - ImportObserver* observer, - HWND parent_window, - bool bookmarks_import) - : state_bookmarks_(new views::CheckmarkThrobber), - state_searches_(new views::CheckmarkThrobber), - state_passwords_(new views::CheckmarkThrobber), - state_history_(new views::CheckmarkThrobber), - state_cookies_(new views::CheckmarkThrobber), - label_bookmarks_(new views::Label( - l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS))), - label_searches_(new views::Label( - l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_SEARCH))), - label_passwords_(new views::Label( - l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_PASSWORDS))), - label_history_(new views::Label( - l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_HISTORY))), - label_cookies_(new views::Label( - l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_COOKIES))), - parent_window_(parent_window), - coordinator_(coordinator), - import_observer_(observer), - items_(items), - importing_(true), - bookmarks_import_(bookmarks_import) { - std::wstring info_text = bookmarks_import ? - l10n_util::GetString(IDS_IMPORT_BOOKMARKS) : - l10n_util::GetStringF(IDS_IMPORT_PROGRESS_INFO, source_name); - label_info_ = new views::Label(info_text); - coordinator_->SetObserver(this); - label_info_->SetMultiLine(true); - label_info_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label_bookmarks_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label_searches_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label_passwords_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label_history_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label_cookies_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - // These are scoped pointers, so we don't need the parent to delete them. - state_bookmarks_->set_parent_owned(false); - state_searches_->set_parent_owned(false); - state_passwords_->set_parent_owned(false); - state_history_->set_parent_owned(false); - state_cookies_->set_parent_owned(false); - label_bookmarks_->set_parent_owned(false); - label_searches_->set_parent_owned(false); - label_passwords_->set_parent_owned(false); - label_history_->set_parent_owned(false); - label_cookies_->set_parent_owned(false); -} - -ImportingProgressView::~ImportingProgressView() { - RemoveChildView(state_bookmarks_.get()); - RemoveChildView(state_searches_.get()); - RemoveChildView(state_passwords_.get()); - RemoveChildView(state_history_.get()); - RemoveChildView(state_cookies_.get()); - RemoveChildView(label_bookmarks_.get()); - RemoveChildView(label_searches_.get()); - RemoveChildView(label_passwords_.get()); - RemoveChildView(label_history_.get()); - RemoveChildView(label_cookies_.get()); - - if (importing_) { - // We're being deleted while importing, clean up state so that the importer - // doesn't have a reference to us and cancel the import. We can get here - // if our parent window is closed, which closes our window and deletes us. - importing_ = false; - coordinator_->SetObserver(NULL); - coordinator_->Cancel(); - if (import_observer_) - import_observer_->ImportComplete(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ImportingProgressView, ImporterObserver implementation: - -void ImportingProgressView::ImportItemStarted(importer::ImportItem item) { - DCHECK(items_ & item); - switch (item) { - case importer::FAVORITES: - state_bookmarks_->Start(); - break; - case importer::SEARCH_ENGINES: - state_searches_->Start(); - break; - case importer::PASSWORDS: - state_passwords_->Start(); - break; - case importer::HISTORY: - state_history_->Start(); - break; - case importer::COOKIES: - state_cookies_->Start(); - break; - } -} - -void ImportingProgressView::ImportItemEnded(importer::ImportItem item) { - DCHECK(items_ & item); - switch (item) { - case importer::FAVORITES: - state_bookmarks_->Stop(); - state_bookmarks_->SetChecked(true); - break; - case importer::SEARCH_ENGINES: - state_searches_->Stop(); - state_searches_->SetChecked(true); - break; - case importer::PASSWORDS: - state_passwords_->Stop(); - state_passwords_->SetChecked(true); - break; - case importer::HISTORY: - state_history_->Stop(); - state_history_->SetChecked(true); - break; - case importer::COOKIES: - state_cookies_->Stop(); - state_cookies_->SetChecked(true); - break; - } -} - -void ImportingProgressView::ImportStarted() { - importing_ = true; -} - -void ImportingProgressView::ImportEnded() { - // This can happen because: - // - the import completed successfully. - // - the import was canceled by the user. - // - the user chose to skip the import because they didn't want to shut down - // Firefox. - // In every case, we need to close the UI now. - importing_ = false; - coordinator_->SetObserver(NULL); - window()->Close(); - if (import_observer_) - import_observer_->ImportComplete(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ImportingProgressView, views::View overrides: - -gfx::Size ImportingProgressView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_IMPORTPROGRESS_DIALOG_WIDTH_CHARS, - IDS_IMPORTPROGRESS_DIALOG_HEIGHT_LINES)); -} - -void ImportingProgressView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - InitControlLayout(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ImportingProgressView, views::DialogDelegate implementation: - -int ImportingProgressView::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring ImportingProgressView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - DCHECK(button == MessageBoxFlags::DIALOGBUTTON_CANCEL); - return l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_CANCEL); -} - -bool ImportingProgressView::IsModal() const { - return parent_window_ != NULL; -} - -std::wstring ImportingProgressView::GetWindowTitle() const { - return l10n_util::GetString(IDS_IMPORT_PROGRESS_TITLE); -} - -bool ImportingProgressView::Cancel() { - // When the user cancels the import, we need to tell the coordinator to stop - // importing and return false so that the window lives long enough to receive - // ImportEnded, which will close the window. Closing the window results in - // another call to this function and at that point we must return true to - // allow the window to close. - if (!importing_) - return true; // We have received ImportEnded, so we can close. - - // Cancel the import and wait for further instructions. - coordinator_->Cancel(); - return false; -} - -views::View* ImportingProgressView::GetContentsView() { - return this; -} - -//////////////////////////////////////////////////////////////////////////////// -// ImportingProgressView, private: - -void ImportingProgressView::InitControlLayout() { - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - gfx::Size ps = state_history_->GetPreferredSize(); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - if (bookmarks_import_) { - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::FIXED, ps.width(), 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - } - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - const int double_column_view_set_id = 1; - column_set = layout->AddColumnSet(double_column_view_set_id); - column_set->AddPaddingColumn(0, kUnrelatedControlLargeHorizontalSpacing); - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::FIXED, ps.width(), 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kUnrelatedControlLargeHorizontalSpacing); - - layout->StartRow(0, single_column_view_set_id); - if (bookmarks_import_) - layout->AddView(state_bookmarks_.get()); - layout->AddView(label_info_); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - if (items_ & importer::HISTORY) { - layout->StartRow(0, double_column_view_set_id); - layout->AddView(state_history_.get()); - layout->AddView(label_history_.get()); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - if (items_ & importer::FAVORITES && !bookmarks_import_) { - layout->StartRow(0, double_column_view_set_id); - layout->AddView(state_bookmarks_.get()); - layout->AddView(label_bookmarks_.get()); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - if (items_ & importer::SEARCH_ENGINES) { - layout->StartRow(0, double_column_view_set_id); - layout->AddView(state_searches_.get()); - layout->AddView(label_searches_.get()); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - if (items_ & importer::PASSWORDS) { - layout->StartRow(0, double_column_view_set_id); - layout->AddView(state_passwords_.get()); - layout->AddView(label_passwords_.get()); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - if (items_ & importer::COOKIES) { - layout->StartRow(0, double_column_view_set_id); - layout->AddView(state_cookies_.get()); - layout->AddView(label_cookies_.get()); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// StartImportingWithUI - -void StartImportingWithUI(HWND parent_window, - uint16 items, - ImporterHost* coordinator, - const ProfileInfo& source_profile, - Profile* target_profile, - ImportObserver* observer, - bool first_run) { - DCHECK(items != 0); - ImportingProgressView* v = new ImportingProgressView( - source_profile.description, items, coordinator, observer, parent_window, - source_profile.browser_type == importer::BOOKMARKS_HTML); - views::Window* window = - views::Window::CreateChromeWindow(parent_window, gfx::Rect(), v); - - if (!coordinator->is_headless() && !first_run) - window->Show(); - - coordinator->StartImportSettings(source_profile, target_profile, items, - new ProfileWriter(target_profile), - first_run); -} diff --git a/chrome/browser/views/importing_progress_view.h b/chrome/browser/views/importing_progress_view.h index ec842e79..5805c52 100644 --- a/chrome/browser/views/importing_progress_view.h +++ b/chrome/browser/views/importing_progress_view.h @@ -6,90 +6,8 @@ #define CHROME_BROWSER_VIEWS_IMPORTING_PROGRESS_VIEW_H_ #pragma once -#include "chrome/browser/importer/importer.h" -#include "chrome/browser/importer/importer_data_types.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -namespace views { -class CheckmarkThrobber; -class Label; -} - -class ImportingProgressView : public views::View, - public views::DialogDelegate, - public ImporterHost::Observer { - public: - // |items| is a bitmask of ImportItems being imported. - // |bookmark_import| is true if we're importing bookmarks from a - // bookmarks.html file. - ImportingProgressView(const std::wstring& source_name, - int16 items, - ImporterHost* coordinator, - ImportObserver* observer, - HWND parent_window, - bool bookmarks_import); - virtual ~ImportingProgressView(); - - protected: - // Overridden from ImporterHost::Observer: - virtual void ImportItemStarted(importer::ImportItem item); - virtual void ImportItemEnded(importer::ImportItem item); - virtual void ImportStarted(); - virtual void ImportEnded(); - - // Overridden from views::DialogDelegate: - virtual int GetDialogButtons() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool Cancel(); - virtual views::View* GetContentsView(); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - private: - // Set up the control layout within this dialog. - void InitControlLayout(); - - // Various dialog controls. - scoped_ptr<views::CheckmarkThrobber> state_bookmarks_; - scoped_ptr<views::CheckmarkThrobber> state_searches_; - scoped_ptr<views::CheckmarkThrobber> state_passwords_; - scoped_ptr<views::CheckmarkThrobber> state_history_; - scoped_ptr<views::CheckmarkThrobber> state_cookies_; - views::Label* label_info_; - scoped_ptr<views::Label> label_bookmarks_; - scoped_ptr<views::Label> label_searches_; - scoped_ptr<views::Label> label_passwords_; - scoped_ptr<views::Label> label_history_; - scoped_ptr<views::Label> label_cookies_; - - // The native window that we are parented to. Can be NULL. - HWND parent_window_; - - // The importer host coordinating the import. - scoped_refptr<ImporterHost> coordinator_; - - // An object that wants to be notified when the import is complete. - ImportObserver* import_observer_; - - // The ImportItems we are importing. - int16 items_; - - // True if the import operation is in progress. - bool importing_; - - // Are we importing a bookmarks.html file? - bool bookmarks_import_; - - DISALLOW_COPY_AND_ASSIGN(ImportingProgressView); -}; +#include "chrome/browser/ui/views/importing_progress_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_IMPORTING_PROGRESS_VIEW_H_ + diff --git a/chrome/browser/views/indexed_db_info_view.cc b/chrome/browser/views/indexed_db_info_view.cc deleted file mode 100644 index 733ef6e..0000000 --- a/chrome/browser/views/indexed_db_info_view.cc +++ /dev/null @@ -1,131 +0,0 @@ -// 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/indexed_db_info_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "base/i18n/time_formatting.h" -#include "base/utf_string_conversions.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" - -static const int kIndexedDBInfoViewBorderSize = 1; -static const int kIndexedDBInfoViewInsetSize = 3; - -/////////////////////////////////////////////////////////////////////////////// -// IndexedDBInfoView, public: - -IndexedDBInfoView::IndexedDBInfoView() - : origin_value_field_(NULL), - size_value_field_(NULL), - last_modified_value_field_(NULL) { -} - -IndexedDBInfoView::~IndexedDBInfoView() { -} - -void IndexedDBInfoView::SetIndexedDBInfo( - const BrowsingDataIndexedDBHelper::IndexedDBInfo& indexed_db_info) { - origin_value_field_->SetText(UTF8ToWide(indexed_db_info.origin)); - size_value_field_->SetText( - FormatBytes(indexed_db_info.size, - GetByteDisplayUnits(indexed_db_info.size), - true)); - last_modified_value_field_->SetText( - base::TimeFormatFriendlyDateAndTime(indexed_db_info.last_modified)); - EnableIndexedDBDisplay(true); -} - -void IndexedDBInfoView::EnableIndexedDBDisplay(bool enabled) { - origin_value_field_->SetEnabled(enabled); - size_value_field_->SetEnabled(enabled); - last_modified_value_field_->SetEnabled(enabled); -} - -void IndexedDBInfoView::ClearIndexedDBDisplay() { - std::wstring no_cookie_string = - l10n_util::GetString(IDS_COOKIES_COOKIE_NONESELECTED); - origin_value_field_->SetText(no_cookie_string); - size_value_field_->SetText(no_cookie_string); - last_modified_value_field_->SetText(no_cookie_string); - EnableIndexedDBDisplay(false); -} - -/////////////////////////////////////////////////////////////////////////////// -// IndexedDBInfoView, views::View overrides: - -void IndexedDBInfoView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// IndexedDBInfoView, private: - -void IndexedDBInfoView::Init() { - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kIndexedDBInfoViewBorderSize, border_color); - set_border(border); - - views::Label* origin_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL)); - origin_value_field_ = new views::Textfield; - views::Label* size_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL)); - size_value_field_ = new views::Textfield; - views::Label* last_modified_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL)); - last_modified_value_field_ = new views::Textfield; - - using views::GridLayout; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kIndexedDBInfoViewInsetSize, - kIndexedDBInfoViewInsetSize, - kIndexedDBInfoViewInsetSize, - kIndexedDBInfoViewInsetSize); - SetLayoutManager(layout); - - int three_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, three_column_layout_id); - layout->AddView(origin_label); - layout->AddView(origin_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(size_label); - layout->AddView(size_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(last_modified_label); - layout->AddView(last_modified_value_field_); - - // Color these borderless text areas the same as the containing dialog. - SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); - // Now that the Textfields are in the view hierarchy, we can initialize them. - origin_value_field_->SetReadOnly(true); - origin_value_field_->RemoveBorder(); - origin_value_field_->SetBackgroundColor(text_area_background); - size_value_field_->SetReadOnly(true); - size_value_field_->RemoveBorder(); - size_value_field_->SetBackgroundColor(text_area_background); - last_modified_value_field_->SetReadOnly(true); - last_modified_value_field_->RemoveBorder(); - last_modified_value_field_->SetBackgroundColor(text_area_background); -} diff --git a/chrome/browser/views/indexed_db_info_view.h b/chrome/browser/views/indexed_db_info_view.h index 4be00a5..6f2ccb4 100644 --- a/chrome/browser/views/indexed_db_info_view.h +++ b/chrome/browser/views/indexed_db_info_view.h @@ -6,50 +6,8 @@ #define CHROME_BROWSER_VIEWS_INDEXED_DB_INFO_VIEW_H_ #pragma once -#include "views/view.h" -#include "chrome/browser/browsing_data_indexed_db_helper.h" - -namespace views { -class Label; -class Textfield; -} - -/////////////////////////////////////////////////////////////////////////////// -// IndexedDBInfoView -// -// Responsible for displaying a tabular grid of IndexedDB information. -class IndexedDBInfoView : public views::View { - public: - IndexedDBInfoView(); - virtual ~IndexedDBInfoView(); - - // Update the display from the specified Local Storage info. - void SetIndexedDBInfo( - const BrowsingDataIndexedDBHelper::IndexedDBInfo& - indexed_db_info); - - // Clears the cookie display to indicate that no or multiple local storages - // are selected. - void ClearIndexedDBDisplay(); - - // Enables or disables the local storate property text fields. - void EnableIndexedDBDisplay(bool enabled); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child); - - private: - // Set up the view layout - void Init(); - - // Individual property labels - views::Textfield* origin_value_field_; - views::Textfield* size_value_field_; - views::Textfield* last_modified_value_field_; - - DISALLOW_COPY_AND_ASSIGN(IndexedDBInfoView); -}; +#include "chrome/browser/ui/views/indexed_db_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INDEXED_DB_INFO_VIEW_H_ + diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc deleted file mode 100644 index 3ee1317..0000000 --- a/chrome/browser/views/info_bubble.cc +++ /dev/null @@ -1,542 +0,0 @@ -// 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/info_bubble.h" - -#include "app/keyboard_codes.h" -#include "chrome/browser/window_sizer.h" -#include "chrome/common/notification_service.h" -#include "gfx/canvas_skia.h" -#include "gfx/color_utils.h" -#include "gfx/path.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "views/fill_layout.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" -#include "views/window/client_view.h" -#include "views/window/window.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/wm_ipc.h" -#include "cros/chromeos_wm_ipc_enums.h" -#endif - -// How long the fade should last for. -static const int kHideFadeDurationMS = 200; - -// Background color of the bubble. -#if defined(OS_WIN) -const SkColor InfoBubble::kBackgroundColor = - color_utils::GetSysSkColor(COLOR_WINDOW); -#else -// TODO(beng): source from theme provider. -const SkColor InfoBubble::kBackgroundColor = SK_ColorWHITE; -#endif - -void BorderContents::Init() { - // Default arrow location. - BubbleBorder::ArrowLocation arrow_location = BubbleBorder::TOP_LEFT; - if (base::i18n::IsRTL()) - arrow_location = BubbleBorder::horizontal_mirror(arrow_location); - DCHECK(!bubble_border_); - bubble_border_ = new BubbleBorder(arrow_location); - set_border(bubble_border_); - bubble_border_->set_background_color(InfoBubble::kBackgroundColor); -} - -void BorderContents::SizeAndGetBounds( - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - bool allow_bubble_offscreen, - const gfx::Size& contents_size, - gfx::Rect* contents_bounds, - gfx::Rect* window_bounds) { - if (base::i18n::IsRTL()) - arrow_location = BubbleBorder::horizontal_mirror(arrow_location); - bubble_border_->set_arrow_location(arrow_location); - // Set the border. - set_border(bubble_border_); - bubble_border_->set_background_color(InfoBubble::kBackgroundColor); - - // Give the contents a margin. - gfx::Size local_contents_size(contents_size); - local_contents_size.Enlarge(kLeftMargin + kRightMargin, - kTopMargin + kBottomMargin); - - // Try putting the arrow in its initial location, and calculating the bounds. - *window_bounds = - bubble_border_->GetBounds(position_relative_to, local_contents_size); - if (!allow_bubble_offscreen) { - gfx::Rect monitor_bounds = GetMonitorBounds(position_relative_to); - if (!monitor_bounds.IsEmpty()) { - // Try to resize vertically if this does not fit on the screen. - MirrorArrowIfOffScreen(true, // |vertical|. - position_relative_to, monitor_bounds, - local_contents_size, &arrow_location, - window_bounds); - // Then try to resize horizontally if it still does not fit on the screen. - MirrorArrowIfOffScreen(false, // |vertical|. - position_relative_to, monitor_bounds, - local_contents_size, &arrow_location, - window_bounds); - } - } - - // Calculate the bounds of the contained contents (in window coordinates) by - // subtracting the border dimensions and margin amounts. - *contents_bounds = gfx::Rect(gfx::Point(), window_bounds->size()); - gfx::Insets insets; - bubble_border_->GetInsets(&insets); - contents_bounds->Inset(insets.left() + kLeftMargin, insets.top() + kTopMargin, - insets.right() + kRightMargin, insets.bottom() + kBottomMargin); -} - -gfx::Rect BorderContents::GetMonitorBounds(const gfx::Rect& rect) { - scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider( - WindowSizer::CreateDefaultMonitorInfoProvider()); - return monitor_provider->GetMonitorWorkAreaMatching(rect); -} - -void BorderContents::Paint(gfx::Canvas* canvas) { - // The border of this view creates an anti-aliased round-rect region for the - // contents, which we need to fill with the background color. - // NOTE: This doesn't handle an arrow location of "NONE", which has square top - // corners. - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(InfoBubble::kBackgroundColor); - gfx::Path path; - gfx::Rect bounds(GetLocalBounds(false)); - SkRect rect; - rect.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()), - SkIntToScalar(bounds.right()), SkIntToScalar(bounds.bottom())); - SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); - path.addRoundRect(rect, radius, radius); - canvas->AsCanvasSkia()->drawPath(path, paint); - - // Now we paint the border, so it will be alpha-blended atop the contents. - // This looks slightly better in the corners than drawing the contents atop - // the border. - PaintBorder(canvas); -} - -void BorderContents::MirrorArrowIfOffScreen( - bool vertical, - const gfx::Rect& position_relative_to, - const gfx::Rect& monitor_bounds, - const gfx::Size& local_contents_size, - BubbleBorder::ArrowLocation* arrow_location, - gfx::Rect* window_bounds) { - // If the bounds don't fit, move the arrow to its mirrored position to see if - // it improves things. - gfx::Insets offscreen_insets; - if (ComputeOffScreenInsets(monitor_bounds, *window_bounds, - &offscreen_insets) && - GetInsetsLength(offscreen_insets, vertical) > 0) { - BubbleBorder::ArrowLocation original_arrow_location = *arrow_location; - *arrow_location = - vertical ? BubbleBorder::vertical_mirror(*arrow_location) : - BubbleBorder::horizontal_mirror(*arrow_location); - - // Change the arrow and get the new bounds. - bubble_border_->set_arrow_location(*arrow_location); - *window_bounds = bubble_border_->GetBounds(position_relative_to, - local_contents_size); - gfx::Insets new_offscreen_insets; - // If there is more of the window offscreen, we'll keep the old arrow. - if (ComputeOffScreenInsets(monitor_bounds, *window_bounds, - &new_offscreen_insets) && - GetInsetsLength(new_offscreen_insets, vertical) >= - GetInsetsLength(offscreen_insets, vertical)) { - *arrow_location = original_arrow_location; - bubble_border_->set_arrow_location(*arrow_location); - *window_bounds = bubble_border_->GetBounds(position_relative_to, - local_contents_size); - } - } -} - -// static -bool BorderContents::ComputeOffScreenInsets(const gfx::Rect& monitor_bounds, - const gfx::Rect& window_bounds, - gfx::Insets* offscreen_insets) { - if (monitor_bounds.Contains(window_bounds)) - return false; - - if (!offscreen_insets) - return true; - - int top = 0; - int left = 0; - int bottom = 0; - int right = 0; - - if (window_bounds.y() < monitor_bounds.y()) - top = monitor_bounds.y() - window_bounds.y(); - if (window_bounds.x() < monitor_bounds.x()) - left = monitor_bounds.x() - window_bounds.x(); - if (window_bounds.bottom() > monitor_bounds.bottom()) - bottom = window_bounds.bottom() - monitor_bounds.bottom(); - if (window_bounds.right() > monitor_bounds.right()) - right = window_bounds.right() - monitor_bounds.right(); - - offscreen_insets->Set(top, left, bottom, right); - return true; -} - -// static -int BorderContents::GetInsetsLength(const gfx::Insets& insets, bool vertical) { - return vertical ? insets.height() : insets.width(); -} - -#if defined(OS_WIN) -// BorderWidget --------------------------------------------------------------- - -BorderWidget::BorderWidget() : border_contents_(NULL) { - set_window_style(WS_POPUP); - set_window_ex_style(WS_EX_TOOLWINDOW | WS_EX_LAYERED); -} - -void BorderWidget::Init(BorderContents* border_contents, HWND owner) { - DCHECK(!border_contents_); - border_contents_ = border_contents; - border_contents_->Init(); - WidgetWin::Init(owner, gfx::Rect()); - SetContentsView(border_contents_); - SetWindowPos(owner, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW); -} - -gfx::Rect BorderWidget::SizeAndGetBounds( - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - const gfx::Size& contents_size) { - // Ask the border view to calculate our bounds (and our contents'). - gfx::Rect contents_bounds; - gfx::Rect window_bounds; - border_contents_->SizeAndGetBounds(position_relative_to, arrow_location, - false, contents_size, &contents_bounds, - &window_bounds); - SetBounds(window_bounds); - - // Return |contents_bounds| in screen coordinates. - contents_bounds.Offset(window_bounds.origin()); - return contents_bounds; -} - -LRESULT BorderWidget::OnMouseActivate(HWND window, - UINT hit_test, - UINT mouse_message) { - // Never activate. - return MA_NOACTIVATE; -} -#endif - -// InfoBubble ----------------------------------------------------------------- - -// static -InfoBubble* InfoBubble::Show(views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - views::View* contents, - InfoBubbleDelegate* delegate) { - InfoBubble* window = new InfoBubble; - window->Init(parent, position_relative_to, arrow_location, - contents, delegate); - return window; -} - -#if defined(OS_CHROMEOS) -// static -InfoBubble* InfoBubble::ShowFocusless( - views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - views::View* contents, - InfoBubbleDelegate* delegate) { - InfoBubble* window = new InfoBubble(views::WidgetGtk::TYPE_POPUP); - window->Init(parent, position_relative_to, arrow_location, - contents, delegate); - return window; -} -#endif - -void InfoBubble::Close() { - if (show_status_ != kOpen) - return; - - show_status_ = kClosing; - - if (fade_away_on_close_) - FadeOut(); - else - DoClose(false); -} - -void InfoBubble::AnimationEnded(const Animation* animation) { - if (static_cast<int>(animation_->GetCurrentValue()) == 0) { - // When fading out we just need to close the bubble at the end - DoClose(false); - } else { -#if defined(OS_WIN) - // When fading in we need to remove the layered window style flag, since - // that style prevents some bubble content from working properly. - SetWindowLong(GWL_EXSTYLE, GetWindowLong(GWL_EXSTYLE) & ~WS_EX_LAYERED); -#endif - } -} - -void InfoBubble::AnimationProgressed(const Animation* animation) { -#if defined(OS_WIN) - // Set the opacity for the main contents window. - unsigned char opacity = static_cast<unsigned char>( - animation_->GetCurrentValue() * 255); - SetLayeredWindowAttributes(GetNativeView(), 0, - static_cast<byte>(opacity), LWA_ALPHA); - contents_->SchedulePaint(); - - // Also fade in/out the bubble border window. - border_->SetOpacity(opacity); - border_->border_contents()->SchedulePaint(); -#else - NOTIMPLEMENTED(); -#endif -} - -InfoBubble::InfoBubble() - : -#if defined(OS_LINUX) - WidgetGtk(TYPE_WINDOW), - border_contents_(NULL), -#elif defined(OS_WIN) - border_(NULL), -#endif - delegate_(NULL), - show_status_(kOpen), - fade_away_on_close_(false) { -} - -#if defined(OS_CHROMEOS) -InfoBubble::InfoBubble(views::WidgetGtk::Type type) - : WidgetGtk(type), - border_contents_(NULL), - delegate_(NULL), - show_status_(kOpen), - fade_away_on_close_(false) { -} -#endif - -void InfoBubble::Init(views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - views::View* contents, - InfoBubbleDelegate* delegate) { - delegate_ = delegate; - position_relative_to_ = position_relative_to; - arrow_location_ = arrow_location; - contents_ = contents; - - // Create the main window. -#if defined(OS_WIN) - views::Window* parent_window = parent->GetWindow(); - if (parent_window) - parent_window->DisableInactiveRendering(); - set_window_style(WS_POPUP | WS_CLIPCHILDREN); - int extended_style = WS_EX_TOOLWINDOW; - // During FadeIn we need to turn on the layered window style to deal with - // transparency. This flag needs to be reset after fading in is complete. - bool fade_in = delegate_ && delegate_->FadeInOnShow(); - if (fade_in) - extended_style |= WS_EX_LAYERED; - set_window_ex_style(extended_style); - - DCHECK(!border_); - border_ = new BorderWidget(); - - if (fade_in) { - border_->SetOpacity(0); - SetOpacity(0); - } - - border_->Init(CreateBorderContents(), parent->GetNativeView()); - - // We make the BorderWidget the owner of the InfoBubble HWND, so that the - // latter is displayed on top of the former. - WidgetWin::Init(border_->GetNativeView(), gfx::Rect()); - - SetWindowText(GetNativeView(), delegate_->accessible_name().c_str()); -#elif defined(OS_LINUX) - MakeTransparent(); - make_transient_to_parent(); - WidgetGtk::InitWithWidget(parent, gfx::Rect()); -#if defined(OS_CHROMEOS) - chromeos::WmIpc::instance()->SetWindowType( - GetNativeView(), - chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE, - NULL); -#endif -#endif - - // Create a View to hold the contents of the main window. - views::View* contents_view = new views::View; - // We add |contents_view| to ourselves before the AddChildView() call below so - // that when |contents| gets added, it will already have a widget, and thus - // any NativeButtons it creates in ViewHierarchyChanged() will be functional - // (e.g. calling SetChecked() on checkboxes is safe). - SetContentsView(contents_view); - // Adding |contents| as a child has to be done before we call - // contents->GetPreferredSize() below, since some supplied views don't - // actually initialize themselves until they're added to a hierarchy. - contents_view->AddChildView(contents); - - // Calculate and set the bounds for all windows and views. - gfx::Rect window_bounds; - -#if defined(OS_WIN) - // Initialize and position the border window. - window_bounds = border_->SizeAndGetBounds(position_relative_to, - arrow_location, - contents->GetPreferredSize()); - - // Make |contents| take up the entire contents view. - contents_view->SetLayoutManager(new views::FillLayout); - - // Paint the background color behind the contents. - contents_view->set_background( - views::Background::CreateSolidBackground(kBackgroundColor)); -#else - // Create a view to paint the border and background. - border_contents_ = CreateBorderContents(); - border_contents_->Init(); - gfx::Rect contents_bounds; - border_contents_->SizeAndGetBounds(position_relative_to, - arrow_location, false, contents->GetPreferredSize(), - &contents_bounds, &window_bounds); - // This new view must be added before |contents| so it will paint under it. - contents_view->AddChildView(0, border_contents_); - - // |contents_view| has no layout manager, so we have to explicitly position - // its children. - border_contents_->SetBounds(gfx::Rect(gfx::Point(), window_bounds.size())); - contents->SetBounds(contents_bounds); -#endif - SetBounds(window_bounds); - - // Register the Escape accelerator for closing. - GetFocusManager()->RegisterAccelerator( - views::Accelerator(app::VKEY_ESCAPE, false, false, false), this); - - // Done creating the bubble. - NotificationService::current()->Notify(NotificationType::INFO_BUBBLE_CREATED, - Source<InfoBubble>(this), - NotificationService::NoDetails()); - - // Show the window. -#if defined(OS_WIN) - border_->ShowWindow(SW_SHOW); - ShowWindow(SW_SHOW); - if (fade_in) - FadeIn(); -#elif defined(OS_LINUX) - views::WidgetGtk::Show(); -#endif -} - -BorderContents* InfoBubble::CreateBorderContents() { - return new BorderContents(); -} - -void InfoBubble::SizeToContents() { - gfx::Rect window_bounds; - -#if defined(OS_WIN) - // Initialize and position the border window. - window_bounds = border_->SizeAndGetBounds(position_relative_to_, - arrow_location_, - contents_->GetPreferredSize()); -#else - gfx::Rect contents_bounds; - border_contents_->SizeAndGetBounds(position_relative_to_, - arrow_location_, false, contents_->GetPreferredSize(), - &contents_bounds, &window_bounds); - // |contents_view| has no layout manager, so we have to explicitly position - // its children. - border_contents_->SetBounds(gfx::Rect(gfx::Point(), window_bounds.size())); - contents_->SetBounds(contents_bounds); -#endif - SetBounds(window_bounds); -} - -#if defined(OS_WIN) -void InfoBubble::OnActivate(UINT action, BOOL minimized, HWND window) { - // The popup should close when it is deactivated. - if (action == WA_INACTIVE) { - Close(); - } else if (action == WA_ACTIVE) { - DCHECK_GT(GetRootView()->GetChildViewCount(), 0); - GetRootView()->GetChildViewAt(0)->RequestFocus(); - } -} -#elif defined(OS_LINUX) -void InfoBubble::IsActiveChanged() { - if (!IsActive()) - Close(); -} -#endif - -void InfoBubble::DoClose(bool closed_by_escape) { - if (show_status_ == kClosed) - return; - - GetFocusManager()->UnregisterAccelerator( - views::Accelerator(app::VKEY_ESCAPE, false, false, false), this); - if (delegate_) - delegate_->InfoBubbleClosing(this, closed_by_escape); - show_status_ = kClosed; -#if defined(OS_WIN) - border_->Close(); - WidgetWin::Close(); -#elif defined(OS_LINUX) - WidgetGtk::Close(); -#endif -} - -void InfoBubble::FadeIn() { - Fade(true); // |fade_in|. -} - -void InfoBubble::FadeOut() { -#if defined(OS_WIN) - // The contents window cannot have the layered flag on by default, since its - // content doesn't always work inside a layered window, but when animating it - // is ok to set that style on the window for the purpose of fading it out. - SetWindowLong(GWL_EXSTYLE, GetWindowLong(GWL_EXSTYLE) | WS_EX_LAYERED); - // This must be the very next call, otherwise we can get flicker on close. - SetLayeredWindowAttributes(GetNativeView(), 0, - static_cast<byte>(255), LWA_ALPHA); -#endif - - Fade(false); // |fade_in|. -} - -void InfoBubble::Fade(bool fade_in) { - animation_.reset(new SlideAnimation(this)); - animation_->SetSlideDuration(kHideFadeDurationMS); - animation_->SetTweenType(Tween::LINEAR); - - animation_->Reset(fade_in ? 0.0 : 1.0); - if (fade_in) - animation_->Show(); - else - animation_->Hide(); -} - -bool InfoBubble::AcceleratorPressed(const views::Accelerator& accelerator) { - if (!delegate_ || delegate_->CloseOnEscape()) { - DoClose(true); - return true; - } - return false; -} diff --git a/chrome/browser/views/info_bubble.h b/chrome/browser/views/info_bubble.h index 52bffe4..bd7dba6 100644 --- a/chrome/browser/views/info_bubble.h +++ b/chrome/browser/views/info_bubble.h @@ -6,302 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFO_BUBBLE_H_ #pragma once -#include "app/slide_animation.h" -#include "third_party/skia/include/core/SkColor.h" -#include "views/accelerator.h" -#include "views/view.h" -#include "chrome/browser/views/bubble_border.h" -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#elif defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -// InfoBubble is used to display an arbitrary view above all other windows. -// Think of InfoBubble as a tooltip that allows you to embed an arbitrary view -// in the tooltip. Additionally the InfoBubble renders an arrow pointing at -// the region the info bubble is providing the information about. -// -// To use an InfoBubble, invoke Show() and it'll take care of the rest. The -// InfoBubble insets the contents for you, so the contents typically shouldn't -// have any additional margins. - -#if defined(OS_WIN) -class BorderWidget; -#endif -class InfoBubble; - -namespace views { -class Widget; -} - -namespace gfx { -class Path; -} - -// This is used to paint the border of the InfoBubble. Windows uses this via -// BorderWidget (see below), while others can use it directly in the bubble. -class BorderContents : public views::View { - public: - BorderContents() : bubble_border_(NULL) { } - - // Must be called before this object can be used. - void Init(); - - // Given the size of the contents and the rect to point at, returns the bounds - // of both the border and the contents inside the bubble. - // |arrow_location| specifies the preferred location for the arrow - // anchor. If the bubble does not fit on the monitor and - // |allow_bubble_offscreen| is false, the arrow location may change so the - // bubble shows entirely. - virtual void SizeAndGetBounds( - const gfx::Rect& position_relative_to, // In screen coordinates - BubbleBorder::ArrowLocation arrow_location, - bool allow_bubble_offscreen, - const gfx::Size& contents_size, - gfx::Rect* contents_bounds, // Returned in window coordinates - gfx::Rect* window_bounds); // Returned in screen coordinates - - protected: - virtual ~BorderContents() { } - - // Returns the bounds for the monitor showing the specified |rect|. - // Overridden in unit-tests. - virtual gfx::Rect GetMonitorBounds(const gfx::Rect& rect); - - // Margins between the contents and the inside of the border, in pixels. - static const int kLeftMargin = 6; - static const int kTopMargin = 6; - static const int kRightMargin = 6; - static const int kBottomMargin = 9; - - BubbleBorder* bubble_border_; - - private: - // Overridden from View: - virtual void Paint(gfx::Canvas* canvas); - - // Changes |arrow_location| to its mirrored version, vertically if |vertical| - // is true, horizontally otherwise, if |window_bounds| don't fit in - // |monitor_bounds|. - void MirrorArrowIfOffScreen(bool vertical, - const gfx::Rect& position_relative_to, - const gfx::Rect& monitor_bounds, - const gfx::Size& local_contents_size, - BubbleBorder::ArrowLocation* arrow_location, - gfx::Rect* window_bounds); - - // Computes how much |window_bounds| is off-screen of the monitor bounds - // |monitor_bounds| and puts the values in |offscreen_insets|. - // Returns false if |window_bounds| is actually contained in |monitor_bounds|, - // in which case |offscreen_insets| is not modified. - static bool ComputeOffScreenInsets(const gfx::Rect& monitor_bounds, - const gfx::Rect& window_bounds, - gfx::Insets* offscreen_insets); - - // Convenience methods that returns the height of |insets| if |vertical| is - // true, its width otherwise. - static int GetInsetsLength(const gfx::Insets& insets, bool vertical); - - DISALLOW_COPY_AND_ASSIGN(BorderContents); -}; - -#if defined(OS_WIN) -// This is a window that surrounds the info bubble and paints the margin and -// border. It is a separate window so that it can be a layered window, so that -// we can use >1-bit alpha shadow images on the borders, which look nicer than -// the Windows CS_DROPSHADOW shadows. The info bubble window itself cannot be a -// layered window because that prevents it from hosting native child controls. -class BorderWidget : public views::WidgetWin { - public: - BorderWidget(); - virtual ~BorderWidget() { } - - // Initializes the BrowserWidget making |owner| its owning window. - void Init(BorderContents* border_contents, HWND owner); - - // Given the size of the contained contents (without margins), and the rect - // (in screen coordinates) to point to, sets the border window positions and - // sizes the border window and returns the bounds (in screen coordinates) the - // contents should use. |arrow_location| is prefered arrow location, - // the function tries to preserve the location and direction, in case of RTL - // arrow location is mirrored. - virtual gfx::Rect SizeAndGetBounds(const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - const gfx::Size& contents_size); - - // Simple accessors. - BorderContents* border_contents() { return border_contents_; } - - protected: - BorderContents* border_contents_; - - private: - // Overridden from WidgetWin: - virtual LRESULT OnMouseActivate(HWND window, - UINT hit_test, - UINT mouse_message); - - DISALLOW_COPY_AND_ASSIGN(BorderWidget); -}; -#endif - -class InfoBubbleDelegate { - public: - // Called when the InfoBubble is closing and is about to be deleted. - // |closed_by_escape| is true if the close is the result of the user pressing - // escape. - virtual void InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape) = 0; - - // Whether the InfoBubble should be closed when the Esc key is pressed. - virtual bool CloseOnEscape() = 0; - - // Whether the InfoBubble should fade in when opening. When trying to - // determine whether to use FadeIn, consider whether the bubble is shown as a - // direct result of a user action or not. For example, if the bubble is being - // shown as a direct result of a mouse-click, we should not use FadeIn. - // However, if the bubble appears as a notification that something happened - // in the background, we use FadeIn. - virtual bool FadeInOnShow() = 0; - - // The name of the window to which this delegate belongs. - virtual std::wstring accessible_name() { return L""; } -}; - -// TODO(sky): this code is ifdef-tastic. It might be cleaner to refactor the -// WidgetFoo subclass into a separate class that calls into InfoBubble. -// That way InfoBubble has no (or very few) ifdefs. -class InfoBubble -#if defined(OS_WIN) - : public views::WidgetWin, -#elif defined(OS_LINUX) - : public views::WidgetGtk, -#endif - public views::AcceleratorTarget, - public AnimationDelegate { - public: - // Shows the InfoBubble. |parent| is set as the parent window, |contents| are - // the contents shown in the bubble, and |position_relative_to| is a rect in - // screen coordinates at which the InfoBubble will point. Show() takes - // ownership of |contents| and deletes the created InfoBubble when another - // window is activated. You can explicitly close the bubble by invoking - // Close(). |arrow_location| specifies preferred bubble alignment. - // You may provide an optional |delegate| to: - // - Be notified when the InfoBubble is closed. - // - Prevent the InfoBubble from being closed when the Escape key is - // pressed (the default behavior). - static InfoBubble* Show(views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - views::View* contents, - InfoBubbleDelegate* delegate); - -#if defined(OS_CHROMEOS) - // Shows the InfoBubble not grabbing the focus. Others are the same as above. - // TYPE_POPUP widget is used to achieve the focusless effect. - static InfoBubble* ShowFocusless(views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - views::View* contents, - InfoBubbleDelegate* delegate); -#endif - - // Resizes and potentially moves the InfoBubble to best accommodate the - // contents preferred size. - void SizeToContents(); - - // Whether the InfoBubble should fade away when it closes. Generally speaking, - // we use FadeOut when the user selects something within the bubble that - // causes the bubble to dismiss. We don't use it when the bubble gets - // deactivated as a result of clicking outside the bubble. - void set_fade_away_on_close(bool fade_away_on_close) { - fade_away_on_close_ = fade_away_on_close; - } - - // Overridden from WidgetWin: - virtual void Close(); - - // Overridden from AnimationDelegate: - virtual void AnimationEnded(const Animation* animation); - virtual void AnimationProgressed(const Animation* animation); - - static const SkColor kBackgroundColor; - - protected: - InfoBubble(); -#if defined(OS_CHROMEOS) - explicit InfoBubble(views::WidgetGtk::Type type); -#endif - virtual ~InfoBubble() {} - - // Creates the InfoBubble. - virtual void Init(views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - views::View* contents, - InfoBubbleDelegate* delegate); - - // Instantiates and returns the BorderContents this InfoBubble should use. - // Subclasses can return their own BorderContents implementation. - virtual BorderContents* CreateBorderContents(); - -#if defined(OS_WIN) - // Overridden from WidgetWin: - virtual void OnActivate(UINT action, BOOL minimized, HWND window); -#elif defined(OS_LINUX) - // Overridden from WidgetGtk: - virtual void IsActiveChanged(); -#endif - -#if defined(OS_WIN) - // The window used to render the padding, border and arrow. - BorderWidget* border_; -#elif defined(OS_LINUX) - // The view displaying the border. - BorderContents* border_contents_; -#endif - - private: - enum ShowStatus { - kOpen, - kClosing, - kClosed - }; - - // Closes the window notifying the delegate. |closed_by_escape| is true if - // the close is the result of pressing escape. - void DoClose(bool closed_by_escape); - - // Animates to a visible state. - void FadeIn(); - // Animates to a hidden state. - void FadeOut(); - - // Animates to a visible/hidden state (visible if |fade_in| is true). - void Fade(bool fade_in); - - // Overridden from AcceleratorTarget: - virtual bool AcceleratorPressed(const views::Accelerator& accelerator); - - // The delegate, if any. - InfoBubbleDelegate* delegate_; - - // The animation used to fade the bubble out. - scoped_ptr<SlideAnimation> animation_; - - // The current visibility status of the bubble. - ShowStatus show_status_; - - // Whether to fade away when the bubble closes. - bool fade_away_on_close_; - - gfx::Rect position_relative_to_; - BubbleBorder::ArrowLocation arrow_location_; - - views::View* contents_; - - DISALLOW_COPY_AND_ASSIGN(InfoBubble); -}; +#include "chrome/browser/ui/views/info_bubble.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFO_BUBBLE_H_ + diff --git a/chrome/browser/views/info_bubble_unittest.cc b/chrome/browser/views/info_bubble_unittest.cc deleted file mode 100644 index 8d7f8ece..0000000 --- a/chrome/browser/views/info_bubble_unittest.cc +++ /dev/null @@ -1,237 +0,0 @@ -// 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/info_bubble.h" -#include "testing/gtest/include/gtest/gtest.h" - -typedef testing::Test InfoBubbleTest; - -class TestBorderContents : public BorderContents { - public: - TestBorderContents() {} - - void set_monitor_bounds(const gfx::Rect& bounds) { - monitor_bounds_ = bounds; - } - - BubbleBorder* bubble_border() const { return bubble_border_; } - - protected: - virtual gfx::Rect GetMonitorBounds(const gfx::Rect& rect) { - return monitor_bounds_; - } - - private: - gfx::Rect monitor_bounds_; - - DISALLOW_COPY_AND_ASSIGN(TestBorderContents); -}; - -// Tests that the arrow is moved appropriately when the info-bubble does not fit -// the screen. -TEST_F(InfoBubbleTest, BorderContentsSizeAndGetBounds) { - TestBorderContents border_contents; - border_contents.Init(); - - // Test that the info bubble displays normally when it fits. - gfx::Rect contents_bounds; - gfx::Rect window_bounds; - border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); - border_contents.SizeAndGetBounds( - gfx::Rect(100, 100, 50, 50), // |position_relative_to| - BubbleBorder::TOP_LEFT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - // The arrow shouldn't have changed from TOP_LEFT. - BubbleBorder::ArrowLocation arrow_location = - border_contents.bubble_border()->arrow_location(); - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); - EXPECT_GT(window_bounds.x(), 100); - EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for - // arrow overlap. - - // Test bubble not fitting on left. - border_contents.SizeAndGetBounds( - gfx::Rect(100, 100, 50, 50), // |position_relative_to| - BubbleBorder::TOP_RIGHT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to TOP_LEFT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); - EXPECT_GT(window_bounds.x(), 100); - EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for - // arrow overlap. - - // Test bubble not fitting on left or top. - border_contents.SizeAndGetBounds( - gfx::Rect(100, 100, 50, 50), // |position_relative_to| - BubbleBorder::BOTTOM_RIGHT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to TOP_LEFT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); - EXPECT_GT(window_bounds.x(), 100); - EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for - // arrow overlap. - - // Test bubble not fitting on top. - border_contents.SizeAndGetBounds( - gfx::Rect(100, 100, 50, 50), // |position_relative_to| - BubbleBorder::BOTTOM_LEFT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to TOP_LEFT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); - EXPECT_GT(window_bounds.x(), 100); - EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for - // arrow overlap. - - // Test bubble not fitting on top and right. - border_contents.SizeAndGetBounds( - gfx::Rect(900, 100, 50, 50), // |position_relative_to| - BubbleBorder::BOTTOM_LEFT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to TOP_RIGHT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); - EXPECT_LT(window_bounds.x(), 900 + 50 - 500); - EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for - // arrow overlap. - - // Test bubble not fitting on right. - border_contents.SizeAndGetBounds( - gfx::Rect(900, 100, 50, 50), // |position_relative_to| - BubbleBorder::TOP_LEFT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to TOP_RIGHT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); - EXPECT_LT(window_bounds.x(), 900 + 50 - 500); - EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for - // arrow overlap. - - // Test bubble not fitting on bottom and right. - border_contents.SizeAndGetBounds( - gfx::Rect(900, 900, 50, 50), // |position_relative_to| - BubbleBorder::TOP_LEFT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to BOTTOM_RIGHT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); - EXPECT_LT(window_bounds.x(), 900 + 50 - 500); - EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate - // for arrow height. - - // Test bubble not fitting at the bottom. - border_contents.SizeAndGetBounds( - gfx::Rect(100, 900, 50, 50), // |position_relative_to| - BubbleBorder::TOP_LEFT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to BOTTOM_LEFT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); - // The window should be right aligned with the position_relative_to. - EXPECT_LT(window_bounds.x(), 900 + 50 - 500); - EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate - // for arrow height. - - // Test bubble not fitting at the bottom and left. - border_contents.SizeAndGetBounds( - gfx::Rect(100, 900, 50, 50), // |position_relative_to| - BubbleBorder::TOP_RIGHT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - arrow_location = border_contents.bubble_border()->arrow_location(); - // The arrow should have changed to BOTTOM_LEFT. - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); - // The window should be right aligned with the position_relative_to. - EXPECT_LT(window_bounds.x(), 900 + 50 - 500); - EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate - // for arrow height. -} - -// Tests that the arrow is not moved when the info-bubble does not fit the -// screen but moving it would make matter worse. -TEST_F(InfoBubbleTest, BorderContentsSizeAndGetBoundsDontMoveArrow) { - TestBorderContents border_contents; - border_contents.Init(); - gfx::Rect contents_bounds; - gfx::Rect window_bounds; - border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); - border_contents.SizeAndGetBounds( - gfx::Rect(400, 100, 50, 50), // |position_relative_to| - BubbleBorder::TOP_LEFT, - false, // |allow_bubble_offscreen| - gfx::Size(500, 700), // |contents_size| - &contents_bounds, &window_bounds); - - // The arrow should not have changed, as it would make it the bubble even more - // offscreen. - BubbleBorder::ArrowLocation arrow_location = - border_contents.bubble_border()->arrow_location(); - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); -} - -// Test that the 'allow offscreen' prevents the bubble from moving. -TEST_F(InfoBubbleTest, BorderContentsSizeAndGetBoundsAllowOffscreen) { - TestBorderContents border_contents; - border_contents.Init(); - gfx::Rect contents_bounds; - gfx::Rect window_bounds; - border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); - border_contents.SizeAndGetBounds( - gfx::Rect(100, 900, 50, 50), // |position_relative_to| - BubbleBorder::TOP_RIGHT, - true, // |allow_bubble_offscreen| - gfx::Size(500, 500), // |contents_size| - &contents_bounds, &window_bounds); - - // The arrow should not have changed (eventhough the bubble does not fit). - BubbleBorder::ArrowLocation arrow_location = - border_contents.bubble_border()->arrow_location(); - EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); - EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); - EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); - // The coordinates should be pointing to 'positive relative to' from - // TOP_RIGHT. - EXPECT_LT(window_bounds.x(), 100 + 50 - 500); - EXPECT_GT(window_bounds.y(), 900 + 50 - 10); // -10 to roughly compensate for - // arrow overlap. -} diff --git a/chrome/browser/views/infobars/after_translate_infobar.cc b/chrome/browser/views/infobars/after_translate_infobar.cc deleted file mode 100644 index 63b6c8a..0000000 --- a/chrome/browser/views/infobars/after_translate_infobar.cc +++ /dev/null @@ -1,169 +0,0 @@ -// 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/infobars/after_translate_infobar.h" - -#include "app/l10n_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/translate/options_menu_model.h" -#include "chrome/browser/translate/translate_infobar_delegate.h" -#include "chrome/browser/views/infobars/infobar_button_border.h" -#include "chrome/browser/views/infobars/infobar_text_button.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/button/text_button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/menu/menu_2.h" - -AfterTranslateInfoBar::AfterTranslateInfoBar( - TranslateInfoBarDelegate* delegate) - : TranslateInfoBarBase(delegate), - original_language_menu_model_(delegate, LanguagesMenuModel::ORIGINAL), - target_language_menu_model_(delegate, LanguagesMenuModel::TARGET), - options_menu_model_(delegate), - swapped_language_buttons_(false) { - std::vector<string16> strings; - TranslateInfoBarDelegate::GetAfterTranslateStrings( - &strings, &swapped_language_buttons_); - DCHECK(strings.size() == 3U); - - label_1_ = CreateLabel(strings[0]); - AddChildView(label_1_); - - label_2_ = CreateLabel(strings[1]); - AddChildView(label_2_); - - label_3_ = CreateLabel(strings[2]); - AddChildView(label_3_); - - original_language_menu_button_ = CreateMenuButton(string16(), true, this); - AddChildView(original_language_menu_button_); - - target_language_menu_button_ = CreateMenuButton(string16(), true, this); - AddChildView(target_language_menu_button_); - - options_menu_button_ = - CreateMenuButton(l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), - false, this); - AddChildView(options_menu_button_); - - revert_button_ = InfoBarTextButton::Create(this, - l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_REVERT)); - AddChildView(revert_button_); - - UpdateLanguageButtonText(LanguagesMenuModel::ORIGINAL); - UpdateLanguageButtonText(LanguagesMenuModel::TARGET); -} - -AfterTranslateInfoBar::~AfterTranslateInfoBar() { -} - -// Overridden from views::View: -void AfterTranslateInfoBar::Layout() { - // Layout the icon and close button. - TranslateInfoBarBase::Layout(); - - // Layout the options menu button on right of bar. - int available_width = InfoBar::GetAvailableWidth(); - gfx::Size pref_size = options_menu_button_->GetPreferredSize(); - options_menu_button_->SetBounds(available_width - pref_size.width(), - OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - - views::MenuButton* left_button = swapped_language_buttons_ ? - target_language_menu_button_ : original_language_menu_button_; - views::MenuButton* right_button = swapped_language_buttons_ ? - original_language_menu_button_ : target_language_menu_button_; - - pref_size = label_1_->GetPreferredSize(); - label_1_->SetBounds(icon_->bounds().right() + InfoBar::kIconLabelSpacing, - InfoBar::OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - - pref_size = left_button->GetPreferredSize(); - left_button->SetBounds(label_1_->bounds().right() + - InfoBar::kButtonInLabelSpacing, OffsetY(this, pref_size), - pref_size.width(), pref_size.height()); - - pref_size = label_2_->GetPreferredSize(); - label_2_->SetBounds(left_button->bounds().right() + - InfoBar::kButtonInLabelSpacing, InfoBar::OffsetY(this, pref_size), - pref_size.width(), pref_size.height()); - - pref_size = right_button->GetPreferredSize(); - right_button->SetBounds(label_2_->bounds().right() + - InfoBar::kButtonInLabelSpacing, OffsetY(this, pref_size), - pref_size.width(), pref_size.height()); - - pref_size = label_3_->GetPreferredSize(); - label_3_->SetBounds(right_button->bounds().right() + - InfoBar::kButtonInLabelSpacing, InfoBar::OffsetY(this, pref_size), - pref_size.width(), pref_size.height()); - - pref_size = revert_button_->GetPreferredSize(); - revert_button_->SetBounds(label_3_->bounds().right() + - InfoBar::kButtonInLabelSpacing, InfoBar::OffsetY(this, pref_size), - pref_size.width(), pref_size.height()); -} - -void AfterTranslateInfoBar::OriginalLanguageChanged() { - UpdateLanguageButtonText(LanguagesMenuModel::ORIGINAL); -} - -void AfterTranslateInfoBar::TargetLanguageChanged() { - UpdateLanguageButtonText(LanguagesMenuModel::TARGET); -} - -void AfterTranslateInfoBar::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == revert_button_) { - GetDelegate()->RevertTranslation(); - return; - } - TranslateInfoBarBase::ButtonPressed(sender, event); -} - -void AfterTranslateInfoBar::RunMenu(views::View* source, - const gfx::Point& pt) { - if (source == original_language_menu_button_) { - if (!original_language_menu_.get()) { - original_language_menu_.reset( - new views::Menu2(&original_language_menu_model_)); - } - original_language_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); - } else if (source == target_language_menu_button_) { - if (!target_language_menu_.get()) { - target_language_menu_.reset( - new views::Menu2(&target_language_menu_model_)); - } - target_language_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); - } else if (source == options_menu_button_) { - if (!options_menu_.get()) - options_menu_.reset(new views::Menu2(&options_menu_model_)); - options_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); - } else { - NOTREACHED(); - } -} - -void AfterTranslateInfoBar::UpdateLanguageButtonText( - LanguagesMenuModel::LanguageType language_type) { - int language_index; - views::MenuButton* language_button; - if (language_type == LanguagesMenuModel::ORIGINAL) { - language_index = GetDelegate()->original_language_index(); - language_button = original_language_menu_button_; - } else { - language_index = GetDelegate()->target_language_index(); - language_button = target_language_menu_button_; - } - string16 language = - GetDelegate()->GetLanguageDisplayableNameAt(language_index); - language_button->SetText(UTF16ToWideHack(language)); - // The following line is necessary for the preferred size to be recomputed. - language_button->ClearMaxTextSize(); - // The button may have to grow to show the new text. - Layout(); - SchedulePaint(); -} diff --git a/chrome/browser/views/infobars/after_translate_infobar.h b/chrome/browser/views/infobars/after_translate_infobar.h index 1b94ec8..d0c8fcc 100644 --- a/chrome/browser/views/infobars/after_translate_infobar.h +++ b/chrome/browser/views/infobars/after_translate_infobar.h @@ -6,74 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_AFTER_TRANSLATE_INFOBAR_H_ #pragma once -#include "chrome/browser/translate/languages_menu_model.h" -#include "chrome/browser/translate/options_menu_model.h" -#include "chrome/browser/translate/translate_infobar_view.h" -#include "chrome/browser/views/infobars/translate_infobar_base.h" -#include "views/controls/button/button.h" -#include "views/controls/link.h" -#include "views/controls/menu/view_menu_delegate.h" - -class InfoBarTextButton; -class TranslateInfoBarDelegate; - -namespace views { -class Menu2; -class MenuButton; -} - -class AfterTranslateInfoBar : public TranslateInfoBarBase, - public views::ViewMenuDelegate { - public: - explicit AfterTranslateInfoBar(TranslateInfoBarDelegate* delegate); - virtual ~AfterTranslateInfoBar(); - - // Overridden from views::View: - virtual void Layout(); - - // Overridden from TranslateInfoBarView: - virtual void OriginalLanguageChanged(); - virtual void TargetLanguageChanged(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - protected: - // Overridden from views::ViewMenuDelegate: - virtual void RunMenu(View* source, const gfx::Point& pt); - - private: - // Sets the text of the original or target language menu buttons to reflect - // the current value from the delegate. - void UpdateLanguageButtonText(LanguagesMenuModel::LanguageType language); - - // The text displayed in the infobar is something like: - // "Translated from <lang1> to <lang2>" - // Where <lang1> and <lang2> are displayed in a combobox. - // So the text is split in 3 chunks, each one displayed in one of the label - // below. - views::Label* label_1_; - views::Label* label_2_; - views::Label* label_3_; - - views::MenuButton* original_language_menu_button_; - views::MenuButton* target_language_menu_button_; - views::MenuButton* options_menu_button_; - InfoBarTextButton* revert_button_; - - scoped_ptr<views::Menu2> original_language_menu_; - LanguagesMenuModel original_language_menu_model_; - - scoped_ptr<views::Menu2> target_language_menu_; - LanguagesMenuModel target_language_menu_model_; - - scoped_ptr<views::Menu2> options_menu_; - OptionsMenuModel options_menu_model_; - - // True if the target language comes before the original one. - bool swapped_language_buttons_; - - DISALLOW_COPY_AND_ASSIGN(AfterTranslateInfoBar); -}; +#include "chrome/browser/ui/views/infobars/after_translate_infobar.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_AFTER_TRANSLATE_INFOBAR_H_ + diff --git a/chrome/browser/views/infobars/before_translate_infobar.cc b/chrome/browser/views/infobars/before_translate_infobar.cc deleted file mode 100644 index f4d636a..0000000 --- a/chrome/browser/views/infobars/before_translate_infobar.cc +++ /dev/null @@ -1,173 +0,0 @@ -// 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/infobars/before_translate_infobar.h" - -#include "app/l10n_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/translate/options_menu_model.h" -#include "chrome/browser/translate/translate_infobar_delegate.h" -#include "chrome/browser/views/infobars/infobar_text_button.h" -#include "grit/generated_resources.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/image_view.h" -#include "views/controls/menu/menu_2.h" - -BeforeTranslateInfoBar::BeforeTranslateInfoBar( - TranslateInfoBarDelegate* delegate) - : TranslateInfoBarBase(delegate), - never_translate_button_(NULL), - always_translate_button_(NULL), - languages_menu_model_(delegate, LanguagesMenuModel::ORIGINAL), - options_menu_model_(delegate) { - size_t offset = 0; - string16 text = - l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE, - string16(), &offset); - - label_1_ = CreateLabel(text.substr(0, offset)); - AddChildView(label_1_); - - label_2_ = CreateLabel(text.substr(offset)); - AddChildView(label_2_); - - accept_button_ = - InfoBarTextButton::CreateWithMessageID(this, - IDS_TRANSLATE_INFOBAR_ACCEPT); - AddChildView(accept_button_); - - deny_button_ = - InfoBarTextButton::CreateWithMessageID(this, - IDS_TRANSLATE_INFOBAR_DENY); - AddChildView(deny_button_); - - language_menu_button_ = CreateMenuButton(string16(), true, this); - AddChildView(language_menu_button_); - - options_menu_button_ = - CreateMenuButton(l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), - false, this); - AddChildView(options_menu_button_); - - if (delegate->ShouldShowNeverTranslateButton()) { - const string16& language = delegate->GetLanguageDisplayableNameAt( - delegate->original_language_index()); - never_translate_button_ = InfoBarTextButton::CreateWithMessageIDAndParam( - this, IDS_TRANSLATE_INFOBAR_NEVER_TRANSLATE, language); - AddChildView(never_translate_button_); - } - - if (delegate->ShouldShowAlwaysTranslateButton()) { - const string16& language = delegate->GetLanguageDisplayableNameAt( - delegate->original_language_index()); - always_translate_button_ = InfoBarTextButton::CreateWithMessageIDAndParam( - this, IDS_TRANSLATE_INFOBAR_ALWAYS_TRANSLATE, language); - AddChildView(always_translate_button_); - } - - UpdateOriginalButtonText(); -} - -BeforeTranslateInfoBar::~BeforeTranslateInfoBar() { -} - -// Overridden from views::View: -void BeforeTranslateInfoBar::Layout() { - // Layout the icon and close button. - TranslateInfoBarBase::Layout(); - - // Layout the options menu button on right of bar. - int available_width = InfoBar::GetAvailableWidth(); - gfx::Size pref_size = options_menu_button_->GetPreferredSize(); - options_menu_button_->SetBounds(available_width - pref_size.width(), - OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - - pref_size = label_1_->GetPreferredSize(); - label_1_->SetBounds(icon_->bounds().right() + InfoBar::kIconLabelSpacing, - InfoBar::OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - - pref_size = language_menu_button_->GetPreferredSize(); - language_menu_button_->SetBounds(label_1_->bounds().right() + - InfoBar::kButtonInLabelSpacing, OffsetY(this, pref_size), - pref_size.width(), pref_size.height()); - - pref_size = label_2_->GetPreferredSize(); - label_2_->SetBounds(language_menu_button_->bounds().right() + - InfoBar::kButtonInLabelSpacing , InfoBar::OffsetY(this, pref_size), - pref_size.width(), pref_size.height()); - - pref_size = accept_button_->GetPreferredSize(); - accept_button_->SetBounds( - label_2_->bounds().right() + InfoBar::kEndOfLabelSpacing, - OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - - pref_size = deny_button_->GetPreferredSize(); - deny_button_->SetBounds( - accept_button_->bounds().right() + InfoBar::kButtonButtonSpacing, - OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - - if (never_translate_button_) { - pref_size = never_translate_button_->GetPreferredSize(); - never_translate_button_->SetBounds( - deny_button_->bounds().right() + InfoBar::kButtonButtonSpacing, - OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - } - if (always_translate_button_) { - DCHECK(!never_translate_button_); - pref_size = always_translate_button_->GetPreferredSize(); - always_translate_button_->SetBounds( - deny_button_->bounds().right() + InfoBar::kButtonButtonSpacing, - OffsetY(this, pref_size), pref_size.width(), pref_size.height()); - } -} - -void BeforeTranslateInfoBar::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == accept_button_) { - GetDelegate()->Translate(); - } else if (sender == deny_button_) { - RemoveInfoBar(); - GetDelegate()->TranslationDeclined(); - } else if (sender == never_translate_button_) { - GetDelegate()->NeverTranslatePageLanguage(); - } else if (sender == always_translate_button_) { - GetDelegate()->AlwaysTranslatePageLanguage(); - } else { - TranslateInfoBarBase::ButtonPressed(sender, event); - } -} - -void BeforeTranslateInfoBar::OriginalLanguageChanged() { - UpdateOriginalButtonText(); -} - -void BeforeTranslateInfoBar::TargetLanguageChanged() { - NOTREACHED(); -} - -void BeforeTranslateInfoBar::RunMenu(views::View* source, - const gfx::Point& pt) { - if (source == language_menu_button_) { - if (!languages_menu_.get()) - languages_menu_.reset(new views::Menu2(&languages_menu_model_)); - languages_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); - } else if (source == options_menu_button_) { - if (!options_menu_.get()) - options_menu_.reset(new views::Menu2(&options_menu_model_)); - options_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); - } else { - NOTREACHED(); - } -} - -void BeforeTranslateInfoBar::UpdateOriginalButtonText() { - string16 language = GetDelegate()->GetLanguageDisplayableNameAt( - GetDelegate()->original_language_index()); - language_menu_button_->SetText(UTF16ToWideHack(language)); - // The following line is necessary for the preferred size to be recomputed. - language_menu_button_->ClearMaxTextSize(); - // The button may have to grow to show the new text. - Layout(); - SchedulePaint(); -} diff --git a/chrome/browser/views/infobars/before_translate_infobar.h b/chrome/browser/views/infobars/before_translate_infobar.h index 7ac6208..1cf685c 100644 --- a/chrome/browser/views/infobars/before_translate_infobar.h +++ b/chrome/browser/views/infobars/before_translate_infobar.h @@ -6,71 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_BEFORE_TRANSLATE_INFOBAR_H_ #pragma once -#include "chrome/browser/translate/languages_menu_model.h" -#include "chrome/browser/translate/options_menu_model.h" -#include "chrome/browser/translate/translate_infobar_view.h" -#include "chrome/browser/views/infobars/infobars.h" -#include "chrome/browser/views/infobars/translate_infobar_base.h" -#include "views/controls/button/button.h" -#include "views/controls/link.h" -#include "views/controls/menu/view_menu_delegate.h" - -class InfoBarTextButton; -class TranslateInfoBarDelegate; - -namespace views { -class Menu2; -class MenuButton; -} - -class BeforeTranslateInfoBar - : public TranslateInfoBarBase, - public views::ViewMenuDelegate { - public: - explicit BeforeTranslateInfoBar(TranslateInfoBarDelegate* delegate); - virtual ~BeforeTranslateInfoBar(); - - // Overridden from views::View: - virtual void Layout(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from TranslateInfoBarView: - virtual void OriginalLanguageChanged(); - virtual void TargetLanguageChanged(); - - protected: - // Overridden from views::ViewMenuDelegate: - virtual void RunMenu(View* source, const gfx::Point& pt); - - private: - // Sets the text of the original language menu button to reflect the current - // value from the delegate. - void UpdateOriginalButtonText(); - - // The text displayed in the infobar is something like: - // "The page is in <lang>. Would you like to translate it?" - // Where <lang> is displayed in a combobox. - // So the text is split in 2 chunks, each one displayed in one of the label - // below. - views::Label* label_1_; - views::Label* label_2_; - - views::MenuButton* language_menu_button_; - views::MenuButton* options_menu_button_; - InfoBarTextButton* accept_button_; - InfoBarTextButton* deny_button_; - InfoBarTextButton* never_translate_button_; - InfoBarTextButton* always_translate_button_; - - scoped_ptr<views::Menu2> languages_menu_; - LanguagesMenuModel languages_menu_model_; - - scoped_ptr<views::Menu2> options_menu_; - OptionsMenuModel options_menu_model_; - - DISALLOW_COPY_AND_ASSIGN(BeforeTranslateInfoBar); -}; +#include "chrome/browser/ui/views/infobars/before_translate_infobar.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_BEFORE_TRANSLATE_INFOBAR_H_ + diff --git a/chrome/browser/views/infobars/extension_infobar.cc b/chrome/browser/views/infobars/extension_infobar.cc deleted file mode 100644 index e2fb43f..0000000 --- a/chrome/browser/views/infobars/extension_infobar.cc +++ /dev/null @@ -1,183 +0,0 @@ -// 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/infobars/extension_infobar.h" - -#include "app/resource_bundle.h" -#include "app/slide_animation.h" -#include "chrome/browser/extensions/extension_context_menu_model.h" -#include "chrome/browser/extensions/extension_infobar_delegate.h" -#include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/platform_util.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/extension_icon_set.h" -#include "chrome/common/extensions/extension_resource.h" -#include "gfx/canvas_skia.h" -#include "grit/theme_resources.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/menu/menu_2.h" -#include "views/widget/widget.h" - -// The horizontal margin between the menu and the Extension (HTML) view. -static const int kMenuHorizontalMargin = 1; - -// The amount of space to the right of the Extension (HTML) view (to avoid -// overlapping the close button for the InfoBar). -static const int kFarRightMargin = 30; - -// The margin between the extension icon and the drop-down arrow bitmap. -static const int kDropArrowLeftMargin = 3; - -ExtensionInfoBar::ExtensionInfoBar(ExtensionInfoBarDelegate* delegate) - : InfoBar(delegate), - delegate_(delegate), - ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) { - delegate_->set_observer(this); - - ExtensionHost* extension_host = delegate_->extension_host(); - - // We set the target height for the InfoBar to be the height of the - // ExtensionView it contains (plus 1 because the view should not overlap the - // separator line at the bottom). When the InfoBar is first created, however, - // this value is 0 but becomes positive after the InfoBar has been shown. See - // function: OnExtensionPreferredSizeChanged. - gfx::Size sz = extension_host->view()->GetPreferredSize(); - if (sz.height() > 0) - sz.set_height(sz.height() + 1); - set_target_height(sz.height()); - - // Setup the extension icon and its associated drop down menu. - SetupIconAndMenu(); - - // Get notified of resize events for the ExtensionView. - extension_host->view()->SetContainer(this); - // We show the ExtensionView, but we don't want it deleted when we get - // destroyed, which happens on tab switching (for example). - extension_host->view()->set_parent_owned(false); - AddChildView(extension_host->view()); -} - -ExtensionInfoBar::~ExtensionInfoBar() { - if (delegate_) { - delegate_->extension_host()->view()->SetContainer(NULL); - delegate_->set_observer(NULL); - } -} - -void ExtensionInfoBar::OnExtensionPreferredSizeChanged(ExtensionView* view) { - DCHECK(view == delegate_->extension_host()->view()); - - // When the infobar is closed, it animates to 0 vertical height. We'll - // continue to get size changed notifications from the ExtensionView, but we - // need to ignore them otherwise we'll try to re-animate open (and leak the - // infobar view). - if (delegate_->closing()) - return; - - delegate_->extension_host()->view()->SetVisible(true); - - gfx::Size sz = view->GetPreferredSize(); - // Clamp height to a min and a max size of between 1 and 2 InfoBars. - int default_height = static_cast<int>(InfoBar::kDefaultTargetHeight); - sz.set_height(std::max(default_height, sz.height())); - sz.set_height(std::min(2 * default_height, sz.height())); - - if (height() == 0) - animation()->Reset(0.0); - set_target_height(sz.height()); - animation()->Show(); -} - -void ExtensionInfoBar::Layout() { - // Layout the close button and the background. - InfoBar::Layout(); - - // Layout the extension icon + drop down menu. - int x = 0; - gfx::Size sz = menu_->GetPreferredSize(); - menu_->SetBounds(x, - (height() - sz.height()) / 2, - sz.width(), sz.height()); - x += sz.width() + kMenuHorizontalMargin; - - // Layout the ExtensionView, showing the HTML InfoBar. - ExtensionView* view = delegate_->extension_host()->view(); - view->SetBounds(x, 0, width() - x - kFarRightMargin - 1, height() - 1); -} - -void ExtensionInfoBar::OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index) { - if (!delegate_) - return; // The delegate can go away while we asynchronously load images. - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - // We fall back on the default extension icon on failure. - SkBitmap* icon; - if (!image || image->empty()) - icon = rb.GetBitmapNamed(IDR_EXTENSIONS_SECTION); - else - icon = image; - - SkBitmap* drop_image = rb.GetBitmapNamed(IDR_APP_DROPARROW); - - int image_size = Extension::EXTENSION_ICON_BITTY; - scoped_ptr<gfx::CanvasSkia> canvas( - new gfx::CanvasSkia( - image_size + kDropArrowLeftMargin + drop_image->width(), - image_size, false)); - canvas->DrawBitmapInt(*icon, - 0, 0, icon->width(), icon->height(), - 0, 0, image_size, image_size, - false); - canvas->DrawBitmapInt(*drop_image, - image_size + kDropArrowLeftMargin, - image_size / 2); - menu_->SetIcon(canvas->ExtractBitmap()); - menu_->SetVisible(true); - - Layout(); -} - -void ExtensionInfoBar::OnDelegateDeleted() { - delegate_->extension_host()->view()->SetContainer(NULL); - delegate_ = NULL; -} - -void ExtensionInfoBar::RunMenu(View* source, const gfx::Point& pt) { - if (!options_menu_contents_.get()) { - Browser* browser = BrowserView::GetBrowserViewForNativeWindow( - platform_util::GetTopLevel(source->GetWidget()->GetNativeView()))-> - browser(); - options_menu_contents_ = new ExtensionContextMenuModel( - delegate_->extension_host()->extension(), browser, NULL); - } - - options_menu_menu_.reset(new views::Menu2(options_menu_contents_.get())); - options_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPLEFT); -} - -void ExtensionInfoBar::SetupIconAndMenu() { - menu_ = new views::MenuButton(NULL, std::wstring(), this, false); - menu_->SetVisible(false); - AddChildView(menu_); - - const Extension* extension = delegate_->extension_host()->extension(); - ExtensionResource icon_resource = extension->GetIconResource( - Extension::EXTENSION_ICON_BITTY, ExtensionIconSet::MATCH_EXACTLY); - if (!icon_resource.relative_path().empty()) { - // Create a tracker to load the image. It will report back on OnImageLoaded. - tracker_.LoadImage(extension, icon_resource, - gfx::Size(Extension::EXTENSION_ICON_BITTY, - Extension::EXTENSION_ICON_BITTY), - ImageLoadingTracker::DONT_CACHE); - } else { - OnImageLoaded(NULL, icon_resource, 0); // |image|, |index|. - } -} - -InfoBar* ExtensionInfoBarDelegate::CreateInfoBar() { - return new ExtensionInfoBar(this); -} diff --git a/chrome/browser/views/infobars/extension_infobar.h b/chrome/browser/views/infobars/extension_infobar.h index b4bab7e..0b1ae4a 100644 --- a/chrome/browser/views/infobars/extension_infobar.h +++ b/chrome/browser/views/infobars/extension_infobar.h @@ -6,67 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_EXTENSION_INFOBAR_H_ #pragma once -#include "chrome/browser/views/infobars/infobars.h" - -#include "chrome/browser/extensions/extension_infobar_delegate.h" -#include "chrome/browser/extensions/image_loading_tracker.h" -#include "chrome/browser/views/extensions/extension_view.h" -#include "views/controls/menu/view_menu_delegate.h" - -class ExtensionContextMenuModel; -class ExtensionInfoBarDelegate; - -namespace views { - class MenuButton; - class Menu2; -} - -// This class implements InfoBars for Extensions. -class ExtensionInfoBar : public InfoBar, - public ExtensionView::Container, - public ImageLoadingTracker::Observer, - public ExtensionInfoBarDelegate::DelegateObserver, - public views::ViewMenuDelegate { - public: - explicit ExtensionInfoBar(ExtensionInfoBarDelegate* delegate); - virtual ~ExtensionInfoBar(); - - // Overridden from ExtensionView::Container: - virtual void OnExtensionMouseMove(ExtensionView* view) {} - virtual void OnExtensionMouseLeave(ExtensionView* view) {} - virtual void OnExtensionPreferredSizeChanged(ExtensionView* view); - - // Overridden from views::View: - virtual void Layout(); - - // Overridden from ImageLoadingTracker::Observer: - virtual void OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index); - - // Overridden from ExtensionInfoBarDelegate::DelegateObserver: - virtual void OnDelegateDeleted(); - - // Overridden from views::ViewMenuDelegate: - virtual void RunMenu(View* source, const gfx::Point& pt); - - private: - // Setup the menu button showing the small extension icon and its dropdown - // menu. - void SetupIconAndMenu(); - - NotificationRegistrar notification_registrar_; - - ExtensionInfoBarDelegate* delegate_; - - // The dropdown menu for accessing the contextual extension actions. - scoped_refptr<ExtensionContextMenuModel> options_menu_contents_; - scoped_ptr<views::Menu2> options_menu_menu_; - views::MenuButton* menu_; - - // Keeps track of images being loaded on the File thread. - ImageLoadingTracker tracker_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionInfoBar); -}; +#include "chrome/browser/ui/views/infobars/extension_infobar.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_EXTENSION_INFOBAR_H_ + diff --git a/chrome/browser/views/infobars/infobar_button_border.cc b/chrome/browser/views/infobars/infobar_button_border.cc deleted file mode 100644 index ed65885..0000000 --- a/chrome/browser/views/infobars/infobar_button_border.cc +++ /dev/null @@ -1,141 +0,0 @@ -// 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/infobars/infobar_button_border.h" - -#include "app/resource_bundle.h" -#include "gfx/canvas.h" -#include "grit/theme_resources.h" -#include "views/controls/button/text_button.h" - -// Preferred padding between text and edge -static const int kPreferredPaddingHorizontal = 6; -static const int kPreferredPaddingVertical = 5; - -// InfoBarButtonBorder, public: ---------------------------------------------- - -InfoBarButtonBorder::InfoBarButtonBorder() { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - normal_set_.top_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_LEFT_N); - normal_set_.top = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_N); - normal_set_.top_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_RIGHT_N); - normal_set_.left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_LEFT_N); - normal_set_.center = rb.GetBitmapNamed(IDR_INFOBARBUTTON_CENTER_N); - normal_set_.right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_RIGHT_N); - normal_set_.bottom_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_LEFT_N); - normal_set_.bottom = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_N); - normal_set_.bottom_right = - rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_RIGHT_N); - - hot_set_.top_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_LEFT_H); - hot_set_.top = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_H); - hot_set_.top_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_RIGHT_H); - hot_set_.left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_LEFT_H); - hot_set_.center = rb.GetBitmapNamed(IDR_INFOBARBUTTON_CENTER_H); - hot_set_.right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_RIGHT_H); - hot_set_.bottom_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_LEFT_H); - hot_set_.bottom = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_H); - hot_set_.bottom_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_RIGHT_H); - - pushed_set_.top_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_LEFT_P); - pushed_set_.top = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_P); - pushed_set_.top_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_RIGHT_P); - pushed_set_.left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_LEFT_P); - pushed_set_.center = rb.GetBitmapNamed(IDR_INFOBARBUTTON_CENTER_P); - pushed_set_.right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_RIGHT_P); - pushed_set_.bottom_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_LEFT_P); - pushed_set_.bottom = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_P); - pushed_set_.bottom_right = - rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_RIGHT_P); -} - -InfoBarButtonBorder::~InfoBarButtonBorder() { -} - -// InfoBarButtonBorder, Border overrides: ------------------------------------ - -void InfoBarButtonBorder::GetInsets(gfx::Insets* insets) const { - insets->Set(kPreferredPaddingVertical, kPreferredPaddingHorizontal, - kPreferredPaddingVertical, kPreferredPaddingHorizontal); -} - -void InfoBarButtonBorder::Paint(const views::View& view, - gfx::Canvas* canvas) const { - const views::TextButton* mb = static_cast<const views::TextButton*>(&view); - int state = mb->state(); - - // TextButton takes care of deciding when to call Paint. - const MBBImageSet* set = &normal_set_; - if (state == views::TextButton::BS_HOT) - set = &hot_set_; - else if (state == views::TextButton::BS_PUSHED) - set = &pushed_set_; - - gfx::Rect bounds = view.bounds(); - - // Draw top left image. - canvas->DrawBitmapInt(*set->top_left, 0, 0); - - // Stretch top image. - canvas->DrawBitmapInt( - *set->top, - 0, 0, set->top->width(), set->top->height(), - set->top_left->width(), - 0, - bounds.width() - set->top_right->width() - set->top_left->width(), - set->top->height(), false); - - // Draw top right image. - canvas->DrawBitmapInt(*set->top_right, - bounds.width() - set->top_right->width(), 0); - - // Stretch left image. - canvas->DrawBitmapInt( - *set->left, - 0, 0, set->left->width(), set->left->height(), - 0, - set->top_left->height(), - set->top_left->width(), - bounds.height() - set->top->height() - set->bottom_left->height(), false); - - // Stretch center image. - canvas->DrawBitmapInt( - *set->center, - 0, 0, set->center->width(), set->center->height(), - set->left->width(), - set->top->height(), - bounds.width() - set->right->width() - set->left->width(), - bounds.height() - set->bottom->height() - set->top->height(), false); - - // Stretch right image. - canvas->DrawBitmapInt( - *set->right, - 0, 0, set->right->width(), set->right->height(), - bounds.width() - set->right->width(), - set->top_right->height(), - set->right->width(), - bounds.height() - set->bottom_right->height() - - set->top_right->height(), false); - - // Draw bottom left image. - canvas->DrawBitmapInt(*set->bottom_left, - 0, - bounds.height() - set->bottom_left->height()); - - // Stretch bottom image. - canvas->DrawBitmapInt( - *set->bottom, - 0, 0, set->bottom->width(), set->bottom->height(), - set->bottom_left->width(), - bounds.height() - set->bottom->height(), - bounds.width() - set->bottom_right->width() - - set->bottom_left->width(), - set->bottom->height(), false); - - // Draw bottom right image. - canvas->DrawBitmapInt(*set->bottom_right, - bounds.width() - set->bottom_right->width(), - bounds.height() - set->bottom_right->height()); -} diff --git a/chrome/browser/views/infobars/infobar_button_border.h b/chrome/browser/views/infobars/infobar_button_border.h index 865e4f8..daafb16 100644 --- a/chrome/browser/views/infobars/infobar_button_border.h +++ b/chrome/browser/views/infobars/infobar_button_border.h @@ -6,48 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_BUTTON_BORDER_H_ #pragma once -#include "views/border.h" - -#include "third_party/skia/include/core/SkBitmap.h" - -namespace gfx { -class Canvas; -} -namespace views { -class View; -} - -// A TextButtonBorder that is dark and also paints the button frame in the -// normal state. - -class InfoBarButtonBorder : public views::Border { - public: - InfoBarButtonBorder(); - virtual ~InfoBarButtonBorder(); - - // Overriden from Border: - virtual void GetInsets(gfx::Insets* insets) const; - virtual void Paint(const views::View& view, gfx::Canvas* canvas) const; - - private: - // Images - struct MBBImageSet { - SkBitmap* top_left; - SkBitmap* top; - SkBitmap* top_right; - SkBitmap* left; - SkBitmap* center; - SkBitmap* right; - SkBitmap* bottom_left; - SkBitmap* bottom; - SkBitmap* bottom_right; - }; - - MBBImageSet normal_set_; - MBBImageSet hot_set_; - MBBImageSet pushed_set_; - - DISALLOW_COPY_AND_ASSIGN(InfoBarButtonBorder); -}; +#include "chrome/browser/ui/views/infobars/infobar_button_border.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_BUTTON_BORDER_H_ + diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc deleted file mode 100644 index 5779fde..0000000 --- a/chrome/browser/views/infobars/infobar_container.cc +++ /dev/null @@ -1,164 +0,0 @@ -// 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/infobars/infobar_container.h" - -#include "app/l10n_util.h" -#include "chrome/browser/tab_contents/infobar_delegate.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/infobars/infobars.h" -#include "chrome/common/notification_service.h" -#include "grit/generated_resources.h" - -// InfoBarContainer, public: --------------------------------------------------- - -InfoBarContainer::InfoBarContainer(Delegate* delegate) - : delegate_(delegate), - tab_contents_(NULL) { - SetID(VIEW_ID_INFO_BAR_CONTAINER); - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_INFOBAR_CONTAINER)); -} - -InfoBarContainer::~InfoBarContainer() { - // We NULL this pointer before resetting the TabContents to prevent view - // hierarchy modifications from attempting to resize the delegate which - // could be in the process of shutting down. - delegate_ = NULL; - ChangeTabContents(NULL); -} - -void InfoBarContainer::ChangeTabContents(TabContents* contents) { - registrar_.RemoveAll(); - // No need to delete the child views here, their removal from the view - // hierarchy does this automatically (see InfoBar::InfoBarRemoved). - RemoveAllChildViews(false); - tab_contents_ = contents; - if (tab_contents_) { - UpdateInfoBars(); - Source<TabContents> tc_source(tab_contents_); - registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED, - tc_source); - registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, - tc_source); - registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REPLACED, - tc_source); - } -} - -void InfoBarContainer::InfoBarAnimated(bool completed) { - if (delegate_) - delegate_->InfoBarSizeChanged(!completed); -} - -void InfoBarContainer::RemoveDelegate(InfoBarDelegate* delegate) { - tab_contents_->RemoveInfoBar(delegate); -} - -// InfoBarContainer, views::View overrides: ------------------------------------ - -gfx::Size InfoBarContainer::GetPreferredSize() { - // We do not have a preferred width (we will expand to fit the available width - // of the delegate). Our preferred height is the sum of the preferred - // heights of the InfoBars contained within us. - int height = 0; - for (int i = 0; i < GetChildViewCount(); ++i) - height += GetChildViewAt(i)->GetPreferredSize().height(); - return gfx::Size(0, height); -} - -void InfoBarContainer::Layout() { - int top = 0; - for (int i = 0; i < GetChildViewCount(); ++i) { - views::View* child = GetChildViewAt(i); - gfx::Size ps = child->GetPreferredSize(); - child->SetBounds(0, top, width(), ps.height()); - top += ps.height(); - } -} - -AccessibilityTypes::Role InfoBarContainer::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -void InfoBarContainer::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (parent == this && child->GetParent() == this) { - if (delegate_) { - // An InfoBar child was added or removed. Tell the delegate it needs to - // re-layout since our preferred size will have changed. - delegate_->InfoBarSizeChanged(false); - } - } -} - -// InfoBarContainer, NotificationObserver implementation: ---------------------- - -void InfoBarContainer::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) { - AddInfoBar(Details<InfoBarDelegate>(details).ptr(), true); // animated - } else if (type == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED) { - RemoveInfoBar(Details<InfoBarDelegate>(details).ptr(), true); // animated - } else if (type == NotificationType::TAB_CONTENTS_INFOBAR_REPLACED) { - std::pair<InfoBarDelegate*, InfoBarDelegate*>* delegates = - Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> >(details).ptr(); - ReplaceInfoBar(delegates->first, delegates->second); - } else { - NOTREACHED(); - } -} - -// InfoBarContainer, private: -------------------------------------------------- - -void InfoBarContainer::UpdateInfoBars() { - for (int i = 0; i < tab_contents_->infobar_delegate_count(); ++i) { - InfoBarDelegate* delegate = tab_contents_->GetInfoBarDelegateAt(i); - InfoBar* infobar = delegate->CreateInfoBar(); - infobar->set_container(this); - AddChildView(infobar); - infobar->Open(); - } -} - -void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate, - bool use_animation) { - InfoBar* infobar = delegate->CreateInfoBar(); - infobar->set_container(this); - AddChildView(infobar); - - if (use_animation) - infobar->AnimateOpen(); - else - infobar->Open(); -} - -void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate, - bool use_animation) { - // Search for infobar associated with |delegate| among child views. - // We cannot search for |delegate| in tab_contents, because an infobar remains - // a child view until its close animation completes, which can result in - // different number of infobars in container and infobar delegates in tab - // contents. - for (int i = 0; i < GetChildViewCount(); ++i) { - InfoBar* infobar = static_cast<InfoBar*>(GetChildViewAt(i)); - if (infobar->delegate() == delegate) { - if (use_animation) { - // The View will be removed once the Close animation completes. - infobar->AnimateClose(); - } else { - infobar->Close(); - } - break; - } - } -} - -void InfoBarContainer::ReplaceInfoBar(InfoBarDelegate* old_delegate, - InfoBarDelegate* new_delegate) { - RemoveInfoBar(old_delegate, false); // no animation - AddInfoBar(new_delegate, false); // no animation -} diff --git a/chrome/browser/views/infobars/infobar_container.h b/chrome/browser/views/infobars/infobar_container.h index 89d5a91..13c3f56 100644 --- a/chrome/browser/views/infobars/infobar_container.h +++ b/chrome/browser/views/infobars/infobar_container.h @@ -6,89 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_ #pragma once -#include "chrome/browser/views/accessible_pane_view.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "views/view.h" - -class BrowserView; -class InfoBarDelegate; -class TabContents; - -// A views::View subclass that contains a collection of InfoBars associated with -// a TabContents. -class InfoBarContainer : public AccessiblePaneView, - public NotificationObserver { - public: - // Implement this interface when you want to receive notifications from the - // InfoBarContainer - class Delegate { - public: - virtual ~Delegate() {} - virtual void InfoBarSizeChanged(bool is_animating) = 0; - }; - - explicit InfoBarContainer(Delegate* delegate); - virtual ~InfoBarContainer(); - - // Changes the TabContents for which this container is showing InfoBars. Can - // be NULL. - void ChangeTabContents(TabContents* contents); - - // Called by child InfoBars as they animate. If |completed| is true, the - // animation has finished running. - void InfoBarAnimated(bool completed); - - // Remove the specified InfoBarDelegate from the selected TabContents. This - // will notify us back and cause us to close the View. This is called from - // the InfoBar's close button handler. - void RemoveDelegate(InfoBarDelegate* delegate); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - protected: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - private: - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Constructs the InfoBars needed to reflect the state of the current - // TabContents associated with this container. No animations are run during - // this process. - void UpdateInfoBars(); - - // Adds an InfoBar for the specified delegate, in response to a notification - // from the selected TabContents. The InfoBar's appearance will be animated - // if |use_animation| is true. - void AddInfoBar(InfoBarDelegate* delegate, bool use_animation); - - // Removes an InfoBar for the specified delegate, in response to a - // notification from the selected TabContents. The InfoBar's disappearance - // will be animated if |use_animation| is true. - void RemoveInfoBar(InfoBarDelegate* delegate, bool use_animation); - - // Replaces an InfoBar for the specified delegate with a new one. There is no - // animation. - void ReplaceInfoBar(InfoBarDelegate* old_delegate, - InfoBarDelegate* new_delegate); - - NotificationRegistrar registrar_; - - // The Delegate which receives notifications from the InfoBarContainer. - Delegate* delegate_; - - // The TabContents for which we are currently showing InfoBars. - TabContents* tab_contents_; - - DISALLOW_COPY_AND_ASSIGN(InfoBarContainer); -}; +#include "chrome/browser/ui/views/infobars/infobar_container.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_ + diff --git a/chrome/browser/views/infobars/infobar_text_button.cc b/chrome/browser/views/infobars/infobar_text_button.cc deleted file mode 100644 index ebf5d22..0000000 --- a/chrome/browser/views/infobars/infobar_text_button.cc +++ /dev/null @@ -1,57 +0,0 @@ -// 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/infobars/infobar_text_button.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/views/infobars/infobar_button_border.h" - -// static -InfoBarTextButton* InfoBarTextButton::Create(views::ButtonListener* listener, - const string16& text) { - return new InfoBarTextButton(listener, text); -} - -// static -InfoBarTextButton* InfoBarTextButton::CreateWithMessageID( - views::ButtonListener* listener, int message_id) { - return new InfoBarTextButton(listener, - l10n_util::GetStringUTF16(message_id)); -} - -// static -InfoBarTextButton* InfoBarTextButton::CreateWithMessageIDAndParam( - views::ButtonListener* listener, int message_id, const string16& param) { - return new InfoBarTextButton(listener, - l10n_util::GetStringFUTF16(message_id, param)); -} - -InfoBarTextButton::~InfoBarTextButton() { -} - -bool InfoBarTextButton::OnMousePressed(const views::MouseEvent& e) { - return views::CustomButton::OnMousePressed(e); -} - -InfoBarTextButton::InfoBarTextButton(views::ButtonListener* listener, - const string16& text) - // Don't use text to construct TextButton because we need to set font - // before setting text so that the button will resize to fit entire text. - : TextButton(listener, std::wstring()) { - set_border(new InfoBarButtonBorder); - SetNormalHasBorder(true); // Normal button state has border. - SetAnimationDuration(0); // Disable animation during state change. - // Set font colors for different states. - SetEnabledColor(SK_ColorBLACK); - SetHighlightColor(SK_ColorBLACK); - SetHoverColor(SK_ColorBLACK); - // Set font then text, then size button to fit text. - SetFont( - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); - SetText(UTF16ToWideHack(text)); - ClearMaxTextSize(); - SizeToPreferredSize(); -} diff --git a/chrome/browser/views/infobars/infobar_text_button.h b/chrome/browser/views/infobars/infobar_text_button.h index 35f16a1..7255f0d 100644 --- a/chrome/browser/views/infobars/infobar_text_button.h +++ b/chrome/browser/views/infobars/infobar_text_button.h @@ -6,33 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_TEXT_BUTTON_H_ #pragma once -#include "views/controls/button/text_button.h" - -// A TextButton subclass that overrides OnMousePressed to default to -// CustomButton so as to create pressed state effect. - -class InfoBarTextButton : public views::TextButton { - public: - // Creates a button with the specified |text|. - static InfoBarTextButton* Create(views::ButtonListener* listener, - const string16& text); - // Creates a button which text is the resource string identified by - // |message_id|. - static InfoBarTextButton* CreateWithMessageID(views::ButtonListener* listener, - int message_id); - static InfoBarTextButton* CreateWithMessageIDAndParam( - views::ButtonListener* listener, int message_id, const string16& param); - - virtual ~InfoBarTextButton(); - - protected: - InfoBarTextButton(views::ButtonListener* listener, const string16& text); - - // Overriden from TextButton: - virtual bool OnMousePressed(const views::MouseEvent& e); - - private: - DISALLOW_COPY_AND_ASSIGN(InfoBarTextButton); -}; +#include "chrome/browser/ui/views/infobars/infobar_text_button.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_TEXT_BUTTON_H_ + diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc deleted file mode 100644 index c96f72f..0000000 --- a/chrome/browser/views/infobars/infobars.cc +++ /dev/null @@ -1,614 +0,0 @@ -// 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/infobars/infobars.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/slide_animation.h" -#if defined(OS_WIN) -#include "app/win_util.h" -#endif // defined(OS_WIN) -#include "base/message_loop.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/views/event_utils.h" -#include "chrome/browser/views/infobars/infobar_container.h" -#include "gfx/canvas.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/background.h" -#include "views/controls/button/image_button.h" -#include "views/controls/button/native_button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/focus/external_focus_tracker.h" -#include "views/widget/widget.h" - -// static -const double InfoBar::kDefaultTargetHeight = 36.0; -const int InfoBar::kHorizontalPadding = 6; -const int InfoBar::kIconLabelSpacing = 6; -const int InfoBar::kButtonButtonSpacing = 10; -const int InfoBar::kEndOfLabelSpacing = 16; -const int InfoBar::kCloseButtonSpacing = 12; -const int InfoBar::kButtonInLabelSpacing = 5; - -static const SkColor kWarningBackgroundColorTop = SkColorSetRGB(255, 242, 183); -static const SkColor kWarningBackgroundColorBottom = - SkColorSetRGB(250, 230, 145); - -static const SkColor kPageActionBackgroundColorTop = - SkColorSetRGB(218, 231, 249); -static const SkColor kPageActionBackgroundColorBottom = - SkColorSetRGB(179, 202, 231); - -static const int kSeparatorLineHeight = 1; - -// InfoBarBackground, public: -------------------------------------------------- - -InfoBarBackground::InfoBarBackground(InfoBarDelegate::Type infobar_type) { - SkColor top_color; - SkColor bottom_color; - switch (infobar_type) { - case InfoBarDelegate::WARNING_TYPE: - top_color = kWarningBackgroundColorTop; - bottom_color = kWarningBackgroundColorBottom; - break; - case InfoBarDelegate::PAGE_ACTION_TYPE: - top_color = kPageActionBackgroundColorTop; - bottom_color = kPageActionBackgroundColorBottom; - break; - default: - NOTREACHED(); - break; - } - gradient_background_.reset( - views::Background::CreateVerticalGradientBackground(top_color, - bottom_color)); -} - -// InfoBarBackground, views::Background overrides: ----------------------------- - -void InfoBarBackground::Paint(gfx::Canvas* canvas, views::View* view) const { - // First paint the gradient background. - gradient_background_->Paint(canvas, view); - - // Now paint the separator line. - canvas->FillRectInt(ResourceBundle::toolbar_separator_color, 0, - view->height() - kSeparatorLineHeight, view->width(), - kSeparatorLineHeight); -} - -// InfoBar, public: ------------------------------------------------------------ - -InfoBar::InfoBar(InfoBarDelegate* delegate) - : delegate_(delegate), - ALLOW_THIS_IN_INITIALIZER_LIST( - close_button_(new views::ImageButton(this))), - ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)), - target_height_(kDefaultTargetHeight) { - // We delete ourselves when we're removed from the view hierarchy. - set_parent_owned(false); - - set_background(new InfoBarBackground(delegate->GetInfoBarType())); - - switch (delegate->GetInfoBarType()) { - case InfoBarDelegate::WARNING_TYPE: - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_INFOBAR_WARNING)); - break; - case InfoBarDelegate::PAGE_ACTION_TYPE: - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_INFOBAR_PAGE_ACTION)); - break; - default: - NOTREACHED(); - break; - } - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_CLOSE_BAR)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); - close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); - AddChildView(close_button_); - - animation_.reset(new SlideAnimation(this)); - animation_->SetTweenType(Tween::LINEAR); -} - -InfoBar::~InfoBar() { -} - -// InfoBar, views::View overrides: --------------------------------------------- - -AccessibilityTypes::Role InfoBar::GetAccessibleRole() { - return AccessibilityTypes::ROLE_ALERT; -} - -gfx::Size InfoBar::GetPreferredSize() { - int height = static_cast<int>(target_height_ * animation_->GetCurrentValue()); - return gfx::Size(0, height); -} - -void InfoBar::Layout() { - gfx::Size button_ps = close_button_->GetPreferredSize(); - close_button_->SetBounds(width() - kHorizontalPadding - button_ps.width(), - OffsetY(this, button_ps), button_ps.width(), - button_ps.height()); -} - -void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child) { - if (child == this) { - if (is_add) { - InfoBarAdded(); - } else { - InfoBarRemoved(); - } - } - - if (GetWidget() && GetWidget()->IsAccessibleWidget()) { - // For accessibility, make the close button the last child view. - if (parent == this && child != close_button_ && - HasChildView(close_button_) && - GetChildViewAt(GetChildViewCount() - 1) != close_button_) { - RemoveChildView(close_button_); - AddChildView(close_button_); - } - - // Allow screen reader users to focus the close button. - close_button_->SetFocusable(true); - } -} - -// InfoBar, protected: --------------------------------------------------------- - -int InfoBar::GetAvailableWidth() const { - return close_button_->x() - kCloseButtonSpacing; -} - -void InfoBar::RemoveInfoBar() const { - if (container_) - container_->RemoveDelegate(delegate()); -} - -int InfoBar::CenterY(const gfx::Size prefsize) { - return std::max((static_cast<int>(target_height_) - - prefsize.height()) / 2, 0); -} - -int InfoBar::OffsetY(views::View* parent, const gfx::Size prefsize) { - return CenterY(prefsize) - - (static_cast<int>(target_height_) - parent->height()); -} - -// InfoBar, views::ButtonListener implementation: ------------------ - -void InfoBar::ButtonPressed(views::Button* sender, const views::Event& event) { - if (sender == close_button_) { - if (delegate_) - delegate_->InfoBarDismissed(); - RemoveInfoBar(); - } -} - -// InfoBar, views::FocusChangeListener implementation: ------------------ - -void InfoBar::FocusWillChange(View* focused_before, View* focused_now) { - // This will trigger some screen readers to read the entire contents of this - // infobar. - if (focused_before && focused_now && - !this->IsParentOf(focused_before) && this->IsParentOf(focused_now)) { - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); - } -} - -// InfoBar, AnimationDelegate implementation: ---------------------------------- - -void InfoBar::AnimationProgressed(const Animation* animation) { - if (container_) - container_->InfoBarAnimated(true); -} - -void InfoBar::AnimationEnded(const Animation* animation) { - if (container_) { - container_->InfoBarAnimated(false); - - if (!animation_->IsShowing()) - Close(); - } -} - -// InfoBar, private: ----------------------------------------------------------- - -void InfoBar::AnimateOpen() { - animation_->Show(); -} - -void InfoBar::Open() { - // Set the animation value to 1.0 so that GetPreferredSize() returns the right - // size. - animation_->Reset(1.0); - if (container_) - container_->InfoBarAnimated(false); -} - -void InfoBar::AnimateClose() { - bool restore_focus = true; -#if defined(OS_WIN) - // Do not restore focus (and active state with it) on Windows if some other - // top-level window became active. - if (GetWidget() && - !win_util::DoesWindowBelongToActiveWindow(GetWidget()->GetNativeView())) { - restore_focus = false; - } -#endif // defined(OS_WIN) - DestroyFocusTracker(restore_focus); - animation_->Hide(); -} - -void InfoBar::Close() { - GetParent()->RemoveChildView(this); - // Note that we only tell the delegate we're closed here, and not when we're - // simply destroyed (by virtue of a tab switch or being moved from window to - // window), since this action can cause the delegate to destroy itself. - if (delegate_) { - delegate_->InfoBarClosed(); - delegate_ = NULL; - } -} - -void InfoBar::InfoBarAdded() { - // The container_ pointer must be set before adding to the view hierarchy. - DCHECK(container_); -#if defined(OS_WIN) - // When we're added to a view hierarchy within a widget, we create an - // external focus tracker to track what was focused in case we obtain - // focus so that we can restore focus when we're removed. - views::Widget* widget = GetWidget(); - if (widget) { - focus_tracker_.reset(new views::ExternalFocusTracker(this, - GetFocusManager())); - } -#endif - - if (GetFocusManager()) - GetFocusManager()->AddFocusChangeListener(this); - - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); -} - -void InfoBar::InfoBarRemoved() { - DestroyFocusTracker(false); - // NULL our container_ pointer so that if Animation::Stop results in - // AnimationEnded being called, we do not try and delete ourselves twice. - container_ = NULL; - animation_->Stop(); - // Finally, clean ourselves up when we're removed from the view hierarchy - // since no-one refers to us now. - MessageLoop::current()->PostTask(FROM_HERE, - delete_factory_.NewRunnableMethod(&InfoBar::DeleteSelf)); - - if (GetFocusManager()) - GetFocusManager()->RemoveFocusChangeListener(this); -} - -void InfoBar::DestroyFocusTracker(bool restore_focus) { - if (focus_tracker_.get()) { - if (restore_focus) - focus_tracker_->FocusLastFocusedExternalView(); - focus_tracker_->SetFocusManager(NULL); - focus_tracker_.reset(NULL); - } -} - -void InfoBar::DeleteSelf() { - delete this; -} - -// AlertInfoBar, public: ------------------------------------------------------- - -AlertInfoBar::AlertInfoBar(AlertInfoBarDelegate* delegate) - : InfoBar(delegate) { - label_ = new views::Label( - UTF16ToWideHack(delegate->GetMessageText()), - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); - label_->SetColor(SK_ColorBLACK); - label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label_); - - icon_ = new views::ImageView; - if (delegate->GetIcon()) - icon_->SetImage(delegate->GetIcon()); - AddChildView(icon_); -} - -AlertInfoBar::~AlertInfoBar() { -} - -// AlertInfoBar, views::View overrides: ---------------------------------------- - -void AlertInfoBar::Layout() { - // Layout the close button. - InfoBar::Layout(); - - // Layout the icon and text. - gfx::Size icon_ps = icon_->GetPreferredSize(); - icon_->SetBounds(kHorizontalPadding, OffsetY(this, icon_ps), icon_ps.width(), - icon_ps.height()); - - gfx::Size text_ps = label_->GetPreferredSize(); - int text_width = std::min( - text_ps.width(), - GetAvailableWidth() - icon_->bounds().right() - kIconLabelSpacing); - label_->SetBounds(icon_->bounds().right() + kIconLabelSpacing, - OffsetY(this, text_ps), text_width, text_ps.height()); -} - -// AlertInfoBar, private: ------------------------------------------------------ - -AlertInfoBarDelegate* AlertInfoBar::GetDelegate() { - return delegate()->AsAlertInfoBarDelegate(); -} - -// LinkInfoBar, public: -------------------------------------------------------- - -LinkInfoBar::LinkInfoBar(LinkInfoBarDelegate* delegate) - : InfoBar(delegate), - icon_(new views::ImageView), - label_1_(new views::Label), - label_2_(new views::Label), - link_(new views::Link) { - // Set up the icon. - if (delegate->GetIcon()) - icon_->SetImage(delegate->GetIcon()); - AddChildView(icon_); - - // Set up the labels. - size_t offset; - string16 message_text = delegate->GetMessageTextWithOffset(&offset); - if (offset != string16::npos) { - label_1_->SetText(UTF16ToWideHack(message_text.substr(0, offset))); - label_2_->SetText(UTF16ToWideHack(message_text.substr(offset))); - } else { - label_1_->SetText(UTF16ToWideHack(message_text)); - } - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - label_1_->SetFont(rb.GetFont(ResourceBundle::MediumFont)); - label_2_->SetFont(rb.GetFont(ResourceBundle::MediumFont)); - label_1_->SetColor(SK_ColorBLACK); - label_2_->SetColor(SK_ColorBLACK); - label_1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - label_2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label_1_); - AddChildView(label_2_); - - // Set up the link. - link_->SetText(UTF16ToWideHack(delegate->GetLinkText())); - link_->SetFont(rb.GetFont(ResourceBundle::MediumFont)); - link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - link_->SetController(this); - link_->MakeReadableOverBackgroundColor(background()->get_color()); - AddChildView(link_); -} - -LinkInfoBar::~LinkInfoBar() { -} - -// LinkInfoBar, views::LinkController implementation: -------------------------- - -void LinkInfoBar::LinkActivated(views::Link* source, int event_flags) { - DCHECK(source == link_); - if (GetDelegate()->LinkClicked( - event_utils::DispositionFromEventFlags(event_flags))) { - RemoveInfoBar(); - } -} - -// LinkInfoBar, views::View overrides: ----------------------------------------- - -void LinkInfoBar::Layout() { - // Layout the close button. - InfoBar::Layout(); - - // Layout the icon. - gfx::Size icon_ps = icon_->GetPreferredSize(); - icon_->SetBounds(kHorizontalPadding, OffsetY(this, icon_ps), icon_ps.width(), - icon_ps.height()); - - int label_1_x = icon_->bounds().right() + kIconLabelSpacing; - - // Figure out the amount of space available to the rest of the content now - // that the close button and the icon have been positioned. - int available_width = GetAvailableWidth() - label_1_x; - - // Layout the left label. - gfx::Size label_1_ps = label_1_->GetPreferredSize(); - label_1_->SetBounds(label_1_x, OffsetY(this, label_1_ps), label_1_ps.width(), - label_1_ps.height()); - - // Layout the link. - gfx::Size link_ps = link_->GetPreferredSize(); - bool has_second_label = !label_2_->GetText().empty(); - if (has_second_label) { - // Embed the link in the text string between the two labels. - link_->SetBounds(label_1_->bounds().right(), - OffsetY(this, link_ps), link_ps.width(), link_ps.height()); - } else { - // Right-align the link toward the edge of the InfoBar. - link_->SetBounds(label_1_x + available_width - link_ps.width(), - OffsetY(this, link_ps), link_ps.width(), link_ps.height()); - } - - // Layout the right label (we do this regardless of whether or not it has - // text). - gfx::Size label_2_ps = label_2_->GetPreferredSize(); - label_2_->SetBounds(link_->bounds().right(), - OffsetY(this, label_2_ps), label_2_ps.width(), - label_2_ps.height()); -} - -// LinkInfoBar, private: ------------------------------------------------------- - -LinkInfoBarDelegate* LinkInfoBar::GetDelegate() { - return delegate()->AsLinkInfoBarDelegate(); -} - -// ConfirmInfoBar, public: ----------------------------------------------------- - -ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) - : AlertInfoBar(delegate), - ok_button_(NULL), - cancel_button_(NULL), - link_(NULL), - initialized_(false) { - ok_button_ = new views::NativeButton(this, - UTF16ToWideHack(delegate->GetButtonLabel( - ConfirmInfoBarDelegate::BUTTON_OK))); - ok_button_->SetAccessibleName(ok_button_->label()); - if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK_DEFAULT) - ok_button_->SetAppearsAsDefault(true); - if (delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_OK)) - ok_button_->SetNeedElevation(true); - cancel_button_ = new views::NativeButton( - this, UTF16ToWideHack( - delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL))); - cancel_button_->SetAccessibleName(cancel_button_->label()); - - // Set up the link. - link_ = new views::Link; - link_->SetText(UTF16ToWideHack(delegate->GetLinkText())); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - link_->SetFont(rb.GetFont(ResourceBundle::MediumFont)); - link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - link_->SetController(this); - link_->MakeReadableOverBackgroundColor(background()->get_color()); -} - -ConfirmInfoBar::~ConfirmInfoBar() { - if (!initialized_) { - delete ok_button_; - delete cancel_button_; - delete link_; - } -} - -// ConfirmInfoBar, views::LinkController implementation: ----------------------- - -void ConfirmInfoBar::LinkActivated(views::Link* source, int event_flags) { - DCHECK(source == link_); - DCHECK(link_->IsVisible()); - DCHECK(!link_->GetText().empty()); - if (GetDelegate()->LinkClicked( - event_utils::DispositionFromEventFlags(event_flags))) { - RemoveInfoBar(); - } -} - -// ConfirmInfoBar, views::View overrides: -------------------------------------- - -void ConfirmInfoBar::Layout() { - // First layout right aligned items (from right to left) in order to determine - // the space avalable, then layout the left aligned items. - - // Layout the close button. - InfoBar::Layout(); - - // Layout the cancel and OK buttons. - int available_width = AlertInfoBar::GetAvailableWidth(); - int ok_button_width = 0; - int cancel_button_width = 0; - gfx::Size ok_ps = ok_button_->GetPreferredSize(); - gfx::Size cancel_ps = cancel_button_->GetPreferredSize(); - - if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) { - ok_button_width = ok_ps.width(); - } else { - ok_button_->SetVisible(false); - } - if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) { - cancel_button_width = cancel_ps.width(); - } else { - cancel_button_->SetVisible(false); - } - - cancel_button_->SetBounds(available_width - cancel_button_width, - OffsetY(this, cancel_ps), cancel_ps.width(), - cancel_ps.height()); - int spacing = cancel_button_width > 0 ? kButtonButtonSpacing : 0; - ok_button_->SetBounds(cancel_button_->x() - spacing - ok_button_width, - OffsetY(this, ok_ps), ok_ps.width(), ok_ps.height()); - - // Layout the icon and label. - AlertInfoBar::Layout(); - - // Now append the link to the label's right edge. - link_->SetVisible(!link_->GetText().empty()); - gfx::Size link_ps = link_->GetPreferredSize(); - int link_x = label()->bounds().right() + kEndOfLabelSpacing; - int link_w = std::min(GetAvailableWidth() - link_x, link_ps.width()); - link_->SetBounds(link_x, OffsetY(this, link_ps), link_w, link_ps.height()); -} - -void ConfirmInfoBar::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this && !initialized_) { - Init(); - initialized_ = true; - } - InfoBar::ViewHierarchyChanged(is_add, parent, child); -} - -// ConfirmInfoBar, views::ButtonListener implementation: --------------- - -void ConfirmInfoBar::ButtonPressed( - views::Button* sender, const views::Event& event) { - InfoBar::ButtonPressed(sender, event); - if (sender == ok_button_) { - if (GetDelegate()->Accept()) - RemoveInfoBar(); - } else if (sender == cancel_button_) { - if (GetDelegate()->Cancel()) - RemoveInfoBar(); - } -} - -// ConfirmInfoBar, InfoBar overrides: ------------------------------------------ - -int ConfirmInfoBar::GetAvailableWidth() const { - return ok_button_->x() - kEndOfLabelSpacing; -} - -// ConfirmInfoBar, private: ---------------------------------------------------- - -ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() { - return delegate()->AsConfirmInfoBarDelegate(); -} - -void ConfirmInfoBar::Init() { - AddChildView(ok_button_); - AddChildView(cancel_button_); - AddChildView(link_); -} - -// AlertInfoBarDelegate, InfoBarDelegate overrides: ---------------------------- - -InfoBar* AlertInfoBarDelegate::CreateInfoBar() { - return new AlertInfoBar(this); -} - -// LinkInfoBarDelegate, InfoBarDelegate overrides: ----------------------------- - -InfoBar* LinkInfoBarDelegate::CreateInfoBar() { - return new LinkInfoBar(this); -} - -// ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- - -InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { - return new ConfirmInfoBar(this); -} diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h index ec270d5..9345bdc 100644 --- a/chrome/browser/views/infobars/infobars.h +++ b/chrome/browser/views/infobars/infobars.h @@ -6,246 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_INFOBARS_H_ #pragma once -#include "app/animation.h" -#include "base/task.h" -#include "chrome/browser/tab_contents/infobar_delegate.h" -#include "views/controls/button/button.h" -#include "views/controls/link.h" -#include "views/focus/focus_manager.h" - -class InfoBarContainer; -class SlideAnimation; -namespace views { -class ExternalFocusTracker; -class ImageButton; -class ImageView; -class Label; -class NativeButton; -} - -// This file contains implementations for some general purpose InfoBars. See -// chrome/browser/tab_contents/infobar_delegate.h for the delegate interface(s) -// that you must implement to use these. - -class InfoBarBackground : public views::Background { - public: - explicit InfoBarBackground(InfoBarDelegate::Type infobar_type); - - // Overridden from views::Background: - virtual void Paint(gfx::Canvas* canvas, views::View* view) const; - - private: - scoped_ptr<views::Background> gradient_background_; - - DISALLOW_COPY_AND_ASSIGN(InfoBarBackground); -}; - -class InfoBar : public views::View, - public views::ButtonListener, - public views::FocusChangeListener, - public AnimationDelegate { - public: - explicit InfoBar(InfoBarDelegate* delegate); - virtual ~InfoBar(); - - InfoBarDelegate* delegate() const { return delegate_; } - - // Set a link to the parent InfoBarContainer. This must be set before the - // InfoBar is added to the view hierarchy. - void set_container(InfoBarContainer* container) { container_ = container; } - - // The target height of the InfoBar, regardless of what its current height - // is (due to animation). - static const double kDefaultTargetHeight; - - static const int kHorizontalPadding; - static const int kIconLabelSpacing; - static const int kButtonButtonSpacing; - static const int kEndOfLabelSpacing; - static const int kCloseButtonSpacing; - static const int kButtonInLabelSpacing; - - // Overridden from views::View: - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - protected: - // Overridden from views::View: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // Returns the available width of the View for use by child view layout, - // excluding the close button. - virtual int GetAvailableWidth() const; - - // Removes our associated InfoBarDelegate from the associated TabContents. - // (Will lead to this InfoBar being closed). - void RemoveInfoBar() const; - - void set_target_height(double height) { target_height_ = height; } - - SlideAnimation* animation() { return animation_.get(); } - - // Returns a centered y-position of a control of height specified in - // |prefsize| within the standard InfoBar height. Stable during an animation. - int CenterY(const gfx::Size prefsize); - - // Returns a centered y-position of a control of height specified in - // |prefsize| within the standard InfoBar height, adjusted according to the - // current amount of animation offset the |parent| InfoBar currently has. - // Changes during an animation. - int OffsetY(views::View* parent, const gfx::Size prefsize); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from views::FocusChangeListener: - virtual void FocusWillChange(View* focused_before, View* focused_now); - - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation); - virtual void AnimationEnded(const Animation* animation); - - private: - friend class InfoBarContainer; - - // Starts animating the InfoBar open. - void AnimateOpen(); - - // Opens the InfoBar immediately. - void Open(); - - // Starts animating the InfoBar closed. It will not be closed until the - // animation has completed, when |Close| will be called. - void AnimateClose(); - - // Closes the InfoBar immediately and removes it from its container. Notifies - // the delegate that it has closed. The InfoBar is deleted after this function - // is called. - void Close(); - - // Called when an InfoBar is added or removed from a view hierarchy to do - // setup and shutdown. - void InfoBarAdded(); - void InfoBarRemoved(); - - // Destroys the external focus tracker, if present. If |restore_focus| is - // true, restores focus to the view tracked by the focus tracker before doing - // so. - void DestroyFocusTracker(bool restore_focus); - - // Deletes this object (called after a return to the message loop to allow - // the stack in ViewHierarchyChanged to unwind). - void DeleteSelf(); - - // The InfoBar's container - InfoBarContainer* container_; - - // The InfoBar's delegate. - InfoBarDelegate* delegate_; - - // The Close Button at the right edge of the InfoBar. - views::ImageButton* close_button_; - - // The animation that runs when the InfoBar is opened or closed. - scoped_ptr<SlideAnimation> animation_; - - // Tracks and stores the last focused view which is not the InfoBar or any of - // its children. Used to restore focus once the InfoBar is closed. - scoped_ptr<views::ExternalFocusTracker> focus_tracker_; - - // Used to delete this object after a return to the message loop. - ScopedRunnableMethodFactory<InfoBar> delete_factory_; - - // The target height for the InfoBar. - double target_height_; - - DISALLOW_COPY_AND_ASSIGN(InfoBar); -}; - -class AlertInfoBar : public InfoBar { - public: - explicit AlertInfoBar(AlertInfoBarDelegate* delegate); - virtual ~AlertInfoBar(); - - // Overridden from views::View: - virtual void Layout(); - - protected: - views::Label* label() const { return label_; } - views::ImageView* icon() const { return icon_; } - - private: - AlertInfoBarDelegate* GetDelegate(); - - views::Label* label_; - views::ImageView* icon_; - - DISALLOW_COPY_AND_ASSIGN(AlertInfoBar); -}; - -class LinkInfoBar : public InfoBar, - public views::LinkController { - public: - explicit LinkInfoBar(LinkInfoBarDelegate* delegate); - virtual ~LinkInfoBar(); - - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - // Overridden from views::View: - virtual void Layout(); - - private: - LinkInfoBarDelegate* GetDelegate(); - - views::ImageView* icon_; - views::Label* label_1_; - views::Label* label_2_; - views::Link* link_; - - DISALLOW_COPY_AND_ASSIGN(LinkInfoBar); -}; - -class ConfirmInfoBar : public AlertInfoBar, - public views::LinkController { - public: - explicit ConfirmInfoBar(ConfirmInfoBarDelegate* delegate); - virtual ~ConfirmInfoBar(); - - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - // Overridden from views::View: - virtual void Layout(); - - protected: - // Overridden from views::View: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from InfoBar: - virtual int GetAvailableWidth() const; - - private: - void Init(); - - ConfirmInfoBarDelegate* GetDelegate(); - - views::NativeButton* ok_button_; - views::NativeButton* cancel_button_; - views::Link* link_; - - bool initialized_; - - DISALLOW_COPY_AND_ASSIGN(ConfirmInfoBar); -}; - +#include "chrome/browser/ui/views/infobars/infobars.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_INFOBARS_H_ + diff --git a/chrome/browser/views/infobars/translate_infobar_base.cc b/chrome/browser/views/infobars/translate_infobar_base.cc deleted file mode 100644 index 4eb0bdd..0000000 --- a/chrome/browser/views/infobars/translate_infobar_base.cc +++ /dev/null @@ -1,178 +0,0 @@ -// 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/infobars/translate_infobar_base.h" - -#include "app/resource_bundle.h" -#include "app/slide_animation.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/translate/translate_infobar_delegate.h" -#include "chrome/browser/views/infobars/after_translate_infobar.h" -#include "chrome/browser/views/infobars/before_translate_infobar.h" -#include "chrome/browser/views/infobars/translate_message_infobar.h" -#include "chrome/browser/views/infobars/infobar_button_border.h" -#include "gfx/canvas_skia.h" -#include "grit/theme_resources.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/image_view.h" - -TranslateInfoBarBase::TranslateInfoBarBase( - TranslateInfoBarDelegate* delegate) - : InfoBar(delegate), - normal_background_(InfoBarDelegate::PAGE_ACTION_TYPE), - error_background_(InfoBarDelegate::WARNING_TYPE) { - icon_ = new views::ImageView; - SkBitmap* image = delegate->GetIcon(); - if (image) - icon_->SetImage(image); - AddChildView(icon_); - - TranslateInfoBarDelegate::BackgroundAnimationType animation = - delegate->background_animation_type(); - if (animation != TranslateInfoBarDelegate::NONE) { - background_color_animation_.reset(new SlideAnimation(this)); - background_color_animation_->SetTweenType(Tween::LINEAR); - background_color_animation_->SetSlideDuration(500); - if (animation == TranslateInfoBarDelegate::NORMAL_TO_ERROR) { - background_color_animation_->Show(); - } else { - DCHECK_EQ(TranslateInfoBarDelegate::ERROR_TO_NORMAL, animation); - // Hide() runs the animation in reverse. - background_color_animation_->Reset(1.0); - background_color_animation_->Hide(); - } - } -} - -TranslateInfoBarBase::~TranslateInfoBarBase() { -} - -// Overridden from views::View: -void TranslateInfoBarBase::Layout() { - // Layout the close button. - InfoBar::Layout(); - - // Layout the icon on left of bar. - gfx::Size icon_ps = icon_->GetPreferredSize(); - icon_->SetBounds(InfoBar::kHorizontalPadding, InfoBar::OffsetY(this, icon_ps), - icon_ps.width(), icon_ps.height()); -} - -views::Label* TranslateInfoBarBase::CreateLabel(const string16& text) { - views::Label* label = new views::Label(UTF16ToWideHack(text), - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); - label->SetColor(SK_ColorBLACK); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - return label; -} - -void TranslateInfoBarBase::PaintBackground(gfx::Canvas* canvas) { - // If we're not animating, simply paint the background for the current state. - if (background_color_animation_ == NULL || - !background_color_animation_->is_animating()) { - GetBackground().Paint(canvas, this); - return; - } - - FadeBackground(canvas, 1.0 - background_color_animation_->GetCurrentValue(), - normal_background_); - FadeBackground(canvas, background_color_animation_->GetCurrentValue(), - error_background_); -} - -void TranslateInfoBarBase::AnimationProgressed(const Animation* animation) { - if (background_color_animation_.get() == animation) - SchedulePaint(); // That'll trigger a PaintBackgroud. - else - InfoBar::AnimationProgressed(animation); -} - -views::MenuButton* TranslateInfoBarBase::CreateMenuButton( - const string16& text, - bool normal_has_border, - views::ViewMenuDelegate* menu_delegate) { - // Don't use text to instantiate MenuButton because we need to set font before - // setting text so that the button will resize to fit the entire text. - views::MenuButton* menu_button = - new views::MenuButton(NULL, std::wstring(), menu_delegate, true); - menu_button->set_border(new InfoBarButtonBorder); - menu_button->set_menu_marker(ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_INFOBARBUTTON_MENU_DROPARROW)); - if (normal_has_border) { - menu_button->SetNormalHasBorder(true); // Normal button state has border. - // Disable animation during state change. - menu_button->SetAnimationDuration(0); - } - // Set font colors for different states. - menu_button->SetEnabledColor(SK_ColorBLACK); - menu_button->SetHighlightColor(SK_ColorBLACK); - menu_button->SetHoverColor(SK_ColorBLACK); - - // Set font then text, then size button to fit text. - menu_button->SetFont(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::MediumFont)); - menu_button->SetText(UTF16ToWideHack(text)); - menu_button->ClearMaxTextSize(); - menu_button->SizeToPreferredSize(); - return menu_button; -} - -gfx::Point TranslateInfoBarBase::DetermineMenuPosition( - views::MenuButton* menu_button) { - gfx::Rect lb = menu_button->GetLocalBounds(true); - gfx::Point menu_position(lb.origin()); - menu_position.Offset(2, lb.height() - 3); - if (base::i18n::IsRTL()) - menu_position.Offset(lb.width() - 4, 0); - - View::ConvertPointToScreen(menu_button, &menu_position); -#if defined(OS_WIN) - int left_bound = GetSystemMetrics(SM_XVIRTUALSCREEN); - if (menu_position.x() < left_bound) - menu_position.set_x(left_bound); -#endif - return menu_position; -} - -TranslateInfoBarDelegate* TranslateInfoBarBase::GetDelegate() const { - return static_cast<TranslateInfoBarDelegate*>(delegate()); -} - -const InfoBarBackground& TranslateInfoBarBase::GetBackground() const { - return GetDelegate()->IsError() ? error_background_ : normal_background_; -} - -void TranslateInfoBarBase::FadeBackground(gfx::Canvas* canvas, - double animation_value, - const InfoBarBackground& background) { - // Draw the background into an offscreen buffer with alpha value per animation - // value, then blend it back into the current canvas. - canvas->SaveLayerAlpha(static_cast<int>(animation_value * 255)); - canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); - background.Paint(canvas, this); - canvas->Restore(); -} - -// TranslateInfoBarDelegate views specific method: -InfoBar* TranslateInfoBarDelegate::CreateInfoBar() { - TranslateInfoBarBase* infobar = NULL; - switch (type_) { - case BEFORE_TRANSLATE: - infobar = new BeforeTranslateInfoBar(this); - break; - case AFTER_TRANSLATE: - infobar = new AfterTranslateInfoBar(this); - break; - case TRANSLATING: - case TRANSLATION_ERROR: - infobar = new TranslateMessageInfoBar(this); - break; - default: - NOTREACHED(); - } - // Set |infobar_view_| so that the model can notify the infobar when it - // changes. - infobar_view_ = infobar; - return infobar; -} diff --git a/chrome/browser/views/infobars/translate_infobar_base.h b/chrome/browser/views/infobars/translate_infobar_base.h index a16d1ca..84b68dc 100644 --- a/chrome/browser/views/infobars/translate_infobar_base.h +++ b/chrome/browser/views/infobars/translate_infobar_base.h @@ -6,70 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_INFOBAR_BASE_H_ #pragma once -#include "chrome/browser/translate/translate_infobar_view.h" -#include "chrome/browser/views/infobars/infobars.h" - -class TranslateInfoBarDelegate; - -namespace views { -class MenuButton; -class ViewMenuDelegate; -} - -// This class contains some of the base functionality that translate infobars -// use. -class TranslateInfoBarBase : public TranslateInfoBarView, - public InfoBar { - public: - explicit TranslateInfoBarBase(TranslateInfoBarDelegate* delegate); - virtual ~TranslateInfoBarBase(); - - // TranslateInfoBarView implementation: - virtual void OriginalLanguageChanged() {} - virtual void TargetLanguageChanged() {} - - // Overridden from views::View: - virtual void Layout(); - virtual void PaintBackground(gfx::Canvas* canvas); - - protected: - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation); - - // Creates a label with the appropriate font and color for the translate - // infobars. - views::Label* CreateLabel(const string16& text); - - // Creates a menu-button with a custom appearance for the translate infobars. - views::MenuButton* CreateMenuButton(const string16& text, - bool normal_has_border, - views::ViewMenuDelegate* menu_delegate); - - // Returns the location at which the menu triggered by |menu_button| should be - // positioned. - gfx::Point DetermineMenuPosition(views::MenuButton* menu_button); - - // Convenience to retrieve the TranslateInfoBarDelegate for this infobar. - TranslateInfoBarDelegate* GetDelegate() const; - - // The translate icon. - views::ImageView* icon_; - - InfoBarBackground normal_background_; - InfoBarBackground error_background_; - scoped_ptr<SlideAnimation> background_color_animation_; - - private: - // Returns the background that should be displayed when not animating. - const InfoBarBackground& GetBackground() const; - - // Paints |background| to |canvas| with the opacity level based on - // |animation_value|. - void FadeBackground(gfx::Canvas* canvas, - double animation_value, - const InfoBarBackground& background); - - DISALLOW_COPY_AND_ASSIGN(TranslateInfoBarBase); -}; +#include "chrome/browser/ui/views/infobars/translate_infobar_base.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_INFOBAR_BASE_H_ + diff --git a/chrome/browser/views/infobars/translate_message_infobar.cc b/chrome/browser/views/infobars/translate_message_infobar.cc deleted file mode 100644 index 8094d4e..0000000 --- a/chrome/browser/views/infobars/translate_message_infobar.cc +++ /dev/null @@ -1,57 +0,0 @@ -// 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/infobars/translate_message_infobar.h" - -#include "chrome/browser/translate/translate_infobar_delegate.h" -#include "chrome/browser/views/infobars/infobar_text_button.h" -#include "views/controls/image_view.h" - -TranslateMessageInfoBar::TranslateMessageInfoBar( - TranslateInfoBarDelegate* delegate) - : TranslateInfoBarBase(delegate) { - label_ = CreateLabel(delegate->GetMessageInfoBarText()); - AddChildView(label_); - - string16 button_text = delegate->GetMessageInfoBarButtonText(); - if (button_text.empty()) { - button_ = NULL; - } else { - button_ = InfoBarTextButton::Create(this, button_text); - AddChildView(button_); - } -} - -void TranslateMessageInfoBar::Layout() { - TranslateInfoBarBase::Layout(); - - int x = icon_->bounds().right() + InfoBar::kIconLabelSpacing; - gfx::Size label_pref_size = label_->GetPreferredSize(); - int available_width = GetAvailableWidth() - x; - gfx::Size button_pref_size; - if (button_) { - button_pref_size = button_->GetPreferredSize(); - available_width -= - (button_pref_size.width() + InfoBar::kButtonInLabelSpacing); - } - label_->SetBounds(x, InfoBar::OffsetY(this, label_pref_size), - std::min(label_pref_size.width(), available_width), - label_pref_size.height()); - - if (button_) { - button_->SetBounds(label_->bounds().right() + - InfoBar::kButtonInLabelSpacing, - InfoBar::OffsetY(this, button_pref_size), - button_pref_size.width(), button_pref_size.height()); - } -} - -void TranslateMessageInfoBar::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == button_) { - GetDelegate()->MessageInfoBarButtonPressed(); - return; - } - TranslateInfoBarBase::ButtonPressed(sender, event); -} diff --git a/chrome/browser/views/infobars/translate_message_infobar.h b/chrome/browser/views/infobars/translate_message_infobar.h index e77bcf2..d893fe7 100644 --- a/chrome/browser/views/infobars/translate_message_infobar.h +++ b/chrome/browser/views/infobars/translate_message_infobar.h @@ -6,24 +6,8 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_MESSAGE_INFOBAR_H_ #pragma once -#include "chrome/browser/views/infobars/translate_infobar_base.h" - -class InfoBarTextButton; - -class TranslateMessageInfoBar : public TranslateInfoBarBase { - public: - explicit TranslateMessageInfoBar(TranslateInfoBarDelegate* delegate); - - virtual void Layout(); - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - private: - views::Label* label_; - InfoBarTextButton* button_; - - DISALLOW_COPY_AND_ASSIGN(TranslateMessageInfoBar); -}; +#include "chrome/browser/ui/views/infobars/translate_message_infobar.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_MESSAGE_INFOBAR_H_ + diff --git a/chrome/browser/views/instant_confirm_view.cc b/chrome/browser/views/instant_confirm_view.cc deleted file mode 100644 index 4a714b2f..0000000 --- a/chrome/browser/views/instant_confirm_view.cc +++ /dev/null @@ -1,97 +0,0 @@ -// 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/instant_confirm_view.h" - -#include "app/l10n_util.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/instant/instant_confirm_dialog.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/common/pref_names.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/label.h" -#include "views/grid_layout.h" -#include "views/layout_manager.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -InstantConfirmView::InstantConfirmView(Profile* profile) : profile_(profile) { - views::Label* description_label = new views::Label( - l10n_util::GetString(IDS_INSTANT_OPT_IN_MESSAGE)); - description_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - description_label->SetMultiLine(true); - - views::Link* learn_more_link = new views::Link( - l10n_util::GetString(IDS_LEARN_MORE)); - learn_more_link->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - learn_more_link->SetController(this); - - views::GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int first_column_set = 1; - views::ColumnSet* column_set = layout->AddColumnSet(first_column_set); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, - views::GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, first_column_set); - layout->AddView(description_label); - layout->StartRow(0, first_column_set); - layout->AddView(learn_more_link); -} - -bool InstantConfirmView::Accept(bool window_closing) { - return Accept(); -} - -bool InstantConfirmView::Accept() { - PrefService* prefs = profile_->GetPrefs(); - if (prefs) { - prefs->SetBoolean(prefs::kInstantEnabled, true); - prefs->SetBoolean(prefs::kInstantConfirmDialogShown, true); - } - return true; -} - -bool InstantConfirmView::Cancel() { - return true; -} - -views::View* InstantConfirmView::GetContentsView() { - return this; -} - -std::wstring InstantConfirmView::GetWindowTitle() const { - return l10n_util::GetString(IDS_INSTANT_OPT_IN_TITLE); -} - -gfx::Size InstantConfirmView::GetPreferredSize() { - DCHECK(GetLayoutManager()); - int pref_width = views::Window::GetLocalizedContentsWidth( - IDS_INSTANT_CONFIRM_DIALOG_WIDTH_CHARS); - int pref_height = - GetLayoutManager()->GetPreferredHeightForWidth(this, pref_width); - return gfx::Size(pref_width, pref_height); -} - -bool InstantConfirmView::IsModal() const { - return true; -} - -void InstantConfirmView::LinkActivated(views::Link* source, int event_flags) { - Browser* browser = BrowserList::GetLastActive(); - browser->OpenURL(GURL(browser::kInstantLearnMoreURL), GURL(), - NEW_FOREGROUND_TAB, PageTransition::TYPED); -} - -namespace browser { - -void ShowInstantConfirmDialog(gfx::NativeWindow parent, Profile* profile) { - views::Window::CreateChromeWindow(parent, gfx::Rect(), - new InstantConfirmView(profile))->Show(); -} - -} // namespace browser diff --git a/chrome/browser/views/instant_confirm_view.h b/chrome/browser/views/instant_confirm_view.h index 958837c..d0f87d4 100644 --- a/chrome/browser/views/instant_confirm_view.h +++ b/chrome/browser/views/instant_confirm_view.h @@ -6,36 +6,8 @@ #define CHROME_BROWSER_VIEWS_INSTANT_CONFIRM_VIEW_H_ #pragma once -#include "views/controls/label.h" -#include "views/controls/link.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -class Profile; - -// The view shown in the instant confirm dialog. -class InstantConfirmView : public views::View, - public views::DialogDelegate, - public views::LinkController { - public: - explicit InstantConfirmView(Profile* profile); - - // DialogDelegate overrides: - virtual bool Accept(bool window_closing); - virtual bool Accept(); - virtual bool Cancel(); - virtual views::View* GetContentsView(); - virtual std::wstring GetWindowTitle() const; - virtual gfx::Size GetPreferredSize(); - virtual bool IsModal() const; - - // LinkController overrides: - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(InstantConfirmView); -}; +#include "chrome/browser/ui/views/instant_confirm_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_INSTANT_CONFIRM_VIEW_H_ + diff --git a/chrome/browser/views/js_modal_dialog_views.cc b/chrome/browser/views/js_modal_dialog_views.cc deleted file mode 100644 index c6348ea..0000000 --- a/chrome/browser/views/js_modal_dialog_views.cc +++ /dev/null @@ -1,155 +0,0 @@ -// 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/js_modal_dialog_views.h" - -#include "app/keyboard_codes.h" -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "chrome/browser/app_modal_dialog.h" -#include "chrome/browser/views/window.h" -#include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" -#include "views/window/window.h" - -//////////////////////////////////////////////////////////////////////////////// -// JSModalDialogViews, public: - -JSModalDialogViews::JSModalDialogViews( - JavaScriptAppModalDialog* parent) - : parent_(parent), - message_box_view_(new MessageBoxView( - parent->dialog_flags() | MessageBoxFlags::kAutoDetectAlignment, - parent->message_text(), parent->default_prompt_text())) { - DCHECK(message_box_view_); - - message_box_view_->AddAccelerator( - views::Accelerator(app::VKEY_C, false, true, false)); - if (parent->display_suppress_checkbox()) { - message_box_view_->SetCheckBoxLabel( - l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION)); - } -} - -JSModalDialogViews::~JSModalDialogViews() { -} - -//////////////////////////////////////////////////////////////////////////////// -// JSModalDialogViews, NativeAppModalDialog implementation: - -int JSModalDialogViews::GetAppModalDialogButtons() const { - return GetDialogButtons(); -} - -void JSModalDialogViews::ShowAppModalDialog() { - window()->Show(); -} - -void JSModalDialogViews::ActivateAppModalDialog() { - window()->Show(); - window()->Activate(); -} - -void JSModalDialogViews::CloseAppModalDialog() { - window()->Close(); -} - -void JSModalDialogViews::AcceptAppModalDialog() { - GetDialogClientView()->AcceptWindow(); -} - -void JSModalDialogViews::CancelAppModalDialog() { - GetDialogClientView()->CancelWindow(); -} - -////////////////////////////////////////////////////////////////////////////// -// JSModalDialogViews, views::DialogDelegate implementation: - -int JSModalDialogViews::GetDefaultDialogButton() const { - if (parent_->dialog_flags() & MessageBoxFlags::kFlagHasOKButton) - return MessageBoxFlags::DIALOGBUTTON_OK; - - if (parent_->dialog_flags() & MessageBoxFlags::kFlagHasCancelButton) - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - - return MessageBoxFlags::DIALOGBUTTON_NONE; -} - -int JSModalDialogViews::GetDialogButtons() const { - int dialog_buttons = 0; - if (parent_->dialog_flags() & MessageBoxFlags::kFlagHasOKButton) - dialog_buttons = MessageBoxFlags::DIALOGBUTTON_OK; - - if (parent_->dialog_flags() & MessageBoxFlags::kFlagHasCancelButton) - dialog_buttons |= MessageBoxFlags::DIALOGBUTTON_CANCEL; - - return dialog_buttons; -} - -std::wstring JSModalDialogViews::GetWindowTitle() const { - return parent_->title(); -} - - -void JSModalDialogViews::WindowClosing() { -} - -void JSModalDialogViews::DeleteDelegate() { - delete parent_; - delete this; -} - -bool JSModalDialogViews::Cancel() { - parent_->OnCancel(message_box_view_->IsCheckBoxSelected()); - return true; -} - -bool JSModalDialogViews::Accept() { - parent_->OnAccept(message_box_view_->GetInputText(), - message_box_view_->IsCheckBoxSelected()); - return true; -} - -void JSModalDialogViews::OnClose() { - parent_->OnClose(); -} - -std::wstring JSModalDialogViews::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (parent_->is_before_unload_dialog()) { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return l10n_util::GetString(IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL); - } else if (button == MessageBoxFlags::DIALOGBUTTON_CANCEL) { - return l10n_util::GetString( - IDS_BEFOREUNLOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL); - } - } - return DialogDelegate::GetDialogButtonLabel(button); -} - -/////////////////////////////////////////////////////////////////////////////// -// JSModalDialogViews, views::WindowDelegate implementation: - -views::View* JSModalDialogViews::GetContentsView() { - return message_box_view_; -} - -views::View* JSModalDialogViews::GetInitiallyFocusedView() { - if (message_box_view_->text_box()) - return message_box_view_->text_box(); - return views::DialogDelegate::GetInitiallyFocusedView(); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeAppModalDialog, public: - -// static -NativeAppModalDialog* NativeAppModalDialog::CreateNativeJavaScriptPrompt( - JavaScriptAppModalDialog* dialog, - gfx::NativeWindow parent_window) { - JSModalDialogViews* d = new JSModalDialogViews(dialog); - - browser::CreateViewsWindow(parent_window, gfx::Rect(), d); - return d; -} diff --git a/chrome/browser/views/js_modal_dialog_views.h b/chrome/browser/views/js_modal_dialog_views.h index 00d1bb7..a5c6425 100644 --- a/chrome/browser/views/js_modal_dialog_views.h +++ b/chrome/browser/views/js_modal_dialog_views.h @@ -6,55 +6,8 @@ #define CHROME_BROWSER_VIEWS_JS_MODAL_DIALOG_VIEWS_H_ #pragma once -#include "chrome/browser/js_modal_dialog.h" - -#include <string> - -#include "app/message_box_flags.h" -#include "chrome/browser/native_app_modal_dialog.h" -#include "views/window/dialog_delegate.h" - -class MessageBoxView; - -class JSModalDialogViews : public NativeAppModalDialog, - public views::DialogDelegate { - public: - explicit JSModalDialogViews(JavaScriptAppModalDialog* parent); - virtual ~JSModalDialogViews(); - - // Overridden from NativeAppModalDialog: - virtual int GetAppModalDialogButtons() const; - virtual void ShowAppModalDialog(); - virtual void ActivateAppModalDialog(); - virtual void CloseAppModalDialog(); - virtual void AcceptAppModalDialog(); - virtual void CancelAppModalDialog(); - - // Overridden from views::DialogDelegate: - virtual int GetDefaultDialogButton() const; - virtual int GetDialogButtons() const; - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual void DeleteDelegate(); - virtual bool Cancel(); - virtual bool Accept(); - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - - // Overridden from views::WindowDelegate: - virtual bool IsModal() const { return true; } - virtual views::View* GetContentsView(); - virtual views::View* GetInitiallyFocusedView(); - virtual void OnClose(); - - private: - // A pointer to the AppModalDialog that owns us. - JavaScriptAppModalDialog* parent_; - - // The message box view whose commands we handle. - MessageBoxView* message_box_view_; - - DISALLOW_COPY_AND_ASSIGN(JSModalDialogViews); -}; +#include "chrome/browser/ui/views/js_modal_dialog_views.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_JS_MODAL_DIALOG_VIEWS_H_ + diff --git a/chrome/browser/views/keyword_editor_view.cc b/chrome/browser/views/keyword_editor_view.cc deleted file mode 100644 index 6cd877c..0000000 --- a/chrome/browser/views/keyword_editor_view.cc +++ /dev/null @@ -1,306 +0,0 @@ -// 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/keyword_editor_view.h" - -#include <vector> - -#include "app/l10n_util.h" -#include "base/stl_util-inl.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/search_engines/template_url_table_model.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "chrome/browser/views/first_run_search_engine_view.h" -#include "chrome/common/pref_names.h" -#include "gfx/point.h" -#include "googleurl/src/gurl.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "views/background.h" -#include "views/grid_layout.h" -#include "views/controls/button/native_button.h" -#include "views/controls/table/table_view.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -using views::GridLayout; -using views::NativeButton; - -namespace browser { - -// Declared in browser_dialogs.h so others don't have to depend on our header. -void ShowKeywordEditorView(Profile* profile) { - KeywordEditorView::Show(profile); -} - -} // namespace browser - - -// KeywordEditorView ---------------------------------------------------------- - -// If non-null, there is an open editor and this is the window it is contained -// in. -static views::Window* open_window = NULL; - -// static -// The typical case for showing a KeywordEditorView does not involve an -// observer, so use this function signature generally. -void KeywordEditorView::Show(Profile* profile) { - KeywordEditorView::ShowAndObserve(profile, NULL); -} - -// static -void KeywordEditorView::ShowAndObserve(Profile* profile, - SearchEngineSelectionObserver* observer) { - // If this panel is opened from an Incognito window, closing that window can - // leave this with a stale pointer. Use the original profile instead. - // See http://crbug.com/23359. - profile = profile ->GetOriginalProfile(); - if (!profile->GetTemplateURLModel()) - return; - - if (open_window != NULL) - open_window->Close(); - DCHECK(!open_window); - - // Both of these will be deleted when the dialog closes. - KeywordEditorView* keyword_editor = new KeywordEditorView(profile, observer); - - // Initialize the UI. By passing in an empty rect KeywordEditorView is - // queried for its preferred size. - open_window = views::Window::CreateChromeWindow(NULL, gfx::Rect(), - keyword_editor); - - open_window->Show(); -} - -KeywordEditorView::KeywordEditorView(Profile* profile, - SearchEngineSelectionObserver* observer) - : profile_(profile), - observer_(observer), - controller_(new KeywordEditorController(profile)), - default_chosen_(false) { - DCHECK(controller_->url_model()); - controller_->url_model()->AddObserver(this); - Init(); -} - -KeywordEditorView::~KeywordEditorView() { - table_view_->SetModel(NULL); - controller_->url_model()->RemoveObserver(this); -} - -void KeywordEditorView::OnEditedKeyword(const TemplateURL* template_url, - const string16& title, - const string16& keyword, - const std::string& url) { - if (template_url) { - controller_->ModifyTemplateURL(template_url, title, keyword, url); - - // Force the make default button to update. - OnSelectionChanged(); - } else { - table_view_->Select(controller_->AddTemplateURL(title, keyword, url)); - } -} - - -gfx::Size KeywordEditorView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_SEARCHENGINES_DIALOG_WIDTH_CHARS, - IDS_SEARCHENGINES_DIALOG_HEIGHT_LINES)); -} - -bool KeywordEditorView::CanResize() const { - return true; -} - -std::wstring KeywordEditorView::GetWindowTitle() const { - return l10n_util::GetString(IDS_SEARCH_ENGINES_EDITOR_WINDOW_TITLE); -} - -std::wstring KeywordEditorView::GetWindowName() const { - return UTF8ToWide(prefs::kKeywordEditorWindowPlacement); -} - -int KeywordEditorView::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -bool KeywordEditorView::Accept() { - open_window = NULL; - return true; -} - -bool KeywordEditorView::Cancel() { - open_window = NULL; - return true; -} - -views::View* KeywordEditorView::GetContentsView() { - return this; -} - -void KeywordEditorView::Init() { - std::vector<TableColumn> columns; - columns.push_back( - TableColumn(IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_COLUMN, - TableColumn::LEFT, -1, .75)); - columns.back().sortable = true; - columns.push_back( - TableColumn(IDS_SEARCH_ENGINES_EDITOR_KEYWORD_COLUMN, - TableColumn::LEFT, -1, .25)); - columns.back().sortable = true; - table_view_ = new views::TableView(controller_->table_model(), columns, - views::ICON_AND_TEXT, false, true, true); - table_view_->SetObserver(this); - - add_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_SEARCH_ENGINES_EDITOR_NEW_BUTTON)); - add_button_->SetEnabled(controller_->loaded()); - add_button_->AddAccelerator( - views::Accelerator(app::VKEY_A, false, false, true)); - add_button_->SetAccessibleKeyboardShortcut(L"A"); - - edit_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_SEARCH_ENGINES_EDITOR_EDIT_BUTTON)); - edit_button_->SetEnabled(false); - - remove_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_SEARCH_ENGINES_EDITOR_REMOVE_BUTTON)); - remove_button_->SetEnabled(false); - remove_button_->AddAccelerator( - views::Accelerator(app::VKEY_R, false, false, true)); - remove_button_->SetAccessibleKeyboardShortcut(L"R"); - - make_default_button_ = new views::NativeButton( - this, - l10n_util::GetString(IDS_SEARCH_ENGINES_EDITOR_MAKE_DEFAULT_BUTTON)); - make_default_button_->SetEnabled(false); - - InitLayoutManager(); -} - -void KeywordEditorView::InitLayoutManager() { - const int related_x = kRelatedControlHorizontalSpacing; - const int related_y = kRelatedControlVerticalSpacing; - const int unrelated_y = kUnrelatedControlVerticalSpacing; - - GridLayout* contents_layout = CreatePanelGridLayout(this); - SetLayoutManager(contents_layout); - - // For the table and buttons. - views::ColumnSet* column_set = contents_layout->AddColumnSet(0); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, related_x); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - contents_layout->StartRow(0, 0); - contents_layout->AddView(table_view_, 1, 8, GridLayout::FILL, - GridLayout::FILL); - contents_layout->AddView(add_button_); - - contents_layout->StartRowWithPadding(0, 0, 0, related_y); - contents_layout->SkipColumns(2); - contents_layout->AddView(edit_button_); - - contents_layout->StartRowWithPadding(0, 0, 0, related_y); - contents_layout->SkipColumns(2); - contents_layout->AddView(remove_button_); - - contents_layout->StartRowWithPadding(0, 0, 0, related_y); - contents_layout->SkipColumns(2); - contents_layout->AddView(make_default_button_); - - contents_layout->AddPaddingRow(1, 0); -} - -void KeywordEditorView::OnSelectionChanged() { - bool only_one_url_left = - controller_->url_model()->GetTemplateURLs().size() == 1; - if (table_view_->SelectedRowCount() == 1) { - const TemplateURL* selected_url = - controller_->GetTemplateURL(table_view_->FirstSelectedRow()); - edit_button_->SetEnabled(controller_->CanEdit(selected_url)); - make_default_button_->SetEnabled(controller_->CanMakeDefault(selected_url)); - remove_button_->SetEnabled(!only_one_url_left && - controller_->CanRemove(selected_url)); - } else { - edit_button_->SetEnabled(false); - make_default_button_->SetEnabled(false); - for (views::TableView::iterator i = table_view_->SelectionBegin(); - i != table_view_->SelectionEnd(); ++i) { - const TemplateURL* selected_url = controller_->GetTemplateURL(*i); - if (!controller_->CanRemove(selected_url)) { - remove_button_->SetEnabled(false); - return; - } - } - remove_button_->SetEnabled(!only_one_url_left); - } -} - -void KeywordEditorView::OnDoubleClick() { - if (edit_button_->IsEnabled()) { - DWORD pos = GetMessagePos(); - gfx::Point cursor_point(pos); - views::MouseEvent event(views::Event::ET_MOUSE_RELEASED, - cursor_point.x(), cursor_point.y(), - views::Event::EF_LEFT_BUTTON_DOWN); - ButtonPressed(edit_button_, event); - } -} - -void KeywordEditorView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == add_button_) { - browser::EditSearchEngine(GetWindow()->GetNativeWindow(), NULL, this, - profile_); - } else if (sender == remove_button_) { - DCHECK_GT(table_view_->SelectedRowCount(), 0); - int last_view_row = -1; - for (views::TableView::iterator i = table_view_->SelectionBegin(); - i != table_view_->SelectionEnd(); ++i) { - last_view_row = table_view_->ModelToView(*i); - controller_->RemoveTemplateURL(*i); - } - if (last_view_row >= controller_->table_model()->RowCount()) - last_view_row = controller_->table_model()->RowCount() - 1; - if (last_view_row >= 0) - table_view_->Select(table_view_->ViewToModel(last_view_row)); - } else if (sender == edit_button_) { - const int selected_row = table_view_->FirstSelectedRow(); - const TemplateURL* template_url = - controller_->GetTemplateURL(selected_row); - browser::EditSearchEngine(GetWindow()->GetNativeWindow(), template_url, - this, profile_); - } else if (sender == make_default_button_) { - MakeDefaultTemplateURL(); - } else { - NOTREACHED(); - } -} - -void KeywordEditorView::OnTemplateURLModelChanged() { - add_button_->SetEnabled(controller_->loaded()); -} - -void KeywordEditorView::MakeDefaultTemplateURL() { - int new_index = - controller_->MakeDefaultTemplateURL(table_view_->FirstSelectedRow()); - if (new_index >= 0) - table_view_->Select(new_index); - default_chosen_ = true; -} diff --git a/chrome/browser/views/keyword_editor_view.h b/chrome/browser/views/keyword_editor_view.h index b4e7736..a3f5b8f 100644 --- a/chrome/browser/views/keyword_editor_view.h +++ b/chrome/browser/views/keyword_editor_view.h @@ -6,112 +6,8 @@ #define CHROME_BROWSER_VIEWS_KEYWORD_EDITOR_VIEW_H_ #pragma once -#include <Windows.h> - -#include "base/string16.h" -#include "chrome/browser/search_engines/edit_search_engine_controller.h" -#include "chrome/browser/search_engines/keyword_editor_controller.h" -#include "chrome/browser/search_engines/template_url_model_observer.h" -#include "views/controls/button/button.h" -#include "views/controls/table/table_view_observer.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Label; -class NativeButton; -} - -namespace { -class BorderView; -} - -class SearchEngineSelectionObserver; -class SkBitmap; -class TemplateURL; - -// KeywordEditorView allows the user to edit keywords. - -class KeywordEditorView : public views::View, - public views::TableViewObserver, - public views::ButtonListener, - public TemplateURLModelObserver, - public views::DialogDelegate, - public EditSearchEngineControllerDelegate { - public: - // Shows the KeywordEditorView for the specified profile. If there is a - // KeywordEditorView already open, it is closed and a new one is shown. - static void Show(Profile* profile); - - // Shows the KeywordEditorView for the specified profile, and passes in - // an observer to be called back on view close. - static void ShowAndObserve(Profile* profile, - SearchEngineSelectionObserver* observer); - - KeywordEditorView(Profile* profile, - SearchEngineSelectionObserver* observer); - - virtual ~KeywordEditorView(); - - // Overridden from EditSearchEngineControllerDelegate. - // Calls AddTemplateURL or ModifyTemplateURL as appropriate. - virtual void OnEditedKeyword(const TemplateURL* template_url, - const string16& title, - const string16& keyword, - const std::string& url); - - // Overridden to invoke Layout. - virtual gfx::Size GetPreferredSize(); - - // views::DialogDelegate methods: - virtual bool CanResize() const; - virtual std::wstring GetWindowTitle() const; - virtual std::wstring GetWindowName() const; - virtual int GetDialogButtons() const; - virtual bool Accept(); - virtual bool Cancel(); - virtual views::View* GetContentsView(); - - private: - void Init(); - - // Creates the layout and adds the views to it. - void InitLayoutManager(); - - // TableViewObserver method. Updates buttons contingent on the selection. - virtual void OnSelectionChanged(); - // Edits the selected item. - virtual void OnDoubleClick(); - - // Button::ButtonListener method. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // TemplateURLModelObserver notification. - virtual void OnTemplateURLModelChanged(); - - // Toggles whether the selected keyword is the default search provider. - void MakeDefaultTemplateURL(); - - // The profile. - Profile* profile_; - - // Observer gets a callback when the KeywordEditorView closes. - SearchEngineSelectionObserver* observer_; - - scoped_ptr<KeywordEditorController> controller_; - - // True if the user has set a default search engine in this dialog. - bool default_chosen_; - - // All the views are added as children, so that we don't need to delete - // them directly. - views::TableView* table_view_; - views::NativeButton* add_button_; - views::NativeButton* edit_button_; - views::NativeButton* remove_button_; - views::NativeButton* make_default_button_; - - DISALLOW_COPY_AND_ASSIGN(KeywordEditorView); -}; +#include "chrome/browser/ui/views/keyword_editor_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_KEYWORD_EDITOR_VIEW_H_ + diff --git a/chrome/browser/views/list_background.h b/chrome/browser/views/list_background.h index 4f29a34..4cf550b 100644 --- a/chrome/browser/views/list_background.h +++ b/chrome/browser/views/list_background.h @@ -6,32 +6,8 @@ #define CHROME_BROWSER_VIEWS_LIST_BACKGROUND_H_ #pragma once -#include "gfx/canvas_skia.h" -#include "gfx/native_theme_win.h" -#include "views/background.h" - -// A background object that paints the scrollable list background, -// which may be rendered by the system visual styles system. -class ListBackground : public views::Background { - public: - explicit ListBackground() { - SkColor list_color = - gfx::NativeTheme::instance()->GetThemeColorWithDefault( - gfx::NativeTheme::LIST, 1, TS_NORMAL, TMT_FILLCOLOR, COLOR_WINDOW); - SetNativeControlColor(list_color); - } - virtual ~ListBackground() {} - - virtual void Paint(gfx::Canvas* canvas, views::View* view) const { - HDC dc = canvas->BeginPlatformPaint(); - RECT native_lb = view->GetLocalBounds(true).ToRECT(); - gfx::NativeTheme::instance()->PaintListBackground(dc, true, &native_lb); - canvas->EndPlatformPaint(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ListBackground); -}; +#include "chrome/browser/ui/views/list_background.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LIST_BACKGROUND_H_ diff --git a/chrome/browser/views/local_storage_info_view.cc b/chrome/browser/views/local_storage_info_view.cc deleted file mode 100644 index 35c7c49..0000000 --- a/chrome/browser/views/local_storage_info_view.cc +++ /dev/null @@ -1,133 +0,0 @@ -// 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/local_storage_info_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "base/i18n/time_formatting.h" -#include "base/utf_string_conversions.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" - -static const int kLocalStorageInfoViewBorderSize = 1; -static const int kLocalStorageInfoViewInsetSize = 3; - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageInfoView, public: - -LocalStorageInfoView::LocalStorageInfoView() - : origin_value_field_(NULL), - size_value_field_(NULL), - last_modified_value_field_(NULL) { -} - -LocalStorageInfoView::~LocalStorageInfoView() { -} - -void LocalStorageInfoView::SetLocalStorageInfo( - const BrowsingDataLocalStorageHelper::LocalStorageInfo& - local_storage_info) { - origin_value_field_->SetText(UTF8ToWide(local_storage_info.origin)); - size_value_field_->SetText( - FormatBytes(local_storage_info.size, - GetByteDisplayUnits(local_storage_info.size), - true)); - last_modified_value_field_->SetText( - base::TimeFormatFriendlyDateAndTime(local_storage_info.last_modified)); - EnableLocalStorageDisplay(true); -} - -void LocalStorageInfoView::EnableLocalStorageDisplay(bool enabled) { - origin_value_field_->SetEnabled(enabled); - size_value_field_->SetEnabled(enabled); - last_modified_value_field_->SetEnabled(enabled); -} - -void LocalStorageInfoView::ClearLocalStorageDisplay() { - std::wstring no_cookie_string = - l10n_util::GetString(IDS_COOKIES_COOKIE_NONESELECTED); - origin_value_field_->SetText(no_cookie_string); - size_value_field_->SetText(no_cookie_string); - last_modified_value_field_->SetText(no_cookie_string); - EnableLocalStorageDisplay(false); -} - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageInfoView, views::View overrides: - -void LocalStorageInfoView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageInfoView, private: - -void LocalStorageInfoView::Init() { - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kLocalStorageInfoViewBorderSize, border_color); - set_border(border); - - views::Label* origin_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL)); - origin_value_field_ = new views::Textfield; - views::Label* size_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL)); - size_value_field_ = new views::Textfield; - views::Label* last_modified_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL)); - last_modified_value_field_ = new views::Textfield; - - using views::GridLayout; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kLocalStorageInfoViewInsetSize, - kLocalStorageInfoViewInsetSize, - kLocalStorageInfoViewInsetSize, - kLocalStorageInfoViewInsetSize); - SetLayoutManager(layout); - - int three_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, three_column_layout_id); - layout->AddView(origin_label); - layout->AddView(origin_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(size_label); - layout->AddView(size_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(last_modified_label); - layout->AddView(last_modified_value_field_); - - // Color these borderless text areas the same as the containing dialog. - SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); - // Now that the Textfields are in the view hierarchy, we can initialize them. - origin_value_field_->SetReadOnly(true); - origin_value_field_->RemoveBorder(); - origin_value_field_->SetBackgroundColor(text_area_background); - size_value_field_->SetReadOnly(true); - size_value_field_->RemoveBorder(); - size_value_field_->SetBackgroundColor(text_area_background); - last_modified_value_field_->SetReadOnly(true); - last_modified_value_field_->RemoveBorder(); - last_modified_value_field_->SetBackgroundColor(text_area_background); -} - diff --git a/chrome/browser/views/local_storage_info_view.h b/chrome/browser/views/local_storage_info_view.h index aa3e14f..3550959 100644 --- a/chrome/browser/views/local_storage_info_view.h +++ b/chrome/browser/views/local_storage_info_view.h @@ -6,52 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCAL_STORAGE_INFO_VIEW_H_ #pragma once -#include "views/view.h" -#include "chrome/browser/browsing_data_local_storage_helper.h" - -namespace views { -class Label; -class Textfield; -} - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageInfoView -// -// Responsible for displaying a tabular grid of Local Storage information. -class LocalStorageInfoView : public views::View { - public: - LocalStorageInfoView(); - virtual ~LocalStorageInfoView(); - - // Update the display from the specified Local Storage info. - void SetLocalStorageInfo( - const BrowsingDataLocalStorageHelper::LocalStorageInfo& - local_storage_info); - - // Clears the cookie display to indicate that no or multiple local storages - // are selected. - void ClearLocalStorageDisplay(); - - // Enables or disables the local storate property text fields. - void EnableLocalStorageDisplay(bool enabled); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child); - - private: - // Set up the view layout - void Init(); - - // Individual property labels - views::Textfield* origin_value_field_; - views::Textfield* size_value_field_; - views::Textfield* last_modified_value_field_; - - DISALLOW_COPY_AND_ASSIGN(LocalStorageInfoView); -}; - +#include "chrome/browser/ui/views/local_storage_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCAL_STORAGE_INFO_VIEW_H_ diff --git a/chrome/browser/views/local_storage_set_item_info_view.cc b/chrome/browser/views/local_storage_set_item_info_view.cc deleted file mode 100644 index 8df4de4..0000000 --- a/chrome/browser/views/local_storage_set_item_info_view.cc +++ /dev/null @@ -1,127 +0,0 @@ -// 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/local_storage_set_item_info_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "base/utf_string_conversions.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" - -static const int kLocalStorageSetItemInfoViewBorderSize = 1; -static const int kLocalStorageSetItemInfoViewInsetSize = 3; - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageSetItemInfoView, public: - -LocalStorageSetItemInfoView::LocalStorageSetItemInfoView() - : host_value_field_(NULL), - key_value_field_(NULL), - value_value_field_(NULL) { -} - -LocalStorageSetItemInfoView::~LocalStorageSetItemInfoView() { -} - -void LocalStorageSetItemInfoView::SetFields(const std::string& host, - const string16& key, - const string16& value) { - host_value_field_->SetText(UTF8ToWide(host)); - key_value_field_->SetText(key); - value_value_field_->SetText(value); - EnableLocalStorageDisplay(true); -} - -void LocalStorageSetItemInfoView::EnableLocalStorageDisplay(bool enabled) { - host_value_field_->SetEnabled(enabled); - key_value_field_->SetEnabled(enabled); - value_value_field_->SetEnabled(enabled); -} - -void LocalStorageSetItemInfoView::ClearLocalStorageDisplay() { - std::wstring no_cookie_string = - l10n_util::GetString(IDS_COOKIES_COOKIE_NONESELECTED); - host_value_field_->SetText(no_cookie_string); - key_value_field_->SetText(no_cookie_string); - value_value_field_->SetText(no_cookie_string); - EnableLocalStorageDisplay(false); -} - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageSetItemInfoView, views::View overrides: - -void LocalStorageSetItemInfoView::ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageSetItemInfoView, private: - -void LocalStorageSetItemInfoView::Init() { - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kLocalStorageSetItemInfoViewBorderSize, border_color); - set_border(border); - - // TODO(jorlow): These strings are not quite right, but we're post-freeze. - views::Label* host_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_COOKIE_DOMAIN_LABEL)); - host_value_field_ = new views::Textfield; - views::Label* key_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_KEY_LABEL)); - key_value_field_ = new views::Textfield; - views::Label* value_label = new views::Label( - l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_VALUE_LABEL)); - value_value_field_ = new views::Textfield; - - using views::GridLayout; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kLocalStorageSetItemInfoViewInsetSize, - kLocalStorageSetItemInfoViewInsetSize, - kLocalStorageSetItemInfoViewInsetSize, - kLocalStorageSetItemInfoViewInsetSize); - SetLayoutManager(layout); - - int three_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); - column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, three_column_layout_id); - layout->AddView(host_label); - layout->AddView(host_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(key_label); - layout->AddView(key_value_field_); - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); - layout->StartRow(0, three_column_layout_id); - layout->AddView(value_label); - layout->AddView(value_value_field_); - - // Color these borderless text areas the same as the containing dialog. - SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); - // Now that the Textfields are in the view hierarchy, we can initialize them. - host_value_field_->SetReadOnly(true); - host_value_field_->RemoveBorder(); - host_value_field_->SetBackgroundColor(text_area_background); - key_value_field_->SetReadOnly(true); - key_value_field_->RemoveBorder(); - key_value_field_->SetBackgroundColor(text_area_background); - value_value_field_->SetReadOnly(true); - value_value_field_->RemoveBorder(); - value_value_field_->SetBackgroundColor(text_area_background); -} diff --git a/chrome/browser/views/local_storage_set_item_info_view.h b/chrome/browser/views/local_storage_set_item_info_view.h index 9b555b6..ee16aaa 100644 --- a/chrome/browser/views/local_storage_set_item_info_view.h +++ b/chrome/browser/views/local_storage_set_item_info_view.h @@ -6,55 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCAL_STORAGE_SET_ITEM_INFO_VIEW_H_ #pragma once -#include <string> - -#include "base/string16.h" -#include "views/view.h" - -namespace views { -class Label; -class Textfield; -} - -/////////////////////////////////////////////////////////////////////////////// -// LocalStorageSetItemInfoView -// -// Responsible for displaying a tabular grid of Local Storage information when -// prompting for permission to set an item. -class LocalStorageSetItemInfoView : public views::View { - public: - LocalStorageSetItemInfoView(); - virtual ~LocalStorageSetItemInfoView(); - - // Update the display from the specified Local Storage info. - void SetFields(const std::string& host, - const string16& key, - const string16& value); - - // Clears the display to indicate that no or multiple local storages - // are selected. - void ClearLocalStorageDisplay(); - - // Enables or disables the local storate property text fields. - void EnableLocalStorageDisplay(bool enabled); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child); - - private: - // Set up the view layout - void Init(); - - // Individual property labels - views::Textfield* host_value_field_; - views::Textfield* key_value_field_; - views::Textfield* value_value_field_; - - DISALLOW_COPY_AND_ASSIGN(LocalStorageSetItemInfoView); -}; - +#include "chrome/browser/ui/views/local_storage_set_item_info_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCAL_STORAGE_SET_ITEM_INFO_VIEW_H_ diff --git a/chrome/browser/views/location_bar/click_handler.cc b/chrome/browser/views/location_bar/click_handler.cc deleted file mode 100644 index e9c414c..0000000 --- a/chrome/browser/views/location_bar/click_handler.cc +++ /dev/null @@ -1,36 +0,0 @@ -// 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/location_bar/click_handler.h" - -#include "chrome/browser/tab_contents/navigation_controller.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "views/view.h" - -ClickHandler::ClickHandler(const views::View* owner, - const LocationBarView* location_bar) - : owner_(owner), - location_bar_(location_bar) { -} - -void ClickHandler::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - if (canceled || !owner_->HitTest(event.location())) - return; - - // Do not show page info if the user has been editing the location - // bar, or the location bar is at the NTP. - if (location_bar_->location_entry()->IsEditingOrEmpty()) - return; - - TabContents* tab = location_bar_->GetTabContents(); - NavigationEntry* nav_entry = tab->controller().GetActiveEntry(); - if (!nav_entry) { - NOTREACHED(); - return; - } - tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true); -} - diff --git a/chrome/browser/views/location_bar/click_handler.h b/chrome/browser/views/location_bar/click_handler.h index dc8c917..155e501f 100644 --- a/chrome/browser/views/location_bar/click_handler.h +++ b/chrome/browser/views/location_bar/click_handler.h @@ -6,29 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_CLICK_HANDLER_H_ #pragma once -#include "base/basictypes.h" - -class LocationBarView; - -namespace views { -class MouseEvent; -class View; -} - -// This helper class is kept as a member by classes that need to show the Page -// Info dialog on click, to encapsulate that logic in one place. -class ClickHandler { - public: - ClickHandler(const views::View* owner, const LocationBarView* location_bar); - - void OnMouseReleased(const views::MouseEvent& event, bool canceled); - - private: - const views::View* owner_; - const LocationBarView* location_bar_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ClickHandler); -}; +#include "chrome/browser/ui/views/location_bar/click_handler.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_CLICK_HANDLER_H_ diff --git a/chrome/browser/views/location_bar/content_setting_image_view.cc b/chrome/browser/views/location_bar/content_setting_image_view.cc deleted file mode 100644 index 2d5af65..0000000 --- a/chrome/browser/views/location_bar/content_setting_image_view.cc +++ /dev/null @@ -1,92 +0,0 @@ -// 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/location_bar/content_setting_image_view.h" - -#include "app/resource_bundle.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/content_setting_bubble_model.h" -#include "chrome/browser/content_setting_image_model.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/content_setting_bubble_contents.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" - -ContentSettingImageView::ContentSettingImageView( - ContentSettingsType content_type, - const LocationBarView* parent, - Profile* profile) - : content_setting_image_model_( - ContentSettingImageModel::CreateContentSettingImageModel( - content_type)), - parent_(parent), - profile_(profile), - info_bubble_(NULL) { -} - -ContentSettingImageView::~ContentSettingImageView() { - if (info_bubble_) - info_bubble_->Close(); -} - -void ContentSettingImageView::UpdateFromTabContents( - const TabContents* tab_contents) { - int old_icon = content_setting_image_model_->get_icon(); - content_setting_image_model_->UpdateFromTabContents(tab_contents); - if (!content_setting_image_model_->is_visible()) { - SetVisible(false); - return; - } - if (old_icon != content_setting_image_model_->get_icon()) { - SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed( - content_setting_image_model_->get_icon())); - } - SetTooltipText(UTF8ToWide(content_setting_image_model_->get_tooltip())); - SetVisible(true); -} - -bool ContentSettingImageView::OnMousePressed(const views::MouseEvent& event) { - // We want to show the bubble on mouse release; that is the standard behavior - // for buttons. - return true; -} - -void ContentSettingImageView::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - if (canceled || !HitTest(event.location())) - return; - - TabContents* tab_contents = parent_->GetTabContents(); - if (!tab_contents) - return; - - gfx::Rect screen_bounds(GetImageBounds()); - gfx::Point origin(screen_bounds.origin()); - views::View::ConvertPointToScreen(this, &origin); - screen_bounds.set_origin(origin); - ContentSettingBubbleContents* bubble_contents = - new ContentSettingBubbleContents( - ContentSettingBubbleModel::CreateContentSettingBubbleModel( - tab_contents, profile_, - content_setting_image_model_->get_content_settings_type()), - profile_, tab_contents); - info_bubble_ = InfoBubble::Show(GetWidget(), screen_bounds, - BubbleBorder::TOP_RIGHT, bubble_contents, this); - bubble_contents->set_info_bubble(info_bubble_); -} - -void ContentSettingImageView::VisibilityChanged(View* starting_from, - bool is_visible) { - if (!is_visible && info_bubble_) - info_bubble_->Close(); -} - -void ContentSettingImageView::InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape) { - info_bubble_ = NULL; -} - -bool ContentSettingImageView::CloseOnEscape() { - return true; -} - diff --git a/chrome/browser/views/location_bar/content_setting_image_view.h b/chrome/browser/views/location_bar/content_setting_image_view.h index 366ed48..1bcb7bf 100644 --- a/chrome/browser/views/location_bar/content_setting_image_view.h +++ b/chrome/browser/views/location_bar/content_setting_image_view.h @@ -6,56 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_CONTENT_SETTING_IMAGE_VIEW_H_ #pragma once -#include "base/scoped_ptr.h" -#include "chrome/browser/views/info_bubble.h" -#include "chrome/common/content_settings_types.h" -#include "views/controls/image_view.h" - -class ContentSettingImageModel; -class InfoBubble; -class LocationBarView; -class Profile; -class TabContents; - -namespace views { -class MouseEvent; -} - -class ContentSettingImageView : public views::ImageView, - public InfoBubbleDelegate { - public: - ContentSettingImageView(ContentSettingsType content_type, - const LocationBarView* parent, - Profile* profile); - virtual ~ContentSettingImageView(); - - void set_profile(Profile* profile) { profile_ = profile; } - void UpdateFromTabContents(const TabContents* tab_contents); - - private: - // views::ImageView overrides: - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - virtual void VisibilityChanged(View* starting_from, bool is_visible); - - // InfoBubbleDelegate overrides: - virtual void InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape); - virtual bool CloseOnEscape(); - virtual bool FadeInOnShow() { return false; } - - scoped_ptr<ContentSettingImageModel> content_setting_image_model_; - - // The owning LocationBarView. - const LocationBarView* parent_; - - // The currently active profile. - Profile* profile_; - - // The currently shown info bubble if any. - InfoBubble* info_bubble_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ContentSettingImageView); -}; +#include "chrome/browser/ui/views/location_bar/content_setting_image_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_CONTENT_SETTING_IMAGE_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/ev_bubble_view.cc b/chrome/browser/views/location_bar/ev_bubble_view.cc deleted file mode 100644 index 215ad51..0000000 --- a/chrome/browser/views/location_bar/ev_bubble_view.cc +++ /dev/null @@ -1,29 +0,0 @@ -// 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/location_bar/ev_bubble_view.h" - -EVBubbleView::EVBubbleView(const int background_images[], - int contained_image, - const SkColor& color, - const LocationBarView* location_bar) - : IconLabelBubbleView(background_images, contained_image, color), - ALLOW_THIS_IN_INITIALIZER_LIST(click_handler_(this, location_bar)) { - SetElideInMiddle(true); -} - -EVBubbleView::~EVBubbleView() { -} - -bool EVBubbleView::OnMousePressed(const views::MouseEvent& event) { - // We want to show the dialog on mouse release; that is the standard behavior - // for buttons. - return true; -} - -void EVBubbleView::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - click_handler_.OnMouseReleased(event, canceled); -} - diff --git a/chrome/browser/views/location_bar/ev_bubble_view.h b/chrome/browser/views/location_bar/ev_bubble_view.h index 058c8a2..1070a6b 100644 --- a/chrome/browser/views/location_bar/ev_bubble_view.h +++ b/chrome/browser/views/location_bar/ev_bubble_view.h @@ -6,33 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_EV_BUBBLE_VIEW_H_ #pragma once -#include "chrome/browser/views/location_bar/click_handler.h" -#include "chrome/browser/views/location_bar/icon_label_bubble_view.h" - -class LocationBarView; - -namespace views { -class MouseEvent; -} - -// EVBubbleView displays the EV Bubble in the LocationBarView. -class EVBubbleView : public IconLabelBubbleView { - public: - EVBubbleView(const int background_images[], - int contained_image, - const SkColor& color, - const LocationBarView* location_bar); - virtual ~EVBubbleView(); - - // Overridden from view. - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - - private: - ClickHandler click_handler_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(EVBubbleView); -}; +#include "chrome/browser/ui/views/location_bar/ev_bubble_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_EV_BUBBLE_VIEW_H_ diff --git a/chrome/browser/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/views/location_bar/icon_label_bubble_view.cc deleted file mode 100644 index 1e0159b..0000000 --- a/chrome/browser/views/location_bar/icon_label_bubble_view.cc +++ /dev/null @@ -1,79 +0,0 @@ -// 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/location_bar/icon_label_bubble_view.h" - -#include "app/resource_bundle.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "gfx/canvas.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" - -// Amount of padding at the edges of the bubble. -static const int kBubbleOuterPadding = - LocationBarView::kEdgeItemPadding - LocationBarView::kBubblePadding; - -// Amount of padding after the label. -static const int kLabelPadding = 5; - -IconLabelBubbleView::IconLabelBubbleView(const int background_images[], - int contained_image, - const SkColor& color) - : background_painter_(background_images), - item_padding_(LocationBarView::kItemPadding) { - image_ = new views::ImageView(); - AddChildView(image_); - image_->SetImage( - ResourceBundle::GetSharedInstance().GetBitmapNamed(contained_image)); - label_ = new views::Label(); - AddChildView(label_); - label_->SetColor(color); -} - -IconLabelBubbleView::~IconLabelBubbleView() { -} - -void IconLabelBubbleView::SetFont(const gfx::Font& font) { - label_->SetFont(font); -} - -void IconLabelBubbleView::SetLabel(const std::wstring& label) { - label_->SetText(label); -} - -void IconLabelBubbleView::SetImage(const SkBitmap& bitmap) { - image_->SetImage(bitmap); -} - -void IconLabelBubbleView::Paint(gfx::Canvas* canvas) { - background_painter_.Paint(width(), height(), canvas); -} - -gfx::Size IconLabelBubbleView::GetPreferredSize() { - gfx::Size size(GetNonLabelSize()); - size.Enlarge(label_->GetPreferredSize().width(), 0); - return size; -} - -void IconLabelBubbleView::Layout() { - image_->SetBounds(kBubbleOuterPadding, 0, image_->GetPreferredSize().width(), - height()); - const int label_height = label_->GetPreferredSize().height(); - label_->SetBounds(image_->x() + image_->width() + - item_padding_ , (height() - label_height) / 2, - width() - GetNonLabelWidth(), label_height); -} - -void IconLabelBubbleView::SetElideInMiddle(bool elide_in_middle) { - label_->SetElideInMiddle(elide_in_middle); -} - -gfx::Size IconLabelBubbleView::GetNonLabelSize() { - return gfx::Size(GetNonLabelWidth(), background_painter_.height()); -} - -int IconLabelBubbleView::GetNonLabelWidth() { - return kBubbleOuterPadding + image_->GetPreferredSize().width() + - item_padding_ + kBubbleOuterPadding; -} diff --git a/chrome/browser/views/location_bar/icon_label_bubble_view.h b/chrome/browser/views/location_bar/icon_label_bubble_view.h index d2e4b78..9e3dde6 100644 --- a/chrome/browser/views/location_bar/icon_label_bubble_view.h +++ b/chrome/browser/views/location_bar/icon_label_bubble_view.h @@ -6,59 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_ICON_LABEL_BUBBLE_VIEW_H_ #pragma once -#include <string> - -#include "gfx/size.h" -#include "views/painter.h" -#include "views/view.h" - -namespace gfx { -class Canvas; -class Font; -} -namespace views { -class ImageView; -class Label; -} - -class SkBitmap; - -// View used to draw a bubble to the left of the address, containing an icon and -// a label. We use this as a base for the classes that handle the EV bubble and -// tab-to-search UI. -class IconLabelBubbleView : public views::View { - public: - IconLabelBubbleView(const int background_images[], - int contained_image, - const SkColor& color); - virtual ~IconLabelBubbleView(); - - void SetFont(const gfx::Font& font); - void SetLabel(const std::wstring& label); - void SetImage(const SkBitmap& bitmap); - void SetItemPadding(int padding) { item_padding_ = padding; } - - virtual void Paint(gfx::Canvas* canvas); - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - protected: - void SetElideInMiddle(bool elide_in_middle); - gfx::Size GetNonLabelSize(); - - private: - int GetNonLabelWidth(); - - // For painting the background. - views::HorizontalPainter background_painter_; - - // The contents of the bubble. - views::ImageView* image_; - views::Label* label_; - - int item_padding_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(IconLabelBubbleView); -}; +#include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_ICON_LABEL_BUBBLE_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/keyword_hint_view.cc b/chrome/browser/views/location_bar/keyword_hint_view.cc deleted file mode 100644 index eec0dd1..0000000 --- a/chrome/browser/views/location_bar/keyword_hint_view.cc +++ /dev/null @@ -1,127 +0,0 @@ -// 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/location_bar/keyword_hint_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/logging.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "gfx/canvas.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/label.h" -#include "third_party/skia/include/core/SkBitmap.h" - -// Amount of space to offset the tab image from the top of the view by. -static const int kTabImageYOffset = 4; - -// The tab key image. -static const SkBitmap* kTabButtonBitmap = NULL; - -KeywordHintView::KeywordHintView(Profile* profile) : profile_(profile) { - leading_label_ = new views::Label(); - trailing_label_ = new views::Label(); - AddChildView(leading_label_); - AddChildView(trailing_label_); - - if (!kTabButtonBitmap) { - kTabButtonBitmap = ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_LOCATION_BAR_KEYWORD_HINT_TAB); - } -} - -KeywordHintView::~KeywordHintView() { -} - -void KeywordHintView::SetFont(const gfx::Font& font) { - leading_label_->SetFont(font); - trailing_label_->SetFont(font); -} - -void KeywordHintView::SetColor(const SkColor& color) { - leading_label_->SetColor(color); - trailing_label_->SetColor(color); -} - -void KeywordHintView::SetKeyword(const std::wstring& keyword) { - keyword_ = keyword; - if (keyword_.empty()) - return; - DCHECK(profile_); - if (!profile_->GetTemplateURLModel()) - return; - - std::vector<size_t> content_param_offsets; - bool is_extension_keyword; - std::wstring short_name = profile_->GetTemplateURLModel()-> - GetKeywordShortName(keyword, &is_extension_keyword); - int message_id = is_extension_keyword ? - IDS_OMNIBOX_EXTENSION_KEYWORD_HINT : IDS_OMNIBOX_KEYWORD_HINT; - const std::wstring keyword_hint(l10n_util::GetStringF( - message_id, std::wstring(), short_name, &content_param_offsets)); - if (content_param_offsets.size() == 2) { - leading_label_->SetText( - keyword_hint.substr(0, content_param_offsets.front())); - trailing_label_->SetText( - keyword_hint.substr(content_param_offsets.front())); - } else { - // See comments on an identical NOTREACHED() in search_provider.cc. - NOTREACHED(); - } -} - -void KeywordHintView::Paint(gfx::Canvas* canvas) { - int image_x = leading_label_->IsVisible() ? leading_label_->width() : 0; - - // Since we paint the button image directly on the canvas (instead of using a - // child view), we must mirror the button's position manually if the locale - // is right-to-left. - gfx::Rect tab_button_bounds(image_x, - kTabImageYOffset, - kTabButtonBitmap->width(), - kTabButtonBitmap->height()); - tab_button_bounds.set_x(MirroredLeftPointForRect(tab_button_bounds)); - canvas->DrawBitmapInt(*kTabButtonBitmap, - tab_button_bounds.x(), - tab_button_bounds.y()); -} - -gfx::Size KeywordHintView::GetPreferredSize() { - // TODO(sky): currently height doesn't matter, once baseline support is - // added this should check baselines. - gfx::Size prefsize = leading_label_->GetPreferredSize(); - int width = prefsize.width(); - width += kTabButtonBitmap->width(); - prefsize = trailing_label_->GetPreferredSize(); - width += prefsize.width(); - return gfx::Size(width, prefsize.height()); -} - -gfx::Size KeywordHintView::GetMinimumSize() { - // TODO(sky): currently height doesn't matter, once baseline support is - // added this should check baselines. - return gfx::Size(kTabButtonBitmap->width(), 0); -} - -void KeywordHintView::Layout() { - // TODO(sky): baseline layout. - bool show_labels = (width() != kTabButtonBitmap->width()); - - leading_label_->SetVisible(show_labels); - trailing_label_->SetVisible(show_labels); - int x = 0; - gfx::Size pref; - - if (show_labels) { - pref = leading_label_->GetPreferredSize(); - leading_label_->SetBounds(x, 0, pref.width(), height()); - - x += pref.width() + kTabButtonBitmap->width(); - pref = trailing_label_->GetPreferredSize(); - trailing_label_->SetBounds(x, 0, pref.width(), height()); - } -} diff --git a/chrome/browser/views/location_bar/keyword_hint_view.h b/chrome/browser/views/location_bar/keyword_hint_view.h index af11a84..defea0e 100644 --- a/chrome/browser/views/location_bar/keyword_hint_view.h +++ b/chrome/browser/views/location_bar/keyword_hint_view.h @@ -6,57 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_KEYWORD_HINT_VIEW_H_ #pragma once -#include <string> - -#include "gfx/size.h" -#include "views/view.h" - -namespace gfx { -class Font; -} -class Profile; -namespace views { -class Label; -} - -// KeywordHintView is used by the location bar view to display a hint to the -// user when the selected url has a corresponding keyword. -// -// Internally KeywordHintView uses two labels to render the text, and draws -// the tab image itself. -// -// NOTE: This should really be called LocationBarKeywordHintView, but I -// couldn't bring myself to use such a long name. -class KeywordHintView : public views::View { - public: - explicit KeywordHintView(Profile* profile); - virtual ~KeywordHintView(); - - void SetFont(const gfx::Font& font); - - void SetColor(const SkColor& color); - - void SetKeyword(const std::wstring& keyword); - std::wstring keyword() const { return keyword_; } - - virtual void Paint(gfx::Canvas* canvas); - virtual gfx::Size GetPreferredSize(); - // The minimum size is just big enough to show the tab. - virtual gfx::Size GetMinimumSize(); - virtual void Layout(); - - void set_profile(Profile* profile) { profile_ = profile; } - - private: - views::Label* leading_label_; - views::Label* trailing_label_; - - // The keyword. - std::wstring keyword_; - - Profile* profile_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(KeywordHintView); -}; +#include "chrome/browser/ui/views/location_bar/keyword_hint_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_KEYWORD_HINT_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/location_bar_view.cc b/chrome/browser/views/location_bar/location_bar_view.cc deleted file mode 100644 index 09c18a9..0000000 --- a/chrome/browser/views/location_bar/location_bar_view.cc +++ /dev/null @@ -1,1195 +0,0 @@ -// 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/location_bar/location_bar_view.h" - -#if defined(OS_LINUX) -#include <gtk/gtk.h> -#endif - -#include "app/drag_drop_types.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/theme_provider.h" -#include "base/stl_util-inl.h" -#include "base/utf_string_conversions.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/alternate_nav_url_fetcher.h" -#include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/defaults.h" -#include "chrome/browser/extensions/extension_browser_event_router.h" -#include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/instant/instant_controller.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "chrome/browser/views/location_bar/content_setting_image_view.h" -#include "chrome/browser/views/location_bar/ev_bubble_view.h" -#include "chrome/browser/views/location_bar/keyword_hint_view.h" -#include "chrome/browser/views/location_bar/location_icon_view.h" -#include "chrome/browser/views/location_bar/page_action_image_view.h" -#include "chrome/browser/views/location_bar/page_action_with_badge_view.h" -#include "chrome/browser/views/location_bar/selected_keyword_view.h" -#include "chrome/browser/views/location_bar/star_view.h" -#include "gfx/canvas_skia.h" -#include "gfx/color_utils.h" -#include "gfx/skia_util.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/label.h" -#include "views/drag_utils.h" - -#if defined(OS_WIN) -#include "chrome/browser/views/first_run_bubble.h" -#endif - -using views::View; - -// static -const int LocationBarView::kNormalHorizontalEdgeThickness = 1; -const int LocationBarView::kVerticalEdgeThickness = 2; -const int LocationBarView::kItemPadding = 3; -const int LocationBarView::kExtensionItemPadding = 5; -const int LocationBarView::kEdgeItemPadding = kItemPadding; -const int LocationBarView::kBubblePadding = 1; -const char LocationBarView::kViewClassName[] = - "browser/views/location_bar/LocationBarView"; - -static const int kEVBubbleBackgroundImages[] = { - IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_L, - IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_C, - IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_R, -}; - -static const int kSelectedKeywordBackgroundImages[] = { - IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_L, - IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_C, - IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_R, -}; - -static const int kNormalModeBackgroundImages[] = { - IDR_LOCATIONBG_L, - IDR_LOCATIONBG_C, - IDR_LOCATIONBG_R, -}; - -// LocationBarView ----------------------------------------------------------- - -LocationBarView::LocationBarView(Profile* profile, - CommandUpdater* command_updater, - ToolbarModel* model, - Delegate* delegate, - Mode mode) - : profile_(profile), - command_updater_(command_updater), - model_(model), - delegate_(delegate), - disposition_(CURRENT_TAB), - transition_(PageTransition::LINK), - location_icon_view_(NULL), - ev_bubble_view_(NULL), - location_entry_view_(NULL), - selected_keyword_view_(NULL), - suggested_text_view_(NULL), - keyword_hint_view_(NULL), - star_view_(NULL), - mode_(mode), - show_focus_rect_(false), - bubble_type_(FirstRun::MINIMAL_BUBBLE), - template_url_model_(NULL), - update_instant_(true) { - DCHECK(profile_); - SetID(VIEW_ID_LOCATION_BAR); - SetFocusable(true); - - if (mode_ == NORMAL) - painter_.reset(new views::HorizontalPainter(kNormalModeBackgroundImages)); -} - -LocationBarView::~LocationBarView() { - if (template_url_model_) - template_url_model_->RemoveObserver(this); -} - -void LocationBarView::Init() { - if (mode_ == POPUP) { - font_ = ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont); - } else { - // Use a larger version of the system font. - font_ = font_.DeriveFont(3); - } - - // If this makes the font too big, try to make it smaller so it will fit. - const int height = - std::max(GetPreferredSize().height() - (kVerticalEdgeThickness * 2), 0); - while ((font_.GetHeight() > height) && (font_.GetFontSize() > 1)) - font_ = font_.DeriveFont(-1); - - location_icon_view_ = new LocationIconView(this); - AddChildView(location_icon_view_); - location_icon_view_->SetVisible(true); - location_icon_view_->SetDragController(this); - - ev_bubble_view_ = - new EVBubbleView(kEVBubbleBackgroundImages, IDR_OMNIBOX_HTTPS_VALID, - GetColor(ToolbarModel::EV_SECURE, SECURITY_TEXT), this); - AddChildView(ev_bubble_view_); - ev_bubble_view_->SetVisible(false); - ev_bubble_view_->SetDragController(this); - - // URL edit field. - // View container for URL edit field. -#if defined(OS_WIN) - location_entry_.reset(new AutocompleteEditViewWin(font_, this, model_, this, - GetWidget()->GetNativeView(), profile_, command_updater_, - mode_ == POPUP, this)); -#else - location_entry_.reset(new AutocompleteEditViewGtk(this, model_, profile_, - command_updater_, mode_ == POPUP, this)); - location_entry_->Init(); - // Make all the children of the widget visible. NOTE: this won't display - // anything, it just toggles the visible flag. - gtk_widget_show_all(location_entry_->GetNativeView()); - // Hide the widget. NativeViewHostGtk will make it visible again as - // necessary. - gtk_widget_hide(location_entry_->GetNativeView()); - - // Associate an accessible name with the location entry. - accessible_widget_helper_.reset(new AccessibleWidgetHelper( - location_entry_->text_view(), profile_)); - accessible_widget_helper_->SetWidgetName( - location_entry_->text_view(), - l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION)); -#endif - location_entry_view_ = new views::NativeViewHost; - location_entry_view_->SetID(VIEW_ID_AUTOCOMPLETE); - AddChildView(location_entry_view_); - location_entry_view_->set_focus_view(this); - location_entry_view_->Attach(location_entry_->GetNativeView()); - location_entry_view_->SetAccessibleName( - l10n_util::GetString(IDS_ACCNAME_LOCATION)); - - selected_keyword_view_ = new SelectedKeywordView( - kSelectedKeywordBackgroundImages, IDR_KEYWORD_SEARCH_MAGNIFIER, - GetColor(ToolbarModel::NONE, TEXT), profile_), - AddChildView(selected_keyword_view_); - selected_keyword_view_->SetFont(font_); - selected_keyword_view_->SetVisible(false); - - SkColor dimmed_text = GetColor(ToolbarModel::NONE, DEEMPHASIZED_TEXT); - - keyword_hint_view_ = new KeywordHintView(profile_); - AddChildView(keyword_hint_view_); - keyword_hint_view_->SetVisible(false); - keyword_hint_view_->SetFont(font_); - keyword_hint_view_->SetColor(dimmed_text); - - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - ContentSettingImageView* content_blocked_view = new ContentSettingImageView( - static_cast<ContentSettingsType>(i), this, profile_); - content_setting_views_.push_back(content_blocked_view); - AddChildView(content_blocked_view); - content_blocked_view->SetVisible(false); - } - - // The star is not visible in popups and in the app launcher. - if (browser_defaults::bookmarks_enabled && (mode_ == NORMAL)) { - star_view_ = new StarView(command_updater_); - AddChildView(star_view_); - star_view_->SetVisible(true); - } - - // Notify us when any ancestor is resized. In this case we want to tell the - // AutocompleteEditView to close its popup. - SetNotifyWhenVisibleBoundsInRootChanges(true); - - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_LOCATION)); - - // Initialize the location entry. We do this to avoid a black flash which is - // visible when the location entry has just been initialized. - Update(NULL); - - OnChanged(); -} - -bool LocationBarView::IsInitialized() const { - return location_entry_view_ != NULL; -} - -// static -SkColor LocationBarView::GetColor(ToolbarModel::SecurityLevel security_level, - ColorKind kind) { - switch (kind) { -#if defined(OS_WIN) - case BACKGROUND: return color_utils::GetSysSkColor(COLOR_WINDOW); - case TEXT: return color_utils::GetSysSkColor(COLOR_WINDOWTEXT); - case SELECTED_TEXT: return color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); -#else - // TODO(beng): source from theme provider. - case BACKGROUND: return SK_ColorWHITE; - case TEXT: return SK_ColorBLACK; - case SELECTED_TEXT: return SK_ColorWHITE; -#endif - - case DEEMPHASIZED_TEXT: - return color_utils::AlphaBlend(GetColor(security_level, TEXT), - GetColor(security_level, BACKGROUND), 128); - - case SECURITY_TEXT: { - SkColor color; - switch (security_level) { - case ToolbarModel::EV_SECURE: - case ToolbarModel::SECURE: - color = SkColorSetRGB(7, 149, 0); - break; - - case ToolbarModel::SECURITY_WARNING: - return GetColor(security_level, DEEMPHASIZED_TEXT); - break; - - case ToolbarModel::SECURITY_ERROR: - color = SkColorSetRGB(162, 0, 0); - break; - - default: - NOTREACHED(); - return GetColor(security_level, TEXT); - } - return color_utils::GetReadableColor(color, GetColor(security_level, - BACKGROUND)); - } - - default: - NOTREACHED(); - return GetColor(security_level, TEXT); - } -} - -void LocationBarView::Update(const TabContents* tab_for_state_restoring) { - bool star_enabled = star_view_ && !model_->input_in_progress(); - command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE, star_enabled); - if (star_view_) - star_view_->SetVisible(star_enabled); - RefreshContentSettingViews(); - RefreshPageActionViews(); - // Don't Update in app launcher mode so that the location entry does not show - // a URL or security background. - if (mode_ != APP_LAUNCHER) - location_entry_->Update(tab_for_state_restoring); - OnChanged(); -} - -void LocationBarView::UpdateContentSettingsIcons() { - RefreshContentSettingViews(); - - Layout(); - SchedulePaint(); -} - -void LocationBarView::UpdatePageActions() { - size_t count_before = page_action_views_.size(); - RefreshPageActionViews(); - if (page_action_views_.size() != count_before) { - NotificationService::current()->Notify( - NotificationType::EXTENSION_PAGE_ACTION_COUNT_CHANGED, - Source<LocationBar>(this), - NotificationService::NoDetails()); - } - - Layout(); - SchedulePaint(); -} - -void LocationBarView::InvalidatePageActions() { - size_t count_before = page_action_views_.size(); - DeletePageActionViews(); - if (page_action_views_.size() != count_before) { - NotificationService::current()->Notify( - NotificationType::EXTENSION_PAGE_ACTION_COUNT_CHANGED, - Source<LocationBar>(this), - NotificationService::NoDetails()); - } -} - -void LocationBarView::Focus() { - // Focus the location entry native view. - location_entry_->SetFocus(); -} - -void LocationBarView::SetProfile(Profile* profile) { - DCHECK(profile); - if (profile_ != profile) { - profile_ = profile; - location_entry_->model()->SetProfile(profile); - selected_keyword_view_->set_profile(profile); - keyword_hint_view_->set_profile(profile); - for (ContentSettingViews::const_iterator i(content_setting_views_.begin()); - i != content_setting_views_.end(); ++i) - (*i)->set_profile(profile); - } -} - -TabContents* LocationBarView::GetTabContents() const { - return delegate_->GetTabContents(); -} - -void LocationBarView::SetPreviewEnabledPageAction(ExtensionAction* page_action, - bool preview_enabled) { - if (mode_ != NORMAL) - return; - - DCHECK(page_action); - TabContents* contents = delegate_->GetTabContents(); - - RefreshPageActionViews(); - PageActionWithBadgeView* page_action_view = - static_cast<PageActionWithBadgeView*>(GetPageActionView(page_action)); - DCHECK(page_action_view); - if (!page_action_view) - return; - - page_action_view->image_view()->set_preview_enabled(preview_enabled); - page_action_view->UpdateVisibility(contents, - GURL(WideToUTF8(model_->GetText()))); - Layout(); - SchedulePaint(); -} - -views::View* LocationBarView::GetPageActionView( - ExtensionAction *page_action) { - DCHECK(page_action); - for (PageActionViews::const_iterator i(page_action_views_.begin()); - i != page_action_views_.end(); ++i) { - if ((*i)->image_view()->page_action() == page_action) - return *i; - } - return NULL; -} - -void LocationBarView::SetStarToggled(bool on) { - if (star_view_) - star_view_->SetToggled(on); -} - -void LocationBarView::ShowStarBubble(const GURL& url, bool newly_bookmarked) { - gfx::Rect screen_bounds(star_view_->GetImageBounds()); - // Compensate for some built-in padding in the Star image. - screen_bounds.Inset(1, 1, 1, 2); - gfx::Point origin(screen_bounds.origin()); - views::View::ConvertPointToScreen(star_view_, &origin); - screen_bounds.set_origin(origin); - browser::ShowBookmarkBubbleView(GetWindow(), screen_bounds, star_view_, - profile_, url, newly_bookmarked); -} - -gfx::Size LocationBarView::GetPreferredSize() { - return gfx::Size(0, GetThemeProvider()->GetBitmapNamed(mode_ == POPUP ? - IDR_LOCATIONBG_POPUPMODE_CENTER : IDR_LOCATIONBG_C)->height()); -} - -void LocationBarView::Layout() { - if (!location_entry_.get()) - return; - - // TODO(sky): baseline layout. - int location_y = kVerticalEdgeThickness; - // In some cases (e.g. fullscreen mode) we may have 0 height. We still want - // to position our child views in this case, because other things may be - // positioned relative to them (e.g. the "bookmark added" bubble if the user - // hits ctrl-d). - int location_height = std::max(height() - (kVerticalEdgeThickness * 2), 0); - - // The edge stroke is 1 px thick. In popup mode, the edges are drawn by the - // omnibox' parent, so there isn't any edge to account for at all. - const int kEdgeThickness = (mode_ == NORMAL) ? - kNormalHorizontalEdgeThickness : 0; - // The edit has 1 px of horizontal whitespace inside it before the text. - const int kEditInternalSpace = 1; - // The space between an item and the edit is the normal item space, minus the - // edit's built-in space (so the apparent space will be the same). - const int kItemEditPadding = - LocationBarView::kItemPadding - kEditInternalSpace; - const int kEdgeEditPadding = - LocationBarView::kEdgeItemPadding - kEditInternalSpace; - - // Start by reserving the padding at the right edge. - int entry_width = width() - kEdgeThickness - kEdgeItemPadding; - - // |location_icon_view_| is visible except when |ev_bubble_view_| or - // |selected_keyword_view_| are visible. - int location_icon_width = 0; - int ev_bubble_width = 0; - location_icon_view_->SetVisible(false); - ev_bubble_view_->SetVisible(false); - const std::wstring keyword(location_entry_->model()->keyword()); - const bool is_keyword_hint(location_entry_->model()->is_keyword_hint()); - const bool show_selected_keyword = !keyword.empty() && !is_keyword_hint; - if (show_selected_keyword) { - // Assume the keyword might be hidden. - entry_width -= (kEdgeThickness + kEdgeEditPadding); - } else if (model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) { - ev_bubble_view_->SetVisible(true); - ev_bubble_view_->SetLabel(model_->GetEVCertName()); - ev_bubble_width = ev_bubble_view_->GetPreferredSize().width(); - // We'll adjust this width and take it out of |entry_width| below. - } else { - location_icon_view_->SetVisible(true); - location_icon_width = location_icon_view_->GetPreferredSize().width(); - entry_width -= (kEdgeThickness + kEdgeItemPadding + location_icon_width + - kItemEditPadding); - } - - if (star_view_ && star_view_->IsVisible()) - entry_width -= star_view_->GetPreferredSize().width() + kItemPadding; - for (PageActionViews::const_iterator i(page_action_views_.begin()); - i != page_action_views_.end(); ++i) { - if ((*i)->IsVisible()) - entry_width -= ((*i)->GetPreferredSize().width() + kItemPadding); - } - for (ContentSettingViews::const_iterator i(content_setting_views_.begin()); - i != content_setting_views_.end(); ++i) { - if ((*i)->IsVisible()) - entry_width -= ((*i)->GetPreferredSize().width() + kItemPadding); - } - // The gap between the edit and whatever is to its right is shortened. - entry_width += kEditInternalSpace; - - // Size the EV bubble. We do this after taking the star/page actions/content - // settings out of |entry_width| so we won't take too much space. - if (ev_bubble_width) { - // Try to elide the bubble to be no larger than half the total available - // space, but never elide it any smaller than 150 px. - static const int kMinElidedBubbleWidth = 150; - static const double kMaxBubbleFraction = 0.5; - const int total_padding = - kEdgeThickness + kBubblePadding + kItemEditPadding; - ev_bubble_width = std::min(ev_bubble_width, std::max(kMinElidedBubbleWidth, - static_cast<int>((entry_width - total_padding) * kMaxBubbleFraction))); - entry_width -= (total_padding + ev_bubble_width); - } - -#if defined(OS_WIN) - RECT formatting_rect; - location_entry_->GetRect(&formatting_rect); - RECT edit_bounds; - location_entry_->GetClientRect(&edit_bounds); - int max_edit_width = entry_width - formatting_rect.left - - (edit_bounds.right - formatting_rect.right); -#else - int max_edit_width = entry_width; -#endif - - if (max_edit_width < 0) - return; - const int available_width = AvailableWidth(max_edit_width); - - const bool show_keyword_hint = !keyword.empty() && is_keyword_hint; - selected_keyword_view_->SetVisible(show_selected_keyword); - keyword_hint_view_->SetVisible(show_keyword_hint); - if (show_selected_keyword) { - if (selected_keyword_view_->keyword() != keyword) { - selected_keyword_view_->SetKeyword(keyword); - const TemplateURL* template_url = - profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword); - if (template_url && template_url->IsExtensionKeyword()) { - const SkBitmap& bitmap = profile_->GetExtensionsService()-> - GetOmniboxIcon(template_url->GetExtensionId()); - selected_keyword_view_->SetImage(bitmap); - selected_keyword_view_->SetItemPadding(kExtensionItemPadding); - } else { - selected_keyword_view_->SetImage(*ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_OMNIBOX_SEARCH)); - selected_keyword_view_->SetItemPadding(kItemPadding); - } - } - } else if (show_keyword_hint) { - if (keyword_hint_view_->keyword() != keyword) - keyword_hint_view_->SetKeyword(keyword); - } - - // Lay out items to the right of the edit field. - int offset = width() - kEdgeThickness - kEdgeItemPadding; - if (star_view_ && star_view_->IsVisible()) { - int star_width = star_view_->GetPreferredSize().width(); - offset -= star_width; - star_view_->SetBounds(offset, location_y, star_width, location_height); - offset -= kItemPadding; - } - - for (PageActionViews::const_iterator i(page_action_views_.begin()); - i != page_action_views_.end(); ++i) { - if ((*i)->IsVisible()) { - int page_action_width = (*i)->GetPreferredSize().width(); - offset -= page_action_width; - (*i)->SetBounds(offset, location_y, page_action_width, location_height); - offset -= kItemPadding; - } - } - // We use a reverse_iterator here because we're laying out the views from - // right to left but in the vector they're ordered left to right. - for (ContentSettingViews::const_reverse_iterator - i(content_setting_views_.rbegin()); i != content_setting_views_.rend(); - ++i) { - if ((*i)->IsVisible()) { - int content_blocked_width = (*i)->GetPreferredSize().width(); - offset -= content_blocked_width; - (*i)->SetBounds(offset, location_y, content_blocked_width, - location_height); - offset -= kItemPadding; - } - } - - // Now lay out items to the left of the edit field. - if (location_icon_view_->IsVisible()) { - location_icon_view_->SetBounds(kEdgeThickness + kEdgeItemPadding, - location_y, location_icon_width, location_height); - offset = location_icon_view_->bounds().right() + kItemEditPadding; - } else if (ev_bubble_view_->IsVisible()) { - ev_bubble_view_->SetBounds(kEdgeThickness + kBubblePadding, - location_y + kBubblePadding, ev_bubble_width, - ev_bubble_view_->GetPreferredSize().height()); - offset = ev_bubble_view_->bounds().right() + kItemEditPadding; - } else { - offset = kEdgeThickness + - (show_selected_keyword ? kBubblePadding : kEdgeEditPadding); - } - - // Now lay out the edit field and views that autocollapse to give it more - // room. - gfx::Rect location_bounds(offset, location_y, entry_width, location_height); - if (show_selected_keyword) { - selected_keyword_view_->SetBounds(0, location_y + kBubblePadding, 0, - selected_keyword_view_->GetPreferredSize().height()); - LayoutView(selected_keyword_view_, kItemEditPadding, available_width, - true, &location_bounds); - location_bounds.set_x(selected_keyword_view_->IsVisible() ? - (offset + selected_keyword_view_->width() + kItemEditPadding) : - (kEdgeThickness + kEdgeEditPadding)); - } else if (show_keyword_hint) { - keyword_hint_view_->SetBounds(0, location_y, 0, location_height); - // Tricky: |entry_width| has already been enlarged by |kEditInternalSpace|. - // But if we add a trailing view, it needs to have that enlargement be to - // its left. So we undo the enlargement, then include it in the padding for - // the added view. - location_bounds.Inset(0, 0, kEditInternalSpace, 0); - LayoutView(keyword_hint_view_, kItemEditPadding, available_width, false, - &location_bounds); - if (!keyword_hint_view_->IsVisible()) { - // Put back the enlargement that we undid above. - location_bounds.Inset(0, 0, -kEditInternalSpace, 0); - } - } - - // Layout out the suggested text view right aligned to the location - // entry. Only show the suggested text if we can fit the text from one - // character before the end of the selection to the end of the text and the - // suggested text. If we can't it means either the suggested text is too big, - // or the user has scrolled. - - // TODO(sky): We could potentially combine this with the previous step to - // force using minimum size if necessary, but currently the chance of showing - // keyword hints and suggested text is minimal and we're not confident this - // is the right approach for suggested text. - if (suggested_text_view_) { - // TODO(sky): need to layout when the user changes caret position. - int suggested_text_width = suggested_text_view_->GetPreferredSize().width(); - int vis_text_width = location_entry_->WidthOfTextAfterCursor(); - if (vis_text_width + suggested_text_width > entry_width) { - // Hide the suggested text if the user has scrolled or we can't fit all - // the suggested text. - suggested_text_view_->SetBounds(0, 0, 0, 0); - } else { - int location_needed_width = location_entry_->TextWidth(); - location_bounds.set_width(std::min(location_needed_width, - entry_width - suggested_text_width)); - suggested_text_view_->SetBounds(location_bounds.right(), - location_bounds.y(), - suggested_text_width, - location_bounds.height()); - } - } - - location_entry_view_->SetBounds(location_bounds); -} - -void LocationBarView::Paint(gfx::Canvas* canvas) { - View::Paint(canvas); - - if (painter_.get()) { - painter_->Paint(width(), height(), canvas); - } else if (mode_ == POPUP) { - canvas->TileImageInt(*GetThemeProvider()->GetBitmapNamed( - IDR_LOCATIONBG_POPUPMODE_CENTER), 0, 0, 0, 0, width(), height()); - } - // When used in the app launcher, don't draw a border, the LocationBarView has - // its own views::Border. - - // Draw the background color so that the graphical elements at the edges - // appear over the correct color. (The edit draws its own background, so this - // isn't important for that.) - // TODO(pkasting): We need images that are transparent in the middle, so we - // can draw the border images over the background color instead of the - // reverse; this antialiases better (see comments in - // AutocompletePopupContentsView::Paint()). - gfx::Rect bounds(GetLocalBounds(false)); - bounds.Inset(0, kVerticalEdgeThickness); - SkColor color(GetColor(ToolbarModel::NONE, BACKGROUND)); - if (mode_ == NORMAL) { - SkPaint paint; - paint.setColor(color); - paint.setStyle(SkPaint::kFill_Style); - paint.setAntiAlias(true); - // The round corners of the omnibox match the round corners of the dropdown - // below, and all our other bubbles. - const SkScalar radius(SkIntToScalar(BubbleBorder::GetCornerRadius())); - bounds.Inset(kNormalHorizontalEdgeThickness, 0); - canvas->AsCanvasSkia()->drawRoundRect(gfx::RectToSkRect(bounds), radius, - radius, paint); - } else { - canvas->FillRectInt(color, bounds.x(), bounds.y(), bounds.width(), - bounds.height()); - } - - if (show_focus_rect_ && HasFocus()) { - gfx::Rect r = location_entry_view_->bounds(); -#if defined(OS_WIN) - canvas->DrawFocusRect(r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2); -#else - canvas->DrawFocusRect(r.x() - 1, r.y(), r.width() + 2, r.height()); -#endif - } -} - -void LocationBarView::VisibleBoundsInRootChanged() { - location_entry_->ClosePopup(); -} - -void LocationBarView::SetShowFocusRect(bool show) { - show_focus_rect_ = show; - SchedulePaint(); -} - -void LocationBarView::SelectAll() { - location_entry_->SelectAll(true); -} - -#if defined(OS_WIN) -bool LocationBarView::OnMousePressed(const views::MouseEvent& event) { - UINT msg; - if (event.IsLeftMouseButton()) { - msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ? - WM_LBUTTONDBLCLK : WM_LBUTTONDOWN; - } else if (event.IsMiddleMouseButton()) { - msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ? - WM_MBUTTONDBLCLK : WM_MBUTTONDOWN; - } else if (event.IsRightMouseButton()) { - msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ? - WM_RBUTTONDBLCLK : WM_RBUTTONDOWN; - } else { - NOTREACHED(); - return false; - } - OnMouseEvent(event, msg); - return true; -} - -bool LocationBarView::OnMouseDragged(const views::MouseEvent& event) { - OnMouseEvent(event, WM_MOUSEMOVE); - return true; -} - -void LocationBarView::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - UINT msg; - if (canceled) { - msg = WM_CAPTURECHANGED; - } else if (event.IsLeftMouseButton()) { - msg = WM_LBUTTONUP; - } else if (event.IsMiddleMouseButton()) { - msg = WM_MBUTTONUP; - } else if (event.IsRightMouseButton()) { - msg = WM_RBUTTONUP; - } else { - NOTREACHED(); - return; - } - OnMouseEvent(event, msg); -} -#endif - -void LocationBarView::OnAutocompleteWillClosePopup() { - if (!update_instant_) - return; - - InstantController* instant = delegate_->GetInstant(); - if (instant && !instant->commit_on_mouse_up()) - instant->DestroyPreviewContents(); -} - -void LocationBarView::OnAutocompleteLosingFocus( - gfx::NativeView view_gaining_focus) { - SetSuggestedText(string16()); - - InstantController* instant = delegate_->GetInstant(); - if (instant) - instant->OnAutocompleteLostFocus(view_gaining_focus); -} - -void LocationBarView::OnAutocompleteWillAccept() { - update_instant_ = false; -} - -bool LocationBarView::OnCommitSuggestedText(const std::wstring& typed_text) { - InstantController* instant = delegate_->GetInstant(); - if (!instant || !suggested_text_view_ || - suggested_text_view_->size().IsEmpty() || - suggested_text_view_->GetText().empty()) { - return false; - } - // TODO(sky): I may need to route this through InstantController so that we - // don't fetch suggestions for the new combined text. - location_entry_->SetUserText(typed_text + suggested_text_view_->GetText()); - return true; -} - -void LocationBarView::OnSetSuggestedSearchText(const string16& suggested_text) { - SetSuggestedText(suggested_text); -} - -void LocationBarView::OnPopupBoundsChanged(const gfx::Rect& bounds) { - InstantController* instant = delegate_->GetInstant(); - if (instant) - instant->SetOmniboxBounds(bounds); -} - -void LocationBarView::OnAutocompleteAccept( - const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition, - const GURL& alternate_nav_url) { - // WARNING: don't add an early return here. The calls after the if must - // happen. - if (url.is_valid()) { - location_input_ = UTF8ToWide(url.spec()); - disposition_ = disposition; - transition_ = transition; - - if (command_updater_) { - if (!alternate_nav_url.is_valid()) { - command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL); - } else { - AlternateNavURLFetcher* fetcher = - new AlternateNavURLFetcher(alternate_nav_url); - // The AlternateNavURLFetcher will listen for the pending navigation - // notification that will be issued as a result of the "open URL." It - // will automatically install itself into that navigation controller. - command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL); - if (fetcher->state() == AlternateNavURLFetcher::NOT_STARTED) { - // I'm not sure this should be reachable, but I'm not also sure enough - // that it shouldn't to stick in a NOTREACHED(). In any case, this is - // harmless. - delete fetcher; - } else { - // The navigation controller will delete the fetcher. - } - } - } - } - - if (delegate_->GetInstant()) - delegate_->GetInstant()->DestroyPreviewContents(); - - update_instant_ = true; -} - -void LocationBarView::OnChanged() { - location_icon_view_->SetImage( - ResourceBundle::GetSharedInstance().GetBitmapNamed( - location_entry_->GetIcon())); - Layout(); - SchedulePaint(); - - InstantController* instant = delegate_->GetInstant(); - string16 suggested_text; - if (update_instant_ && instant && GetTabContents()) { - if (location_entry_->model()->user_input_in_progress() && - location_entry_->model()->popup_model()->IsOpen()) { - instant->Update(GetTabContents(), - location_entry_->model()->CurrentMatch(), - WideToUTF16(location_entry_->GetText()), - &suggested_text); - } else { - instant->DestroyPreviewContents(); - } - } - - SetSuggestedText(suggested_text); -} - -void LocationBarView::OnInputInProgress(bool in_progress) { - delegate_->OnInputInProgress(in_progress); -} - -void LocationBarView::OnKillFocus() { -} - -void LocationBarView::OnSetFocus() { - views::FocusManager* focus_manager = GetFocusManager(); - if (!focus_manager) { - NOTREACHED(); - return; - } - focus_manager->SetFocusedView(this); -} - -SkBitmap LocationBarView::GetFavIcon() const { - DCHECK(delegate_); - DCHECK(delegate_->GetTabContents()); - return delegate_->GetTabContents()->GetFavIcon(); -} - -std::wstring LocationBarView::GetTitle() const { - DCHECK(delegate_); - DCHECK(delegate_->GetTabContents()); - return UTF16ToWideHack(delegate_->GetTabContents()->GetTitle()); -} - -int LocationBarView::AvailableWidth(int location_bar_width) { - return location_bar_width - location_entry_->TextWidth(); -} - -void LocationBarView::LayoutView(views::View* view, - int padding, - int available_width, - bool leading, - gfx::Rect* bounds) { - DCHECK(view && bounds); - gfx::Size view_size = view->GetPreferredSize(); - if ((view_size.width() + padding) > available_width) - view_size = view->GetMinimumSize(); - int desired_width = view_size.width() + padding; - view->SetVisible(desired_width < bounds->width()); - if (view->IsVisible()) { - view->SetBounds( - leading ? bounds->x() : (bounds->right() - view_size.width()), - view->y(), view_size.width(), view->height()); - bounds->set_width(bounds->width() - desired_width); - } -} - -void LocationBarView::RefreshContentSettingViews() { - const TabContents* tab_contents = delegate_->GetTabContents(); - for (ContentSettingViews::const_iterator i(content_setting_views_.begin()); - i != content_setting_views_.end(); ++i) { - (*i)->UpdateFromTabContents( - model_->input_in_progress() ? NULL : tab_contents); - } -} - -void LocationBarView::DeletePageActionViews() { - for (PageActionViews::const_iterator i(page_action_views_.begin()); - i != page_action_views_.end(); ++i) - RemoveChildView(*i); - STLDeleteElements(&page_action_views_); -} - -void LocationBarView::RefreshPageActionViews() { - if (mode_ != NORMAL) - return; - - ExtensionsService* service = profile_->GetExtensionsService(); - if (!service) - return; - - std::map<ExtensionAction*, bool> old_visibility; - for (PageActionViews::const_iterator i(page_action_views_.begin()); - i != page_action_views_.end(); ++i) - old_visibility[(*i)->image_view()->page_action()] = (*i)->IsVisible(); - - // Remember the previous visibility of the page actions so that we can - // notify when this changes. - std::vector<ExtensionAction*> page_actions; - for (size_t i = 0; i < service->extensions()->size(); ++i) { - if (service->extensions()->at(i)->page_action()) - page_actions.push_back(service->extensions()->at(i)->page_action()); - } - - // On startup we sometimes haven't loaded any extensions. This makes sure - // we catch up when the extensions (and any page actions) load. - if (page_actions.size() != page_action_views_.size()) { - DeletePageActionViews(); // Delete the old views (if any). - - page_action_views_.resize(page_actions.size()); - - // Add the page actions in reverse order, so that the child views are - // inserted in left-to-right order for accessibility. - for (int i = page_actions.size() - 1; i >= 0; --i) { - page_action_views_[i] = new PageActionWithBadgeView( - new PageActionImageView(this, profile_, page_actions[i])); - page_action_views_[i]->SetVisible(false); - AddChildView(GetChildIndex(star_view_), page_action_views_[i]); - } - } - - TabContents* contents = delegate_->GetTabContents(); - if (!page_action_views_.empty() && contents) { - GURL url = GURL(WideToUTF8(model_->GetText())); - - for (PageActionViews::const_iterator i(page_action_views_.begin()); - i != page_action_views_.end(); ++i) { - (*i)->UpdateVisibility(model_->input_in_progress() ? NULL : contents, - url); - - // Check if the visibility of the action changed and notify if it did. - ExtensionAction* action = (*i)->image_view()->page_action(); - if (old_visibility.find(action) == old_visibility.end() || - old_visibility[action] != (*i)->IsVisible()) { - NotificationService::current()->Notify( - NotificationType::EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED, - Source<ExtensionAction>(action), - Details<TabContents>(contents)); - } - } - } -} - -#if defined(OS_WIN) -void LocationBarView::OnMouseEvent(const views::MouseEvent& event, UINT msg) { - UINT flags = 0; - if (event.IsControlDown()) - flags |= MK_CONTROL; - if (event.IsShiftDown()) - flags |= MK_SHIFT; - if (event.IsLeftMouseButton()) - flags |= MK_LBUTTON; - if (event.IsMiddleMouseButton()) - flags |= MK_MBUTTON; - if (event.IsRightMouseButton()) - flags |= MK_RBUTTON; - - gfx::Point screen_point(event.location()); - ConvertPointToScreen(this, &screen_point); - location_entry_->HandleExternalMsg(msg, flags, screen_point.ToPOINT()); -} -#endif - -void LocationBarView::ShowFirstRunBubbleInternal( - FirstRun::BubbleType bubble_type) { -#if defined(OS_WIN) // First run bubble doesn't make sense for Chrome OS. - // If the browser is no longer active, let's not show the info bubble, as this - // would make the browser the active window again. - if (!location_entry_view_ || !location_entry_view_->GetWidget()->IsActive()) - return; - - // Point at the start of the edit control; adjust to look as good as possible. - const int kXOffset = kNormalHorizontalEdgeThickness + kEdgeItemPadding + - ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_OMNIBOX_HTTP)->width() + kItemPadding; - const int kYOffset = -(kVerticalEdgeThickness + 2); - gfx::Point origin(location_entry_view_->bounds().x() + kXOffset, - y() + height() + kYOffset); - // If the UI layout is RTL, the coordinate system is not transformed and - // therefore we need to adjust the X coordinate so that bubble appears on the - // right hand side of the location bar. - if (base::i18n::IsRTL()) - origin.set_x(width() - origin.x()); - views::View::ConvertPointToScreen(this, &origin); - FirstRunBubble::Show(profile_, GetWidget(), gfx::Rect(origin, gfx::Size()), - BubbleBorder::TOP_LEFT, bubble_type); -#endif -} - -std::string LocationBarView::GetClassName() const { - return kViewClassName; -} - -bool LocationBarView::SkipDefaultKeyEventProcessing(const views::KeyEvent& e) { - if (keyword_hint_view_->IsVisible() && - views::FocusManager::IsTabTraversalKeyEvent(e)) { - // We want to receive tab key events when the hint is showing. - return true; - } - -#if defined(OS_WIN) - return location_entry_->SkipDefaultKeyEventProcessing(e); -#else - // TODO(jcampan): We need to refactor the code of - // AutocompleteEditViewWin::SkipDefaultKeyEventProcessing into this class so - // it can be shared between Windows and Linux. - // For now, we just override back-space and tab keys, as back-space is the - // accelerator for back navigation and tab key is used by some input methods. - if (e.GetKeyCode() == app::VKEY_BACK || - views::FocusManager::IsTabTraversalKeyEvent(e)) - return true; - return false; -#endif -} - -AccessibilityTypes::Role LocationBarView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -void LocationBarView::WriteDragData(views::View* sender, - const gfx::Point& press_pt, - OSExchangeData* data) { - DCHECK(GetDragOperations(sender, press_pt) != DragDropTypes::DRAG_NONE); - - TabContents* tab_contents = delegate_->GetTabContents(); - DCHECK(tab_contents); - drag_utils::SetURLAndDragImage(tab_contents->GetURL(), - UTF16ToWideHack(tab_contents->GetTitle()), - tab_contents->GetFavIcon(), data); -} - -int LocationBarView::GetDragOperations(views::View* sender, - const gfx::Point& p) { - DCHECK((sender == location_icon_view_) || (sender == ev_bubble_view_)); - TabContents* tab_contents = delegate_->GetTabContents(); - return (tab_contents && tab_contents->GetURL().is_valid() && - !location_entry()->IsEditingOrEmpty()) ? - (DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK) : - DragDropTypes::DRAG_NONE; -} - -bool LocationBarView::CanStartDrag(View* sender, - const gfx::Point& press_pt, - const gfx::Point& p) { - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, LocationBar implementation: - -void LocationBarView::ShowFirstRunBubble(FirstRun::BubbleType bubble_type) { - // Wait until search engines have loaded to show the first run bubble. - if (!profile_->GetTemplateURLModel()->loaded()) { - bubble_type_ = bubble_type; - template_url_model_ = profile_->GetTemplateURLModel(); - template_url_model_->AddObserver(this); - template_url_model_->Load(); - return; - } - ShowFirstRunBubbleInternal(bubble_type); -} - -void LocationBarView::SetSuggestedText(const string16& text) { - if (!text.empty()) { - if (!suggested_text_view_) { - suggested_text_view_ = new views::Label(); - suggested_text_view_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - suggested_text_view_->SetColor( - GetColor(ToolbarModel::NONE, - LocationBarView::DEEMPHASIZED_TEXT)); - suggested_text_view_->SetText(UTF16ToWide(text)); - suggested_text_view_->SetFont(location_entry_->GetFont()); - AddChildView(suggested_text_view_); - } else if (suggested_text_view_->GetText() == UTF16ToWide(text)) { - return; - } else { - suggested_text_view_->SetText(UTF16ToWide(text)); - } - } else if (suggested_text_view_) { - delete suggested_text_view_; - suggested_text_view_ = NULL; - } else { - return; - } - - Layout(); - SchedulePaint(); -} - -std::wstring LocationBarView::GetInputString() const { - return location_input_; -} - -WindowOpenDisposition LocationBarView::GetWindowOpenDisposition() const { - return disposition_; -} - -PageTransition::Type LocationBarView::GetPageTransition() const { - return transition_; -} - -void LocationBarView::AcceptInput() { - location_entry_->model()->AcceptInput(CURRENT_TAB, false); -} - -void LocationBarView::FocusLocation(bool select_all) { - location_entry_->SetFocus(); - if (select_all) - location_entry_->SelectAll(true); -} - -void LocationBarView::FocusSearch() { - location_entry_->SetFocus(); - location_entry_->SetForcedQuery(); -} - -void LocationBarView::SaveStateToContents(TabContents* contents) { - location_entry_->SaveStateToTab(contents); -} - -void LocationBarView::Revert() { - location_entry_->RevertAll(); -} - -int LocationBarView::PageActionVisibleCount() { - int result = 0; - for (size_t i = 0; i < page_action_views_.size(); i++) { - if (page_action_views_[i]->IsVisible()) - ++result; - } - return result; -} - -ExtensionAction* LocationBarView::GetPageAction(size_t index) { - if (index < page_action_views_.size()) - return page_action_views_[index]->image_view()->page_action(); - - NOTREACHED(); - return NULL; -} - -ExtensionAction* LocationBarView::GetVisiblePageAction(size_t index) { - size_t current = 0; - for (size_t i = 0; i < page_action_views_.size(); ++i) { - if (page_action_views_[i]->IsVisible()) { - if (current == index) - return page_action_views_[i]->image_view()->page_action(); - - ++current; - } - } - - NOTREACHED(); - return NULL; -} - -void LocationBarView::TestPageActionPressed(size_t index) { - size_t current = 0; - for (size_t i = 0; i < page_action_views_.size(); ++i) { - if (page_action_views_[i]->IsVisible()) { - if (current == index) { - const int kLeftMouseButton = 1; - page_action_views_[i]->image_view()->ExecuteAction(kLeftMouseButton, - false); // inspect_with_devtools - return; - } - ++current; - } - } - - NOTREACHED(); -} - -void LocationBarView::OnTemplateURLModelChanged() { - template_url_model_->RemoveObserver(this); - template_url_model_ = NULL; - ShowFirstRunBubble(bubble_type_); -} diff --git a/chrome/browser/views/location_bar/location_bar_view.h b/chrome/browser/views/location_bar/location_bar_view.h index 019e7a1..1e2b2d7 100644 --- a/chrome/browser/views/location_bar/location_bar_view.h +++ b/chrome/browser/views/location_bar/location_bar_view.h @@ -6,399 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_ #pragma once -#include <string> -#include <vector> - -#include "base/task.h" -#include "chrome/browser/autocomplete/autocomplete_edit.h" -#include "chrome/browser/extensions/extension_context_menu_model.h" -#include "chrome/browser/first_run/first_run.h" -#include "chrome/browser/location_bar.h" -#include "chrome/browser/search_engines/template_url_model_observer.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/toolbar_model.h" -#include "chrome/browser/views/extensions/extension_popup.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "gfx/font.h" -#include "gfx/rect.h" -#include "views/controls/native/native_view_host.h" - -#if defined(OS_WIN) -#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" -#else -#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" -#include "chrome/browser/gtk/accessible_widget_helper_gtk.h" -#endif - -class CommandUpdater; -class ContentSettingImageView; -class EVBubbleView; -class ExtensionAction; -class GURL; -class InstantController; -class KeywordHintView; -class LocationIconView; -class PageActionWithBadgeView; -class Profile; -class SelectedKeywordView; -class StarView; -class TemplateURLModel; - -namespace views { -class HorizontalPainter; -class Label; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// LocationBarView class -// -// The LocationBarView class is a View subclass that paints the background -// of the URL bar strip and contains its content. -// -///////////////////////////////////////////////////////////////////////////// -class LocationBarView : public LocationBar, - public LocationBarTesting, - public views::View, - public views::DragController, - public AutocompleteEditController, - public TemplateURLModelObserver { - public: - // The location bar view's class name. - static const char kViewClassName[]; - - class Delegate { - public: - // Should return the current tab contents. - virtual TabContents* GetTabContents() = 0; - - // Returns the InstantController, or NULL if there isn't one. - virtual InstantController* GetInstant() = 0; - - // Called by the location bar view when the user starts typing in the edit. - // This forces our security style to be UNKNOWN for the duration of the - // editing. - virtual void OnInputInProgress(bool in_progress) = 0; - }; - - enum ColorKind { - BACKGROUND = 0, - TEXT, - SELECTED_TEXT, - DEEMPHASIZED_TEXT, - SECURITY_TEXT, - }; - - // The modes reflect the different scenarios where a location bar can be used. - // The normal mode is the mode used in a regular browser window. - // In popup mode, the location bar view is read only and has a slightly - // different presentation (font size / color). - // In app launcher mode, the location bar is empty and no security states or - // page/browser actions are displayed. - enum Mode { - NORMAL = 0, - POPUP, - APP_LAUNCHER - }; - - LocationBarView(Profile* profile, - CommandUpdater* command_updater, - ToolbarModel* model, - Delegate* delegate, - Mode mode); - virtual ~LocationBarView(); - - void Init(); - - // True if this instance has been initialized by calling Init, which can only - // be called when the receiving instance is attached to a view container. - bool IsInitialized() const; - - // Returns the appropriate color for the desired kind, based on the user's - // system theme. - static SkColor GetColor(ToolbarModel::SecurityLevel security_level, - ColorKind kind); - - // Updates the location bar. We also reset the bar's permanent text and - // security style, and, if |tab_for_state_restoring| is non-NULL, also restore - // saved state that the tab holds. - void Update(const TabContents* tab_for_state_restoring); - - void SetProfile(Profile* profile); - Profile* profile() const { return profile_; } - - // Returns the current TabContents. - TabContents* GetTabContents() const; - - // Sets |preview_enabled| for the PageAction View associated with this - // |page_action|. If |preview_enabled| is true, the view will display the - // PageActions icon even though it has not been activated by the extension. - // This is used by the ExtensionInstalledBubble to preview what the icon - // will look like for the user upon installation of the extension. - void SetPreviewEnabledPageAction(ExtensionAction *page_action, - bool preview_enabled); - - // Retrieves the PageAction View which is associated with |page_action|. - views::View* GetPageActionView(ExtensionAction* page_action); - - // Toggles the star on or off. - void SetStarToggled(bool on); - - // Shows the bookmark bubble. - void ShowStarBubble(const GURL& url, bool newly_bookmarked); - - // Sizing functions - virtual gfx::Size GetPreferredSize(); - - // Layout and Painting functions - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - - // No focus border for the location bar, the caret is enough. - virtual void PaintFocusBorder(gfx::Canvas* canvas) { } - - // Called when any ancestor changes its size, asks the AutocompleteEditModel - // to close its popup. - virtual void VisibleBoundsInRootChanged(); - - // Set if we should show a focus rect while the location entry field is - // focused. Used when the toolbar is in full keyboard accessibility mode. - // Repaints if necessary. - virtual void SetShowFocusRect(bool show); - - // Select all of the text. Needed when the user tabs through controls - // in the toolbar in full keyboard accessibility mode. - virtual void SelectAll(); - -#if defined(OS_WIN) - // Event Handlers - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual bool OnMouseDragged(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); -#endif - - // AutocompleteEditController - virtual void OnAutocompleteWillClosePopup(); - virtual void OnAutocompleteLosingFocus(gfx::NativeView view_gaining_focus); - virtual void OnAutocompleteWillAccept(); - virtual bool OnCommitSuggestedText(const std::wstring& typed_text); - virtual void OnSetSuggestedSearchText(const string16& suggested_text); - virtual void OnPopupBoundsChanged(const gfx::Rect& bounds); - virtual void OnAutocompleteAccept(const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition, - const GURL& alternate_nav_url); - virtual void OnChanged(); - virtual void OnInputInProgress(bool in_progress); - virtual void OnKillFocus(); - virtual void OnSetFocus(); - virtual SkBitmap GetFavIcon() const; - virtual std::wstring GetTitle() const; - - // Overridden from views::View: - virtual std::string GetClassName() const; - virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // Overridden from views::DragController: - virtual void WriteDragData(View* sender, - const gfx::Point& press_pt, - OSExchangeData* data); - virtual int GetDragOperations(View* sender, const gfx::Point& p); - virtual bool CanStartDrag(View* sender, - const gfx::Point& press_pt, - const gfx::Point& p); - - // Overridden from LocationBar: - virtual void ShowFirstRunBubble(FirstRun::BubbleType bubble_type); - virtual void SetSuggestedText(const string16& text); - virtual std::wstring GetInputString() const; - virtual WindowOpenDisposition GetWindowOpenDisposition() const; - virtual PageTransition::Type GetPageTransition() const; - virtual void AcceptInput(); - virtual void FocusLocation(bool select_all); - virtual void FocusSearch(); - virtual void UpdateContentSettingsIcons(); - virtual void UpdatePageActions(); - virtual void InvalidatePageActions(); - virtual void SaveStateToContents(TabContents* contents); - virtual void Revert(); - virtual const AutocompleteEditView* location_entry() const { - return location_entry_.get(); - } - virtual AutocompleteEditView* location_entry() { - return location_entry_.get(); - } - virtual LocationBarTesting* GetLocationBarForTesting() { return this; } - - // Overridden from LocationBarTesting: - virtual int PageActionCount() { return page_action_views_.size(); } - virtual int PageActionVisibleCount(); - virtual ExtensionAction* GetPageAction(size_t index); - virtual ExtensionAction* GetVisiblePageAction(size_t index); - virtual void TestPageActionPressed(size_t index); - - // Overridden from TemplateURLModelObserver - virtual void OnTemplateURLModelChanged(); - - // Thickness of the left and right edges of the omnibox, in normal mode. - static const int kNormalHorizontalEdgeThickness; - // Thickness of the top and bottom edges of the omnibox. - static const int kVerticalEdgeThickness; - // Space between items in the location bar. - static const int kItemPadding; - // Space between items in the location bar when an extension keyword is - // showing. - static const int kExtensionItemPadding; - // Space between the edges and the items next to them. - static const int kEdgeItemPadding; - // Space between the edge and a bubble. - static const int kBubblePadding; - - protected: - void Focus(); - - private: - typedef std::vector<ContentSettingImageView*> ContentSettingViews; - - friend class PageActionImageView; - friend class PageActionWithBadgeView; - typedef std::vector<PageActionWithBadgeView*> PageActionViews; - - // Returns the amount of horizontal space (in pixels) out of - // |location_bar_width| that is not taken up by the actual text in - // location_entry_. - int AvailableWidth(int location_bar_width); - - // If |view| fits in |available_width|, it is made visible and positioned at - // the leading or trailing end of |bounds|, which are then shrunk - // appropriately. Otherwise |view| is made invisible. - // Note: |view| is expected to have already been positioned and sized - // vertically. - void LayoutView(views::View* view, - int padding, - int available_width, - bool leading, - gfx::Rect* bounds); - - // Update the visibility state of the Content Blocked icons to reflect what is - // actually blocked on the current page. - void RefreshContentSettingViews(); - - // Delete all page action views that we have created. - void DeletePageActionViews(); - - // Update the views for the Page Actions, to reflect state changes for - // PageActions. - void RefreshPageActionViews(); - - // Sets the visibility of view to new_vis. - void ToggleVisibility(bool new_vis, views::View* view); - -#if defined(OS_WIN) - // Helper for the Mouse event handlers that does all the real work. - void OnMouseEvent(const views::MouseEvent& event, UINT msg); -#endif - - // Helper to show the first run info bubble. - void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type); - - // Current profile. Not owned by us. - Profile* profile_; - - // The Autocomplete Edit field. -#if defined(OS_WIN) - scoped_ptr<AutocompleteEditViewWin> location_entry_; -#else - scoped_ptr<AutocompleteEditViewGtk> location_entry_; -#endif - - // The CommandUpdater for the Browser object that corresponds to this View. - CommandUpdater* command_updater_; - - // The model. - ToolbarModel* model_; - - // Our delegate. - Delegate* delegate_; - - // This is the string of text from the autocompletion session that the user - // entered or selected. - std::wstring location_input_; - - // The user's desired disposition for how their input should be opened - WindowOpenDisposition disposition_; - - // The transition type to use for the navigation - PageTransition::Type transition_; - - // Font used by edit and some of the hints. - gfx::Font font_; - - // An object used to paint the normal-mode background. - scoped_ptr<views::HorizontalPainter> painter_; - - // An icon to the left of the edit field. - LocationIconView* location_icon_view_; - - // A bubble displayed for EV HTTPS sites. - EVBubbleView* ev_bubble_view_; - - // Location_entry view wrapper - views::NativeViewHost* location_entry_view_; - - // The following views are used to provide hints and remind the user as to - // what is going in the edit. They are all added a children of the - // LocationBarView. At most one is visible at a time. Preference is - // given to the keyword_view_, then hint_view_. - // These autocollapse when the edit needs the room. - - // Shown if the user has selected a keyword. - SelectedKeywordView* selected_keyword_view_; - - // View responsible for showing suggested text. This is NULL when there is no - // suggested text. - views::Label* suggested_text_view_; - - // Shown if the selected url has a corresponding keyword. - KeywordHintView* keyword_hint_view_; - - // The content setting views. - ContentSettingViews content_setting_views_; - - // The page action icon views. - PageActionViews page_action_views_; - - // The star. - StarView* star_view_; - - // The mode that dictates how the bar shows. - Mode mode_; - - // True if we should show a focus rect while the location entry field is - // focused. Used when the toolbar is in full keyboard accessibility mode. - bool show_focus_rect_; - - // Whether bubble text is short or long. - FirstRun::BubbleType bubble_type_; - - // This is in case we're destroyed before the model loads. We store the model - // because calling profile_->GetTemplateURLModel() in the destructor causes a - // crash. - TemplateURLModel* template_url_model_; - -#if defined(OS_LINUX) - scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_; -#endif - - // Should instant be updated? This is set to false in OnAutocompleteWillAccept - // and true in OnAutocompleteAccept. This is needed as prior to accepting an - // autocomplete suggestion the model is reverted which triggers resetting - // instant. - bool update_instant_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(LocationBarView); -}; +#include "chrome/browser/ui/views/location_bar/location_bar_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/location_icon_view.cc b/chrome/browser/views/location_bar/location_icon_view.cc deleted file mode 100644 index b862559..0000000 --- a/chrome/browser/views/location_bar/location_icon_view.cc +++ /dev/null @@ -1,23 +0,0 @@ -// 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/location_bar/location_icon_view.h" - -LocationIconView::LocationIconView(const LocationBarView* location_bar) - : ALLOW_THIS_IN_INITIALIZER_LIST(click_handler_(this, location_bar)) { -} - -LocationIconView::~LocationIconView() { -} - -bool LocationIconView::OnMousePressed(const views::MouseEvent& event) { - // We want to show the dialog on mouse release; that is the standard behavior - // for buttons. - return true; -} - -void LocationIconView::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - click_handler_.OnMouseReleased(event, canceled); -} diff --git a/chrome/browser/views/location_bar/location_icon_view.h b/chrome/browser/views/location_bar/location_icon_view.h index 524da4e..d0de238 100644 --- a/chrome/browser/views/location_bar/location_icon_view.h +++ b/chrome/browser/views/location_bar/location_icon_view.h @@ -6,30 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_ICON_VIEW_H_ #pragma once -#include "chrome/browser/views/location_bar/click_handler.h" -#include "views/controls/image_view.h" - -class LocationBarView; -namespace views { -class MouseEvent; -} - -// LocationIconView is used to display an icon to the left of the edit field. -// This shows the user's current action while editing, the page security -// status on https pages, or a globe for other URLs. -class LocationIconView : public views::ImageView { - public: - explicit LocationIconView(const LocationBarView* location_bar); - virtual ~LocationIconView(); - - // Overridden from view. - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - - private: - ClickHandler click_handler_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(LocationIconView); -}; +#include "chrome/browser/ui/views/location_bar/location_icon_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_ICON_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/page_action_image_view.cc b/chrome/browser/views/location_bar/page_action_image_view.cc deleted file mode 100644 index c7155bf..0000000 --- a/chrome/browser/views/location_bar/page_action_image_view.cc +++ /dev/null @@ -1,243 +0,0 @@ -// 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/location_bar/page_action_image_view.h" - -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/extensions/extension_browser_event_router.h" -#include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "chrome/browser/platform_util.h" -#include "chrome/common/extensions/extension_action.h" -#include "chrome/common/extensions/extension_resource.h" -#include "views/controls/menu/menu_2.h" - -PageActionImageView::PageActionImageView(LocationBarView* owner, - Profile* profile, - ExtensionAction* page_action) - : owner_(owner), - profile_(profile), - page_action_(page_action), - ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)), - current_tab_id_(-1), - preview_enabled_(false), - popup_(NULL) { - const Extension* extension = profile->GetExtensionsService()-> - GetExtensionById(page_action->extension_id(), false); - DCHECK(extension); - - // Load all the icons declared in the manifest. This is the contents of the - // icons array, plus the default_icon property, if any. - std::vector<std::string> icon_paths(*page_action->icon_paths()); - if (!page_action_->default_icon_path().empty()) - icon_paths.push_back(page_action_->default_icon_path()); - - for (std::vector<std::string>::iterator iter = icon_paths.begin(); - iter != icon_paths.end(); ++iter) { - tracker_.LoadImage(extension, extension->GetResource(*iter), - gfx::Size(Extension::kPageActionIconMaxSize, - Extension::kPageActionIconMaxSize), - ImageLoadingTracker::DONT_CACHE); - } - - set_accessibility_focusable(true); -} - -PageActionImageView::~PageActionImageView() { - if (popup_) - HidePopup(); -} - -void PageActionImageView::ExecuteAction(int button, - bool inspect_with_devtools) { - if (current_tab_id_ < 0) { - NOTREACHED() << "No current tab."; - return; - } - - if (page_action_->HasPopup(current_tab_id_)) { - // In tests, GetLastActive could return NULL, so we need to have - // a fallback. - // TODO(erikkay): Find a better way to get the Browser that this - // button is in. - Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); - if (!browser) - browser = BrowserList::FindBrowserWithProfile(profile_); - DCHECK(browser); - - bool popup_showing = popup_ != NULL; - - // Always hide the current popup. Only one popup at a time. - HidePopup(); - - // If we were already showing, then treat this click as a dismiss. - if (popup_showing) - return; - - gfx::Rect screen_bounds(GetImageBounds()); - gfx::Point origin(screen_bounds.origin()); - View::ConvertPointToScreen(this, &origin); - screen_bounds.set_origin(origin); - - popup_ = ExtensionPopup::Show( - page_action_->GetPopupUrl(current_tab_id_), - browser, - browser->profile(), - browser->window()->GetNativeHandle(), - screen_bounds, - BubbleBorder::TOP_RIGHT, - true, // Activate the popup window. - inspect_with_devtools, - ExtensionPopup::BUBBLE_CHROME, - this); // ExtensionPopup::Observer - } else { - ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted( - profile_, page_action_->extension_id(), page_action_->id(), - current_tab_id_, current_url_.spec(), button); - } -} - -AccessibilityTypes::Role PageActionImageView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PUSHBUTTON; -} - -bool PageActionImageView::OnMousePressed(const views::MouseEvent& event) { - // We want to show the bubble on mouse release; that is the standard behavior - // for buttons. (Also, triggering on mouse press causes bugs like - // http://crbug.com/33155.) - return true; -} - -void PageActionImageView::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - if (canceled || !HitTest(event.location())) - return; - - int button = -1; - if (event.IsLeftMouseButton()) { - button = 1; - } else if (event.IsMiddleMouseButton()) { - button = 2; - } else if (event.IsRightMouseButton()) { - // Get the top left point of this button in screen coordinates. - gfx::Point menu_origin; - ConvertPointToScreen(this, &menu_origin); - // Make the menu appear below the button. - menu_origin.Offset(0, height()); - ShowContextMenu(menu_origin, true); - return; - } - - ExecuteAction(button, false); // inspect_with_devtools -} - -bool PageActionImageView::OnKeyPressed(const views::KeyEvent& e) { - if (e.GetKeyCode() == app::VKEY_SPACE || - e.GetKeyCode() == app::VKEY_RETURN) { - ExecuteAction(1, false); - return true; - } - return false; -} - -void PageActionImageView::ShowContextMenu(const gfx::Point& p, - bool is_mouse_gesture) { - const Extension* extension = profile_->GetExtensionsService()-> - GetExtensionById(page_action()->extension_id(), false); - Browser* browser = BrowserView::GetBrowserViewForNativeWindow( - platform_util::GetTopLevel(GetWidget()->GetNativeView()))->browser(); - context_menu_contents_ = - new ExtensionContextMenuModel(extension, browser, this); - context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get())); - context_menu_menu_->RunContextMenuAt(p); -} - -void PageActionImageView::OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index) { - // We loaded icons()->size() icons, plus one extra if the page action had - // a default icon. - int total_icons = static_cast<int>(page_action_->icon_paths()->size()); - if (!page_action_->default_icon_path().empty()) - total_icons++; - DCHECK(index < total_icons); - - // Map the index of the loaded image back to its name. If we ever get an - // index greater than the number of icons, it must be the default icon. - if (image) { - if (index < static_cast<int>(page_action_->icon_paths()->size())) - page_action_icons_[page_action_->icon_paths()->at(index)] = *image; - else - page_action_icons_[page_action_->default_icon_path()] = *image; - } - - // During object construction (before the parent has been set) we are already - // in a UpdatePageActions call, so we don't need to start another one (and - // doing so causes crash described in http://crbug.com/57333). - if (GetParent()) - owner_->UpdatePageActions(); -} - -void PageActionImageView::UpdateVisibility(TabContents* contents, - const GURL& url) { - // Save this off so we can pass it back to the extension when the action gets - // executed. See PageActionImageView::OnMousePressed. - current_tab_id_ = contents ? ExtensionTabUtil::GetTabId(contents) : -1; - current_url_ = url; - - if (!contents || - (!preview_enabled_ && !page_action_->GetIsVisible(current_tab_id_))) { - SetVisible(false); - return; - } - - // Set the tooltip. - tooltip_ = page_action_->GetTitle(current_tab_id_); - SetTooltipText(UTF8ToWide(tooltip_)); - - // Set the image. - // It can come from three places. In descending order of priority: - // - The developer can set it dynamically by path or bitmap. It will be in - // page_action_->GetIcon(). - // - The developer can set it dynamically by index. It will be in - // page_action_->GetIconIndex(). - // - It can be set in the manifest by path. It will be in - // page_action_->default_icon_path(). - - // First look for a dynamically set bitmap. - SkBitmap icon = page_action_->GetIcon(current_tab_id_); - if (icon.isNull()) { - int icon_index = page_action_->GetIconIndex(current_tab_id_); - std::string icon_path = (icon_index < 0) ? - page_action_->default_icon_path() : - page_action_->icon_paths()->at(icon_index); - if (!icon_path.empty()) { - PageActionMap::iterator iter = page_action_icons_.find(icon_path); - if (iter != page_action_icons_.end()) - icon = iter->second; - } - } - if (!icon.isNull()) - SetImage(&icon); - - SetVisible(true); -} - -void PageActionImageView::InspectPopup(ExtensionAction* action) { - ExecuteAction(1, // left-click - true); // inspect_with_devtools -} - -void PageActionImageView::ExtensionPopupIsClosing(ExtensionPopup* popup) { - DCHECK_EQ(popup_, popup); - // ExtensionPopup is ref-counted, so we don't need to delete it. - popup_ = NULL; -} - -void PageActionImageView::HidePopup() { - if (popup_) - popup_->Close(); -} diff --git a/chrome/browser/views/location_bar/page_action_image_view.h b/chrome/browser/views/location_bar/page_action_image_view.h index 71ee6c3..aa01f4d 100644 --- a/chrome/browser/views/location_bar/page_action_image_view.h +++ b/chrome/browser/views/location_bar/page_action_image_view.h @@ -6,108 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_IMAGE_VIEW_H_ #pragma once -#include <map> -#include <string> - -#include "base/scoped_ptr.h" -#include "chrome/browser/extensions/image_loading_tracker.h" -#include "chrome/browser/extensions/extension_context_menu_model.h" -#include "chrome/browser/views/extensions/extension_popup.h" -#include "views/controls/image_view.h" - -class LocationBarView; -namespace views { -class Menu2; -}; - -// PageActionImageView is used by the LocationBarView to display the icon for a -// given PageAction and notify the extension when the icon is clicked. -class PageActionImageView : public views::ImageView, - public ImageLoadingTracker::Observer, - public ExtensionContextMenuModel::PopupDelegate, - public ExtensionPopup::Observer { - public: - PageActionImageView(LocationBarView* owner, - Profile* profile, - ExtensionAction* page_action); - virtual ~PageActionImageView(); - - ExtensionAction* page_action() { return page_action_; } - - int current_tab_id() { return current_tab_id_; } - - void set_preview_enabled(bool preview_enabled) { - preview_enabled_ = preview_enabled; - } - - // Overridden from view. - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - virtual bool OnKeyPressed(const views::KeyEvent& e); - virtual void ShowContextMenu(const gfx::Point& p, bool is_mouse_gesture); - - // Overridden from ImageLoadingTracker. - virtual void OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index); - - // Overridden from ExtensionContextMenuModelModel::Delegate - virtual void InspectPopup(ExtensionAction* action); - - // Overridden from ExtensionPopup::Observer - virtual void ExtensionPopupIsClosing(ExtensionPopup* popup); - - // Called to notify the PageAction that it should determine whether to be - // visible or hidden. |contents| is the TabContents that is active, |url| is - // the current page URL. - void UpdateVisibility(TabContents* contents, const GURL& url); - - // Either notify listeners or show a popup depending on the page action. - void ExecuteAction(int button, bool inspect_with_devtools); - - private: - // Hides the active popup, if there is one. - void HidePopup(); - - // The location bar view that owns us. - LocationBarView* owner_; - - // The current profile (not owned by us). - Profile* profile_; - - // The PageAction that this view represents. The PageAction is not owned by - // us, it resides in the extension of this particular profile. - ExtensionAction* page_action_; - - // A cache of bitmaps the page actions might need to show, mapped by path. - typedef std::map<std::string, SkBitmap> PageActionMap; - PageActionMap page_action_icons_; - - // The context menu for this page action. - scoped_refptr<ExtensionContextMenuModel> context_menu_contents_; - scoped_ptr<views::Menu2> context_menu_menu_; - - // The object that is waiting for the image loading to complete - // asynchronously. - ImageLoadingTracker tracker_; - - // The tab id we are currently showing the icon for. - int current_tab_id_; - - // The URL we are currently showing the icon for. - GURL current_url_; - - // The string to show for a tooltip; - std::string tooltip_; - - // This is used for post-install visual feedback. The page_action icon is - // briefly shown even if it hasn't been enabled by its extension. - bool preview_enabled_; - - // The current popup and the button it came from. NULL if no popup. - ExtensionPopup* popup_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(PageActionImageView); -}; +#include "chrome/browser/ui/views/location_bar/page_action_image_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_IMAGE_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/page_action_with_badge_view.cc b/chrome/browser/views/location_bar/page_action_with_badge_view.cc deleted file mode 100644 index fd2204e..0000000 --- a/chrome/browser/views/location_bar/page_action_with_badge_view.cc +++ /dev/null @@ -1,39 +0,0 @@ -// 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/location_bar/page_action_with_badge_view.h" - -#include "chrome/browser/views/location_bar/page_action_image_view.h" -#include "chrome/common/extensions/extension.h" - -PageActionWithBadgeView::PageActionWithBadgeView( - PageActionImageView* image_view) { - image_view_ = image_view; - AddChildView(image_view_); -} - -AccessibilityTypes::Role PageActionWithBadgeView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -gfx::Size PageActionWithBadgeView::GetPreferredSize() { - return gfx::Size(Extension::kPageActionIconMaxSize, - Extension::kPageActionIconMaxSize); -} - -void PageActionWithBadgeView::Layout() { - // We have 25 pixels of vertical space in the Omnibox to play with, so even - // sized icons (such as 16x16) have either a 5 or a 4 pixel whitespace - // (padding) above and below. It looks better to have the extra pixel above - // the icon than below it, so we add a pixel. http://crbug.com/25708. - const SkBitmap& image = image_view()->GetImage(); - int y = (image.height() + 1) % 2; // Even numbers: 1px padding. Odd: 0px. - image_view_->SetBounds(0, y, width(), height()); -} - -void PageActionWithBadgeView::UpdateVisibility(TabContents* contents, - const GURL& url) { - image_view_->UpdateVisibility(contents, url); - SetVisible(image_view_->IsVisible()); -} diff --git a/chrome/browser/views/location_bar/page_action_with_badge_view.h b/chrome/browser/views/location_bar/page_action_with_badge_view.h index 69d0c36..4bdc71e 100644 --- a/chrome/browser/views/location_bar/page_action_with_badge_view.h +++ b/chrome/browser/views/location_bar/page_action_with_badge_view.h @@ -6,32 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_WITH_BADGE_VIEW_H_ #pragma once -#include "gfx/size.h" -#include "views/view.h" - -class GURL; -class PageActionImageView; -class TabContents; - -// A container for the PageActionImageView plus its badge. -class PageActionWithBadgeView : public views::View { - public: - explicit PageActionWithBadgeView(PageActionImageView* image_view); - - PageActionImageView* image_view() { return image_view_; } - - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual gfx::Size GetPreferredSize(); - - void UpdateVisibility(TabContents* contents, const GURL& url); - - private: - virtual void Layout(); - - // The button this view contains. - PageActionImageView* image_view_; - - DISALLOW_COPY_AND_ASSIGN(PageActionWithBadgeView); -}; +#include "chrome/browser/ui/views/location_bar/page_action_with_badge_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_WITH_BADGE_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/selected_keyword_view.cc b/chrome/browser/views/location_bar/selected_keyword_view.cc deleted file mode 100644 index 182015b..0000000 --- a/chrome/browser/views/location_bar/selected_keyword_view.cc +++ /dev/null @@ -1,71 +0,0 @@ -// 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/location_bar/selected_keyword_view.h" - -#include "app/l10n_util.h" -#include "base/logging.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/location_bar_util.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/location_bar/keyword_hint_view.h" -#include "grit/generated_resources.h" - -SelectedKeywordView::SelectedKeywordView(const int background_images[], - int contained_image, - const SkColor& color, - Profile* profile) - : IconLabelBubbleView(background_images, contained_image, color), - profile_(profile) { - full_label_.SetVisible(false); - partial_label_.SetVisible(false); -} - -SelectedKeywordView::~SelectedKeywordView() { -} - -void SelectedKeywordView::SetFont(const gfx::Font& font) { - IconLabelBubbleView::SetFont(font); - full_label_.SetFont(font); - partial_label_.SetFont(font); -} - -gfx::Size SelectedKeywordView::GetPreferredSize() { - gfx::Size size(GetNonLabelSize()); - size.Enlarge(full_label_.GetPreferredSize().width(), 0); - return size; -} - -gfx::Size SelectedKeywordView::GetMinimumSize() { - gfx::Size size(GetNonLabelSize()); - size.Enlarge(partial_label_.GetMinimumSize().width(), 0); - return size; -} - -void SelectedKeywordView::Layout() { - SetLabel((width() == GetPreferredSize().width()) ? - full_label_.GetText() : partial_label_.GetText()); - IconLabelBubbleView::Layout(); -} - -void SelectedKeywordView::SetKeyword(const std::wstring& keyword) { - keyword_ = keyword; - if (keyword.empty()) - return; - DCHECK(profile_); - if (!profile_->GetTemplateURLModel()) - return; - - bool is_extension_keyword; - const std::wstring short_name = profile_->GetTemplateURLModel()-> - GetKeywordShortName(keyword, &is_extension_keyword); - int message_id = is_extension_keyword ? - IDS_OMNIBOX_EXTENSION_KEYWORD_TEXT : IDS_OMNIBOX_KEYWORD_TEXT; - full_label_.SetText(l10n_util::GetStringF(message_id, short_name)); - const std::wstring min_string( - location_bar_util::CalculateMinString(short_name)); - partial_label_.SetText(min_string.empty() ? - full_label_.GetText() : - l10n_util::GetStringF(message_id, min_string)); -} diff --git a/chrome/browser/views/location_bar/selected_keyword_view.h b/chrome/browser/views/location_bar/selected_keyword_view.h index 0199cea..bce29d0 100644 --- a/chrome/browser/views/location_bar/selected_keyword_view.h +++ b/chrome/browser/views/location_bar/selected_keyword_view.h @@ -6,54 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_SELECTED_KEYWORD_VIEW_H_ #pragma once -#include <string> - -#include "chrome/browser/views/location_bar/icon_label_bubble_view.h" -#include "views/controls/label.h" - -class Profile; -namespace gfx { -class Font; -class Size; -} - -// SelectedKeywordView displays the tab-to-search UI in the location bar view. -class SelectedKeywordView : public IconLabelBubbleView { - public: - SelectedKeywordView(const int background_images[], - int contained_image, - const SkColor& color, - Profile* profile); - virtual ~SelectedKeywordView(); - - void SetFont(const gfx::Font& font); - - virtual gfx::Size GetPreferredSize(); - virtual gfx::Size GetMinimumSize(); - virtual void Layout(); - - // The current keyword, or an empty string if no keyword is displayed. - void SetKeyword(const std::wstring& keyword); - std::wstring keyword() const { return keyword_; } - - void set_profile(Profile* profile) { profile_ = profile; } - - private: - // The keyword we're showing. If empty, no keyword is selected. - // NOTE: we don't cache the TemplateURL as it is possible for it to get - // deleted out from under us. - std::wstring keyword_; - - // These labels are never visible. They are used to size the view. One - // label contains the complete description of the keyword, the second - // contains a truncated version of the description, for if there is not - // enough room to display the complete description. - views::Label full_label_; - views::Label partial_label_; - - Profile* profile_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(SelectedKeywordView); -}; +#include "chrome/browser/ui/views/location_bar/selected_keyword_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_SELECTED_KEYWORD_VIEW_H_ + diff --git a/chrome/browser/views/location_bar/star_view.cc b/chrome/browser/views/location_bar/star_view.cc deleted file mode 100644 index 7d22441..0000000 --- a/chrome/browser/views/location_bar/star_view.cc +++ /dev/null @@ -1,75 +0,0 @@ -// 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/location_bar/star_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/command_updater.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" - -StarView::StarView(CommandUpdater* command_updater) - : command_updater_(command_updater) { - SetID(VIEW_ID_STAR_BUTTON); - SetToggled(false); - set_accessibility_focusable(true); -} - -StarView::~StarView() { -} - -void StarView::SetToggled(bool on) { - SetTooltipText(l10n_util::GetString( - on ? IDS_TOOLTIP_STARRED : IDS_TOOLTIP_STAR)); - // Since StarView is an ImageView, the SetTooltipText changes the accessible - // name. To keep the accessible name unchanged, we need to set the accessible - // name right after we modify the tooltip text for this view. - SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_STAR)); - SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed( - on ? IDR_STAR_LIT : IDR_STAR)); -} - -AccessibilityTypes::Role StarView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PUSHBUTTON; -} - -bool StarView::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { - // Don't show tooltip to distract user if BookmarkBubbleView is showing. - if (browser::IsBookmarkBubbleViewShowing()) - return false; - - return ImageView::GetTooltipText(p, tooltip); -} - -bool StarView::OnMousePressed(const views::MouseEvent& event) { - // We want to show the bubble on mouse release; that is the standard behavior - // for buttons. - return true; -} - -void StarView::OnMouseReleased(const views::MouseEvent& event, bool canceled) { - if (!canceled && HitTest(event.location())) - command_updater_->ExecuteCommand(IDC_BOOKMARK_PAGE); -} - -bool StarView::OnKeyPressed(const views::KeyEvent& e) { - if (e.GetKeyCode() == app::VKEY_SPACE || - e.GetKeyCode() == app::VKEY_RETURN) { - command_updater_->ExecuteCommand(IDC_BOOKMARK_PAGE); - return true; - } - return false; -} - -void StarView::InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape) { -} - -bool StarView::CloseOnEscape() { - return true; -} diff --git a/chrome/browser/views/location_bar/star_view.h b/chrome/browser/views/location_bar/star_view.h index 8e8794c..a964d14 100644 --- a/chrome/browser/views/location_bar/star_view.h +++ b/chrome/browser/views/location_bar/star_view.h @@ -6,43 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOCATION_BAR_STAR_VIEW_H_ #pragma once -#include "chrome/browser/views/info_bubble.h" -#include "views/controls/image_view.h" - -class CommandUpdater; -class InfoBubble; - -namespace views { -class KeyEvent; -class MouseEvent; -} - -class StarView : public views::ImageView, public InfoBubbleDelegate { - public: - explicit StarView(CommandUpdater* command_updater); - virtual ~StarView(); - - // Toggles the star on or off. - void SetToggled(bool on); - - private: - // views::ImageView overrides: - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip); - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - virtual bool OnKeyPressed(const views::KeyEvent& e); - - // InfoBubbleDelegate overrides: - virtual void InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape); - virtual bool CloseOnEscape(); - virtual bool FadeInOnShow() { return false; } - - // The CommandUpdater for the Browser object that owns the location bar. - CommandUpdater* command_updater_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(StarView); -}; +#include "chrome/browser/ui/views/location_bar/star_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_STAR_VIEW_H_ + diff --git a/chrome/browser/views/login_view.cc b/chrome/browser/views/login_view.cc deleted file mode 100644 index 3bf2403..0000000 --- a/chrome/browser/views/login_view.cc +++ /dev/null @@ -1,152 +0,0 @@ -// 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/login_view.h" - -#include <string> - -#include "app/l10n_util.h" -#include "base/compiler_specific.h" -#include "base/message_loop.h" -#include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" -#include "views/widget/root_view.h" - -static const int kMessageWidth = 320; -static const int kTextfieldStackHorizontalSpacing = 30; - -using views::GridLayout; - -/////////////////////////////////////////////////////////////////////////////// -// LoginView, public: - -LoginView::LoginView(const std::wstring& explanation, - bool focus_view) - : username_field_(new views::Textfield), - password_field_(new views::Textfield(views::Textfield::STYLE_PASSWORD)), - username_label_(new views::Label( - l10n_util::GetString(IDS_LOGIN_DIALOG_USERNAME_FIELD))), - password_label_(new views::Label( - l10n_util::GetString(IDS_LOGIN_DIALOG_PASSWORD_FIELD))), - message_label_(new views::Label(explanation)), - ALLOW_THIS_IN_INITIALIZER_LIST(focus_grabber_factory_(this)), - login_model_(NULL), - focus_delayed_(false), - focus_view_(focus_view) { - message_label_->SetMultiLine(true); - message_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - message_label_->SetAllowCharacterBreak(true); - - // Initialize the Grid Layout Manager used for this dialog box. - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - // Add the column set for the information message at the top of the dialog - // box. - const int single_column_view_set_id = 0; - views::ColumnSet* column_set = - layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::FIXED, kMessageWidth, 0); - - // Add the column set for the user name and password fields and labels. - const int labels_column_set_id = 1; - column_set = layout->AddColumnSet(labels_column_set_id); - column_set->AddPaddingColumn(0, kTextfieldStackHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kTextfieldStackHorizontalSpacing); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(message_label_); - - layout->AddPaddingRow(0, kUnrelatedControlLargeVerticalSpacing); - - layout->StartRow(0, labels_column_set_id); - layout->AddView(username_label_); - layout->AddView(username_field_); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, labels_column_set_id); - layout->AddView(password_label_); - layout->AddView(password_field_); - - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); -} - -LoginView::~LoginView() { - if (login_model_) - login_model_->SetObserver(NULL); -} - -std::wstring LoginView::GetUsername() { - return username_field_->text(); -} - -std::wstring LoginView::GetPassword() { - return password_field_->text(); -} - -void LoginView::SetModel(LoginModel* model) { - login_model_ = model; - if (login_model_) - login_model_->SetObserver(this); -} - -void LoginView::RequestFocus() { - if (!focus_view_) - return; - - MessageLoop::current()->PostTask(FROM_HERE, - focus_grabber_factory_.NewRunnableMethod(&LoginView::FocusFirstField)); -} - -/////////////////////////////////////////////////////////////////////////////// -// LoginView, views::View, views::LoginModelObserver overrides: - -void LoginView::ViewHierarchyChanged(bool is_add, View *parent, View *child) { - if (is_add && child == this && focus_view_) { - MessageLoop::current()->PostTask(FROM_HERE, - focus_grabber_factory_.NewRunnableMethod(&LoginView::FocusFirstField)); - } -} - -void LoginView::NativeViewHierarchyChanged(bool attached, - gfx::NativeView native_view, - views::RootView* root_view) { - if (focus_delayed_ && attached && focus_view_) { - focus_delayed_ = false; - MessageLoop::current()->PostTask(FROM_HERE, - focus_grabber_factory_.NewRunnableMethod(&LoginView::FocusFirstField)); - } -} - -void LoginView::OnAutofillDataAvailable(const std::wstring& username, - const std::wstring& password) { - if (username_field_->text().empty()) { - username_field_->SetText(username); - password_field_->SetText(password); - username_field_->SelectAll(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// LoginView, private: - -void LoginView::FocusFirstField() { - DCHECK(focus_view_); - if (GetFocusManager()) { - username_field_->RequestFocus(); - } else { - // We are invisible - delay until it is no longer the case. - focus_delayed_ = true; - } -} diff --git a/chrome/browser/views/login_view.h b/chrome/browser/views/login_view.h index b4c133a..bb45e10 100644 --- a/chrome/browser/views/login_view.h +++ b/chrome/browser/views/login_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,77 +6,8 @@ #define CHROME_BROWSER_VIEWS_LOGIN_VIEW_H_ #pragma once -#include "base/task.h" -#include "chrome/browser/login_model.h" -#include "views/view.h" - -namespace views { -class Label; -class Textfield; -class LoginModel; -} // namespace views - -// This class is responsible for displaying the contents of a login window -// for HTTP/FTP authentication. -class LoginView : public views::View, public LoginModelObserver { - public: - // |focus_view| indicates if the view can be focused. - LoginView(const std::wstring& explanation, bool focus_view); - virtual ~LoginView(); - - // Access the data in the username/password text fields. - std::wstring GetUsername(); - std::wstring GetPassword(); - - // LoginModelObserver implementation. - virtual void OnAutofillDataAvailable(const std::wstring& username, - const std::wstring& password); - - // Sets the model. This lets the observer notify the model - // when it has been closed / freed, so the model should no longer try and - // contact it. The view does not own the model, and it is the responsibility - // of the caller to inform this view if the model is deleted. - void SetModel(LoginModel* model); - - virtual void RequestFocus(); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, views::View *parent, - views::View *child); - - virtual void NativeViewHierarchyChanged(bool attached, - gfx::NativeView native_view, - views::RootView* root_view); - - private: - void FocusFirstField(); - - // Non-owning refs to the input text fields. - views::Textfield* username_field_; - views::Textfield* password_field_; - - // Button labels - views::Label* username_label_; - views::Label* password_label_; - - // Authentication message. - views::Label* message_label_; - - // If not null, points to a model we need to notify of our own destruction - // so it doesn't try and access this when its too late. - LoginModel* login_model_; - - ScopedRunnableMethodFactory<LoginView> focus_grabber_factory_; - - // See description above constructor. - const bool focus_view_; - - // Indicates that this view was created when focus manager was unavailable - // (on the hidden tab, for example). This is only used if focus_view_ is true. - bool focus_delayed_; - - DISALLOW_COPY_AND_ASSIGN(LoginView); -}; +#include "chrome/browser/ui/views/login_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_LOGIN_VIEW_H_ + diff --git a/chrome/browser/views/modal_dialog_delegate.cc b/chrome/browser/views/modal_dialog_delegate.cc deleted file mode 100644 index a08d611..0000000 --- a/chrome/browser/views/modal_dialog_delegate.cc +++ /dev/null @@ -1,40 +0,0 @@ -// 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/modal_dialog_delegate.h" - -#include "base/logging.h" -#include "chrome/browser/views/window.h" -#include "views/window/window.h" - -void ModalDialogDelegate::ShowModalDialog() { - gfx::NativeWindow root_hwnd = GetDialogRootWindow(); - // GetMessageBoxRootWindow() will be NULL if there's no selected tab (e.g., - // during shutdown), in which case we simply skip showing this dialog. - if (!root_hwnd) { - Cancel(); - } else { - dialog_ = browser::CreateViewsWindow(root_hwnd, gfx::Rect(), this); - dialog_->Show(); - } -} - -void ModalDialogDelegate::ActivateModalDialog() { - DCHECK(dialog_); - // Ensure that the dialog is visible and at the top of the z-order. These - // conditions may not be true if the dialog was opened on a different virtual - // desktop to the one the browser window is on. - dialog_->Show(); - dialog_->Activate(); -} - -void ModalDialogDelegate::CloseModalDialog() { - // If the dialog is visible close it. - if (dialog_) - dialog_->Close(); -} - -ModalDialogDelegate::ModalDialogDelegate() : dialog_(NULL) { -} - diff --git a/chrome/browser/views/modal_dialog_delegate.h b/chrome/browser/views/modal_dialog_delegate.h index ad7125e..06cba14 100644 --- a/chrome/browser/views/modal_dialog_delegate.h +++ b/chrome/browser/views/modal_dialog_delegate.h @@ -6,26 +6,8 @@ #define CHROME_BROWSER_VIEWS_MODAL_DIALOG_DELEGATE_H_ #pragma once -#include "views/window/dialog_delegate.h" - -namespace views { -class Window; -} - -class ModalDialogDelegate : public views::DialogDelegate { - public: - virtual ~ModalDialogDelegate() {} - // Methods called from AppModalDialog. - virtual gfx::NativeWindow GetDialogRootWindow() = 0; - virtual void ShowModalDialog(); - virtual void ActivateModalDialog(); - virtual void CloseModalDialog(); - protected: - ModalDialogDelegate(); - - // The dialog if it is currently visible. - views::Window* dialog_; -}; +#include "chrome/browser/ui/views/modal_dialog_delegate.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_MODAL_DIALOG_DELEGATE_H_ diff --git a/chrome/browser/views/notifications/balloon_view.cc b/chrome/browser/views/notifications/balloon_view.cc deleted file mode 100644 index cf0442b..0000000 --- a/chrome/browser/views/notifications/balloon_view.cc +++ /dev/null @@ -1,502 +0,0 @@ -// 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/notifications/balloon_view.h" - -#include <vector> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/message_loop.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/notifications/balloon.h" -#include "chrome/browser/notifications/balloon_collection.h" -#include "chrome/browser/notifications/desktop_notification_service.h" -#include "chrome/browser/notifications/notification_options_menu_model.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/views/bubble_border.h" -#include "chrome/browser/views/notifications/balloon_view_host.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" -#include "gfx/canvas_skia.h" -#include "gfx/insets.h" -#include "gfx/native_widget_types.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/button.h" -#include "views/controls/button/image_button.h" -#include "views/controls/button/text_button.h" -#include "views/controls/menu/menu_2.h" -#include "views/controls/native/native_view_host.h" -#include "views/painter.h" -#include "views/widget/root_view.h" -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#endif -#if defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -using views::Widget; - -namespace { - -const int kTopMargin = 2; -const int kBottomMargin = 0; -const int kLeftMargin = 4; -const int kRightMargin = 4; -const int kShelfBorderTopOverlap = 0; - -// Properties of the dismiss button. -const int kDismissButtonWidth = 14; -const int kDismissButtonHeight = 14; -const int kDismissButtonTopMargin = 6; -const int kDismissButtonRightMargin = 6; - -// Properties of the options menu. -const int kOptionsButtonWidth = 21; -const int kOptionsButtonHeight = 14; -const int kOptionsButtonTopMargin = 5; -const int kOptionsButtonRightMargin = 4; - -// Properties of the origin label. -const int kLabelLeftMargin = 10; -const int kLabelTopMargin = 6; - -// Size of the drop shadow. The shadow is provided by BubbleBorder, -// not this class. -const int kLeftShadowWidth = 0; -const int kRightShadowWidth = 0; -const int kTopShadowWidth = 0; -const int kBottomShadowWidth = 6; - -// Optional animation. -const bool kAnimateEnabled = true; - -// The shelf height for the system default font size. It is scaled -// with changes in the default font size. -const int kDefaultShelfHeight = 22; - -// Menu commands -const int kRevokePermissionCommand = 0; - -// Colors -const SkColor kControlBarBackgroundColor = SkColorSetRGB(245, 245, 245); -const SkColor kControlBarTextColor = SkColorSetRGB(125, 125, 125); -const SkColor kControlBarSeparatorLineColor = SkColorSetRGB(180, 180, 180); - -} // namespace - -BalloonViewImpl::BalloonViewImpl(BalloonCollection* collection) - : balloon_(NULL), - collection_(collection), - frame_container_(NULL), - html_container_(NULL), - html_contents_(NULL), - method_factory_(this), - close_button_(NULL), - animation_(NULL), - options_menu_model_(NULL), - options_menu_menu_(NULL), - options_menu_button_(NULL) { - // This object is not to be deleted by the views hierarchy, - // as it is owned by the balloon. - set_parent_owned(false); - - BubbleBorder* bubble_border = new BubbleBorder(BubbleBorder::FLOAT); - set_border(bubble_border); -} - -BalloonViewImpl::~BalloonViewImpl() { -} - -void BalloonViewImpl::Close(bool by_user) { - MessageLoop::current()->PostTask(FROM_HERE, - method_factory_.NewRunnableMethod( - &BalloonViewImpl::DelayedClose, by_user)); -} - -gfx::Size BalloonViewImpl::GetSize() const { - // BalloonView has no size if it hasn't been shown yet (which is when - // balloon_ is set). - if (!balloon_) - return gfx::Size(0, 0); - - return gfx::Size(GetTotalWidth(), GetTotalHeight()); -} - -void BalloonViewImpl::RunMenu(views::View* source, const gfx::Point& pt) { - RunOptionsMenu(pt); -} - -void BalloonViewImpl::DisplayChanged() { - collection_->DisplayChanged(); -} - -void BalloonViewImpl::WorkAreaChanged() { - collection_->DisplayChanged(); -} - -void BalloonViewImpl::ButtonPressed(views::Button* sender, - const views::Event&) { - // The only button currently is the close button. - DCHECK(sender == close_button_); - Close(true); -} - -void BalloonViewImpl::DelayedClose(bool by_user) { - html_contents_->Shutdown(); - html_container_->CloseNow(); - // The BalloonViewImpl has to be detached from frame_container_ now - // because CloseNow on linux/views destroys the view hierachy - // asynchronously. - frame_container_->GetRootView()->RemoveAllChildViews(true); - frame_container_->CloseNow(); - balloon_->OnClose(by_user); -} - -void BalloonViewImpl::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - SizeContentsWindow(); -} - -void BalloonViewImpl::SizeContentsWindow() { - if (!html_container_ || !frame_container_) - return; - - gfx::Rect contents_rect = GetContentsRectangle(); - html_container_->SetBounds(contents_rect); - html_container_->MoveAbove(frame_container_); - - gfx::Path path; - GetContentsMask(contents_rect, &path); - html_container_->SetShape(path.CreateNativeRegion()); - - close_button_->SetBounds(GetCloseButtonBounds()); - options_menu_button_->SetBounds(GetOptionsButtonBounds()); - source_label_->SetBounds(GetLabelBounds()); -} - -void BalloonViewImpl::RepositionToBalloon() { - DCHECK(frame_container_); - DCHECK(html_container_); - DCHECK(balloon_); - - if (!kAnimateEnabled) { - frame_container_->SetBounds( - gfx::Rect(balloon_->GetPosition().x(), balloon_->GetPosition().y(), - GetTotalWidth(), GetTotalHeight())); - gfx::Rect contents_rect = GetContentsRectangle(); - html_container_->SetBounds(contents_rect); - html_contents_->SetPreferredSize(contents_rect.size()); - RenderWidgetHostView* view = html_contents_->render_view_host()->view(); - if (view) - view->SetSize(contents_rect.size()); - return; - } - - anim_frame_end_ = gfx::Rect( - balloon_->GetPosition().x(), balloon_->GetPosition().y(), - GetTotalWidth(), GetTotalHeight()); - frame_container_->GetBounds(&anim_frame_start_, false); - animation_.reset(new SlideAnimation(this)); - animation_->Show(); -} - -void BalloonViewImpl::Update() { - DCHECK(html_contents_.get()) << "BalloonView::Update called before Show"; - if (html_contents_->render_view_host()) - html_contents_->render_view_host()->NavigateToURL( - balloon_->notification().content_url()); -} - -void BalloonViewImpl::AnimationProgressed(const Animation* animation) { - DCHECK(animation == animation_.get()); - - // Linear interpolation from start to end position. - double e = animation->GetCurrentValue(); - double s = (1.0 - e); - - gfx::Rect frame_position( - static_cast<int>(s * anim_frame_start_.x() + - e * anim_frame_end_.x()), - static_cast<int>(s * anim_frame_start_.y() + - e * anim_frame_end_.y()), - static_cast<int>(s * anim_frame_start_.width() + - e * anim_frame_end_.width()), - static_cast<int>(s * anim_frame_start_.height() + - e * anim_frame_end_.height())); - frame_container_->SetBounds(frame_position); - - gfx::Path path; - gfx::Rect contents_rect = GetContentsRectangle(); - html_container_->SetBounds(contents_rect); - GetContentsMask(contents_rect, &path); - html_container_->SetShape(path.CreateNativeRegion()); - - html_contents_->SetPreferredSize(contents_rect.size()); - RenderWidgetHostView* view = html_contents_->render_view_host()->view(); - if (view) - view->SetSize(contents_rect.size()); -} - -gfx::Rect BalloonViewImpl::GetCloseButtonBounds() const { - return gfx::Rect( - width() - kDismissButtonWidth - - kDismissButtonRightMargin - kRightShadowWidth, - kDismissButtonTopMargin, - kDismissButtonWidth, - kDismissButtonHeight); -} - -gfx::Rect BalloonViewImpl::GetOptionsButtonBounds() const { - gfx::Rect close_rect = GetCloseButtonBounds(); - - return gfx::Rect( - close_rect.x() - kOptionsButtonWidth - kOptionsButtonRightMargin, - kOptionsButtonTopMargin, - kOptionsButtonWidth, - kOptionsButtonHeight); -} - -gfx::Rect BalloonViewImpl::GetLabelBounds() const { - return gfx::Rect( - kLeftShadowWidth + kLabelLeftMargin, - kLabelTopMargin, - std::max(0, width() - kOptionsButtonWidth - - kRightMargin), - kOptionsButtonHeight); -} - -void BalloonViewImpl::Show(Balloon* balloon) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - balloon_ = balloon; - - SetBounds(balloon_->GetPosition().x(), balloon_->GetPosition().y(), - GetTotalWidth(), GetTotalHeight()); - - const string16 source_label_text = l10n_util::GetStringFUTF16( - IDS_NOTIFICATION_BALLOON_SOURCE_LABEL, - balloon->notification().display_source()); - - source_label_ = new views::Label(UTF16ToWide(source_label_text)); - AddChildView(source_label_); - options_menu_button_ = new views::MenuButton(NULL, L"", this, false); - AddChildView(options_menu_button_); - close_button_ = new views::ImageButton(this); - close_button_->SetTooltipText(l10n_util::GetString( - IDS_NOTIFICATION_BALLOON_DISMISS_LABEL)); - AddChildView(close_button_); - - // We have to create two windows: one for the contents and one for the - // frame. Why? - // * The contents is an html window which cannot be a - // layered window (because it may have child windows for instance). - // * The frame is a layered window so that we can have nicely rounded - // corners using alpha blending (and we may do other alpha blending - // effects). - // Unfortunately, layered windows cannot have child windows. (Well, they can - // but the child windows don't render). - // - // We carefully keep these two windows in sync to present the illusion of - // one window to the user. - // - // We don't let the OS manage the RTL layout of these widgets, because - // this code is already taking care of correctly reversing the layout. - gfx::Rect contents_rect = GetContentsRectangle(); - html_contents_.reset(new BalloonViewHost(balloon)); - html_contents_->SetPreferredSize(gfx::Size(10000, 10000)); - html_container_ = Widget::CreatePopupWidget(Widget::NotTransparent, - Widget::AcceptEvents, - Widget::DeleteOnDestroy, - Widget::DontMirrorOriginInRTL); - html_container_->SetAlwaysOnTop(true); - html_container_->Init(NULL, contents_rect); - html_container_->SetContentsView(html_contents_->view()); - - gfx::Rect balloon_rect(x(), y(), GetTotalWidth(), GetTotalHeight()); - frame_container_ = Widget::CreatePopupWidget(Widget::Transparent, - Widget::AcceptEvents, - Widget::DeleteOnDestroy, - Widget::DontMirrorOriginInRTL); - frame_container_->SetWidgetDelegate(this); - frame_container_->SetAlwaysOnTop(true); - frame_container_->Init(NULL, balloon_rect); - frame_container_->SetContentsView(this); - frame_container_->MoveAbove(html_container_); - - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_TAB_CLOSE)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_TAB_CLOSE_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_TAB_CLOSE_P)); - close_button_->SetBounds(GetCloseButtonBounds()); - close_button_->SetBackground(SK_ColorBLACK, - rb.GetBitmapNamed(IDR_TAB_CLOSE), - rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK)); - - options_menu_button_->SetIcon(*rb.GetBitmapNamed(IDR_BALLOON_WRENCH)); - options_menu_button_->SetHoverIcon(*rb.GetBitmapNamed(IDR_BALLOON_WRENCH_H)); - options_menu_button_->SetPushedIcon(*rb.GetBitmapNamed(IDR_BALLOON_WRENCH_P)); - options_menu_button_->set_alignment(views::TextButton::ALIGN_CENTER); - options_menu_button_->set_border(NULL); - options_menu_button_->SetBounds(GetOptionsButtonBounds()); - - source_label_->SetFont(rb.GetFont(ResourceBundle::SmallFont)); - source_label_->SetColor(kControlBarTextColor); - source_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - source_label_->SetBounds(GetLabelBounds()); - - SizeContentsWindow(); - html_container_->Show(); - frame_container_->Show(); - - notification_registrar_.Add(this, - NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon)); -} - -void BalloonViewImpl::RunOptionsMenu(const gfx::Point& pt) { - CreateOptionsMenu(); - options_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); -} - -void BalloonViewImpl::CreateOptionsMenu() { - if (options_menu_model_.get()) - return; - - options_menu_model_.reset(new NotificationOptionsMenuModel(balloon_)); - options_menu_menu_.reset(new views::Menu2(options_menu_model_.get())); -} - -void BalloonViewImpl::GetContentsMask(const gfx::Rect& rect, - gfx::Path* path) const { - // This rounds the corners, and we also cut out a circle for the close - // button, since we can't guarantee the ordering of two top-most windows. - SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); - SkScalar spline_radius = radius - - SkScalarMul(radius, (SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3); - SkScalar left = SkIntToScalar(0); - SkScalar top = SkIntToScalar(0); - SkScalar right = SkIntToScalar(rect.width()); - SkScalar bottom = SkIntToScalar(rect.height()); - - path->moveTo(left, top); - path->lineTo(right, top); - path->lineTo(right, bottom - radius); - path->cubicTo(right, bottom - spline_radius, - right - spline_radius, bottom, - right - radius, bottom); - path->lineTo(left + radius, bottom); - path->cubicTo(left + spline_radius, bottom, - left, bottom - spline_radius, - left, bottom - radius); - path->lineTo(left, top); - path->close(); -} - -void BalloonViewImpl::GetFrameMask(const gfx::Rect& rect, - gfx::Path* path) const { - SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); - SkScalar spline_radius = radius - - SkScalarMul(radius, (SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3); - SkScalar left = SkIntToScalar(rect.x()); - SkScalar top = SkIntToScalar(rect.y()); - SkScalar right = SkIntToScalar(rect.right()); - SkScalar bottom = SkIntToScalar(rect.bottom()); - - path->moveTo(left, bottom); - path->lineTo(left, top + radius); - path->cubicTo(left, top + spline_radius, - left + spline_radius, top, - left + radius, top); - path->lineTo(right - radius, top); - path->cubicTo(right - spline_radius, top, - right, top + spline_radius, - right, top + radius); - path->lineTo(right, bottom); - path->lineTo(left, bottom); - path->close(); -} - -gfx::Point BalloonViewImpl::GetContentsOffset() const { - return gfx::Point(kLeftShadowWidth + kLeftMargin, - kTopShadowWidth + kTopMargin); -} - -int BalloonViewImpl::GetShelfHeight() const { - // TODO(johnnyg): add scaling here. - return kDefaultShelfHeight; -} - -int BalloonViewImpl::GetBalloonFrameHeight() const { - return GetTotalHeight() - GetShelfHeight(); -} - -int BalloonViewImpl::GetTotalWidth() const { - return balloon_->content_size().width() - + kLeftMargin + kRightMargin + kLeftShadowWidth + kRightShadowWidth; -} - -int BalloonViewImpl::GetTotalHeight() const { - return balloon_->content_size().height() - + kTopMargin + kBottomMargin + kTopShadowWidth + kBottomShadowWidth - + GetShelfHeight(); -} - -gfx::Rect BalloonViewImpl::GetContentsRectangle() const { - if (!frame_container_) - return gfx::Rect(); - - gfx::Size content_size = balloon_->content_size(); - gfx::Point offset = GetContentsOffset(); - gfx::Rect frame_rect; - frame_container_->GetBounds(&frame_rect, true); - return gfx::Rect(frame_rect.x() + offset.x(), - frame_rect.y() + GetShelfHeight() + offset.y(), - content_size.width(), - content_size.height()); -} - -void BalloonViewImpl::Paint(gfx::Canvas* canvas) { - DCHECK(canvas); - // Paint the menu bar area white, with proper rounded corners. - gfx::Path path; - gfx::Rect rect = GetLocalBounds(false); - rect.set_height(GetShelfHeight()); - GetFrameMask(rect, &path); - - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(kControlBarBackgroundColor); - canvas->AsCanvasSkia()->drawPath(path, paint); - - // Draw a 1-pixel gray line between the content and the menu bar. - int line_width = GetTotalWidth() - kLeftMargin - kRightMargin; - canvas->FillRectInt(kControlBarSeparatorLineColor, - kLeftMargin, 1 + GetShelfHeight(), line_width, 1); - - View::Paint(canvas); - PaintBorder(canvas); -} - -void BalloonViewImpl::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type != NotificationType::NOTIFY_BALLOON_DISCONNECTED) { - NOTREACHED(); - return; - } - - // If the renderer process attached to this balloon is disconnected - // (e.g., because of a crash), we want to close the balloon. - notification_registrar_.Remove(this, - NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon_)); - Close(false); -} diff --git a/chrome/browser/views/notifications/balloon_view.h b/chrome/browser/views/notifications/balloon_view.h index ad4380e..2896feb 100644 --- a/chrome/browser/views/notifications/balloon_view.h +++ b/chrome/browser/views/notifications/balloon_view.h @@ -2,170 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Draws the view for the balloons. - #ifndef CHROME_BROWSER_VIEWS_NOTIFICATIONS_BALLOON_VIEW_H_ #define CHROME_BROWSER_VIEWS_NOTIFICATIONS_BALLOON_VIEW_H_ #pragma once -#include "app/slide_animation.h" -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/task.h" -#include "chrome/browser/notifications/balloon.h" -#include "chrome/browser/views/notifications/balloon_view_host.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "gfx/path.h" -#include "gfx/point.h" -#include "gfx/rect.h" -#include "gfx/size.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/label.h" -#include "views/controls/menu/view_menu_delegate.h" -#include "views/view.h" -#include "views/widget/widget_delegate.h" - -namespace views { -class ButtonListener; -class ImageButton; -class ImagePainter; -class TextButton; -class WidgetWin; -class Menu2; -} // namespace views - -class BalloonCollection; -class NotificationDetails; -class NotificationOptionsMenuModel; -class NotificationSource; - -// A balloon view is the UI component for a desktop notification toasts. -// It draws a border, and within the border an HTML renderer. -class BalloonViewImpl : public BalloonView, - public views::View, - public views::ViewMenuDelegate, - public views::WidgetDelegate, - public views::ButtonListener, - public NotificationObserver, - public AnimationDelegate { - public: - explicit BalloonViewImpl(BalloonCollection* collection); - ~BalloonViewImpl(); - - // BalloonView interface. - virtual void Show(Balloon* balloon); - virtual void Update(); - virtual void RepositionToBalloon(); - virtual void Close(bool by_user); - virtual gfx::Size GetSize() const; - virtual BalloonHost* GetHost() const { return html_contents_.get(); } - - private: - // views::View interface. - virtual void Paint(gfx::Canvas* canvas); - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - virtual gfx::Size GetPreferredSize() { - return gfx::Size(1000, 1000); - } - - // views::ViewMenuDelegate interface. - void RunMenu(views::View* source, const gfx::Point& pt); - - // views::WidgetDelegate interface. - void DisplayChanged(); - void WorkAreaChanged(); - - // views::ButtonListener interface. - virtual void ButtonPressed(views::Button* sender, const views::Event&); - - // NotificationObserver interface. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // AnimationDelegate interface. - virtual void AnimationProgressed(const Animation* animation); - - // Launches the options menu at screen coordinates |pt|. - void RunOptionsMenu(const gfx::Point& pt); - - // Initializes the options menu. - void CreateOptionsMenu(); - - // Masks the contents to fit within the frame. - void GetContentsMask(const gfx::Rect& contents_rect, gfx::Path* path) const; - - // Masks the frame for the rounded corners of the shadow-bubble. - void GetFrameMask(const gfx::Rect&, gfx::Path* path) const; - - // Adjust the contents window size to be appropriate for the frame. - void SizeContentsWindow(); - - // Do the delayed close work. - void DelayedClose(bool by_user); - - // The height of the balloon's shelf. - // The shelf is where is close button is located. - int GetShelfHeight() const; - - // The height of the part of the frame around the balloon. - int GetBalloonFrameHeight() const; - - int GetTotalWidth() const; - int GetTotalHeight() const; - - gfx::Rect GetCloseButtonBounds() const; - gfx::Rect GetOptionsButtonBounds() const; - gfx::Rect GetLabelBounds() const; - - // Where the balloon contents should be placed with respect to the top left - // of the frame. - gfx::Point GetContentsOffset() const; - - // Where the balloon contents should be in screen coordinates. - gfx::Rect GetContentsRectangle() const; - - // Non-owned pointer to the balloon which owns this object. - Balloon* balloon_; - - // Non-owned pointer to the balloon collection this is a part of. - BalloonCollection* collection_; - - // The window that contains the frame of the notification. - // Pointer owned by the View subclass. - views::Widget* frame_container_; - - // The window that contains the contents of the notification. - // Pointer owned by the View subclass. - views::Widget* html_container_; - - // The renderer of the HTML contents. - scoped_ptr<BalloonViewHost> html_contents_; - - // The following factory is used to call methods at a later time. - ScopedRunnableMethodFactory<BalloonViewImpl> method_factory_; - - // Pointer to sub-view is owned by the View sub-class. - views::ImageButton* close_button_; - - // Pointer to sub-view is owned by View class. - views::Label* source_label_; - - // An animation to move the balloon on the screen as its position changes. - scoped_ptr<SlideAnimation> animation_; - gfx::Rect anim_frame_start_; - gfx::Rect anim_frame_end_; - - // The options menu. - scoped_ptr<NotificationOptionsMenuModel> options_menu_model_; - scoped_ptr<views::Menu2> options_menu_menu_; - views::MenuButton* options_menu_button_; - - NotificationRegistrar notification_registrar_; - - DISALLOW_COPY_AND_ASSIGN(BalloonViewImpl); -}; +#include "chrome/browser/ui/views/notifications/balloon_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_NOTIFICATIONS_BALLOON_VIEW_H_ + diff --git a/chrome/browser/views/notifications/balloon_view_host.cc b/chrome/browser/views/notifications/balloon_view_host.cc deleted file mode 100644 index 24a7fe2..0000000 --- a/chrome/browser/views/notifications/balloon_view_host.cc +++ /dev/null @@ -1,92 +0,0 @@ -// 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/notifications/balloon_view_host.h" - -#include "chrome/browser/notifications/balloon.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#if defined(OS_WIN) -#include "chrome/browser/renderer_host/render_widget_host_view_win.h" -#endif -#if defined(OS_LINUX) -#if defined(TOUCH_UI) -#include "chrome/browser/renderer_host/render_widget_host_view_views.h" -#else -#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" -#endif -#endif -#include "views/widget/widget.h" -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#endif -#if defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -class BalloonViewHostView : public views::NativeViewHost { - public: - explicit BalloonViewHostView(BalloonViewHost* host) - : host_(host), - initialized_(false) { - } - - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - NativeViewHost::ViewHierarchyChanged(is_add, parent, child); - if (is_add && GetWidget() && !initialized_) { - host_->Init(GetWidget()->GetNativeView()); - initialized_ = true; - } - } - - private: - // The host owns this object. - BalloonViewHost* host_; - - bool initialized_; -}; - -BalloonViewHost::BalloonViewHost(Balloon* balloon) - : BalloonHost(balloon) { - native_host_ = new BalloonViewHostView(this); -} - -void BalloonViewHost::Init(gfx::NativeView parent_native_view) { - parent_native_view_ = parent_native_view; - BalloonHost::Init(); -} - -void BalloonViewHost::InitRenderWidgetHostView() { - DCHECK(render_view_host_); - - render_widget_host_view_ = - RenderWidgetHostView::CreateViewForWidget(render_view_host_); - - // TODO(johnnyg): http://crbug.com/23954. Need a cross-platform solution. -#if defined(OS_WIN) - RenderWidgetHostViewWin* view_win = - static_cast<RenderWidgetHostViewWin*>(render_widget_host_view_); - - // Create the HWND. - HWND hwnd = view_win->Create(parent_native_view_); - view_win->ShowWindow(SW_SHOW); - native_host_->Attach(hwnd); -#elif defined(OS_LINUX) -#if defined(TOUCH_UI) - RenderWidgetHostViewViews* view_views = - static_cast<RenderWidgetHostViewViews*>(render_widget_host_view_); - view_views->InitAsChild(); - native_host_->Attach(view_views->native_view()); -#else - RenderWidgetHostViewGtk* view_gtk = - static_cast<RenderWidgetHostViewGtk*>(render_widget_host_view_); - view_gtk->InitAsChild(); - native_host_->Attach(view_gtk->native_view()); -#endif -#else - NOTIMPLEMENTED(); -#endif -} diff --git a/chrome/browser/views/notifications/balloon_view_host.h b/chrome/browser/views/notifications/balloon_view_host.h index 94e47e4..2c1a302 100644 --- a/chrome/browser/views/notifications/balloon_view_host.h +++ b/chrome/browser/views/notifications/balloon_view_host.h @@ -6,54 +6,8 @@ #define CHROME_BROWSER_VIEWS_NOTIFICATIONS_BALLOON_VIEW_HOST_H_ #pragma once -#include "chrome/browser/notifications/balloon_host.h" -#include "views/controls/native/native_view_host.h" - -// BalloonViewHost class is a delegate to the renderer host for the HTML -// notification. When initialized it creates a new RenderViewHost and loads -// the contents of the toast into it. It also handles links within the toast, -// loading them into a new tab. -class BalloonViewHost : public BalloonHost { - public: - explicit BalloonViewHost(Balloon* balloon); - - virtual ~BalloonViewHost() { - Shutdown(); - } - - void SetPreferredSize(const gfx::Size& size) { - native_host_->SetPreferredSize(size); - } - - // Accessors. - views::View* view() { - return native_host_; - } - - gfx::NativeView native_view() const { - return native_host_->native_view(); - } - - // Initialize the view, parented to |parent|, and show it. - void Init(gfx::NativeView parent); - - protected: - virtual void InitRenderWidgetHostView(); - virtual RenderWidgetHostView* render_widget_host_view() const { - return render_widget_host_view_; - } - - private: - // The platform-specific widget host view. Pointer is owned by the RVH. - RenderWidgetHostView* render_widget_host_view_; - - // The views-specific host view. Pointer owned by the views hierarchy. - views::NativeViewHost* native_host_; - - // The handle to the parent view. - gfx::NativeView parent_native_view_; - - DISALLOW_COPY_AND_ASSIGN(BalloonViewHost); -}; +#include "chrome/browser/ui/views/notifications/balloon_view_host.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_NOTIFICATIONS_BALLOON_VIEW_HOST_H_ + diff --git a/chrome/browser/views/options/advanced_contents_view.cc b/chrome/browser/views/options/advanced_contents_view.cc deleted file mode 100644 index b8513b6..0000000 --- a/chrome/browser/views/options/advanced_contents_view.cc +++ /dev/null @@ -1,1725 +0,0 @@ -// 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/options/advanced_contents_view.h" - -#include <windows.h> - -#include <cryptuiapi.h> -#pragma comment(lib, "cryptui.lib") -#include <shellapi.h> -#include <vsstyle.h> -#include <vssym32.h> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/command_line.h" -#include "base/file_util.h" -#include "base/i18n/rtl.h" -#include "base/message_loop.h" -#include "base/path_service.h" -#include "base/scoped_callback_factory.h" -#include "base/thread.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/download/download_manager.h" -#include "chrome/browser/download/download_prefs.h" -#include "chrome/browser/gears_integration.h" -#include "chrome/browser/options_util.h" -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/prefs/pref_set_observer.h" -#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" -#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" -#include "chrome/browser/printing/cloud_print/cloud_print_url.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/resource_dispatcher_host.h" -#include "chrome/browser/safe_browsing/safe_browsing_service.h" -#include "chrome/browser/shell_dialogs.h" -#include "chrome/browser/show_options_url.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "chrome/browser/views/clear_browsing_data.h" -#include "chrome/browser/views/list_background.h" -#include "chrome/browser/views/options/content_settings_window_view.h" -#include "chrome/browser/views/options/fonts_languages_window_view.h" -#include "chrome/browser/views/restart_message_box.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas_skia.h" -#include "gfx/native_theme_win.h" -#include "grit/app_resources.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/base/ssl_config_service_win.h" -#include "skia/ext/skia_utils_win.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "views/background.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/scroll_view.h" -#include "views/controls/textfield/textfield.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -using views::GridLayout; -using views::ColumnSet; - -namespace { - -const int kFileIconSize = 16; -const int kFileIconVerticalSpacing = 3; -const int kFileIconHorizontalSpacing = 3; -const int kFileIconTextFieldSpacing = 3; - -//////////////////////////////////////////////////////////////////////////////// -// FileDisplayArea - -class FileDisplayArea : public views::View { - public: - FileDisplayArea(); - virtual ~FileDisplayArea(); - - void SetFile(const FilePath& file_path); - - // views::View overrides: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - private: - void Init(); - - views::Textfield* text_field_; - SkColor text_field_background_color_; - - gfx::Rect icon_bounds_; - - bool initialized_; - - static void InitClass(); - static SkBitmap default_folder_icon_; - - DISALLOW_COPY_AND_ASSIGN(FileDisplayArea); -}; - -// static -SkBitmap FileDisplayArea::default_folder_icon_; - -FileDisplayArea::FileDisplayArea() - : text_field_(new views::Textfield), - text_field_background_color_(0), - initialized_(false) { - InitClass(); -} - -FileDisplayArea::~FileDisplayArea() { -} - -void FileDisplayArea::SetFile(const FilePath& file_path) { - // Force file path to have LTR directionality. - if (base::i18n::IsRTL()) { - string16 localized_file_path; - base::i18n::WrapPathWithLTRFormatting(file_path, &localized_file_path); - text_field_->SetText(UTF16ToWide(localized_file_path)); - } else { - text_field_->SetText(file_path.ToWStringHack()); - } -} - -void FileDisplayArea::Paint(gfx::Canvas* canvas) { - HDC dc = canvas->BeginPlatformPaint(); - RECT rect = { 0, 0, width(), height() }; - gfx::NativeTheme::instance()->PaintTextField( - dc, EP_EDITTEXT, ETS_READONLY, 0, &rect, - skia::SkColorToCOLORREF(text_field_background_color_), true, true); - canvas->EndPlatformPaint(); - // Mirror left point for icon_bounds_ to draw icon in RTL locales correctly. - canvas->DrawBitmapInt(default_folder_icon_, - MirroredLeftPointForRect(icon_bounds_), - icon_bounds_.y()); -} - -void FileDisplayArea::Layout() { - icon_bounds_.SetRect(kFileIconHorizontalSpacing, kFileIconVerticalSpacing, - kFileIconSize, kFileIconSize); - gfx::Size ps = text_field_->GetPreferredSize(); - text_field_->SetBounds(icon_bounds_.right() + kFileIconTextFieldSpacing, - (height() - ps.height()) / 2, - width() - icon_bounds_.right() - - kFileIconHorizontalSpacing - - kFileIconTextFieldSpacing, ps.height()); -} - -gfx::Size FileDisplayArea::GetPreferredSize() { - return gfx::Size(kFileIconSize + 2 * kFileIconVerticalSpacing, - kFileIconSize + 2 * kFileIconHorizontalSpacing); -} - -void FileDisplayArea::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (!initialized_ && is_add && GetWidget()) - Init(); -} - -void FileDisplayArea::Init() { - initialized_ = true; - AddChildView(text_field_); - text_field_background_color_ = - gfx::NativeTheme::instance()->GetThemeColorWithDefault( - gfx::NativeTheme::TEXTFIELD, EP_EDITTEXT, ETS_READONLY, - TMT_FILLCOLOR, COLOR_3DFACE); - text_field_->SetReadOnly(true); - text_field_->RemoveBorder(); - text_field_->SetBackgroundColor(text_field_background_color_); -} - -// static -void FileDisplayArea::InitClass() { - static bool initialized = false; - if (!initialized) { - // We'd prefer to use base::i18n::IsRTL() to perform the RTL - // environment check, but it's nonstatic, so, instead, we check whether the - // locale is RTL. - bool ui_is_rtl = base::i18n::IsRTL(); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - default_folder_icon_ = *rb.GetBitmapNamed(ui_is_rtl ? - IDR_FOLDER_CLOSED_RTL : - IDR_FOLDER_CLOSED); - initialized = true; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedSection -// A convenience view for grouping advanced options together into related -// sections. -// -class AdvancedSection : public OptionsPageView { - public: - AdvancedSection(Profile* profile, const std::wstring& title); - virtual ~AdvancedSection() {} - - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - - protected: - // Convenience helpers to add different kinds of ColumnSets for specific - // types of layout. - void AddWrappingColumnSet(views::GridLayout* layout, int id); - void AddDependentTwoColumnSet(views::GridLayout* layout, int id); - void AddTwoColumnSet(views::GridLayout* layout, int id); - void AddIndentedColumnSet(views::GridLayout* layout, int id); - - // Convenience helpers for adding controls to specific layouts in an - // aesthetically pleasing way. - void AddWrappingCheckboxRow(views::GridLayout* layout, - views::Checkbox* checkbox, - int id, - bool related_follows); - void AddWrappingLabelRow(views::GridLayout* layout, - views::Label* label, - int id, - bool related_follows); - void AddLabeledTwoColumnRow(views::GridLayout* layout, - views::Label* label, - views::View* control, - bool control_stretches, - int id, - bool related_follows); - void AddTwoColumnRow(views::GridLayout* layout, - views::View* first, - views::View* second, - bool control_stretches, // Whether or not the control - // expands to fill the width. - int id, - int trailing_space); - void AddLeadingControl(views::GridLayout* layout, - views::View* control, - int id, - bool related_follows); - void AddIndentedControl(views::GridLayout* layout, - views::View* control, - int id, - bool related_follows); - void AddSpacing(views::GridLayout* layout, bool related_follows); - - // OptionsPageView overrides: - virtual void InitControlLayout(); - - // The View that contains the contents of the section. - views::View* contents_; - - private: - // The section title. - views::Label* title_label_; - - DISALLOW_COPY_AND_ASSIGN(AdvancedSection); -}; - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedSection, public: - -AdvancedSection::AdvancedSection(Profile* profile, - const std::wstring& title) - : contents_(NULL), - title_label_(new views::Label(title)), - OptionsPageView(profile) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - gfx::Font title_font = - rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); - title_label_->SetFont(title_font); - - SkColor title_color = gfx::NativeTheme::instance()->GetThemeColorWithDefault( - gfx::NativeTheme::BUTTON, BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, - COLOR_WINDOWTEXT); - title_label_->SetColor(title_color); -} - -void AdvancedSection::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - Layout(); -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedSection, protected: - -void AdvancedSection::AddWrappingColumnSet(views::GridLayout* layout, int id) { - ColumnSet* column_set = layout->AddColumnSet(id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); -} - -void AdvancedSection::AddDependentTwoColumnSet(views::GridLayout* layout, - int id) { - ColumnSet* column_set = layout->AddColumnSet(id); - column_set->AddPaddingColumn(0, views::Checkbox::GetTextIndent()); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing); -} - -void AdvancedSection::AddTwoColumnSet(views::GridLayout* layout, int id) { - ColumnSet* column_set = layout->AddColumnSet(id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); -} - -void AdvancedSection::AddIndentedColumnSet(views::GridLayout* layout, int id) { - ColumnSet* column_set = layout->AddColumnSet(id); - column_set->AddPaddingColumn(0, views::Checkbox::GetTextIndent()); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); -} - -void AdvancedSection::AddWrappingCheckboxRow(views::GridLayout* layout, - views::Checkbox* checkbox, - int id, - bool related_follows) { - checkbox->SetMultiLine(true); - layout->StartRow(0, id); - layout->AddView(checkbox); - AddSpacing(layout, related_follows); -} - -void AdvancedSection::AddWrappingLabelRow(views::GridLayout* layout, - views::Label* label, - int id, - bool related_follows) { - label->SetMultiLine(true); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->StartRow(0, id); - layout->AddView(label); - AddSpacing(layout, related_follows); -} - -void AdvancedSection::AddLabeledTwoColumnRow(views::GridLayout* layout, - views::Label* label, - views::View* control, - bool control_stretches, - int id, - bool related_follows) { - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddTwoColumnRow(layout, label, control, control_stretches, id, - related_follows ? - kRelatedControlVerticalSpacing : kUnrelatedControlVerticalSpacing); -} - -void AdvancedSection::AddTwoColumnRow(views::GridLayout* layout, - views::View* first, - views::View* second, - bool control_stretches, - int id, - int trailing_space) { - layout->StartRow(0, id); - layout->AddView(first); - if (control_stretches) { - layout->AddView(second); - } else { - layout->AddView(second, 1, 1, views::GridLayout::LEADING, - views::GridLayout::CENTER); - } - layout->AddPaddingRow(0, trailing_space); -} - -void AdvancedSection::AddLeadingControl(views::GridLayout* layout, - views::View* control, - int id, - bool related_follows) { - layout->StartRow(0, id); - layout->AddView(control, 1, 1, GridLayout::LEADING, GridLayout::CENTER); - AddSpacing(layout, related_follows); -} - -void AdvancedSection::AddSpacing(views::GridLayout* layout, - bool related_follows) { - layout->AddPaddingRow(0, related_follows ? kRelatedControlVerticalSpacing - : kUnrelatedControlVerticalSpacing); -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedSection, OptionsPageView overrides: - -void AdvancedSection::InitControlLayout() { - contents_ = new views::View; - - GridLayout* layout = new GridLayout(this); - SetLayoutManager(layout); - - const int single_column_layout_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, - GridLayout::USE_PREF, 0, 0); - const int inset_column_layout_id = 1; - column_set = layout->AddColumnSet(inset_column_layout_id); - column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_layout_id); - layout->AddView(title_label_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, inset_column_layout_id); - layout->AddView(contents_); -} - -//////////////////////////////////////////////////////////////////////////////// -// PrivacySection - -class PrivacySection : public AdvancedSection, - public views::ButtonListener, - public views::LinkController { - public: - explicit PrivacySection(Profile* profile); - virtual ~PrivacySection() {} - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - protected: - // OptionsPageView overrides: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - // Controls for this section: - views::NativeButton* content_settings_button_; - views::NativeButton* clear_data_button_; - views::Label* section_description_label_; - views::Checkbox* enable_link_doctor_checkbox_; - views::Checkbox* enable_suggest_checkbox_; - views::Checkbox* enable_dns_prefetching_checkbox_; - views::Checkbox* enable_safe_browsing_checkbox_; - views::Checkbox* reporting_enabled_checkbox_; - views::Link* learn_more_link_; - - // Preferences for this section: - BooleanPrefMember alternate_error_pages_; - BooleanPrefMember use_suggest_; - BooleanPrefMember dns_prefetch_enabled_; - BooleanPrefMember safe_browsing_; - BooleanPrefMember enable_metrics_recording_; - - void ResolveMetricsReportingEnabled(); - - DISALLOW_COPY_AND_ASSIGN(PrivacySection); -}; - -PrivacySection::PrivacySection(Profile* profile) - : content_settings_button_(NULL), - clear_data_button_(NULL), - section_description_label_(NULL), - enable_link_doctor_checkbox_(NULL), - enable_suggest_checkbox_(NULL), - enable_dns_prefetching_checkbox_(NULL), - enable_safe_browsing_checkbox_(NULL), - reporting_enabled_checkbox_(NULL), - learn_more_link_(NULL), - AdvancedSection(profile, - l10n_util::GetString(IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY)) { -} - -void PrivacySection::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == enable_link_doctor_checkbox_) { - bool enabled = enable_link_doctor_checkbox_->checked(); - UserMetricsRecordAction(UserMetricsAction(enabled ? - "Options_LinkDoctorCheckbox_Enable" : - "Options_LinkDoctorCheckbox_Disable"), - profile()->GetPrefs()); - alternate_error_pages_.SetValue(enabled); - } else if (sender == enable_suggest_checkbox_) { - bool enabled = enable_suggest_checkbox_->checked(); - UserMetricsRecordAction(UserMetricsAction(enabled ? - "Options_UseSuggestCheckbox_Enable" : - "Options_UseSuggestCheckbox_Disable"), - profile()->GetPrefs()); - use_suggest_.SetValue(enabled); - } else if (sender == enable_dns_prefetching_checkbox_) { - bool enabled = enable_dns_prefetching_checkbox_->checked(); - UserMetricsRecordAction(UserMetricsAction(enabled ? - "Options_DnsPrefetchCheckbox_Enable" : - "Options_DnsPrefetchCheckbox_Disable"), - profile()->GetPrefs()); - dns_prefetch_enabled_.SetValue(enabled); - } else if (sender == enable_safe_browsing_checkbox_) { - bool enabled = enable_safe_browsing_checkbox_->checked(); - UserMetricsRecordAction(UserMetricsAction(enabled ? - "Options_SafeBrowsingCheckbox_Enable" : - "Options_SafeBrowsingCheckbox_Disable"), - profile()->GetPrefs()); - safe_browsing_.SetValue(enabled); - SafeBrowsingService* safe_browsing_service = - g_browser_process->resource_dispatcher_host()->safe_browsing_service(); - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - safe_browsing_service, &SafeBrowsingService::OnEnable, enabled)); - } else if (reporting_enabled_checkbox_ && - (sender == reporting_enabled_checkbox_)) { - bool enabled = reporting_enabled_checkbox_->checked(); - UserMetricsRecordAction(UserMetricsAction(enabled ? - "Options_MetricsReportingCheckbox_Enable" : - "Options_MetricsReportingCheckbox_Disable"), - profile()->GetPrefs()); - ResolveMetricsReportingEnabled(); - if (enabled == reporting_enabled_checkbox_->checked()) - RestartMessageBox::ShowMessageBox(GetWindow()->GetNativeWindow()); - enable_metrics_recording_.SetValue(enabled); - } else if (sender == content_settings_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ContentSettings"), NULL); - browser::ShowContentSettingsWindow(GetWindow()->GetNativeWindow(), - CONTENT_SETTINGS_TYPE_DEFAULT, profile()); - } else if (sender == clear_data_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ClearData"), NULL); - views::Window::CreateChromeWindow( - GetWindow()->GetNativeWindow(), - gfx::Rect(), - new ClearBrowsingDataView(profile()))->Show(); - } -} - -void PrivacySection::LinkActivated(views::Link* source, int event_flags) { - DCHECK(source == learn_more_link_); - browser::ShowOptionsURL( - profile(), - GURL(l10n_util::GetString(IDS_LEARN_MORE_PRIVACY_URL))); -} - -void PrivacySection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - content_settings_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_PRIVACY_CONTENT_SETTINGS_BUTTON)); - clear_data_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_PRIVACY_CLEAR_DATA_BUTTON)); - section_description_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_DISABLE_SERVICES)); - enable_link_doctor_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_LINKDOCTOR_PREF)); - enable_link_doctor_checkbox_->set_listener(this); - enable_suggest_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_SUGGEST_PREF)); - enable_suggest_checkbox_->set_listener(this); - enable_dns_prefetching_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_NETWORK_DNS_PREFETCH_ENABLED_DESCRIPTION)); - enable_dns_prefetching_checkbox_->set_listener(this); - enable_safe_browsing_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_SAFEBROWSING_ENABLEPROTECTION)); - enable_safe_browsing_checkbox_->set_listener(this); -#if defined(GOOGLE_CHROME_BUILD) - reporting_enabled_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_ENABLE_LOGGING)); - reporting_enabled_checkbox_->SetMultiLine(true); - reporting_enabled_checkbox_->set_listener(this); - reporting_enabled_checkbox_->SetVisible(true); -#endif - learn_more_link_ = new views::Link(l10n_util::GetString(IDS_LEARN_MORE)); - learn_more_link_->SetController(this); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - const int leading_column_set_id = 0; - AddTwoColumnSet(layout, leading_column_set_id); - const int single_column_view_set_id = 1; - AddWrappingColumnSet(layout, single_column_view_set_id); - const int dependent_labeled_field_set_id = 2; - AddDependentTwoColumnSet(layout, dependent_labeled_field_set_id); - const int indented_view_set_id = 3; - AddIndentedColumnSet(layout, indented_view_set_id); - const int indented_column_set_id = 4; - AddIndentedColumnSet(layout, indented_column_set_id); - - AddTwoColumnRow(layout, content_settings_button_, clear_data_button_, false, - leading_column_set_id, kUnrelatedControlLargeVerticalSpacing); - - // The description label at the top and label. - section_description_label_->SetMultiLine(true); - AddWrappingLabelRow(layout, section_description_label_, - single_column_view_set_id, true); - // Learn more link. - AddLeadingControl(layout, learn_more_link_, - single_column_view_set_id, true); - - // Link doctor. - AddWrappingCheckboxRow(layout, enable_link_doctor_checkbox_, - indented_view_set_id, true); - // Use Suggest service. - AddWrappingCheckboxRow(layout, enable_suggest_checkbox_, - indented_view_set_id, true); - // DNS pre-fetching. - AddWrappingCheckboxRow(layout, enable_dns_prefetching_checkbox_, - indented_view_set_id, true); - // Safe browsing controls. - AddWrappingCheckboxRow(layout, enable_safe_browsing_checkbox_, - indented_view_set_id, - reporting_enabled_checkbox_ != NULL); - // The "Help make Google Chrome better" checkbox. - if (reporting_enabled_checkbox_) { - AddWrappingCheckboxRow(layout, reporting_enabled_checkbox_, - indented_view_set_id, false); - } - - // Init member prefs so we can update the controls if prefs change. - alternate_error_pages_.Init(prefs::kAlternateErrorPagesEnabled, - profile()->GetPrefs(), this); - use_suggest_.Init(prefs::kSearchSuggestEnabled, - profile()->GetPrefs(), this); - dns_prefetch_enabled_.Init(prefs::kDnsPrefetchingEnabled, - profile()->GetPrefs(), this); - safe_browsing_.Init(prefs::kSafeBrowsingEnabled, profile()->GetPrefs(), this); - enable_metrics_recording_.Init(prefs::kMetricsReportingEnabled, - g_browser_process->local_state(), this); -} - -void PrivacySection::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kAlternateErrorPagesEnabled) { - enable_link_doctor_checkbox_->SetEnabled( - !alternate_error_pages_.IsManaged()); - enable_link_doctor_checkbox_->SetChecked( - alternate_error_pages_.GetValue()); - } - if (!pref_name || *pref_name == prefs::kSearchSuggestEnabled) { - enable_suggest_checkbox_->SetEnabled(!use_suggest_.IsManaged()); - enable_suggest_checkbox_->SetChecked(use_suggest_.GetValue()); - } - if (!pref_name || *pref_name == prefs::kDnsPrefetchingEnabled) { - enable_dns_prefetching_checkbox_->SetEnabled( - !dns_prefetch_enabled_.IsManaged()); - bool enabled = dns_prefetch_enabled_.GetValue(); - enable_dns_prefetching_checkbox_->SetChecked(enabled); - } - if (!pref_name || *pref_name == prefs::kSafeBrowsingEnabled) { - enable_safe_browsing_checkbox_->SetEnabled(!safe_browsing_.IsManaged()); - enable_safe_browsing_checkbox_->SetChecked(safe_browsing_.GetValue()); - } - if (reporting_enabled_checkbox_ && - (!pref_name || *pref_name == prefs::kMetricsReportingEnabled)) { - reporting_enabled_checkbox_->SetEnabled( - !enable_metrics_recording_.IsManaged()); - reporting_enabled_checkbox_->SetChecked( - enable_metrics_recording_.GetValue()); - ResolveMetricsReportingEnabled(); - } -} - -void PrivacySection::ResolveMetricsReportingEnabled() { - DCHECK(reporting_enabled_checkbox_); - bool enabled = reporting_enabled_checkbox_->checked(); - - enabled = OptionsUtil::ResolveMetricsReportingEnabled(enabled); - - reporting_enabled_checkbox_->SetChecked(enabled); -} - -//////////////////////////////////////////////////////////////////////////////// -// WebContentSection - -class WebContentSection : public AdvancedSection, - public views::ButtonListener { - public: - explicit WebContentSection(Profile* profile); - virtual ~WebContentSection() {} - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - protected: - // OptionsPageView overrides: - virtual void InitControlLayout(); - - private: - // Controls for this section: - views::Label* fonts_and_languages_label_; - views::NativeButton* change_content_fonts_button_; - views::Label* gears_label_; - views::NativeButton* gears_settings_button_; - - DISALLOW_COPY_AND_ASSIGN(WebContentSection); -}; - -WebContentSection::WebContentSection(Profile* profile) - : fonts_and_languages_label_(NULL), - change_content_fonts_button_(NULL), - gears_label_(NULL), - gears_settings_button_(NULL), - AdvancedSection(profile, - l10n_util::GetString(IDS_OPTIONS_ADVANCED_SECTION_TITLE_CONTENT)) { -} - -void WebContentSection::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == gears_settings_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_GearsSettings"), NULL); - GearsSettingsPressed(GetAncestor(GetWidget()->GetNativeView(), GA_ROOT)); - } else if (sender == change_content_fonts_button_) { - views::Window::CreateChromeWindow( - GetWindow()->GetNativeWindow(), - gfx::Rect(), - new FontsLanguagesWindowView(profile()))->Show(); - } -} - -void WebContentSection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - if (!base::i18n::IsRTL()) { - gears_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_GEARSSETTINGS_GROUP_NAME)); - } else { - // Add an RTL mark so that - // ":" in "Google Gears:" in Hebrew Chrome is displayed left-most. - std::wstring gearssetting_group_name = - l10n_util::GetString(IDS_OPTIONS_GEARSSETTINGS_GROUP_NAME); - gearssetting_group_name.push_back( - static_cast<wchar_t>(base::i18n::kRightToLeftMark)); - gears_label_ = new views::Label(gearssetting_group_name); - } - gears_settings_button_ = new views::NativeButton( - this, - l10n_util::GetString(IDS_OPTIONS_GEARSSETTINGS_CONFIGUREGEARS_BUTTON)); - fonts_and_languages_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_FONTSETTINGS_INFO)); - - change_content_fonts_button_ = new views::NativeButton( - this, - l10n_util::GetString(IDS_OPTIONS_FONTSETTINGS_CONFIGUREFONTS_BUTTON)); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - AddWrappingColumnSet(layout, single_column_view_set_id); - const int indented_column_set_id = 1; - AddIndentedColumnSet(layout, indented_column_set_id); - const int single_double_column_set = 2; - AddTwoColumnSet(layout, single_double_column_set); - - // Fonts and Languages. - AddWrappingLabelRow(layout, fonts_and_languages_label_, - single_column_view_set_id, - true); - AddLeadingControl(layout, change_content_fonts_button_, - indented_column_set_id, - false); - - // Gears. - AddLabeledTwoColumnRow(layout, gears_label_, gears_settings_button_, false, - single_double_column_set, false); -} - -//////////////////////////////////////////////////////////////////////////////// -// SecuritySection - -class SecuritySection : public AdvancedSection, - public views::ButtonListener { - public: - explicit SecuritySection(Profile* profile); - virtual ~SecuritySection() {} - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - protected: - // OptionsPageView overrides: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - // Controls for this section: - views::Label* ssl_info_label_; - views::Checkbox* enable_ssl2_checkbox_; - views::Checkbox* enable_ssl3_checkbox_; - views::Checkbox* enable_tls1_checkbox_; - views::Checkbox* check_for_cert_revocation_checkbox_; - views::Label* manage_certificates_label_; - views::NativeButton* manage_certificates_button_; - - DISALLOW_COPY_AND_ASSIGN(SecuritySection); -}; - -SecuritySection::SecuritySection(Profile* profile) - : ssl_info_label_(NULL), - enable_ssl2_checkbox_(NULL), - enable_ssl3_checkbox_(NULL), - enable_tls1_checkbox_(NULL), - check_for_cert_revocation_checkbox_(NULL), - manage_certificates_label_(NULL), - manage_certificates_button_(NULL), - AdvancedSection(profile, - l10n_util::GetString(IDS_OPTIONS_ADVANCED_SECTION_TITLE_SECURITY)) { -} - -void SecuritySection::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == enable_ssl2_checkbox_) { - bool enabled = enable_ssl2_checkbox_->checked(); - if (enabled) { - UserMetricsRecordAction(UserMetricsAction("Options_SSL2_Enable"), NULL); - } else { - UserMetricsRecordAction(UserMetricsAction("Options_SSL2_Disable"), NULL); - } - net::SSLConfigServiceWin::SetSSL2Enabled(enabled); - } else if (sender == enable_ssl3_checkbox_) { - bool enabled = enable_ssl3_checkbox_->checked(); - if (enabled) { - UserMetricsRecordAction(UserMetricsAction("Options_SSL3_Enable"), NULL); - } else { - UserMetricsRecordAction(UserMetricsAction("Options_SSL3_Disable"), NULL); - } - net::SSLConfigServiceWin::SetSSL3Enabled(enabled); - } else if (sender == enable_tls1_checkbox_) { - bool enabled = enable_tls1_checkbox_->checked(); - if (enabled) { - UserMetricsRecordAction(UserMetricsAction("Options_TLS1_Enable"), NULL); - } else { - UserMetricsRecordAction(UserMetricsAction("Options_TLS1_Disable"), NULL); - } - net::SSLConfigServiceWin::SetTLS1Enabled(enabled); - } else if (sender == check_for_cert_revocation_checkbox_) { - bool enabled = check_for_cert_revocation_checkbox_->checked(); - if (enabled) { - UserMetricsRecordAction( - UserMetricsAction("Options_CheckCertRevocation_Enable"), NULL); - } else { - UserMetricsRecordAction( - UserMetricsAction("Options_CheckCertRevocation_Disable"), NULL); - } - net::SSLConfigServiceWin::SetRevCheckingEnabled(enabled); - } else if (sender == manage_certificates_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ManagerCerts"), NULL); - CRYPTUI_CERT_MGR_STRUCT cert_mgr = { 0 }; - cert_mgr.dwSize = sizeof(CRYPTUI_CERT_MGR_STRUCT); - cert_mgr.hwndParent = GetWindow()->GetNativeWindow(); - ::CryptUIDlgCertMgr(&cert_mgr); - } -} - -void SecuritySection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - ssl_info_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_SSL_GROUP_DESCRIPTION)); - enable_ssl2_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_SSL_USESSL2)); - enable_ssl2_checkbox_->set_listener(this); - enable_ssl3_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_SSL_USESSL3)); - enable_ssl3_checkbox_->set_listener(this); - enable_tls1_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_SSL_USETLS1)); - enable_tls1_checkbox_->set_listener(this); - check_for_cert_revocation_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_SSL_CHECKREVOCATION)); - check_for_cert_revocation_checkbox_->set_listener(this); - manage_certificates_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_CERTIFICATES_LABEL)); - manage_certificates_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_CERTIFICATES_MANAGE_BUTTON)); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - AddWrappingColumnSet(layout, single_column_view_set_id); - const int dependent_labeled_field_set_id = 1; - AddDependentTwoColumnSet(layout, dependent_labeled_field_set_id); - const int double_column_view_set_id = 2; - AddTwoColumnSet(layout, double_column_view_set_id); - const int indented_column_set_id = 3; - AddIndentedColumnSet(layout, indented_column_set_id); - const int indented_view_set_id = 4; - AddIndentedColumnSet(layout, indented_view_set_id); - - // SSL connection controls and Certificates. - AddWrappingLabelRow(layout, manage_certificates_label_, - single_column_view_set_id, true); - AddLeadingControl(layout, manage_certificates_button_, - indented_column_set_id, false); - AddWrappingLabelRow(layout, ssl_info_label_, single_column_view_set_id, - true); - AddWrappingCheckboxRow(layout, enable_ssl2_checkbox_, - indented_column_set_id, true); - AddWrappingCheckboxRow(layout, enable_ssl3_checkbox_, - indented_column_set_id, true); - AddWrappingCheckboxRow(layout, enable_tls1_checkbox_, - indented_column_set_id, true); - AddWrappingCheckboxRow(layout, check_for_cert_revocation_checkbox_, - indented_column_set_id, false); -} - -// This method is called with a null pref_name when the dialog is initialized. -void SecuritySection::NotifyPrefChanged(const std::string* pref_name) { - // These SSL options are system settings and stored in the OS. - if (!pref_name) { - net::SSLConfig config; - if (net::SSLConfigServiceWin::GetSSLConfigNow(&config)) { - enable_ssl2_checkbox_->SetChecked(config.ssl2_enabled); - enable_ssl3_checkbox_->SetChecked(config.ssl3_enabled); - enable_tls1_checkbox_->SetChecked(config.tls1_enabled); - check_for_cert_revocation_checkbox_->SetChecked( - config.rev_checking_enabled); - } else { - enable_ssl2_checkbox_->SetEnabled(false); - enable_ssl3_checkbox_->SetEnabled(false); - enable_tls1_checkbox_->SetEnabled(false); - check_for_cert_revocation_checkbox_->SetEnabled(false); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NetworkSection - -// A helper method that opens the Internet Options control panel dialog with -// the Connections tab selected. -class OpenConnectionDialogTask : public Task { - public: - OpenConnectionDialogTask() {} - - virtual void Run() { - // Using rundll32 seems better than LaunchConnectionDialog which causes a - // new dialog to be made for each call. rundll32 uses the same global - // dialog and it seems to share with the shortcut in control panel. - FilePath rundll32; - PathService::Get(base::DIR_SYSTEM, &rundll32); - rundll32 = rundll32.AppendASCII("rundll32.exe"); - - FilePath shell32dll; - PathService::Get(base::DIR_SYSTEM, &shell32dll); - shell32dll = shell32dll.AppendASCII("shell32.dll"); - - FilePath inetcpl; - PathService::Get(base::DIR_SYSTEM, &inetcpl); - inetcpl = inetcpl.AppendASCII("inetcpl.cpl,,4"); - - std::wstring args(shell32dll.value()); - args.append(L",Control_RunDLL "); - args.append(inetcpl.value()); - - ShellExecute(NULL, L"open", rundll32.value().c_str(), args.c_str(), NULL, - SW_SHOWNORMAL); - } - - private: - DISALLOW_COPY_AND_ASSIGN(OpenConnectionDialogTask); -}; - -class NetworkSection : public AdvancedSection, - public views::ButtonListener { - public: - explicit NetworkSection(Profile* profile); - virtual ~NetworkSection() {} - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - protected: - // OptionsPageView overrides: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - // Controls for this section: - views::Label* change_proxies_label_; - views::NativeButton* change_proxies_button_; - - // Tracks the proxy preferences. - scoped_ptr<PrefSetObserver> proxy_prefs_; - - DISALLOW_COPY_AND_ASSIGN(NetworkSection); -}; - -NetworkSection::NetworkSection(Profile* profile) - : change_proxies_label_(NULL), - change_proxies_button_(NULL), - AdvancedSection(profile, - l10n_util::GetString(IDS_OPTIONS_ADVANCED_SECTION_TITLE_NETWORK)) { -} - -void NetworkSection::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == change_proxies_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ChangeProxies"), NULL); - base::Thread* thread = g_browser_process->file_thread(); - DCHECK(thread); - thread->message_loop()->PostTask(FROM_HERE, new OpenConnectionDialogTask); - } -} - -void NetworkSection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - change_proxies_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_PROXIES_LABEL)); - change_proxies_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON)); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - AddWrappingColumnSet(layout, single_column_view_set_id); - const int indented_view_set_id = 1; - AddIndentedColumnSet(layout, indented_view_set_id); - const int dependent_labeled_field_set_id = 2; - AddDependentTwoColumnSet(layout, dependent_labeled_field_set_id); - const int dns_set_id = 3; - AddDependentTwoColumnSet(layout, dns_set_id); - - // Proxy settings. - AddWrappingLabelRow(layout, change_proxies_label_, single_column_view_set_id, - true); - AddLeadingControl(layout, change_proxies_button_, indented_view_set_id, - false); - - proxy_prefs_.reset(PrefSetObserver::CreateProxyPrefSetObserver( - profile()->GetPrefs(), this)); - NotifyPrefChanged(NULL); -} - -void NetworkSection::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || proxy_prefs_->IsObserved(*pref_name)) { - change_proxies_button_->SetEnabled(!proxy_prefs_->IsManaged()); - } -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// DownloadSection - -class DownloadSection : public AdvancedSection, - public views::ButtonListener, - public SelectFileDialog::Listener { - public: - explicit DownloadSection(Profile* profile); - virtual ~DownloadSection() { - select_file_dialog_->ListenerDestroyed(); - } - - // Overridden from views::ButtonListener. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // SelectFileDialog::Listener implementation. - virtual void FileSelected(const FilePath& path, int index, void* params); - - // OptionsPageView implementation. - virtual bool CanClose() const; - - protected: - // OptionsPageView overrides. - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - // Controls for this section. - views::Label* download_file_location_label_; - FileDisplayArea* download_default_download_location_display_; - views::NativeButton* download_browse_button_; - views::Checkbox* download_ask_for_save_location_checkbox_; - scoped_refptr<SelectFileDialog> select_file_dialog_; - views::Label* reset_file_handlers_label_; - views::NativeButton* reset_file_handlers_button_; - - // Pref members. - FilePathPrefMember default_download_location_; - BooleanPrefMember ask_for_save_location_; - - // Updates the directory displayed in the default download location view with - // the current value of the pref. - void UpdateDownloadDirectoryDisplay(); - - StringPrefMember auto_open_files_; - - DISALLOW_COPY_AND_ASSIGN(DownloadSection); -}; - -DownloadSection::DownloadSection(Profile* profile) - : download_file_location_label_(NULL), - download_default_download_location_display_(NULL), - download_browse_button_(NULL), - download_ask_for_save_location_checkbox_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST( - select_file_dialog_(SelectFileDialog::Create(this))), - reset_file_handlers_label_(NULL), - reset_file_handlers_button_(NULL), - AdvancedSection(profile, - l10n_util::GetString(IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME)) { -} - -void DownloadSection::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == download_browse_button_) { - const std::wstring dialog_title = - l10n_util::GetString(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE); - select_file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER, - dialog_title, - profile()->GetPrefs()->GetFilePath( - prefs::kDownloadDefaultDirectory), - NULL, 0, std::wstring(), - GetWindow()->GetNativeWindow(), - NULL); - } else if (sender == download_ask_for_save_location_checkbox_) { - bool enabled = download_ask_for_save_location_checkbox_->checked(); - if (enabled) { - UserMetricsRecordAction( - UserMetricsAction("Options_AskForSaveLocation_Enable"), - profile()->GetPrefs()); - } else { - UserMetricsRecordAction( - UserMetricsAction("Options_AskForSaveLocation_Disable"), - profile()->GetPrefs()); - } - ask_for_save_location_.SetValue(enabled); - } else if (sender == reset_file_handlers_button_) { - profile()->GetDownloadManager()->download_prefs()->ResetAutoOpen(); - UserMetricsRecordAction(UserMetricsAction("Options_ResetAutoOpenFiles"), - profile()->GetPrefs()); - } -} - -void DownloadSection::FileSelected(const FilePath& path, - int index, void* params) { - UserMetricsRecordAction(UserMetricsAction("Options_SetDownloadDirectory"), - profile()->GetPrefs()); - default_download_location_.SetValue(path); - // We need to call this manually here since because we're setting the value - // through the pref member which avoids notifying the listener that set the - // value. - UpdateDownloadDirectoryDisplay(); -} - -bool DownloadSection::CanClose() const { - return !select_file_dialog_->IsRunning(GetWindow()->GetNativeWindow()); -} - -void DownloadSection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - // Layout the download components. - download_file_location_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE)); - download_default_download_location_display_ = new FileDisplayArea; - download_browse_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_BUTTON)); - - download_ask_for_save_location_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_DOWNLOADLOCATION_ASKFORSAVELOCATION)); - download_ask_for_save_location_checkbox_->set_listener(this); - download_ask_for_save_location_checkbox_->SetMultiLine(true); - reset_file_handlers_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_AUTOOPENFILETYPES_INFO)); - reset_file_handlers_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_AUTOOPENFILETYPES_RESETTODEFAULT)); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - // Download location label. - const int single_column_view_set_id = 0; - AddWrappingColumnSet(layout, single_column_view_set_id); - AddWrappingLabelRow(layout, download_file_location_label_, - single_column_view_set_id, true); - - // Download location control. - const int double_column_view_set_id = 1; - ColumnSet* column_set = layout->AddColumnSet(double_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing); - layout->StartRow(0, double_column_view_set_id); - layout->AddView(download_default_download_location_display_, 1, 1, - GridLayout::FILL, GridLayout::CENTER); - layout->AddView(download_browse_button_); - AddSpacing(layout, true); - - // Save location checkbox layout. - const int indented_view_set_id = 2; - AddIndentedColumnSet(layout, indented_view_set_id); - AddWrappingCheckboxRow(layout, download_ask_for_save_location_checkbox_, - indented_view_set_id, false); - - // Reset file handlers layout. - AddWrappingLabelRow(layout, reset_file_handlers_label_, - single_column_view_set_id, true); - AddLeadingControl(layout, reset_file_handlers_button_, - indented_view_set_id, - false); - - // Init member prefs so we can update the controls if prefs change. - default_download_location_.Init(prefs::kDownloadDefaultDirectory, - profile()->GetPrefs(), this); - ask_for_save_location_.Init(prefs::kPromptForDownload, - profile()->GetPrefs(), this); - auto_open_files_.Init(prefs::kDownloadExtensionsToOpen, profile()->GetPrefs(), - this); -} - -void DownloadSection::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kDownloadDefaultDirectory) - UpdateDownloadDirectoryDisplay(); - - if (!pref_name || *pref_name == prefs::kPromptForDownload) { - download_ask_for_save_location_checkbox_->SetChecked( - ask_for_save_location_.GetValue()); - } - - if (!pref_name || *pref_name == prefs::kDownloadExtensionsToOpen) { - bool enabled = - profile()->GetDownloadManager()->download_prefs()->IsAutoOpenUsed(); - reset_file_handlers_label_->SetEnabled(enabled); - reset_file_handlers_button_->SetEnabled(enabled); - } -} - -void DownloadSection::UpdateDownloadDirectoryDisplay() { - download_default_download_location_display_->SetFile( - default_download_location_.GetValue()); -} - -//////////////////////////////////////////////////////////////////////////////// -// TranslateSection - -class TranslateSection : public AdvancedSection, - public views::ButtonListener { - public: - explicit TranslateSection(Profile* profile); - virtual ~TranslateSection() {} - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - protected: - // OptionsPageView overrides: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - // Control for this section: - views::Checkbox* enable_translate_checkbox_; - - // Preferences for this section: - BooleanPrefMember enable_translate_; - - DISALLOW_COPY_AND_ASSIGN(TranslateSection); -}; - -TranslateSection::TranslateSection(Profile* profile) - : enable_translate_checkbox_(NULL), - AdvancedSection(profile, - l10n_util::GetString(IDS_OPTIONS_ADVANCED_SECTION_TITLE_TRANSLATE)) { -} - -void TranslateSection::ButtonPressed( - views::Button* sender, const views::Event& event) { - DCHECK(sender == enable_translate_checkbox_); - bool enabled = enable_translate_checkbox_->checked(); - UserMetricsRecordAction(enabled ? - UserMetricsAction("Options_Translate_Enable") : - UserMetricsAction("Options_Translate_Disable"), - profile()->GetPrefs()); - enable_translate_.SetValue(enabled); -} - -void TranslateSection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - AddIndentedColumnSet(layout, 0); - - enable_translate_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE)); - enable_translate_checkbox_->set_listener(this); - AddWrappingCheckboxRow(layout, enable_translate_checkbox_, 0, false); - - // Init member pref so we can update the controls if prefs change. - enable_translate_.Init(prefs::kEnableTranslate, profile()->GetPrefs(), this); -} - -void TranslateSection::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kEnableTranslate) - enable_translate_checkbox_->SetChecked(enable_translate_.GetValue()); -} - -//////////////////////////////////////////////////////////////////////////////// -// ChromeAppsSection - -class ChromeAppsSection : public AdvancedSection, - public views::ButtonListener, - public views::LinkController { - public: - explicit ChromeAppsSection(Profile* profile); - virtual ~ChromeAppsSection() {} - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - protected: - // OptionsPageView overrides: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - // Controls for this section: - views::Checkbox* enable_background_mode_checkbox_; - views::Link* learn_more_link_; - - // Preferences for this section: - BooleanPrefMember enable_background_mode_; - - DISALLOW_COPY_AND_ASSIGN(ChromeAppsSection); -}; - -ChromeAppsSection::ChromeAppsSection(Profile* profile) - : enable_background_mode_checkbox_(NULL), - learn_more_link_(NULL), - AdvancedSection(profile, l10n_util::GetString( - IDS_OPTIONS_ADVANCED_SECTION_TITLE_CHROME_APPS)) { -} - -void ChromeAppsSection::ButtonPressed( - views::Button* sender, const views::Event& event) { - DCHECK(sender == enable_background_mode_checkbox_); - bool enabled = enable_background_mode_checkbox_->checked(); - UserMetricsRecordAction(enabled ? - UserMetricsAction("Options_BackgroundMode_Enable") : - UserMetricsAction("Options_BackgroundMode_Disable"), - profile()->GetPrefs()); - enable_background_mode_.SetValue(enabled); -} - -void ChromeAppsSection::LinkActivated(views::Link* source, int event_flags) { - DCHECK(source == learn_more_link_); - browser::ShowOptionsURL( - profile(), - GURL(l10n_util::GetString(IDS_LEARN_MORE_BACKGROUND_MODE_URL))); -} - -void ChromeAppsSection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - AddIndentedColumnSet(layout, 0); - - enable_background_mode_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_CHROME_APPS_ENABLE_BACKGROUND_MODE)); - enable_background_mode_checkbox_->set_listener(this); - AddWrappingCheckboxRow(layout, enable_background_mode_checkbox_, 0, true); - - // Init member pref so we can update the controls if prefs change. - enable_background_mode_.Init(prefs::kBackgroundModeEnabled, - profile()->GetPrefs(), this); - - // Add our link to the help center page for this feature. - learn_more_link_ = new views::Link(l10n_util::GetString(IDS_LEARN_MORE)); - learn_more_link_->SetController(this); - AddLeadingControl(layout, learn_more_link_, 0, false); -} - -void ChromeAppsSection::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kBackgroundModeEnabled) { - enable_background_mode_checkbox_->SetChecked( - enable_background_mode_.GetValue()); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// CloudPrintProxySection - -class CloudPrintProxySection : public AdvancedSection, - public views::ButtonListener, - public CloudPrintSetupFlow::Delegate { - public: - explicit CloudPrintProxySection(Profile* profile); - virtual ~CloudPrintProxySection() {} - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // CloudPrintSetupFlow::Delegate implementation. - virtual void OnDialogClosed(); - - protected: - // OptionsPageView overrides: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - bool Enabled() const; - - // Controls for this section: - views::Label* section_description_label_; - views::NativeButton* enable_disable_button_; - views::NativeButton* manage_printer_button_; - - // Preferences we tie things to. - StringPrefMember cloud_print_proxy_email_; - - base::ScopedCallbackFactory<CloudPrintProxySection> factory_; - - DISALLOW_COPY_AND_ASSIGN(CloudPrintProxySection); -}; - -CloudPrintProxySection::CloudPrintProxySection(Profile* profile) - : section_description_label_(NULL), - enable_disable_button_(NULL), - manage_printer_button_(NULL), - factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - AdvancedSection(profile, - l10n_util::GetString( - IDS_OPTIONS_ADVANCED_SECTION_TITLE_CLOUD_PRINT)) { -} - -void CloudPrintProxySection::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == enable_disable_button_) { - if (Enabled()) { - // Enabled, we must be the disable button. - UserMetricsRecordAction( - UserMetricsAction("Options_DisableCloudPrintProxy"), NULL); - profile()->GetCloudPrintProxyService()->DisableForUser(); - } else { - UserMetricsRecordAction( - UserMetricsAction("Options_EnableCloudPrintProxy"), NULL); - // We open a new browser window so the Options dialog doesn't - // get lost behind other windows. - enable_disable_button_->SetEnabled(false); - enable_disable_button_->SetLabel( - l10n_util::GetString(IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLING_BUTTON)); - enable_disable_button_->InvalidateLayout(); - Layout(); - CloudPrintSetupFlow::OpenDialog(profile(), this, - GetWindow()->GetNativeWindow()); - } - } else if (sender == manage_printer_button_) { - UserMetricsRecordAction( - UserMetricsAction("Options_ManageCloudPrinters"), NULL); - browser::ShowOptionsURL( - profile(), - CloudPrintURL(profile()).GetCloudPrintServiceManageURL()); - } -} - -void CloudPrintProxySection::OnDialogClosed() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - enable_disable_button_->SetEnabled(true); - // If the dialog is canceled, the preference won't change, and so we - // have to revert the button text back to the disabled state. - if (!Enabled()) { - enable_disable_button_->SetLabel( - l10n_util::GetString(IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_BUTTON)); - enable_disable_button_->InvalidateLayout(); - Layout(); - } -} - -void CloudPrintProxySection::InitControlLayout() { - AdvancedSection::InitControlLayout(); - - section_description_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_LABEL)); - enable_disable_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_BUTTON)); - manage_printer_button_ = new views::NativeButton(this, - l10n_util::GetString( - IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLED_MANAGE_BUTTON)); - - GridLayout* layout = new GridLayout(contents_); - contents_->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - AddWrappingColumnSet(layout, single_column_view_set_id); - const int control_view_set_id = 1; - AddDependentTwoColumnSet(layout, control_view_set_id); - - // The description label at the top and label. - section_description_label_->SetMultiLine(true); - AddWrappingLabelRow(layout, section_description_label_, - single_column_view_set_id, true); - - // The enable / disable button and manage button. - AddTwoColumnRow(layout, enable_disable_button_, manage_printer_button_, false, - control_view_set_id, kRelatedControlVerticalSpacing); - - // Attach the preferences so we can flip things appropriately. - cloud_print_proxy_email_.Init(prefs::kCloudPrintEmail, - profile()->GetPrefs(), this); - - // Start the UI off in the state we think it should be in. - std::string pref_string(prefs::kCloudPrintEmail); - NotifyPrefChanged(&pref_string); - - // Kick off a task to ask the background service what the real - // answer is. - profile()->GetCloudPrintProxyService()->RefreshStatusFromService(); -} - -void CloudPrintProxySection::NotifyPrefChanged(const std::string* pref_name) { - if (pref_name == NULL) - return; - - if (*pref_name == prefs::kCloudPrintEmail) { - if (Enabled()) { - std::string email; - if (profile()->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail)) - email = profile()->GetPrefs()->GetString(prefs::kCloudPrintEmail); - - section_description_label_->SetText( - l10n_util::GetStringF(IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLED_LABEL, - UTF8ToWide(email))); - enable_disable_button_->SetLabel( - l10n_util::GetString(IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLED_BUTTON)); - enable_disable_button_->InvalidateLayout(); - manage_printer_button_->SetVisible(true); - manage_printer_button_->InvalidateLayout(); - } else { - section_description_label_->SetText( - l10n_util::GetString(IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_LABEL)); - enable_disable_button_->SetLabel( - l10n_util::GetString(IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_BUTTON)); - enable_disable_button_->InvalidateLayout(); - manage_printer_button_->SetVisible(false); - } - - // Find the parent ScrollView, and ask it to re-layout since it's - // possible that the section_description_label_ has changed - // heights. And scroll us back to being visible in that case, to - // be nice to the user. - views::View* view = section_description_label_->GetParent(); - while (view && view->GetClassName() != views::ScrollView::kViewClassName) - view = view->GetParent(); - if (view) { - gfx::Rect visible_bounds = GetVisibleBounds(); - bool was_all_visible = (visible_bounds.size() == bounds().size()); - // Our bounds can change across this call, so we have to use the - // new bounds if we want to stay completely visible. - view->Layout(); - ScrollRectToVisible(was_all_visible ? bounds() : visible_bounds); - } else { - Layout(); - } - } -} - -bool CloudPrintProxySection::Enabled() const { - return profile()->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) && - !profile()->GetPrefs()->GetString(prefs::kCloudPrintEmail).empty(); -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedContentsView - -class AdvancedContentsView : public OptionsPageView { - public: - explicit AdvancedContentsView(Profile* profile); - virtual ~AdvancedContentsView(); - - // views::View overrides: - virtual int GetLineScrollIncrement(views::ScrollView* scroll_view, - bool is_horizontal, bool is_positive); - virtual void Layout(); - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - - protected: - // OptionsPageView implementation: - virtual void InitControlLayout(); - - private: - static void InitClass(); - - static int line_height_; - - DISALLOW_COPY_AND_ASSIGN(AdvancedContentsView); -}; - -// static -int AdvancedContentsView::line_height_ = 0; - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedContentsView, public: - -AdvancedContentsView::AdvancedContentsView(Profile* profile) - : OptionsPageView(profile) { - InitClass(); -} - -AdvancedContentsView::~AdvancedContentsView() { -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedContentsView, views::View overrides: - -int AdvancedContentsView::GetLineScrollIncrement( - views::ScrollView* scroll_view, - bool is_horizontal, - bool is_positive) { - - if (!is_horizontal) - return line_height_; - return View::GetPageScrollIncrement(scroll_view, is_horizontal, is_positive); -} - -void AdvancedContentsView::Layout() { - views::View* parent = GetParent(); - if (parent && parent->width()) { - const int width = parent->width(); - const int height = GetHeightForWidth(width); - SetBounds(0, 0, width, height); - } else { - gfx::Size prefsize = GetPreferredSize(); - SetBounds(0, 0, prefsize.width(), prefsize.height()); - } - View::Layout(); -} - -void AdvancedContentsView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - // Override to do nothing. Calling Layout() interferes with our scrolling. -} - - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedContentsView, OptionsPageView implementation: - -void AdvancedContentsView::InitControlLayout() { - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new PrivacySection(profile())); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new NetworkSection(profile())); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new TranslateSection(profile())); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new DownloadSection(profile())); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new WebContentSection(profile())); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new SecuritySection(profile())); - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableCloudPrintProxy) && - profile()->GetCloudPrintProxyService()) { - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new CloudPrintProxySection(profile())); - } - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableBackgroundMode)) { - layout->StartRow(0, single_column_view_set_id); - layout->AddView(new ChromeAppsSection(profile())); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedContentsView, private: - -void AdvancedContentsView::InitClass() { - static bool initialized = false; - if (!initialized) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - line_height_ = rb.GetFont(ResourceBundle::BaseFont).GetHeight(); - initialized = true; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedScrollViewContainer, public: - -AdvancedScrollViewContainer::AdvancedScrollViewContainer(Profile* profile) - : contents_view_(new AdvancedContentsView(profile)), - scroll_view_(new views::ScrollView) { - AddChildView(scroll_view_); - scroll_view_->SetContents(contents_view_); - set_background(new ListBackground()); -} - -AdvancedScrollViewContainer::~AdvancedScrollViewContainer() { -} - -//////////////////////////////////////////////////////////////////////////////// -// AdvancedScrollViewContainer, views::View overrides: - -void AdvancedScrollViewContainer::Layout() { - gfx::Rect lb = GetLocalBounds(false); - - gfx::Size border = gfx::NativeTheme::instance()->GetThemeBorderSize( - gfx::NativeTheme::LIST); - lb.Inset(border.width(), border.height()); - scroll_view_->SetBounds(lb); -} diff --git a/chrome/browser/views/options/advanced_contents_view.h b/chrome/browser/views/options/advanced_contents_view.h index 5adf493..9026e82 100644 --- a/chrome/browser/views/options/advanced_contents_view.h +++ b/chrome/browser/views/options/advanced_contents_view.h @@ -2,38 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_CONTENTS_VIEW_H__ -#define CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_CONTENTS_VIEW_H__ +#ifndef CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_CONTENTS_VIEW_H_ +#define CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_CONTENTS_VIEW_H_ #pragma once -#include "chrome/browser/views/options/options_page_view.h" +#include "chrome/browser/ui/views/options/advanced_contents_view.h" +// TODO(beng): remove this file once all includes have been updated. -class AdvancedContentsView; -namespace views { -class ScrollView; -} +#endif // CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_CONTENTS_VIEW_H_ -/////////////////////////////////////////////////////////////////////////////// -// AdvancedScrollViewContainer -// -// A View that contains a scroll view containing the Advanced options. - -class AdvancedScrollViewContainer : public views::View { - public: - explicit AdvancedScrollViewContainer(Profile* profile); - virtual ~AdvancedScrollViewContainer(); - - // views::View overrides: - virtual void Layout(); - - private: - // The contents of the advanced scroll view. - AdvancedContentsView* contents_view_; - - // The scroll view that contains the advanced options. - views::ScrollView* scroll_view_; - - DISALLOW_COPY_AND_ASSIGN(AdvancedScrollViewContainer); -}; - -#endif // CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_CONTENTS_VIEW_H__ diff --git a/chrome/browser/views/options/advanced_page_view.cc b/chrome/browser/views/options/advanced_page_view.cc deleted file mode 100644 index 712955c..0000000 --- a/chrome/browser/views/options/advanced_page_view.cc +++ /dev/null @@ -1,145 +0,0 @@ -// 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/options/advanced_page_view.h" - -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "base/string_util.h" -#include "chrome/browser/options_util.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/options/advanced_contents_view.h" -#include "chrome/browser/views/options/managed_prefs_banner_view.h" -#include "chrome/common/chrome_constants.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/message_box_view.h" -#include "views/controls/button/native_button.h" -#include "views/controls/scroll_view.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -namespace { - -// A dialog box that asks the user to confirm resetting settings. -class ResetDefaultsConfirmBox : public views::DialogDelegate { - public: - // This box is modal to |parent_hwnd|. - static void ShowConfirmBox(HWND parent_hwnd, AdvancedPageView* page_view) { - // When the window closes, it will delete itself. - new ResetDefaultsConfirmBox(parent_hwnd, page_view); - } - - protected: - // views::DialogDelegate - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString(IDS_OPTIONS_RESET_OKLABEL); - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return l10n_util::GetString(IDS_OPTIONS_RESET_CANCELLABEL); - default: - break; - } - NOTREACHED(); - return std::wstring(); - } - virtual std::wstring GetWindowTitle() const { - return l10n_util::GetString(IDS_PRODUCT_NAME); - } - virtual bool Accept() { - advanced_page_view_->ResetToDefaults(); - return true; - } - // views::WindowDelegate - virtual void DeleteDelegate() { delete this; } - virtual bool IsModal() const { return true; } - virtual views::View* GetContentsView() { return message_box_view_; } - - private: - ResetDefaultsConfirmBox(HWND parent_hwnd, AdvancedPageView* page_view) - : advanced_page_view_(page_view) { - int dialog_width = views::Window::GetLocalizedContentsWidth( - IDS_OPTIONS_RESET_CONFIRM_BOX_WIDTH_CHARS); - // Also deleted when the window closes. - message_box_view_ = new MessageBoxView( - MessageBoxFlags::kFlagHasMessage | MessageBoxFlags::kFlagHasOKButton, - l10n_util::GetString(IDS_OPTIONS_RESET_MESSAGE).c_str(), - std::wstring(), - dialog_width); - views::Window::CreateChromeWindow(parent_hwnd, gfx::Rect(), this)->Show(); - } - virtual ~ResetDefaultsConfirmBox() { } - - MessageBoxView* message_box_view_; - AdvancedPageView* advanced_page_view_; - - DISALLOW_COPY_AND_ASSIGN(ResetDefaultsConfirmBox); -}; - -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// AdvancedPageView, public: - -AdvancedPageView::AdvancedPageView(Profile* profile) - : advanced_scroll_view_(NULL), - reset_to_default_button_(NULL), - OptionsPageView(profile) { -} - -AdvancedPageView::~AdvancedPageView() { -} - -void AdvancedPageView::ResetToDefaults() { - OptionsUtil::ResetToDefaults(profile()); -} - -/////////////////////////////////////////////////////////////////////////////// -// AdvancedPageView, views::ButtonListener implementation: - -void AdvancedPageView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == reset_to_default_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ResetToDefaults"), - NULL); - ResetDefaultsConfirmBox::ShowConfirmBox( - GetWindow()->GetNativeWindow(), this); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// AdvancedPageView, OptionsPageView implementation: - -void AdvancedPageView::InitControlLayout() { - reset_to_default_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_RESET)); - advanced_scroll_view_ = new AdvancedScrollViewContainer(profile()); - - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, single_column_view_set_id); - layout->AddView( - new ManagedPrefsBannerView(profile()->GetPrefs(), OPTIONS_PAGE_ADVANCED)); - - layout->StartRow(1, single_column_view_set_id); - layout->AddView(advanced_scroll_view_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(reset_to_default_button_, 1, 1, - GridLayout::TRAILING, GridLayout::CENTER); -} diff --git a/chrome/browser/views/options/advanced_page_view.h b/chrome/browser/views/options/advanced_page_view.h index 8075021..dccd66e 100644 --- a/chrome/browser/views/options/advanced_page_view.h +++ b/chrome/browser/views/options/advanced_page_view.h @@ -6,41 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/views/options/options_page_view.h" -#include "views/controls/button/button.h" - -class AdvancedOptionsListModel; -class AdvancedScrollViewContainer; -class PrefService; -namespace views { -class NativeButton; -} - -/////////////////////////////////////////////////////////////////////////////// -// AdvancedPageView - -class AdvancedPageView : public OptionsPageView, - public views::ButtonListener { - public: - explicit AdvancedPageView(Profile* profile); - virtual ~AdvancedPageView(); - - // Resets all prefs to their default values. - void ResetToDefaults(); - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - protected: - // OptionsPageView implementation: - virtual void InitControlLayout(); - - private: - // Controls for the Advanced page - AdvancedScrollViewContainer* advanced_scroll_view_; - views::NativeButton* reset_to_default_button_; - - DISALLOW_COPY_AND_ASSIGN(AdvancedPageView); -}; +#include "chrome/browser/ui/views/options/advanced_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_ADVANCED_PAGE_VIEW_H_ + diff --git a/chrome/browser/views/options/content_exceptions_table_view.cc b/chrome/browser/views/options/content_exceptions_table_view.cc deleted file mode 100644 index 1b81aa1..0000000 --- a/chrome/browser/views/options/content_exceptions_table_view.cc +++ /dev/null @@ -1,33 +0,0 @@ -// 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/options/content_exceptions_table_view.h" - -#include "gfx/font.h" - -ContentExceptionsTableView::ContentExceptionsTableView( - ContentExceptionsTableModel* model, - const std::vector<TableColumn>& columns) - : views::TableView(model, columns, views::TEXT_ONLY, false, true, false), - exceptions_(model) { - SetCustomColorsEnabled(true); -} - -bool ContentExceptionsTableView::GetCellColors(int model_row, - int column, - ItemColor* foreground, - ItemColor* background, - LOGFONT* logfont) { - if (!exceptions_->entry_is_off_the_record(model_row)) - return false; - - foreground->color_is_set = false; - background->color_is_set = false; - - gfx::Font font; - font = font.DeriveFont(0, gfx::Font::ITALIC); - HFONT hf = font.GetNativeFont(); - GetObject(hf, sizeof(LOGFONT), logfont); - return true; -} diff --git a/chrome/browser/views/options/content_exceptions_table_view.h b/chrome/browser/views/options/content_exceptions_table_view.h index ac5511f..6cc48fb 100644 --- a/chrome/browser/views/options/content_exceptions_table_view.h +++ b/chrome/browser/views/options/content_exceptions_table_view.h @@ -6,26 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_EXCEPTIONS_TABLE_VIEW_H_ #pragma once -#include "chrome/browser/content_exceptions_table_model.h" -#include "views/controls/table/table_view.h" - -// A thin wrapper around TableView that displays off-the-record entries in -// italics. -class ContentExceptionsTableView : public views::TableView { - public: - ContentExceptionsTableView(ContentExceptionsTableModel* model, - const std::vector<TableColumn>& columns); - - virtual ~ContentExceptionsTableView() {} - - private: - virtual bool GetCellColors(int model_row, - int column, - ItemColor* foreground, - ItemColor* background, - LOGFONT* logfont); - - ContentExceptionsTableModel* exceptions_; -}; +#include "chrome/browser/ui/views/options/content_exceptions_table_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_EXCEPTIONS_TABLE_VIEW_H_ + diff --git a/chrome/browser/views/options/content_filter_page_view.cc b/chrome/browser/views/options/content_filter_page_view.cc deleted file mode 100644 index 756045f..0000000 --- a/chrome/browser/views/options/content_filter_page_view.cc +++ /dev/null @@ -1,227 +0,0 @@ -// 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/options/content_filter_page_view.h" - -#include "app/l10n_util.h" -#include "base/command_line.h" -#include "chrome/browser/geolocation/geolocation_content_settings_map.h" -#include "chrome/browser/geolocation/geolocation_exceptions_table_model.h" -#include "chrome/browser/notifications/desktop_notification_service.h" -#include "chrome/browser/notifications/notification_exceptions_table_model.h" -#include "chrome/browser/plugin_exceptions_table_model.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/options/exceptions_view.h" -#include "chrome/browser/views/options/simple_content_exceptions_view.h" -#include "chrome/common/chrome_switches.h" -#include "grit/generated_resources.h" -#include "views/controls/button/radio_button.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -ContentFilterPageView::ContentFilterPageView(Profile* profile, - ContentSettingsType content_type) - : OptionsPageView(profile), - content_type_(content_type), - allow_radio_(NULL), - ask_radio_(NULL), - block_radio_(NULL), - exceptions_button_(NULL) { -} - -ContentFilterPageView::~ContentFilterPageView() { -} - -//////////////////////////////////////////////////////////////////////////////// -// ContentFilterPageView, OptionsPageView implementation: - -void ContentFilterPageView::InitControlLayout() { - using views::GridLayout; - - GridLayout* layout = new GridLayout(this); - SetLayoutManager(layout); - - const int single_column_set_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(single_column_set_id); - column_set->AddPaddingColumn(0, kRelatedControlVerticalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - static const int kTitleIDs[] = { - IDS_MODIFY_COOKIE_STORING_LABEL, - IDS_IMAGES_SETTING_LABEL, - IDS_JS_SETTING_LABEL, - IDS_PLUGIN_SETTING_LABEL, - IDS_POPUP_SETTING_LABEL, - IDS_GEOLOCATION_SETTING_LABEL, - IDS_NOTIFICATIONS_SETTING_LABEL, - }; - COMPILE_ASSERT(arraysize(kTitleIDs) == CONTENT_SETTINGS_NUM_TYPES, - Need_a_setting_for_every_content_settings_type); - views::Label* title_label = new views::Label( - l10n_util::GetString(kTitleIDs[content_type_])); - title_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - title_label->SetMultiLine(true); - - layout->StartRow(0, single_column_set_id); - layout->AddView(title_label); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - static const int kAllowIDs[] = { - IDS_COOKIES_ALLOW_RADIO, - IDS_IMAGES_LOAD_RADIO, - IDS_JS_ALLOW_RADIO, - IDS_PLUGIN_LOAD_RADIO, - IDS_POPUP_ALLOW_RADIO, - IDS_GEOLOCATION_ALLOW_RADIO, - IDS_NOTIFICATIONS_ALLOW_RADIO, - }; - COMPILE_ASSERT(arraysize(kAllowIDs) == CONTENT_SETTINGS_NUM_TYPES, - Need_a_setting_for_every_content_settings_type); - const int radio_button_group = 0; - allow_radio_ = new views::RadioButton( - l10n_util::GetString(kAllowIDs[content_type_]), radio_button_group); - allow_radio_->set_listener(this); - allow_radio_->SetMultiLine(true); - layout->StartRow(0, single_column_set_id); - layout->AddView(allow_radio_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - static const int kAskIDs[] = { - IDS_COOKIES_ASK_EVERY_TIME_RADIO, - 0, - 0, - IDS_PLUGIN_ASK_RADIO, - 0, - IDS_GEOLOCATION_ASK_RADIO, - IDS_NOTIFICATIONS_ASK_RADIO, - }; - COMPILE_ASSERT(arraysize(kAskIDs) == CONTENT_SETTINGS_NUM_TYPES, - Need_a_setting_for_every_content_settings_type); - DCHECK_EQ(arraysize(kAskIDs), - static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); - if (content_type_ != CONTENT_SETTINGS_TYPE_COOKIES) { - if (kAskIDs[content_type_] != 0) { - ask_radio_ = new views::RadioButton( - l10n_util::GetString(kAskIDs[content_type_]), radio_button_group); - ask_radio_->set_listener(this); - ask_radio_->SetMultiLine(true); - layout->StartRow(0, single_column_set_id); - layout->AddView(ask_radio_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - } - - static const int kBlockIDs[] = { - IDS_COOKIES_BLOCK_RADIO, - IDS_IMAGES_NOLOAD_RADIO, - IDS_JS_DONOTALLOW_RADIO, - IDS_PLUGIN_NOLOAD_RADIO, - IDS_POPUP_BLOCK_RADIO, - IDS_GEOLOCATION_BLOCK_RADIO, - IDS_NOTIFICATIONS_BLOCK_RADIO, - }; - COMPILE_ASSERT(arraysize(kBlockIDs) == CONTENT_SETTINGS_NUM_TYPES, - Need_a_setting_for_every_content_settings_type); - block_radio_ = new views::RadioButton( - l10n_util::GetString(kBlockIDs[content_type_]), radio_button_group); - block_radio_->set_listener(this); - block_radio_->SetMultiLine(true); - layout->StartRow(0, single_column_set_id); - layout->AddView(block_radio_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - ContentSetting default_setting; - if (content_type_ == CONTENT_SETTINGS_TYPE_GEOLOCATION) { - default_setting = profile()->GetGeolocationContentSettingsMap()-> - GetDefaultContentSetting(); - } else if (content_type_ == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { - default_setting = profile()->GetDesktopNotificationService()-> - GetDefaultContentSetting(); - } else { - default_setting = profile()->GetHostContentSettingsMap()-> - GetDefaultContentSetting(content_type_); - } - // Now that these have been added to the view hierarchy, it's safe to call - // SetChecked() on them. - if (default_setting == CONTENT_SETTING_ALLOW) { - allow_radio_->SetChecked(true); - } else if (default_setting == CONTENT_SETTING_ASK) { - DCHECK(ask_radio_ != NULL); - ask_radio_->SetChecked(true); - } else { - DCHECK(default_setting == CONTENT_SETTING_BLOCK); - block_radio_->SetChecked(true); - } - - exceptions_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_COOKIES_EXCEPTIONS_BUTTON)); - - layout->StartRow(0, single_column_set_id); - layout->AddView(exceptions_button_, 1, 1, GridLayout::LEADING, - GridLayout::FILL); -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentFilterPageView, views::ButtonListener implementation: - -void ContentFilterPageView::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == exceptions_button_) { - if (content_type_ == CONTENT_SETTINGS_TYPE_GEOLOCATION) { - SimpleContentExceptionsView::ShowExceptionsWindow( - GetWindow()->GetNativeWindow(), - new GeolocationExceptionsTableModel( - profile()->GetGeolocationContentSettingsMap()), - IDS_GEOLOCATION_EXCEPTION_TITLE); - } else if (content_type_ == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { - SimpleContentExceptionsView::ShowExceptionsWindow( - GetWindow()->GetNativeWindow(), - new NotificationExceptionsTableModel( - profile()->GetDesktopNotificationService()), - IDS_NOTIFICATIONS_EXCEPTION_TITLE); - } else { - HostContentSettingsMap* settings = profile()->GetHostContentSettingsMap(); - HostContentSettingsMap* otr_settings = - profile()->HasOffTheRecordProfile() ? - profile()->GetOffTheRecordProfile()->GetHostContentSettingsMap() : - NULL; - if (content_type_ == CONTENT_SETTINGS_TYPE_PLUGINS && - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableResourceContentSettings)) { - PluginExceptionsTableModel* model = - new PluginExceptionsTableModel(settings, otr_settings); - model->LoadSettings(); - SimpleContentExceptionsView::ShowExceptionsWindow( - GetWindow()->GetNativeWindow(), - model, - IDS_PLUGINS_EXCEPTION_TITLE); - } else { - ExceptionsView::ShowExceptionsWindow(GetWindow()->GetNativeWindow(), - settings, - otr_settings, - content_type_); - } - } - return; - } - - DCHECK((sender == allow_radio_) || (sender == ask_radio_) || - (sender == block_radio_)); - ContentSetting default_setting = allow_radio_->checked() ? - CONTENT_SETTING_ALLOW : - (block_radio_->checked() ? CONTENT_SETTING_BLOCK : CONTENT_SETTING_ASK); - if (content_type_ == CONTENT_SETTINGS_TYPE_GEOLOCATION) { - profile()->GetGeolocationContentSettingsMap()->SetDefaultContentSetting( - default_setting); - } else if (content_type_ == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { - profile()->GetDesktopNotificationService()->SetDefaultContentSetting( - default_setting); - } else { - profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( - content_type_, default_setting); - } -} diff --git a/chrome/browser/views/options/content_filter_page_view.h b/chrome/browser/views/options/content_filter_page_view.h index 8c9bd99..0a1115e 100644 --- a/chrome/browser/views/options/content_filter_page_view.h +++ b/chrome/browser/views/options/content_filter_page_view.h @@ -6,44 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_FILTER_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/views/options/options_page_view.h" -#include "chrome/common/content_settings_types.h" -#include "views/controls/button/button.h" - -namespace views { -class Label; -class NativeButton; -class RadioButton; -} -class PrefService; - -//////////////////////////////////////////////////////////////////////////////// -// The ContentFilterPageView class is used to render the Images, JavaScript, -// Pop-ups and Location pages in the Content Settings window. - -class ContentFilterPageView : public OptionsPageView, - public views::ButtonListener { - public: - ContentFilterPageView(Profile* profile, ContentSettingsType content_type); - virtual ~ContentFilterPageView(); - - protected: - // OptionsPageView implementation: - virtual void InitControlLayout(); - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - private: - ContentSettingsType content_type_; - - // Controls for the content filter tab page. - views::RadioButton* allow_radio_; - views::RadioButton* ask_radio_; - views::RadioButton* block_radio_; - views::NativeButton* exceptions_button_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ContentFilterPageView); -}; +#include "chrome/browser/ui/views/options/content_filter_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_FILTER_PAGE_VIEW_H_ + diff --git a/chrome/browser/views/options/content_page_view.cc b/chrome/browser/views/options/content_page_view.cc deleted file mode 100644 index 7f50426..0000000 --- a/chrome/browser/views/options/content_page_view.cc +++ /dev/null @@ -1,496 +0,0 @@ -// 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/options/content_page_view.h" - -#include <windows.h> -#include <shlobj.h> -#include <vsstyle.h> -#include <vssym32.h> - -#include "app/l10n_util.h" -#include "base/command_line.h" -#include "base/string_util.h" -#include "chrome/browser/autofill/autofill_dialog.h" -#include "chrome/browser/autofill/personal_data_manager.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/importer/importer_data_types.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/sync/sync_ui_util.h" -#include "chrome/browser/sync/sync_setup_wizard.h" -#include "chrome/browser/views/importer_view.h" -#include "chrome/browser/views/options/managed_prefs_banner_view.h" -#include "chrome/browser/views/options/options_group_view.h" -#include "chrome/browser/views/options/passwords_exceptions_window_view.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas.h" -#include "gfx/native_theme_win.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/button/radio_button.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -namespace { - -// All the options pages are in the same view hierarchy. This means we need to -// make sure group identifiers don't collide across different pages. -const int kPasswordSavingRadioGroup = 201; -const int kFormAutofillRadioGroup = 202; - -// Background color for the status label when it's showing an error. -static const SkColor kSyncLabelErrorBgColor = SkColorSetRGB(0xff, 0x9a, 0x9a); - -static views::Background* CreateErrorBackground() { - return views::Background::CreateSolidBackground(kSyncLabelErrorBgColor); -} - -} // namespace - -ContentPageView::ContentPageView(Profile* profile) - : show_passwords_button_(NULL), - passwords_group_(NULL), - passwords_asktosave_radio_(NULL), - passwords_neversave_radio_(NULL), - change_autofill_settings_button_(NULL), - themes_group_(NULL), - themes_reset_button_(NULL), - themes_gallery_link_(NULL), - browsing_data_group_(NULL), - import_button_(NULL), - sync_group_(NULL), - sync_action_link_(NULL), - sync_status_label_(NULL), - sync_start_stop_button_(NULL), - sync_customize_button_(NULL), - privacy_dashboard_link_(NULL), - sync_service_(NULL), - OptionsPageView(profile) { - if (profile->GetProfileSyncService()) { - sync_service_ = profile->GetProfileSyncService(); - sync_service_->AddObserver(this); - } -} - -ContentPageView::~ContentPageView() { - if (sync_service_) - sync_service_->RemoveObserver(this); -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentPageView, views::ButtonListener implementation: - -void ContentPageView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == passwords_asktosave_radio_ || - sender == passwords_neversave_radio_) { - bool enabled = passwords_asktosave_radio_->checked(); - if (enabled) { - UserMetricsRecordAction( - UserMetricsAction("Options_PasswordManager_Enable"), - profile()->GetPrefs()); - } else { - UserMetricsRecordAction( - UserMetricsAction("Options_PasswordManager_Disable"), - profile()->GetPrefs()); - } - ask_to_save_passwords_.SetValue(enabled); - } else if (sender == show_passwords_button_) { - UserMetricsRecordAction( - UserMetricsAction("Options_ShowPasswordsExceptions"), NULL); - PasswordsExceptionsWindowView::Show(profile()); - } else if (sender == change_autofill_settings_button_) { - // This button should be disabled if we lack PersonalDataManager. - DCHECK(profile()->GetPersonalDataManager()); - ShowAutoFillDialog(GetWindow()->GetNativeWindow(), - profile()->GetPersonalDataManager(), - profile()); - } else if (sender == themes_reset_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ThemesReset"), - profile()->GetPrefs()); - profile()->ClearTheme(); - } else if (sender == import_button_) { - views::Window::CreateChromeWindow( - GetWindow()->GetNativeWindow(), - gfx::Rect(), - new ImporterView(profile(), importer::ALL))->Show(); - } else if (sender == sync_start_stop_button_) { - DCHECK(sync_service_ && !sync_service_->IsManaged()); - - if (sync_service_->HasSyncSetupCompleted()) { - ConfirmMessageBoxDialog::RunWithCustomConfiguration( - GetWindow()->GetNativeWindow(), - this, - l10n_util::GetStringF(IDS_SYNC_STOP_SYNCING_EXPLANATION_LABEL, - l10n_util::GetString(IDS_PRODUCT_NAME)), - l10n_util::GetString(IDS_SYNC_STOP_SYNCING_DIALOG_TITLE), - l10n_util::GetString(IDS_SYNC_STOP_SYNCING_CONFIRM_BUTTON_LABEL), - l10n_util::GetString(IDS_CANCEL), - gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_CONFIRM_STOP_SYNCING_DIALOG_WIDTH_CHARS, - IDS_CONFIRM_STOP_SYNCING_DIALOG_HEIGHT_LINES))); - return; - } else { - sync_service_->ShowLoginDialog(GetWindow()->GetNativeWindow()); - ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_OPTIONS); - } - } else if (sender == sync_customize_button_) { - // sync_customize_button_ should be invisible if sync is not yet set up. - DCHECK(sync_service_->HasSyncSetupCompleted()); - sync_service_->ShowConfigure(GetWindow()->GetNativeWindow()); - } -} - -void ContentPageView::LinkActivated(views::Link* source, int event_flags) { - if (source == themes_gallery_link_) { - UserMetricsRecordAction(UserMetricsAction("Options_ThemesGallery"), - profile()->GetPrefs()); - BrowserList::GetLastActive()->OpenThemeGalleryTabAndActivate(); - return; - } - if (source == sync_action_link_) { - DCHECK(sync_service_ && !sync_service_->IsManaged()); - sync_service_->ShowLoginDialog(GetWindow()->GetNativeWindow()); - return; - } - if (source == privacy_dashboard_link_) { - BrowserList::GetLastActive()->OpenPrivacyDashboardTabAndActivate(); - return; - } - NOTREACHED() << "Invalid link source."; -} - -//////////////////////////////////////////////////////////////////////////////// -// ContentPageView, OptionsPageView implementation: - -void ContentPageView::InitControlLayout() { - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(5, 5, 5, 5); - SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView( - new ManagedPrefsBannerView(profile()->GetPrefs(), OPTIONS_PAGE_CONTENT)); - - if (sync_service_) { - layout->StartRow(0, single_column_view_set_id); - InitSyncGroup(); - layout->AddView(sync_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - layout->StartRow(0, single_column_view_set_id); - InitPasswordSavingGroup(); - layout->AddView(passwords_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - InitFormAutofillGroup(); - layout->AddView(form_autofill_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - InitBrowsingDataGroup(); - layout->AddView(browsing_data_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - InitThemesGroup(); - layout->AddView(themes_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Init member prefs so we can update the controls if prefs change. - ask_to_save_passwords_.Init(prefs::kPasswordManagerEnabled, - profile()->GetPrefs(), this); - form_autofill_enabled_.Init(prefs::kAutoFillEnabled, - profile()->GetPrefs(), this); - is_using_default_theme_.Init(prefs::kCurrentThemeID, - profile()->GetPrefs(), this); -} - -void ContentPageView::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kPasswordManagerEnabled) { - if (ask_to_save_passwords_.GetValue()) { - passwords_asktosave_radio_->SetChecked(true); - } else { - passwords_neversave_radio_->SetChecked(true); - } - - // Disable UI elements that are managed via policy. - bool enablePasswordManagerElements = !ask_to_save_passwords_.IsManaged(); - passwords_asktosave_radio_->SetEnabled(enablePasswordManagerElements); - passwords_neversave_radio_->SetEnabled(enablePasswordManagerElements); - show_passwords_button_->SetEnabled(enablePasswordManagerElements || - ask_to_save_passwords_.GetValue()); - } - if (!pref_name || *pref_name == prefs::kAutoFillEnabled) { - bool disabled_by_policy = form_autofill_enabled_.IsManaged() && - !form_autofill_enabled_.GetValue(); - change_autofill_settings_button_->SetEnabled( - !disabled_by_policy && profile()->GetPersonalDataManager()); - } - if (!pref_name || *pref_name == prefs::kCurrentThemeID) { - themes_reset_button_->SetEnabled( - is_using_default_theme_.GetValue().length() > 0); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentsPageView, views::View overrides: - -void ContentPageView::Layout() { - if (is_initialized()) - UpdateSyncControls(); - View::Layout(); -} - - -/////////////////////////////////////////////////////////////////////////////// -// ContentsPageView, ProfileSyncServiceObserver implementation: - -void ContentPageView::OnStateChanged() { - // If the UI controls are not yet initialized, then don't do anything. This - // can happen if the Options dialog is up, but the Content tab is not yet - // clicked. - if (is_initialized()) - Layout(); -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentPageView, private: - -void ContentPageView::InitPasswordSavingGroup() { - passwords_asktosave_radio_ = new views::RadioButton( - l10n_util::GetString(IDS_OPTIONS_PASSWORDS_ASKTOSAVE), - kPasswordSavingRadioGroup); - passwords_asktosave_radio_->set_listener(this); - passwords_asktosave_radio_->SetMultiLine(true); - passwords_neversave_radio_ = new views::RadioButton( - l10n_util::GetString(IDS_OPTIONS_PASSWORDS_NEVERSAVE), - kPasswordSavingRadioGroup); - passwords_neversave_radio_->set_listener(this); - passwords_neversave_radio_->SetMultiLine(true); - show_passwords_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_PASSWORDS_SHOWPASSWORDS)); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(passwords_asktosave_radio_, 1, 1, - GridLayout::FILL, GridLayout::LEADING); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(passwords_neversave_radio_, 1, 1, - GridLayout::FILL, GridLayout::LEADING); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(show_passwords_button_); - - passwords_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_OPTIONS_PASSWORDS_GROUP_NAME), L"", - true); -} - -void ContentPageView::InitFormAutofillGroup() { - change_autofill_settings_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_AUTOFILL_OPTIONS)); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int fill_column_view_set_id = 0; - const int leading_column_view_set_id = 1; - ColumnSet* column_set = layout->AddColumnSet(fill_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set = layout->AddColumnSet(leading_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, leading_column_view_set_id); - layout->AddView(change_autofill_settings_button_); - - form_autofill_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_AUTOFILL_SETTING_WINDOWS_GROUP_NAME), - L"", true); -} - -void ContentPageView::InitThemesGroup() { - themes_reset_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_THEMES_RESET_BUTTON)); - themes_gallery_link_ = new views::Link( - l10n_util::GetString(IDS_THEMES_GALLERY_BUTTON)); - themes_gallery_link_->SetController(this); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int double_column_view_set_id = 1; - ColumnSet* double_col_set = layout->AddColumnSet(double_column_view_set_id); - double_col_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - double_col_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - double_col_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, double_column_view_set_id); - layout->AddView(themes_reset_button_); - layout->AddView(themes_gallery_link_); - - themes_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_THEMES_GROUP_NAME), - L"", false); -} - -void ContentPageView::InitBrowsingDataGroup() { - import_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_OPTIONS_IMPORT_DATA_BUTTON)); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - // Add the browsing data import button. - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(import_button_); - - browsing_data_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_OPTIONS_BROWSING_DATA_GROUP_NAME), - L"", true); -} - -void ContentPageView::OnConfirmMessageAccept() { - sync_service_->DisableForUser(); - ProfileSyncService::SyncEvent(ProfileSyncService::STOP_FROM_OPTIONS); -} - -void ContentPageView::InitSyncGroup() { - sync_status_label_ = new views::Label; - sync_status_label_->SetMultiLine(true); - sync_status_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - sync_action_link_ = new views::Link(); - sync_action_link_->set_collapse_when_hidden(true); - sync_action_link_->SetController(this); - - privacy_dashboard_link_ = new views::Link(); - privacy_dashboard_link_->set_collapse_when_hidden(true); - privacy_dashboard_link_->SetController(this); - privacy_dashboard_link_->SetText( - l10n_util::GetString(IDS_SYNC_PRIVACY_DASHBOARD_LINK_LABEL)); - - sync_start_stop_button_ = new views::NativeButton(this, std::wstring()); - sync_customize_button_ = new views::NativeButton(this, std::wstring()); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(sync_status_label_, 3, 1, - GridLayout::FILL, GridLayout::LEADING); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(sync_action_link_, 3, 1); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(sync_start_stop_button_); - layout->AddView(sync_customize_button_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(privacy_dashboard_link_, 3, 1); - - sync_group_ = new OptionsGroupView(contents, - l10n_util::GetString(IDS_SYNC_OPTIONS_GROUP_NAME), std::wstring(), true); -} - -void ContentPageView::UpdateSyncControls() { - DCHECK(sync_service_); - std::wstring status_label; - std::wstring link_label; - std::wstring customize_button_label; - std::wstring button_label; - bool managed = sync_service_->IsManaged(); - bool sync_setup_completed = sync_service_->HasSyncSetupCompleted(); - bool status_has_error = sync_ui_util::GetStatusLabels(sync_service_, - &status_label, &link_label) == sync_ui_util::SYNC_ERROR; - customize_button_label = - l10n_util::GetString(IDS_SYNC_CUSTOMIZE_BUTTON_LABEL); - if (sync_setup_completed) { - button_label = l10n_util::GetString(IDS_SYNC_STOP_SYNCING_BUTTON_LABEL); - } else if (sync_service_->SetupInProgress()) { - button_label = l10n_util::GetString(IDS_SYNC_NTP_SETUP_IN_PROGRESS); - } else { - button_label = l10n_util::GetString(IDS_SYNC_START_SYNC_BUTTON_LABEL); - } - - sync_status_label_->SetText(status_label); - sync_start_stop_button_->SetEnabled( - !sync_service_->WizardIsVisible() && !managed); - sync_start_stop_button_->SetLabel(button_label); - sync_customize_button_->SetLabel(customize_button_label); - sync_customize_button_->SetVisible(sync_setup_completed && !status_has_error); - sync_customize_button_->SetEnabled(!managed); - sync_action_link_->SetText(link_label); - sync_action_link_->SetVisible(!link_label.empty()); - sync_action_link_->SetEnabled(!managed); - - if (status_has_error) { - sync_status_label_->set_background(CreateErrorBackground()); - sync_action_link_->set_background(CreateErrorBackground()); - } else { - sync_status_label_->set_background(NULL); - sync_action_link_->set_background(NULL); - } -} diff --git a/chrome/browser/views/options/content_page_view.h b/chrome/browser/views/options/content_page_view.h index 181f8a1..1335775 100644 --- a/chrome/browser/views/options/content_page_view.h +++ b/chrome/browser/views/options/content_page_view.h @@ -6,112 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/autofill/personal_data_manager.h" -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/sync/profile_sync_service.h" -#include "chrome/browser/views/options/options_page_view.h" -#include "chrome/browser/views/confirm_message_box_dialog.h" -#include "views/controls/button/button.h" -#include "views/controls/link.h" -#include "views/view.h" - -namespace views { -class Checkbox; -class Label; -class NativeButton; -class RadioButton; -} -class FileDisplayArea; -class OptionsGroupView; -class PrefService; - -//////////////////////////////////////////////////////////////////////////////// -// ContentPageView - -class ContentPageView : public OptionsPageView, - public views::LinkController, - public ProfileSyncServiceObserver, - public views::ButtonListener, - public ConfirmMessageBoxObserver { - public: - explicit ContentPageView(Profile* profile); - virtual ~ContentPageView(); - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::LinkController method. - virtual void LinkActivated(views::Link* source, int event_flags); - - // ConfirmMessageBoxObserver implementation. - virtual void OnConfirmMessageAccept(); - - // ProfileSyncServiceObserver method. - virtual void OnStateChanged(); - - protected: - // OptionsPageView implementation: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - // views::View overrides: - virtual void Layout(); - - private: - // Updates various sync controls based on the current sync state. - void UpdateSyncControls(); - - // Returns whether initialization of controls is done or not. - bool is_initialized() const { - // If initialization is already done, all the UI controls data members - // should be non-NULL. So check for one of them to determine if controls - // are already initialized or not. - return sync_group_ != NULL; - } - - // Init all the dialog controls. - void InitPasswordSavingGroup(); - void InitFormAutofillGroup(); - void InitBrowsingDataGroup(); - void InitThemesGroup(); - void InitSyncGroup(); - - // Controls for the Password Saving group - views::NativeButton* show_passwords_button_; - OptionsGroupView* passwords_group_; - views::RadioButton* passwords_asktosave_radio_; - views::RadioButton* passwords_neversave_radio_; - - // Controls for the Form Autofill group - views::NativeButton* change_autofill_settings_button_; - OptionsGroupView* form_autofill_group_; - - // Controls for the Themes group - OptionsGroupView* themes_group_; - views::NativeButton* themes_reset_button_; - views::Link* themes_gallery_link_; - - // Controls for the browsing data group. - OptionsGroupView* browsing_data_group_; - views::NativeButton* import_button_; - - // Controls for the Sync group. - OptionsGroupView* sync_group_; - views::Label* sync_status_label_; - views::Link* sync_action_link_; - views::NativeButton* sync_start_stop_button_; - views::NativeButton* sync_customize_button_; - views::Link* privacy_dashboard_link_; - - BooleanPrefMember ask_to_save_passwords_; - BooleanPrefMember form_autofill_enabled_; - StringPrefMember is_using_default_theme_; - - // Cached pointer to ProfileSyncService, if it exists. Kept up to date - // and NULL-ed out on destruction. - ProfileSyncService* sync_service_; - - DISALLOW_COPY_AND_ASSIGN(ContentPageView); -}; +#include "chrome/browser/ui/views/options/content_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_PAGE_VIEW_H_ + diff --git a/chrome/browser/views/options/content_settings_window_view.cc b/chrome/browser/views/options/content_settings_window_view.cc deleted file mode 100644 index 2a2146c..0000000 --- a/chrome/browser/views/options/content_settings_window_view.cc +++ /dev/null @@ -1,210 +0,0 @@ -// 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/options/content_settings_window_view.h" - -#include "app/l10n_util.h" -#include "base/stl_util-inl.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/options/advanced_page_view.h" -#include "chrome/browser/views/options/content_filter_page_view.h" -#include "chrome/browser/views/options/cookie_filter_page_view.h" -#include "chrome/browser/views/options/general_page_view.h" -#include "chrome/browser/views/options/plugin_filter_page_view.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/pref_names.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/label.h" -#include "views/widget/root_view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -static ContentSettingsWindowView* instance_ = NULL; -// Content setting dialog bounds padding. -const int kDialogPadding = 7; - -namespace browser { - -// Declared in browser_dialogs.h so others don't have to depend on our header. -void ShowContentSettingsWindow(gfx::NativeWindow parent_window, - ContentSettingsType content_type, - Profile* profile) { - DCHECK(profile); - // If there's already an existing options window, activate it and switch to - // the specified page. - // TODO(beng): note this is not multi-simultaneous-profile-safe. When we care - // about this case this will have to be fixed. - if (!instance_) { - instance_ = new ContentSettingsWindowView(profile); - views::Window::CreateChromeWindow(parent_window, gfx::Rect(), instance_); - } - instance_->ShowContentSettingsTab(content_type); -} - -} // namespace browser - -ContentSettingsWindowView::ContentSettingsWindowView(Profile* profile) - // Always show preferences for the original profile. Most state when off - // the record comes from the original profile, but we explicitly use - // the original profile to avoid potential problems. - : profile_(profile->GetOriginalProfile()), - label_(NULL), - listbox_(NULL), - current_page_(0) { - // We don't need to observe changes in this value. - last_selected_page_.Init(prefs::kContentSettingsWindowLastTabIndex, - profile->GetPrefs(), NULL); -} - -ContentSettingsWindowView::~ContentSettingsWindowView() { - STLDeleteElements(&pages_); -} - -void ContentSettingsWindowView::ShowContentSettingsTab( - ContentSettingsType page) { - // This will show invisible windows and bring visible windows to the front. - window()->Show(); - - if (page == CONTENT_SETTINGS_TYPE_DEFAULT) { - // Remember the last visited page from local state. - page = static_cast<ContentSettingsType>(last_selected_page_.GetValue()); - if (page == CONTENT_SETTINGS_TYPE_DEFAULT) - page = CONTENT_SETTINGS_TYPE_COOKIES; - } - // If the page number is out of bounds, reset to the first tab. - if (page < 0 || page >= listbox_->GetRowCount()) - page = CONTENT_SETTINGS_TYPE_COOKIES; - - listbox_->SelectRow(static_cast<int>(page)); - ShowSettingsPage(listbox_->SelectedRow()); -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentSettingsWindowView, views::DialogDelegate implementation: - -std::wstring ContentSettingsWindowView::GetWindowTitle() const { - return l10n_util::GetString(IDS_CONTENT_SETTINGS_TITLE); -} - -void ContentSettingsWindowView::WindowClosing() { - instance_ = NULL; -} - -bool ContentSettingsWindowView::Cancel() { - return GetCurrentContentSettingsTabView()->CanClose(); -} - -views::View* ContentSettingsWindowView::GetContentsView() { - return this; -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentSettingsWindowView, views::Listbox::Listener implementation: - -void ContentSettingsWindowView::ListboxSelectionChanged( - views::Listbox* sender) { - DCHECK_EQ(listbox_, sender); - ShowSettingsPage(listbox_->SelectedRow()); - last_selected_page_.SetValue(current_page_); -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentSettingsWindowView, views::View overrides: - -void ContentSettingsWindowView::Layout() { - int listbox_width = views::Window::GetLocalizedContentsWidth( - IDS_CONTENT_SETTINGS_DIALOG_LISTBOX_WIDTH_CHARS); - label_->SetBounds(kDialogPadding, - kDialogPadding, - listbox_width, - label_->GetPreferredSize().height()); - - listbox_->SetBounds(kDialogPadding, - 2 * kDialogPadding + label_->height(), - listbox_width, - height() - (3 * kDialogPadding) - label_->height()); - - if (pages_[current_page_]->GetParent()) { - pages_[current_page_]->SetBounds( - 2 * kDialogPadding + listbox_width, - 2 * kDialogPadding + label_->height(), - width() - (3 * kDialogPadding) - listbox_width, - height() - (2 * kDialogPadding)); - } -} - -gfx::Size ContentSettingsWindowView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_CONTENT_SETTINGS_DIALOG_WIDTH_CHARS, - IDS_CONTENT_SETTINGS_DIALOG_HEIGHT_LINES)); -} - -void ContentSettingsWindowView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - // Can't init before we're inserted into a Container, because we require a - // HWND to parent native child controls to. - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// ContentSettingsWindowView, private: - -void ContentSettingsWindowView::Init() { - // Make sure we don't leak memory by calling this twice. - DCHECK(!listbox_); - - label_ = new views::Label( - l10n_util::GetStringUTF16(IDS_CONTENT_SETTINGS_FEATURES_LABEL)); - label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label_); - - pages_.push_back(new CookieFilterPageView(profile_)); - pages_.push_back( - new ContentFilterPageView(profile_, CONTENT_SETTINGS_TYPE_IMAGES)); - pages_.push_back( - new ContentFilterPageView(profile_, CONTENT_SETTINGS_TYPE_JAVASCRIPT)); - pages_.push_back(new PluginFilterPageView(profile_)); - pages_.push_back( - new ContentFilterPageView(profile_, CONTENT_SETTINGS_TYPE_POPUPS)); - pages_.push_back( - new ContentFilterPageView(profile_, CONTENT_SETTINGS_TYPE_GEOLOCATION)); - pages_.push_back( - new ContentFilterPageView(profile_, CONTENT_SETTINGS_TYPE_NOTIFICATIONS)); - for (size_t i = 0; i < pages_.size(); ++i) { - pages_[i]->set_parent_owned(false); - } - DCHECK_EQ(static_cast<int>(pages_.size()), CONTENT_SETTINGS_NUM_TYPES); - - std::vector<string16> strings; - strings.push_back(l10n_util::GetStringUTF16(IDS_COOKIES_TAB_LABEL)); - strings.push_back(l10n_util::GetStringUTF16(IDS_IMAGES_TAB_LABEL)); - strings.push_back(l10n_util::GetStringUTF16(IDS_JAVASCRIPT_TAB_LABEL)); - strings.push_back(l10n_util::GetStringUTF16(IDS_PLUGIN_TAB_LABEL)); - strings.push_back(l10n_util::GetStringUTF16(IDS_POPUP_TAB_LABEL)); - strings.push_back(l10n_util::GetStringUTF16(IDS_GEOLOCATION_TAB_LABEL)); - strings.push_back(l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_TAB_LABEL)); - listbox_ = new views::Listbox(strings, this); - AddChildView(listbox_); - CHECK_EQ(strings.size(), pages_.size()); -} - -void ContentSettingsWindowView::ShowSettingsPage(int page) { - if (pages_[current_page_]->GetParent()) - RemoveChildView(pages_[current_page_]); - current_page_ = page; - AddChildView(pages_[current_page_]); - Layout(); - SchedulePaint(); -} - -const OptionsPageView* - ContentSettingsWindowView::GetCurrentContentSettingsTabView() const { - return static_cast<OptionsPageView*>(pages_[current_page_]); -} diff --git a/chrome/browser/views/options/content_settings_window_view.h b/chrome/browser/views/options/content_settings_window_view.h index 2b843b4..a3bc919 100644 --- a/chrome/browser/views/options/content_settings_window_view.h +++ b/chrome/browser/views/options/content_settings_window_view.h @@ -6,87 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_SETTINGS_WINDOW_VIEW_H_ #pragma once -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/common/content_settings_types.h" -#include "views/controls/listbox/listbox.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -class Profile; -class MessageLoop; -class OptionsPageView; - -namespace views { -class Label; -} // namespace views - -/////////////////////////////////////////////////////////////////////////////// -// ContentSettingsWindowView -// -// The contents of the Options dialog window. -// -class ContentSettingsWindowView : public views::View, - public views::DialogDelegate, - public views::Listbox::Listener { - public: - explicit ContentSettingsWindowView(Profile* profile); - virtual ~ContentSettingsWindowView(); - - // Shows the Tab corresponding to the specified Content Settings page. - void ShowContentSettingsTab(ContentSettingsType page); - - protected: - // views::View overrides: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // views::DialogDelegate implementation: - virtual int GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual bool Cancel(); - virtual views::View* GetContentsView(); - - // views::Listbox::Listener implementation: - virtual void ListboxSelectionChanged(views::Listbox* sender); - - private: - // Initializes the view. - void Init(); - - // Makes |pages_[page]| the currently visible page. - void ShowSettingsPage(int page); - - // Returns the currently selected OptionsPageView. - const OptionsPageView* GetCurrentContentSettingsTabView() const; - - // The Profile associated with these options. - Profile* profile_; - - // The label above the left box. - views::Label* label_; - - // The listbox used to select a page. - views::Listbox* listbox_; - - // The last page the user was on when they opened the Options window. - IntegerPrefMember last_selected_page_; - - // Stores the index of the currently visible page. - int current_page_; - - // Stores the possible content pages displayed on the right. - // |pages_[current_page_]| is the currently displayed page, and it's the only - // parented View in |pages_|. - std::vector<View*> pages_; - - DISALLOW_COPY_AND_ASSIGN(ContentSettingsWindowView); -}; +#include "chrome/browser/ui/views/options/content_settings_window_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_CONTENT_SETTINGS_WINDOW_VIEW_H_ diff --git a/chrome/browser/views/options/cookie_filter_page_view.cc b/chrome/browser/views/options/cookie_filter_page_view.cc deleted file mode 100644 index d8ab81b..0000000 --- a/chrome/browser/views/options/cookie_filter_page_view.cc +++ /dev/null @@ -1,116 +0,0 @@ -// 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/options/cookie_filter_page_view.h" - -#include "app/l10n_util.h" -#include "chrome/browser/host_content_settings_map.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/show_options_url.h" -#include "chrome/browser/views/options/cookies_view.h" -#include "chrome/common/pref_names.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/button/checkbox.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" - -CookieFilterPageView::CookieFilterPageView(Profile* profile) - : ContentFilterPageView(profile, CONTENT_SETTINGS_TYPE_COOKIES), - block_3rdparty_check_(NULL), - clear_on_close_check_(NULL), - show_cookies_button_(NULL) { - clear_site_data_on_exit_.Init(prefs::kClearSiteDataOnExit, - profile->GetPrefs(), NULL); -} - -CookieFilterPageView::~CookieFilterPageView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieFilterPageView, ContentFilterPageView override: - -void CookieFilterPageView::InitControlLayout() { - ContentFilterPageView::InitControlLayout(); - - using views::GridLayout; - - GridLayout* layout = static_cast<GridLayout*>(GetLayoutManager()); - const int single_column_set_id = 0; - layout->AddPaddingRow(0, kUnrelatedControlLargeVerticalSpacing); - - block_3rdparty_check_ = new views::Checkbox( - l10n_util::GetString(IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX)); - block_3rdparty_check_->set_listener(this); - - layout->StartRow(0, single_column_set_id); - layout->AddView(block_3rdparty_check_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Now that this has been added to the view hierarchy, it's safe to call - // SetChecked() on it. - block_3rdparty_check_->SetChecked( - profile()->GetHostContentSettingsMap()->BlockThirdPartyCookies()); - - clear_on_close_check_ = new views::Checkbox( - l10n_util::GetString(IDS_COOKIES_CLEAR_WHEN_CLOSE_CHKBOX)); - clear_on_close_check_->SetMultiLine(true); - clear_on_close_check_->set_listener(this); - - layout->StartRow(0, single_column_set_id); - layout->AddView(clear_on_close_check_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - show_cookies_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_COOKIES_SHOW_COOKIES_BUTTON)); - - layout->StartRow(0, single_column_set_id); - layout->AddView(show_cookies_button_, 1, 1, GridLayout::LEADING, - GridLayout::FILL); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - views::Link* flash_settings_link = new views::Link( - l10n_util::GetString(IDS_FLASH_STORAGE_SETTINGS)); - flash_settings_link->SetController(this); - - layout->StartRow(0, single_column_set_id); - layout->AddView(flash_settings_link, 1, 1, GridLayout::LEADING, - GridLayout::FILL); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieFilterPageView, OptionsPageView implementation: - -void CookieFilterPageView::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kClearSiteDataOnExit) { - clear_on_close_check_->SetChecked( - clear_site_data_on_exit_.GetValue()); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieFilterPageView, views::ButtonListener implementation: - -void CookieFilterPageView::ButtonPressed(views::Button* sender, - const views::Event& event) { - HostContentSettingsMap* settings_map = profile()->GetHostContentSettingsMap(); - if (sender == block_3rdparty_check_) { - settings_map->SetBlockThirdPartyCookies(block_3rdparty_check_->checked()); - } else if (sender == clear_on_close_check_) { - clear_site_data_on_exit_.SetValue(clear_on_close_check_->checked()); - } else if (sender == show_cookies_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ShowCookies"), NULL); - CookiesView::ShowCookiesWindow(profile()); - } else { - ContentFilterPageView::ButtonPressed(sender, event); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// CookieFilterPageView, views::LinkController implementation: - -void CookieFilterPageView::LinkActivated(views::Link* source, int event_flags) { - browser::ShowOptionsURL(profile(), - GURL(l10n_util::GetString(IDS_FLASH_STORAGE_URL))); -} diff --git a/chrome/browser/views/options/cookie_filter_page_view.h b/chrome/browser/views/options/cookie_filter_page_view.h index 0b9b9f7..3168e0e 100644 --- a/chrome/browser/views/options/cookie_filter_page_view.h +++ b/chrome/browser/views/options/cookie_filter_page_view.h @@ -6,47 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_COOKIE_FILTER_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/views/options/content_filter_page_view.h" - -#include "chrome/browser/prefs/pref_member.h" - -namespace views { -class Checkbox; -} - -//////////////////////////////////////////////////////////////////////////////// -// CookieFilterPageView class is used to render the cookie content settings tab. - -class CookieFilterPageView : public ContentFilterPageView, - public views::LinkController { - public: - explicit CookieFilterPageView(Profile* profile); - virtual ~CookieFilterPageView(); - - private: - // Overridden from ContentFilterPageView: - virtual void InitControlLayout(); - - // OptionsPageView implementation: - virtual void NotifyPrefChanged(const std::string* pref_name); - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - // Controls for the cookie filter tab page view. - views::Checkbox* block_3rdparty_check_; - views::Checkbox* clear_on_close_check_; - views::NativeButton* show_cookies_button_; - - // Clear locally stored site data on exit pref. - BooleanPrefMember clear_site_data_on_exit_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(CookieFilterPageView); -}; +#include "chrome/browser/ui/views/options/cookie_filter_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_COOKIE_FILTER_PAGE_VIEW_H_ diff --git a/chrome/browser/views/options/cookies_view.cc b/chrome/browser/views/options/cookies_view.cc deleted file mode 100644 index 5e2b6d0..0000000 --- a/chrome/browser/views/options/cookies_view.cc +++ /dev/null @@ -1,397 +0,0 @@ -// 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/options/cookies_view.h" - -#include <algorithm> - -#include "app/l10n_util.h" -#include "base/message_loop.h" -#include "base/string_util.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/appcache_info_view.h" -#include "chrome/browser/views/cookie_info_view.h" -#include "chrome/browser/views/database_info_view.h" -#include "chrome/browser/views/indexed_db_info_view.h" -#include "chrome/browser/views/local_storage_info_view.h" -#include "gfx/canvas.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/base/cookie_monster.h" -#include "views/border.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/button/native_button.h" -#include "views/controls/tree/tree_view.h" -#include "views/controls/textfield/textfield.h" -#include "views/standard_layout.h" - -// static -views::Window* CookiesView::instance_ = NULL; -static const int kSearchFilterDelayMs = 500; - -/////////////////////////////////////////////////////////////////////////////// -// CookiesTreeView -// Overridden to handle Delete key presses - -class CookiesTreeView : public views::TreeView { - public: - explicit CookiesTreeView(CookiesTreeModel* cookies_model); - virtual ~CookiesTreeView() {} - - // Removes the items associated with the selected node in the TreeView - void RemoveSelectedItems(); - - private: - DISALLOW_COPY_AND_ASSIGN(CookiesTreeView); -}; - -CookiesTreeView::CookiesTreeView(CookiesTreeModel* cookies_model) { - SetModel(cookies_model); - SetRootShown(false); - SetEditable(false); -} - -void CookiesTreeView::RemoveSelectedItems() { - TreeModelNode* selected_node = GetSelectedNode(); - if (selected_node) { - static_cast<CookiesTreeModel*>(model())->DeleteCookieNode( - static_cast<CookieTreeNode*>(GetSelectedNode())); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView::InfoPanelView -// Overridden to handle layout of the various info views. -// -// This view is a child of the CookiesView and participates -// in its GridLayout. The various info views are all children -// of this view. Only one child is expected to be visible at a time. - -class CookiesView::InfoPanelView : public views::View { - public: - virtual void Layout() { - int child_count = GetChildViewCount(); - for (int i = 0; i < child_count; ++i) - GetChildViewAt(i)->SetBounds(0, 0, width(), height()); - } - - virtual gfx::Size GetPreferredSize() { - DCHECK(GetChildViewCount() > 0); - return GetChildViewAt(0)->GetPreferredSize(); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, public: - -// static -void CookiesView::ShowCookiesWindow(Profile* profile) { - if (!instance_) { - CookiesView* cookies_view = new CookiesView(profile); - instance_ = views::Window::CreateChromeWindow( - NULL, gfx::Rect(), cookies_view); - } - if (!instance_->IsVisible()) { - instance_->Show(); - } else { - instance_->Activate(); - } -} - -CookiesView::~CookiesView() { - cookies_tree_->SetModel(NULL); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, TreeModelObserver overrides: - -void CookiesView::TreeNodesAdded(TreeModel* model, - TreeModelNode* parent, - int start, - int count) { - UpdateRemoveButtonsState(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, views::Buttonlistener implementation: - -void CookiesView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == remove_button_) { - cookies_tree_->RemoveSelectedItems(); - if (cookies_tree_model_->GetRoot()->GetChildCount() == 0) - UpdateForEmptyState(); - } else if (sender == remove_all_button_) { - cookies_tree_model_->DeleteAllStoredObjects(); - UpdateForEmptyState(); - } else if (sender == clear_search_button_) { - ResetSearchQuery(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, views::Textfield::Controller implementation: - -void CookiesView::ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents) { - clear_search_button_->SetEnabled(!search_field_->text().empty()); - search_update_factory_.RevokeAll(); - MessageLoop::current()->PostDelayedTask(FROM_HERE, - search_update_factory_.NewRunnableMethod( - &CookiesView::UpdateSearchResults), kSearchFilterDelayMs); -} - -bool CookiesView::HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key) { - if (key.GetKeyboardCode() == app::VKEY_ESCAPE) { - ResetSearchQuery(); - } else if (key.GetKeyboardCode() == app::VKEY_RETURN) { - search_update_factory_.RevokeAll(); - UpdateSearchResults(); - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, views::DialogDelegate implementation: - -std::wstring CookiesView::GetWindowTitle() const { - return l10n_util::GetString(IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE); -} - -void CookiesView::WindowClosing() { - instance_ = NULL; -} - -views::View* CookiesView::GetContentsView() { - return this; -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, views::View overrides: - -void CookiesView::Layout() { - // Lay out the Remove/Remove All buttons in the parent view. - gfx::Size ps = remove_button_->GetPreferredSize(); - gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false); - int y_buttons = parent_bounds.bottom() - ps.height() - kButtonVEdgeMargin; - - remove_button_->SetBounds(kPanelHorizMargin, y_buttons, ps.width(), - ps.height()); - - ps = remove_all_button_->GetPreferredSize(); - int remove_all_x = remove_button_->x() + remove_button_->width() + - kRelatedControlHorizontalSpacing; - remove_all_button_->SetBounds(remove_all_x, y_buttons, ps.width(), - ps.height()); - - // Lay out this View - View::Layout(); -} - -gfx::Size CookiesView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_COOKIES_DIALOG_WIDTH_CHARS, - IDS_COOKIES_DIALOG_HEIGHT_LINES)); -} - -void CookiesView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, views::TreeViewController overrides: - -void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) { - UpdateRemoveButtonsState(); - CookieTreeNode::DetailedInfo detailed_info = - static_cast<CookieTreeNode*>(tree_view->GetSelectedNode())-> - GetDetailedInfo(); - if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) { - UpdateVisibleDetailedInfo(cookie_info_view_); - cookie_info_view_->SetCookie(detailed_info.cookie->Domain(), - *detailed_info.cookie); - } else if (detailed_info.node_type == - CookieTreeNode::DetailedInfo::TYPE_DATABASE) { - UpdateVisibleDetailedInfo(database_info_view_); - database_info_view_->SetDatabaseInfo(*detailed_info.database_info); - } else if (detailed_info.node_type == - CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) { - UpdateVisibleDetailedInfo(local_storage_info_view_); - local_storage_info_view_->SetLocalStorageInfo( - *detailed_info.local_storage_info); - } else if (detailed_info.node_type == - CookieTreeNode::DetailedInfo::TYPE_APPCACHE) { - UpdateVisibleDetailedInfo(appcache_info_view_); - appcache_info_view_->SetAppCacheInfo(detailed_info.appcache_info); - } else if (detailed_info.node_type == - CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB) { - UpdateVisibleDetailedInfo(indexed_db_info_view_); - indexed_db_info_view_->SetIndexedDBInfo(*detailed_info.indexed_db_info); - } else { - UpdateVisibleDetailedInfo(cookie_info_view_); - cookie_info_view_->ClearCookieDisplay(); - } -} - -void CookiesView::OnTreeViewKeyDown(app::KeyboardCode keycode) { - if (keycode == app::VKEY_DELETE) - cookies_tree_->RemoveSelectedItems(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, public: - -void CookiesView::UpdateSearchResults() { - cookies_tree_model_->UpdateSearchResults(search_field_->text()); - UpdateRemoveButtonsState(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CookiesView, private: - -CookiesView::CookiesView(Profile* profile) - : - search_label_(NULL), - search_field_(NULL), - clear_search_button_(NULL), - description_label_(NULL), - cookies_tree_(NULL), - info_panel_(NULL), - cookie_info_view_(NULL), - database_info_view_(NULL), - local_storage_info_view_(NULL), - appcache_info_view_(NULL), - indexed_db_info_view_(NULL), - remove_button_(NULL), - remove_all_button_(NULL), - profile_(profile), - ALLOW_THIS_IN_INITIALIZER_LIST(search_update_factory_(this)) { -} - -void CookiesView::Init() { - search_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_SEARCH_LABEL)); - search_field_ = new views::Textfield; - search_field_->SetController(this); - clear_search_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_COOKIES_CLEAR_SEARCH_LABEL)); - clear_search_button_->SetEnabled(false); - description_label_ = new views::Label( - l10n_util::GetString(IDS_COOKIES_INFO_LABEL)); - description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - cookies_tree_model_.reset(new CookiesTreeModel( - profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(), - new BrowsingDataDatabaseHelper(profile_), - new BrowsingDataLocalStorageHelper(profile_), - NULL, - new BrowsingDataAppCacheHelper(profile_), - BrowsingDataIndexedDBHelper::Create(profile_))); - cookies_tree_model_->AddObserver(this); - - info_panel_ = new InfoPanelView; - cookie_info_view_ = new CookieInfoView(false); - database_info_view_ = new DatabaseInfoView; - local_storage_info_view_ = new LocalStorageInfoView; - appcache_info_view_ = new AppCacheInfoView; - indexed_db_info_view_ = new IndexedDBInfoView; - info_panel_->AddChildView(cookie_info_view_); - info_panel_->AddChildView(database_info_view_); - info_panel_->AddChildView(local_storage_info_view_); - info_panel_->AddChildView(appcache_info_view_); - info_panel_->AddChildView(indexed_db_info_view_); - - cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get()); - remove_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_COOKIES_REMOVE_LABEL)); - remove_all_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_COOKIES_REMOVE_ALL_LABEL)); - - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int five_column_layout_id = 0; - ColumnSet* column_set = layout->AddColumnSet(five_column_layout_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::USE_PREF, 0, 0); - - const int single_column_layout_id = 1; - column_set = layout->AddColumnSet(single_column_layout_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, five_column_layout_id); - layout->AddView(search_label_); - layout->AddView(search_field_); - layout->AddView(clear_search_button_); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_layout_id); - layout->AddView(description_label_); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(1, single_column_layout_id); - cookies_tree_->set_lines_at_root(true); - cookies_tree_->set_auto_expand_children(true); - layout->AddView(cookies_tree_); - - cookies_tree_->SetController(this); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_layout_id); - layout->AddView(info_panel_); - - // Add the Remove/Remove All buttons to the ClientView - View* parent = GetParent(); - parent->AddChildView(remove_button_); - parent->AddChildView(remove_all_button_); - if (!cookies_tree_model_.get()->GetRoot()->GetChildCount()) { - UpdateForEmptyState(); - } else { - UpdateVisibleDetailedInfo(cookie_info_view_); - UpdateRemoveButtonsState(); - } -} - -void CookiesView::ResetSearchQuery() { - search_field_->SetText(std::wstring()); - clear_search_button_->SetEnabled(false); - UpdateSearchResults(); -} - -void CookiesView::UpdateForEmptyState() { - cookie_info_view_->ClearCookieDisplay(); - remove_button_->SetEnabled(false); - remove_all_button_->SetEnabled(false); - UpdateVisibleDetailedInfo(cookie_info_view_); -} - -void CookiesView::UpdateRemoveButtonsState() { - remove_button_->SetEnabled(cookies_tree_model_->GetRoot()-> - GetTotalNodeCount() > 1 && cookies_tree_->GetSelectedNode()); - remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()-> - GetTotalNodeCount() > 1); -} - -void CookiesView::UpdateVisibleDetailedInfo(views::View* view) { - cookie_info_view_->SetVisible(view == cookie_info_view_); - database_info_view_->SetVisible(view == database_info_view_); - local_storage_info_view_->SetVisible(view == local_storage_info_view_); - appcache_info_view_->SetVisible(view == appcache_info_view_); - indexed_db_info_view_->SetVisible(view == indexed_db_info_view_); -} diff --git a/chrome/browser/views/options/cookies_view.h b/chrome/browser/views/options/cookies_view.h index dc6b9ff..dd74019 100644 --- a/chrome/browser/views/options/cookies_view.h +++ b/chrome/browser/views/options/cookies_view.h @@ -6,154 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_COOKIES_VIEW_H_ #pragma once -#include <string> - -#include "base/task.h" -#include "chrome/browser/cookies_tree_model.h" -#include "net/base/cookie_monster.h" -#include "views/controls/button/button.h" -#include "views/controls/tree/tree_view.h" -#include "views/controls/textfield/textfield.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -namespace views { - -class Label; -class NativeButton; - -} // namespace views - - -class AppCacheInfoView; -class CookieInfoView; -class CookiesTreeView; -class DatabaseInfoView; -class IndexedDBInfoView; -class LocalStorageInfoView; -class Profile; -class Timer; -class TreeModel; -class TreeModelNode; - - -class CookiesView : public CookiesTreeModel::Observer, - public views::View, - public views::DialogDelegate, - public views::ButtonListener, - public views::TreeViewController, - public views::Textfield::Controller { - public: - // Show the Cookies Window, creating one if necessary. - static void ShowCookiesWindow(Profile* profile); - - virtual ~CookiesView(); - - // Updates the display to show only the search results. - void UpdateSearchResults(); - - // Begin TreeModelObserver implementation. - virtual void TreeNodesAdded(TreeModel* model, - TreeModelNode* parent, - int start, - int count); - virtual void TreeNodesRemoved(TreeModel* model, - TreeModelNode* parent, - int start, - int count) {} - virtual void TreeNodeChanged(TreeModel* model, TreeModelNode* node) {} - // End TreeModelObserver implementation. - - // views::ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::TreeViewController implementation. - virtual void OnTreeViewSelectionChanged(views::TreeView* tree_view); - - // views::TreeViewController implementation. - virtual void OnTreeViewKeyDown(app::KeyboardCode keycode); - - // views::Textfield::Controller implementation. - virtual void ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key); - - // views::WindowDelegate implementation. - virtual int GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - virtual views::View* GetInitiallyFocusedView() { - return search_field_; - } - - virtual bool CanResize() const { return true; } - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual views::View* GetContentsView(); - - // views::View overrides: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - private: - class InfoPanelView; - - // Use the static factory method to show. - explicit CookiesView(Profile* profile); - - // Initialize the dialog contents and layout. - void Init(); - - // Resets the display to what it would be if there were no search query. - void ResetSearchQuery(); - - // Update the UI when there are no cookies. - void UpdateForEmptyState(); - - // Enable or disable the remove and remove all buttons. - void UpdateRemoveButtonsState(); - - // Updates view to be visible inside detailed_info_view_; - void UpdateVisibleDetailedInfo(views::View* view); - - // Assorted dialog controls - views::Label* search_label_; - views::Textfield* search_field_; - views::NativeButton* clear_search_button_; - views::Label* description_label_; - CookiesTreeView* cookies_tree_; - InfoPanelView* info_panel_; - CookieInfoView* cookie_info_view_; - DatabaseInfoView* database_info_view_; - LocalStorageInfoView* local_storage_info_view_; - AppCacheInfoView* appcache_info_view_; - IndexedDBInfoView* indexed_db_info_view_; - views::NativeButton* remove_button_; - views::NativeButton* remove_all_button_; - - // The Cookies Tree model - scoped_ptr<CookiesTreeModel> cookies_tree_model_; - - // The Profile for which Cookies are displayed - Profile* profile_; - - // A factory to construct Runnable Methods so that we can be called back to - // re-evaluate the model after the search query string changes. - ScopedRunnableMethodFactory<CookiesView> search_update_factory_; - - // Our containing window. If this is non-NULL there is a visible Cookies - // window somewhere. - static views::Window* instance_; - - DISALLOW_COPY_AND_ASSIGN(CookiesView); -}; +#include "chrome/browser/ui/views/options/cookies_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_COOKIES_VIEW_H_ + diff --git a/chrome/browser/views/options/exception_editor_view.cc b/chrome/browser/views/options/exception_editor_view.cc deleted file mode 100644 index 93ca859..0000000 --- a/chrome/browser/views/options/exception_editor_view.cc +++ /dev/null @@ -1,175 +0,0 @@ -// 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/options/exception_editor_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/content_exceptions_table_model.h" -#include "googleurl/src/url_canon.h" -#include "googleurl/src/url_parse.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/grid_layout.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -ExceptionEditorView::ExceptionEditorView( - Delegate* delegate, - ContentExceptionsTableModel* model, - bool allow_off_the_record, - int index, - const HostContentSettingsMap::Pattern& pattern, - ContentSetting setting, - bool is_off_the_record) - : delegate_(delegate), - model_(model), - cb_model_(model->content_type()), - allow_off_the_record_(allow_off_the_record), - index_(index), - pattern_(pattern), - setting_(setting), - is_off_the_record_(is_off_the_record) { - // Geolocation exceptions are handled by SimpleContentExceptionsView. - DCHECK_NE(setting_, CONTENT_SETTINGS_TYPE_GEOLOCATION); - // Notification exceptions are handled by SimpleContentExceptionsView. - DCHECK_NE(setting_, CONTENT_SETTINGS_TYPE_NOTIFICATIONS); - Init(); -} - -void ExceptionEditorView::Show(gfx::NativeWindow parent) { - views::Window* window = - views::Window::CreateChromeWindow(parent, gfx::Rect(), this); - window->Show(); - GetDialogClientView()->UpdateDialogButtons(); - pattern_tf_->SelectAll(); - pattern_tf_->RequestFocus(); -} - -bool ExceptionEditorView::IsModal() const { - return true; -} - -std::wstring ExceptionEditorView::GetWindowTitle() const { - return is_new() ? l10n_util::GetString(IDS_EXCEPTION_EDITOR_NEW_TITLE) : - l10n_util::GetString(IDS_EXCEPTION_EDITOR_TITLE); -} - -bool ExceptionEditorView::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) { - return IsPatternValid(HostContentSettingsMap::Pattern( - UTF16ToUTF8(pattern_tf_->text())), - incognito_cb_->checked()); - } - return true; -} - -bool ExceptionEditorView::Cancel() { - return true; -} - -bool ExceptionEditorView::Accept() { - HostContentSettingsMap::Pattern new_pattern(UTF16ToUTF8(pattern_tf_->text())); - ContentSetting setting = - cb_model_.SettingForIndex(action_cb_->selected_item()); - bool is_off_the_record = incognito_cb_->checked(); - delegate_->AcceptExceptionEdit( - new_pattern, setting, is_off_the_record, index_, is_new()); - return true; -} - -views::View* ExceptionEditorView::GetContentsView() { - return this; -} - -void ExceptionEditorView::ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents) { - GetDialogClientView()->UpdateDialogButtons(); - UpdateImageView(pattern_iv_, IsPatternValid(HostContentSettingsMap::Pattern( - UTF16ToUTF8(pattern_tf_->text())), incognito_cb_->checked())); -} - -bool ExceptionEditorView::HandleKeystroke( - views::Textfield* sender, - const views::Textfield::Keystroke& key) { - return false; -} - -void ExceptionEditorView::Init() { - using views::GridLayout; - - pattern_tf_ = new views::Textfield(); - pattern_tf_->SetText(UTF8ToUTF16(pattern_.AsString())); - pattern_tf_->SetController(this); - - pattern_iv_ = new views::ImageView; - - UpdateImageView(pattern_iv_, IsPatternValid(HostContentSettingsMap::Pattern( - UTF16ToUTF8(pattern_tf_->text())), is_off_the_record_)); - - action_cb_ = new views::Combobox(&cb_model_); - if (!is_new()) - action_cb_->SetSelectedItem(cb_model_.IndexForSetting(setting_)); - - incognito_cb_ = new views::Checkbox( - l10n_util::GetString(IDS_EXCEPTION_EDITOR_OTR_TITLE)); - incognito_cb_->SetChecked(is_off_the_record_); - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - // For the Textfields. - views::ColumnSet* column_set = layout->AddColumnSet(1); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - // Add the contents. - layout->StartRow(0, 1); - layout->AddView(CreateLabel(IDS_EXCEPTION_EDITOR_PATTERN_TITLE)); - layout->AddView(pattern_tf_); - layout->AddView(pattern_iv_); - - layout->StartRowWithPadding(0, 1, 0, kRelatedControlVerticalSpacing); - layout->AddView(CreateLabel(IDS_EXCEPTION_EDITOR_ACTION_TITLE)); - layout->AddView(action_cb_); - - if (allow_off_the_record_) { - layout->StartRowWithPadding(0, 1, 0, kRelatedControlVerticalSpacing); - layout->AddView(incognito_cb_, 3, 1, GridLayout::FILL, GridLayout::FILL); - } -} - -views::Label* ExceptionEditorView::CreateLabel(int message_id) { - views::Label* label = new views::Label(l10n_util::GetString(message_id)); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - return label; -} - -bool ExceptionEditorView::IsPatternValid( - const HostContentSettingsMap::Pattern& pattern, - bool is_off_the_record) const { - bool is_valid_pattern = pattern.IsValid() && - (model_->IndexOfExceptionByPattern(pattern, is_off_the_record) == -1); - - return is_new() ? is_valid_pattern : (!pattern.AsString().empty() && - ((pattern_ == pattern) || is_valid_pattern)); -} - -void ExceptionEditorView::UpdateImageView(views::ImageView* image_view, - bool is_valid) { - return image_view->SetImage( - ResourceBundle::GetSharedInstance().GetBitmapNamed( - is_valid ? IDR_INPUT_GOOD : IDR_INPUT_ALERT)); -} diff --git a/chrome/browser/views/options/exception_editor_view.h b/chrome/browser/views/options/exception_editor_view.h index 3dfab19..fb63617 100644 --- a/chrome/browser/views/options/exception_editor_view.h +++ b/chrome/browser/views/options/exception_editor_view.h @@ -6,109 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_EXCEPTION_EDITOR_VIEW_H_ #pragma once -#include <string> - -#include "chrome/browser/content_setting_combo_model.h" -#include "chrome/browser/host_content_settings_map.h" -#include "chrome/common/content_settings.h" -#include "chrome/common/content_settings_types.h" -#include "views/window/dialog_delegate.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/textfield/textfield.h" - -namespace views { -class ImageView; -class Label; -} - -class ContentExceptionsTableModel; - -// ExceptionEditorView is responsible for showing a dialog that allows the user -// to create or edit a single content exception. If the user clicks ok the -// delegate is notified and completes the edit. -// -// To use an ExceptionEditorView create one and invoke Show on it. -// ExceptionEditorView is deleted when the dialog closes. -class ExceptionEditorView : public views::View, - public views::Textfield::Controller, - public views::DialogDelegate { - public: - class Delegate { - public: - // Invoked when the user accepts the edit. - virtual void AcceptExceptionEdit( - const HostContentSettingsMap::Pattern& pattern, - ContentSetting setting, - bool is_off_the_record, - int index, - bool is_new) = 0; - - protected: - virtual ~Delegate() {} - }; - - // Creates a new ExceptionEditorView with the supplied args. |index| is the - // index into the ContentExceptionsTableModel of the exception. This is not - // used by ExceptionEditorView but instead passed to the delegate. - ExceptionEditorView(Delegate* delegate, - ContentExceptionsTableModel* model, - bool allow_off_the_record, - int index, - const HostContentSettingsMap::Pattern& pattern, - ContentSetting setting, - bool is_off_the_record); - virtual ~ExceptionEditorView() {} - - void Show(gfx::NativeWindow parent); - - // views::DialogDelegate overrides. - virtual bool IsModal() const; - virtual std::wstring GetWindowTitle() const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual bool Cancel(); - virtual bool Accept(); - virtual views::View* GetContentsView(); - - // views::Textfield::Controller overrides. Updates whether the user can - // accept the dialog as well as updating image views showing whether value is - // valid. - virtual void ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key); - - private: - void Init(); - - views::Label* CreateLabel(int message_id); - - // Returns true if we're adding a new item. - bool is_new() const { return index_ == -1; } - - bool IsPatternValid(const HostContentSettingsMap::Pattern& pattern, - bool is_off_the_record) const; - - void UpdateImageView(views::ImageView* image_view, bool is_valid); - - Delegate* delegate_; - ContentExceptionsTableModel* model_; - ContentSettingComboModel cb_model_; - - // Index of the item being edited. If -1, indices this is a new entry. - const bool allow_off_the_record_; - const int index_; - const HostContentSettingsMap::Pattern pattern_; - const ContentSetting setting_; - const bool is_off_the_record_; - - views::Textfield* pattern_tf_; - views::ImageView* pattern_iv_; - views::Combobox* action_cb_; - views::Checkbox* incognito_cb_; - - DISALLOW_COPY_AND_ASSIGN(ExceptionEditorView); -}; +#include "chrome/browser/ui/views/options/exception_editor_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_EXCEPTION_EDITOR_VIEW_H_ + diff --git a/chrome/browser/views/options/exceptions_page_view.cc b/chrome/browser/views/options/exceptions_page_view.cc deleted file mode 100644 index 7788c5c..0000000 --- a/chrome/browser/views/options/exceptions_page_view.cc +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2009 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/options/exceptions_page_view.h" - -#include "app/l10n_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/common/pref_names.h" -#include "grit/generated_resources.h" -#include "views/background.h" -#include "views/controls/button/native_button.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" - -using views::ColumnSet; -using views::GridLayout; -using webkit_glue::PasswordForm; - -/////////////////////////////////////////////////////////////////////////////// -// ExceptionsTableModel -ExceptionsTableModel::ExceptionsTableModel(Profile* profile) - : PasswordsTableModel(profile) { -} - -ExceptionsTableModel::~ExceptionsTableModel() { -} - -std::wstring ExceptionsTableModel::GetText(int row, int col_id) { - DCHECK_EQ(col_id, IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN); - return PasswordsTableModel::GetText(row, col_id); -} - -int ExceptionsTableModel::CompareValues(int row1, int row2, - int col_id) { - DCHECK_EQ(col_id, IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN); - return PasswordsTableModel::CompareValues(row1, row2, col_id); -} - -void ExceptionsTableModel::GetAllExceptionsForProfile() { - DCHECK(!pending_login_query_); - pending_login_query_ = password_store()->GetBlacklistLogins(this); -} - -void ExceptionsTableModel::OnPasswordStoreRequestDone( - int handle, const std::vector<webkit_glue::PasswordForm*>& result) { - DCHECK_EQ(pending_login_query_, handle); - pending_login_query_ = NULL; - - STLDeleteElements<PasswordRows>(&saved_signons_); - std::wstring languages = - UTF8ToWide(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); - for (size_t i = 0; i < result.size(); ++i) { - saved_signons_.push_back(new PasswordRow( - gfx::SortedDisplayURL(result[i]->origin, languages), result[i])); - } - if (observer_) - observer_->OnModelChanged(); - if (row_count_observer_) - row_count_observer_->OnRowCountChanged(RowCount()); -} - -/////////////////////////////////////////////////////////////////////////////// -// ExceptionsPageView, public -ExceptionsPageView::ExceptionsPageView(Profile* profile) - : OptionsPageView(profile), - ALLOW_THIS_IN_INITIALIZER_LIST(show_button_( - this, - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON), - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON))), - ALLOW_THIS_IN_INITIALIZER_LIST(remove_button_( - this, - l10n_util::GetString(IDS_EXCEPTIONS_PAGE_VIEW_REMOVE_BUTTON))), - ALLOW_THIS_IN_INITIALIZER_LIST(remove_all_button_( - this, - l10n_util::GetString(IDS_EXCEPTIONS_PAGE_VIEW_REMOVE_ALL_BUTTON))), - table_model_(profile), - table_view_(NULL) { -} - -ExceptionsPageView::~ExceptionsPageView() { - // The model is going away, prevent the table from accessing it. - if (table_view_) - table_view_->SetModel(NULL); -} - -void ExceptionsPageView::OnSelectionChanged() { - bool has_selection = table_view_->SelectedRowCount() > 0; - remove_button_.SetEnabled(has_selection); -} - -void ExceptionsPageView::ButtonPressed( - views::Button* sender, const views::Event& event) { - // Close will result in our destruction. - if (sender == &remove_all_button_) { - table_model_.ForgetAndRemoveAllSignons(); - return; - } - - // The following require a selection (and only one, since table is single- - // select only). - views::TableSelectionIterator iter = table_view_->SelectionBegin(); - int row = *iter; - DCHECK(++iter == table_view_->SelectionEnd()); - - if (sender == &remove_button_) { - table_model_.ForgetAndRemoveSignon(row); - } else { - NOTREACHED() << "Invalid button."; - } -} - -void ExceptionsPageView::OnRowCountChanged(size_t rows) { - remove_all_button_.SetEnabled(rows > 0); -} - -/////////////////////////////////////////////////////////////////////////////// -// ExceptionsPageView, protected -void ExceptionsPageView::InitControlLayout() { - SetupButtons(); - SetupTable(); - - // Do the layout thing. - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int top_column_set_id = 0; - - // Design the grid. - ColumnSet* column_set = layout->AddColumnSet(top_column_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - // Fill the grid. - layout->StartRow(0, top_column_set_id); - layout->AddView(table_view_, 1, 6, GridLayout::FILL, - GridLayout::FILL); - layout->AddView(&remove_button_); - layout->StartRowWithPadding(0, top_column_set_id, 0, - kRelatedControlVerticalSpacing); - layout->SkipColumns(1); - layout->AddView(&remove_all_button_); - layout->StartRowWithPadding(0, top_column_set_id, 0, - kRelatedControlVerticalSpacing); - - layout->SkipColumns(1); - layout->AddView(&show_button_); - layout->AddPaddingRow(1, 0); - - // Ask the database for exception data. - table_model_.GetAllExceptionsForProfile(); -} - -/////////////////////////////////////////////////////////////////////////////// -// ExceptionsPageView, private -void ExceptionsPageView::SetupButtons() { - // Disable all buttons in the first place. - remove_button_.set_parent_owned(false); - remove_button_.SetEnabled(false); - - remove_all_button_.set_parent_owned(false); - remove_all_button_.SetEnabled(false); - - show_button_.set_parent_owned(false); - show_button_.SetEnabled(false); - show_button_.SetVisible(false); -} - -void ExceptionsPageView::SetupTable() { - // Tell the table model we are concerned about how many rows it has. - table_model_.set_row_count_observer(this); - - // Creates the different columns for the table. - // The float resize values are the result of much tinkering. - std::vector<TableColumn> columns; - columns.push_back(TableColumn(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN, - TableColumn::LEFT, -1, 0.55f)); - columns.back().sortable = true; - table_view_ = new views::TableView(&table_model_, columns, views::TEXT_ONLY, - true, true, true); - // Make the table initially sorted by host. - views::TableView::SortDescriptors sort; - sort.push_back(views::TableView::SortDescriptor( - IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN, true)); - table_view_->SetSortDescriptors(sort); - table_view_->SetObserver(this); -} diff --git a/chrome/browser/views/options/exceptions_page_view.h b/chrome/browser/views/options/exceptions_page_view.h index 9417118..c9eab58 100644 --- a/chrome/browser/views/options/exceptions_page_view.h +++ b/chrome/browser/views/options/exceptions_page_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,70 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_EXCEPTIONS_PAGE_VIEW_H_ #pragma once -#include <vector> - -#include "chrome/browser/views/options/options_page_view.h" -#include "chrome/browser/views/options/passwords_page_view.h" -#include "views/controls/table/table_view_observer.h" - -class Profile; - -/////////////////////////////////////////////////////////////////////////////// -// ExceptionsTableModel -class ExceptionsTableModel : public PasswordsTableModel { - public: - explicit ExceptionsTableModel(Profile* profile); - virtual ~ExceptionsTableModel(); - - // TableModel methods. - virtual std::wstring GetText(int row, int column); - virtual int CompareValues(int row1, int row2, int col_id); - - // PasswordStoreConsumer implementation. - virtual void OnPasswordStoreRequestDone( - int handle, const std::vector<webkit_glue::PasswordForm*>& result); - // Request all logins data. - void GetAllExceptionsForProfile(); -}; - -/////////////////////////////////////////////////////////////////////////////// -// ExceptionsPageView -class ExceptionsPageView : public OptionsPageView, - public views::TableViewObserver, - public views::ButtonListener, - public PasswordsTableModelObserver { - public: - explicit ExceptionsPageView(Profile* profile); - virtual ~ExceptionsPageView(); - - // views::TableViewObserverImplementation. - virtual void OnSelectionChanged(); - - // views::ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // PasswordsTableModelObserver implementation. - virtual void OnRowCountChanged(size_t rows); - - protected: - virtual void InitControlLayout(); - - private: - // Helper to configure our buttons and labels. - void SetupButtons(); - - // Helper to configure our table view. - void SetupTable(); - - ExceptionsTableModel table_model_; - views::TableView* table_view_; - - // The buttons and labels. - views::NativeButton remove_button_; - views::NativeButton remove_all_button_; - MultiLabelButtons show_button_; - - DISALLOW_COPY_AND_ASSIGN(ExceptionsPageView); -}; +#include "chrome/browser/ui/views/options/exceptions_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_EXCEPTIONS_PAGE_VIEW_H_ + diff --git a/chrome/browser/views/options/exceptions_view.cc b/chrome/browser/views/options/exceptions_view.cc deleted file mode 100644 index eadaf75..0000000 --- a/chrome/browser/views/options/exceptions_view.cc +++ /dev/null @@ -1,275 +0,0 @@ -// 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/options/exceptions_view.h" - -#include <algorithm> -#include <vector> - -#include "app/l10n_util.h" -#include "chrome/browser/views/options/content_exceptions_table_view.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "gfx/rect.h" -#include "views/controls/button/native_button.h" -#include "views/controls/label.h" -#include "views/controls/table/table_view.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -static const int kExceptionsViewInsetSize = 5; -static ExceptionsView* instances[CONTENT_SETTINGS_NUM_TYPES] = { NULL }; - -// static -void ExceptionsView::ShowExceptionsWindow( - gfx::NativeWindow parent, - HostContentSettingsMap* map, - HostContentSettingsMap* off_the_record_map, - ContentSettingsType content_type) { - if (!instances[content_type]) { - instances[content_type] = - new ExceptionsView(map, off_the_record_map, content_type); - views::Window::CreateChromeWindow(parent, gfx::Rect(), - instances[content_type]); - } - - // This will show invisible windows and bring visible windows to the front. - instances[content_type]->window()->Show(); -} - -ExceptionsView::~ExceptionsView() { - instances[model_.content_type()] = NULL; - table_->SetModel(NULL); -} - -void ExceptionsView::OnSelectionChanged() { - UpdateButtonState(); -} - -void ExceptionsView::OnDoubleClick() { - if (table_->SelectedRowCount() == 1) - Edit(); -} - -void ExceptionsView::OnTableViewDelete(views::TableView* table_view) { - Remove(); -} - -void ExceptionsView::ButtonPressed(views::Button* sender, - const views::Event& event) { - switch (sender->tag()) { - case IDS_EXCEPTIONS_ADD_BUTTON: - Add(); - break; - case IDS_EXCEPTIONS_EDIT_BUTTON: - Edit(); - break; - case IDS_EXCEPTIONS_REMOVEALL_BUTTON: - RemoveAll(); - break; - case IDS_EXCEPTIONS_REMOVE_BUTTON: - Remove(); - break; - default: - NOTREACHED(); - } -} - -void ExceptionsView::Layout() { - views::NativeButton* buttons[] = { add_button_, edit_button_, - remove_button_, remove_all_button_ }; - - // The buttons are placed in the parent, but we need to lay them out. - int max_y = GetParent()->GetLocalBounds(false).bottom() - kButtonVEdgeMargin; - int x = kPanelHorizMargin; - - for (size_t i = 0; i < arraysize(buttons); ++i) { - gfx::Size pref = buttons[i]->GetPreferredSize(); - buttons[i]->SetBounds(x, max_y - pref.height(), pref.width(), - pref.height()); - x += pref.width() + kRelatedControlHorizontalSpacing; - } - - // Lay out the rest of this view. - View::Layout(); -} - -gfx::Size ExceptionsView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_CONTENT_EXCEPTION_DIALOG_WIDTH_CHARS, - IDS_CONTENT_EXCEPTION_DIALOG_HEIGHT_LINES)); -} - -void ExceptionsView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -std::wstring ExceptionsView::GetWindowTitle() const { - switch (model_.content_type()) { - case CONTENT_SETTINGS_TYPE_COOKIES: - return l10n_util::GetString(IDS_COOKIE_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_IMAGES: - return l10n_util::GetString(IDS_IMAGES_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_JAVASCRIPT: - return l10n_util::GetString(IDS_JS_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_PLUGINS: - return l10n_util::GetString(IDS_PLUGINS_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_POPUPS: - return l10n_util::GetString(IDS_POPUP_EXCEPTION_TITLE); - default: - NOTREACHED(); - } - return std::wstring(); -} - -void ExceptionsView::AcceptExceptionEdit( - const HostContentSettingsMap::Pattern& pattern, - ContentSetting setting, - bool is_off_the_record, - int index, - bool is_new) { - DCHECK(!is_off_the_record || allow_off_the_record_); - - if (!is_new) - model_.RemoveException(index); - model_.AddException(pattern, setting, is_off_the_record); - - int new_index = model_.IndexOfExceptionByPattern(pattern, is_off_the_record); - DCHECK(new_index != -1); - table_->Select(new_index); -} - -ExceptionsView::ExceptionsView(HostContentSettingsMap* map, - HostContentSettingsMap* off_the_record_map, - ContentSettingsType type) - : model_(map, off_the_record_map, type), - allow_off_the_record_(off_the_record_map != NULL), - table_(NULL), - add_button_(NULL), - edit_button_(NULL), - remove_button_(NULL), - remove_all_button_(NULL) { -} - -void ExceptionsView::Init() { - if (table_) - return; // We've already Init'd. - - using views::GridLayout; - - std::vector<TableColumn> columns; - columns.push_back( - TableColumn(IDS_EXCEPTIONS_PATTERN_HEADER, TableColumn::LEFT, -1, .75)); - columns.back().sortable = true; - columns.push_back( - TableColumn(IDS_EXCEPTIONS_ACTION_HEADER, TableColumn::LEFT, -1, .25)); - columns.back().sortable = true; - table_ = new ContentExceptionsTableView(&model_, columns); - views::TableView::SortDescriptors sort; - sort.push_back( - views::TableView::SortDescriptor(IDS_EXCEPTIONS_PATTERN_HEADER, true)); - table_->SetSortDescriptors(sort); - table_->SetObserver(this); - - add_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_EXCEPTIONS_ADD_BUTTON)); - add_button_->set_tag(IDS_EXCEPTIONS_ADD_BUTTON); - edit_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_EXCEPTIONS_EDIT_BUTTON)); - edit_button_->set_tag(IDS_EXCEPTIONS_EDIT_BUTTON); - remove_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_EXCEPTIONS_REMOVE_BUTTON)); - remove_button_->set_tag(IDS_EXCEPTIONS_REMOVE_BUTTON); - remove_all_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_EXCEPTIONS_REMOVEALL_BUTTON)); - remove_all_button_->set_tag(IDS_EXCEPTIONS_REMOVEALL_BUTTON); - - View* parent = GetParent(); - parent->AddChildView(add_button_); - parent->AddChildView(edit_button_); - parent->AddChildView(remove_button_); - parent->AddChildView(remove_all_button_); - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kExceptionsViewInsetSize, kExceptionsViewInsetSize, - kExceptionsViewInsetSize, kExceptionsViewInsetSize); - SetLayoutManager(layout); - - const int single_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(1, single_column_layout_id); - layout->AddView(table_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - if (allow_off_the_record_) { - views::Label* label = new views::Label(l10n_util::GetString( - IDS_EXCEPTIONS_OTR_IN_ITALICS)); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->StartRow(0, single_column_layout_id); - layout->AddView(label, 1, 1, GridLayout::LEADING, GridLayout::CENTER); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - - UpdateButtonState(); -} - -void ExceptionsView::UpdateButtonState() { - int selected_row_count = table_->SelectedRowCount(); - // TODO: 34177, support editing of more than one entry at a time. - edit_button_->SetEnabled(selected_row_count == 1); - remove_button_->SetEnabled(selected_row_count >= 1); - remove_all_button_->SetEnabled(model_.RowCount() > 0); -} - -void ExceptionsView::Add() { - ExceptionEditorView* view = - new ExceptionEditorView(this, &model_, allow_off_the_record_, -1, - HostContentSettingsMap::Pattern(), - CONTENT_SETTING_BLOCK, false); - view->Show(window()->GetNativeWindow()); - - UpdateButtonState(); -} - -void ExceptionsView::Edit() { - DCHECK(table_->FirstSelectedRow() != -1); - int index = table_->FirstSelectedRow(); - const HostContentSettingsMap::PatternSettingPair& entry = - model_.entry_at(index); - ExceptionEditorView* view = - new ExceptionEditorView(this, &model_, allow_off_the_record_, index, - entry.first, entry.second, - model_.entry_is_off_the_record(index)); - view->Show(window()->GetNativeWindow()); -} - -void ExceptionsView::Remove() { - std::vector<int> indices; - for (views::TableView::iterator i = table_->SelectionBegin(); - i != table_->SelectionEnd(); ++i) { - indices.push_back(*i); - } - std::sort(indices.begin(), indices.end()); - for (std::vector<int>::reverse_iterator i = indices.rbegin(); - i != indices.rend(); ++i) { - model_.RemoveException(*i); - } - - UpdateButtonState(); -} - -void ExceptionsView::RemoveAll() { - model_.RemoveAll(); - - UpdateButtonState(); -} diff --git a/chrome/browser/views/options/exceptions_view.h b/chrome/browser/views/options/exceptions_view.h index 4e66e6d..6ff6f02 100644 --- a/chrome/browser/views/options/exceptions_view.h +++ b/chrome/browser/views/options/exceptions_view.h @@ -6,112 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_EXCEPTIONS_VIEW_H_ #pragma once -#include <string> - -#include "chrome/browser/content_exceptions_table_model.h" -#include "chrome/browser/views/options/exception_editor_view.h" -#include "chrome/common/content_settings.h" -#include "chrome/common/content_settings_types.h" -#include "views/controls/button/button.h" -#include "views/controls/table/table_view_observer.h" -#include "views/window/dialog_delegate.h" - -class HostContentSettingsMap; - -namespace views { -class NativeButton; -class TableView; -} - -// ExceptionsView is responsible for showing the user the set of content -// exceptions for a specific type. The exceptions are shown in a table view -// by way of a ContentExceptionsTableModel. The user can add/edit/remove -// exceptions. Editing and creating new exceptions is done way of the -// ExceptionEditorView. -// Use the ShowExceptionsWindow method to create and show an ExceptionsView -// for a specific type. ExceptionsView is deleted when the window closes. -class ExceptionsView : public ExceptionEditorView::Delegate, - public views::View, - public views::ButtonListener, - public views::DialogDelegate, - public views::TableViewObserver { - public: - // Shows the Exceptions window. - static void ShowExceptionsWindow(gfx::NativeWindow parent, - HostContentSettingsMap* map, - HostContentSettingsMap* off_the_record_map, - ContentSettingsType content_type); - - virtual ~ExceptionsView(); - - // TableViewObserver overrides: - virtual void OnSelectionChanged(); - virtual void OnDoubleClick(); - virtual void OnTableViewDelete(views::TableView* table_view); - - // views::ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::View overrides: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // views::WindowDelegate implementation. - virtual int GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - virtual bool CanResize() const { return true; } - virtual std::wstring GetWindowTitle() const; - virtual views::View* GetContentsView() { return this; } - - // ExceptionEditorView::Delegate implementation. - virtual void AcceptExceptionEdit( - const HostContentSettingsMap::Pattern& pattern, - ContentSetting setting, - bool is_off_the_record, - int index, - bool is_new); - - private: - ExceptionsView(HostContentSettingsMap* map, - HostContentSettingsMap* off_the_record_map, - ContentSettingsType type); - - void Init(); - - // Resets the enabled state of the buttons from the model. - void UpdateButtonState(); - - // Adds a new item. - void Add(); - - // Edits the selected item. - void Edit(); - - // Removes the selected item. - void Remove(); - - // Removes all. - void RemoveAll(); - - // The model displayed in the table. - ContentExceptionsTableModel model_; - - // True if the user can also add off the record entries. - bool allow_off_the_record_; - - views::TableView* table_; - - views::NativeButton* add_button_; - views::NativeButton* edit_button_; - views::NativeButton* remove_button_; - views::NativeButton* remove_all_button_; - - DISALLOW_COPY_AND_ASSIGN(ExceptionsView); -}; +#include "chrome/browser/ui/views/options/exceptions_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_EXCEPTIONS_VIEW_H_ diff --git a/chrome/browser/views/options/fonts_languages_window_view.cc b/chrome/browser/views/options/fonts_languages_window_view.cc deleted file mode 100644 index cab82c7..0000000 --- a/chrome/browser/views/options/fonts_languages_window_view.cc +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2006-2008 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/options/fonts_languages_window_view.h" - -#include "app/l10n_util.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/options/fonts_page_view.h" -#include "chrome/browser/views/options/languages_page_view.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/pref_names.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/tabbed_pane/tabbed_pane.h" -#include "views/window/window.h" - -// static -static FontsLanguagesWindowView* instance_ = NULL; -static const int kDialogPadding = 7; - -/////////////////////////////////////////////////////////////////////////////// -// FontsLanguagesWindowView, public: - -FontsLanguagesWindowView::FontsLanguagesWindowView(Profile* profile) - // Always show preferences for the original profile. Most state when off - // the record comes from the original profile, but we explicitly use - // the original profile to avoid potential problems. - : profile_(profile->GetOriginalProfile()), - fonts_page_(NULL), - languages_page_(NULL) { -} - -FontsLanguagesWindowView::~FontsLanguagesWindowView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// FontsLanguagesWindowView, views::DialogDelegate implementation: - -bool FontsLanguagesWindowView::Accept() { - fonts_page_->SaveChanges(); - languages_page_->SaveChanges(); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// FontsLanguagesWindowView, views::WindowDelegate implementation: - -std::wstring FontsLanguagesWindowView::GetWindowTitle() const { - return l10n_util::GetString(IDS_FONT_LANGUAGE_SETTING_WINDOWS_TITLE); -} - -void FontsLanguagesWindowView::WindowClosing() { - // Clear the static instance so that the next time ShowOptionsWindow() is - // called a new window is opened. - instance_ = NULL; -} - -views::View* FontsLanguagesWindowView::GetContentsView() { - return this; -} - -/////////////////////////////////////////////////////////////////////////////// -// FontsLanguagesWindowView, views::View overrides: - -void FontsLanguagesWindowView::Layout() { - tabs_->SetBounds(kDialogPadding, kDialogPadding, - width() - (2 * kDialogPadding), - height() - (2 * kDialogPadding)); -} - -gfx::Size FontsLanguagesWindowView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_FONTSLANG_DIALOG_WIDTH_CHARS, - IDS_FONTSLANG_DIALOG_HEIGHT_LINES)); -} - -void FontsLanguagesWindowView::ShowTabPage(FontsLanguagesPage page) { - // If the window is not yet visible, we need to show it (it will become - // active), otherwise just bring it to the front. - if (!window()->IsVisible()) { - window()->Show(); - } else { - window()->Activate(); - } - - // If the page is out of bounds, reset to the first tab. - if (page < 0 || page >= tabs_->GetTabCount()) - page = FONTS_ENCODING_PAGE; - - tabs_->SelectTabAt(page); -} - -void FontsLanguagesWindowView::ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child) { - // Can't init before we're inserted into a Container, because we require - // a HWND to parent native child controls to. - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// FontsLanguagesWindowView, private: - -void FontsLanguagesWindowView::Init() { - tabs_ = new views::TabbedPane; - AddChildView(tabs_); - - fonts_page_ = new FontsPageView(profile_); - tabs_->AddTab(l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_TAB_TITLE), fonts_page_); - - languages_page_ = new LanguagesPageView(profile_); - tabs_->AddTab(l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_LANGUAGES_TAB_TITLE), languages_page_); -} - -void ShowFontsLanguagesWindow(gfx::NativeWindow window, - FontsLanguagesPage page, - Profile* profile) { - DCHECK(profile); - - // If there's already an existing fonts and language window, activate it and - // switch to the specified page. - // TODO(beng): note this is not multi-simultaneous-profile-safe. When we care - // about this case this will have to be fixed. - if (!instance_) { - instance_ = new FontsLanguagesWindowView(profile); - views::Window::CreateChromeWindow(window, gfx::Rect(), instance_); - } - instance_->ShowTabPage(page); -} diff --git a/chrome/browser/views/options/fonts_languages_window_view.h b/chrome/browser/views/options/fonts_languages_window_view.h index 4af9d01..1702d9a 100644 --- a/chrome/browser/views/options/fonts_languages_window_view.h +++ b/chrome/browser/views/options/fonts_languages_window_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,69 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_FONTS_LANGUAGES_WINDOW_VIEW_H_ #pragma once -#include "chrome/browser/fonts_languages_window.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -class Profile; -class FontsPageView; -class LanguagesPageView; - -namespace views { -class TabbedPane; -} - -/////////////////////////////////////////////////////////////////////////////// -// FontsLanguagesWindowView -// -// The contents of the "Fonts and Languages Preferences" dialog window. -// -class FontsLanguagesWindowView : public views::View, - public views::DialogDelegate { - public: - explicit FontsLanguagesWindowView(Profile* profile); - virtual ~FontsLanguagesWindowView(); - - // views::DialogDelegate implementation: - virtual bool Accept(); - - // views::WindowDelegate Methods: - virtual bool IsModal() const { return true; } - virtual std::wstring GetWindowTitle() const; - virtual views::View* GetContentsView(); - virtual void WindowClosing(); - - // views::View overrides: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - // Shows the tab corresponding to the specified |page|. - void ShowTabPage(FontsLanguagesPage page); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - private: - // Init the assorted Tabbed pages - void Init(); - - // The Tab view that contains all of the options pages. - views::TabbedPane* tabs_; - - // Fonts Page View handle remembered so that prefs is updated only when - // OK is pressed. - FontsPageView* fonts_page_; - - // Languages Page View handle remembered so that prefs is updated only when - // OK is pressed. - LanguagesPageView* languages_page_; - - // The Profile associated with these options. - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(FontsLanguagesWindowView); -}; +#include "chrome/browser/ui/views/options/fonts_languages_window_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_FONTS_LANGUAGES_WINDOW_VIEW_H_ + diff --git a/chrome/browser/views/options/fonts_page_view.cc b/chrome/browser/views/options/fonts_page_view.cc deleted file mode 100644 index 3a98b15..0000000 --- a/chrome/browser/views/options/fonts_page_view.cc +++ /dev/null @@ -1,435 +0,0 @@ -// 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/options/fonts_page_view.h" - -#include <windows.h> -#include <shlobj.h> -#include <vsstyle.h> -#include <vssym32.h> - -#include <vector> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/file_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/default_encoding_combo_model.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/shell_dialogs.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas_skia.h" -#include "gfx/font.h" -#include "gfx/native_theme_win.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "grit/locale_settings.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "views/controls/button/native_button.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" - -//////////////////////////////////////////////////////////////////////////////// -// FontDisplayView - -class FontDisplayView : public views::View { - public: - FontDisplayView(); - virtual ~FontDisplayView(); - - // This method takes in font size in pixel units, instead of the normal point - // unit because users expect the font size number to represent pixels and not - // points. - void SetFontType(const std::wstring& font_name, - int font_size); - - std::wstring font_name() { return font_name_; } - int font_size() { return font_size_; } - - // views::View overrides: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - private: - views::Label* font_text_label_; - std::wstring font_name_; - int font_size_; - std::wstring font_text_label_string_; - - static const int kFontDisplayMaxWidthChars = 50; - static const int kFontDisplayMaxHeightChars = 1; - static const int kFontDisplayLabelPadding = 5; - - DISALLOW_COPY_AND_ASSIGN(FontDisplayView); -}; - -FontDisplayView::FontDisplayView() - : font_text_label_(new views::Label) { - AddChildView(font_text_label_); -} - -FontDisplayView::~FontDisplayView() { -} - -void FontDisplayView::SetFontType(const std::wstring& font_name, - int font_size) { - if (font_name.empty()) - return; - - font_name_ = font_name; - font_size_ = font_size; - std::wstring displayed_text = font_name_; - - // Append the font type and size. - displayed_text += L", "; - displayed_text += UTF8ToWide(::StringPrintf("%d", font_size_)); - HDC hdc = GetDC(NULL); - int font_size_point = MulDiv(font_size, 72, GetDeviceCaps(hdc, LOGPIXELSY)); - gfx::Font font = gfx::Font(font_name, font_size_point); - font_text_label_->SetFont(font); - font_text_label_->SetText(displayed_text); -} - -void FontDisplayView::Paint(gfx::Canvas* canvas) { - HDC dc = canvas->BeginPlatformPaint(); - RECT rect = { 0, 0, width(), height() }; - gfx::NativeTheme::instance()->PaintTextField( - dc, EP_BACKGROUND, EBS_NORMAL, 0, &rect, ::GetSysColor(COLOR_3DFACE), - true, true); - canvas->EndPlatformPaint(); -} - -void FontDisplayView::Layout() { - font_text_label_->SetBounds(0, 0, width(), height()); -} - -gfx::Size FontDisplayView::GetPreferredSize() { - gfx::Size size = font_text_label_->GetPreferredSize(); - size.set_width(size.width() + 2 * kFontDisplayLabelPadding); - size.set_height(size.height() + 2 * kFontDisplayLabelPadding); - return size; -} - -void EmbellishTitle(views::Label* title_label) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - gfx::Font title_font = - rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); - title_label->SetFont(title_font); - SkColor title_color = - gfx::NativeTheme::instance()->GetThemeColorWithDefault( - gfx::NativeTheme::BUTTON, BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, - COLOR_WINDOWTEXT); - title_label->SetColor(title_color); -} - -FontsPageView::FontsPageView(Profile* profile) - : ALLOW_THIS_IN_INITIALIZER_LIST( - select_font_dialog_(SelectFontDialog::Create(this))), - fonts_group_title_(NULL), - encoding_group_title_(NULL), - fixed_width_font_change_page_button_(NULL), - serif_font_change_page_button_(NULL), - sans_serif_font_change_page_button_(NULL), - fixed_width_font_label_(NULL), - serif_font_label_(NULL), - sans_serif_font_label_(NULL), - default_encoding_combobox_(NULL), - serif_button_pressed_(false), - sans_serif_button_pressed_(false), - fixed_width_button_pressed_(false), - encoding_dropdown_clicked_(false), - font_type_being_changed_(NONE), - OptionsPageView(profile), - font_changed_(false), - default_encoding_changed_(false), - serif_font_size_pixel_(0), - sans_serif_font_size_pixel_(0), - fixed_width_font_size_pixel_(0) { - serif_name_.Init(prefs::kWebKitSerifFontFamily, profile->GetPrefs(), NULL); - serif_size_.Init(prefs::kWebKitDefaultFontSize, profile->GetPrefs(), NULL); - - sans_serif_name_.Init(prefs::kWebKitSansSerifFontFamily, profile->GetPrefs(), - NULL); - sans_serif_size_.Init(prefs::kWebKitDefaultFontSize, profile->GetPrefs(), - NULL); - - fixed_width_name_.Init(prefs::kWebKitFixedFontFamily, profile->GetPrefs(), - NULL); - fixed_width_size_.Init(prefs::kWebKitDefaultFixedFontSize, - profile->GetPrefs(), NULL); - - default_encoding_.Init(prefs::kDefaultCharset, profile->GetPrefs(), NULL); -} - -FontsPageView::~FontsPageView() { -} - -void FontsPageView::ButtonPressed( - views::Button* sender, const views::Event& event) { - HWND owning_hwnd = GetAncestor(GetWidget()->GetNativeView(), GA_ROOT); - std::wstring font_name; - int font_size = 0; - if (sender == serif_font_change_page_button_) { - font_type_being_changed_ = SERIF; - font_name = serif_font_display_view_->font_name(); - font_size = serif_font_size_pixel_; - } else if (sender == sans_serif_font_change_page_button_) { - font_type_being_changed_ = SANS_SERIF; - font_name = sans_serif_font_display_view_->font_name(); - font_size = sans_serif_font_size_pixel_; - } else if (sender == fixed_width_font_change_page_button_) { - font_type_being_changed_ = FIXED_WIDTH; - font_name = fixed_width_font_display_view_->font_name(); - font_size = fixed_width_font_size_pixel_; - } else { - NOTREACHED(); - return; - } - - select_font_dialog_->SelectFont(owning_hwnd, NULL, font_name, font_size); -} - -void FontsPageView::ItemChanged(views::Combobox* combo_box, - int prev_index, int new_index) { - if (combo_box == default_encoding_combobox_) { - if (prev_index != new_index) { // Default-Encoding has been changed. - encoding_dropdown_clicked_ = true; - default_encoding_selected_ = default_encoding_combobox_model_-> - GetEncodingCharsetByIndex(new_index); - default_encoding_changed_ = true; - } - } -} - -void FontsPageView::FontSelected(const gfx::Font& font, void* params) { - if (font.GetFontName().empty()) - return; - int font_size = font.GetFontSize(); - // Currently we do not have separate font sizes for Serif and Sans Serif. - // Therefore, when Serif font size is changed, Sans-Serif font size changes, - // and vice versa. - if (font_type_being_changed_ == SERIF) { - sans_serif_font_size_pixel_ = serif_font_size_pixel_ = font_size; - serif_font_display_view_->SetFontType( - font.GetFontName(), - serif_font_size_pixel_); - sans_serif_font_display_view_->SetFontType( - sans_serif_font_display_view_->font_name(), - sans_serif_font_size_pixel_); - } else if (font_type_being_changed_ == SANS_SERIF) { - sans_serif_font_size_pixel_ = serif_font_size_pixel_ = font_size; - sans_serif_font_display_view_->SetFontType( - font.GetFontName(), - sans_serif_font_size_pixel_); - serif_font_display_view_->SetFontType( - serif_font_display_view_->font_name(), - sans_serif_font_size_pixel_); - } else if (font_type_being_changed_ == FIXED_WIDTH) { - fixed_width_font_size_pixel_ = font_size; - fixed_width_font_display_view_->SetFontType(font.GetFontName(), font_size); - } - font_changed_ = true; -} - -void FontsPageView::SaveChanges() { - // Set Fonts. - if (font_changed_) { - serif_name_.SetValue(WideToUTF8(serif_font_display_view_->font_name())); - serif_size_.SetValue(serif_font_size_pixel_); - sans_serif_name_.SetValue( - WideToUTF8(sans_serif_font_display_view_->font_name())); - sans_serif_size_.SetValue(sans_serif_font_size_pixel_); - fixed_width_name_.SetValue(WideToUTF8( - fixed_width_font_display_view_->font_name())); - fixed_width_size_.SetValue(fixed_width_font_size_pixel_); - } - // Set Encoding. - if (default_encoding_changed_) - default_encoding_.SetValue(default_encoding_selected_); -} - -void FontsPageView::InitControlLayout() { - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - - // Fonts group. - column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1, - GridLayout::USE_PREF, 0, 0); - fonts_group_title_ = new views::Label( - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SUB_DIALOG_FONT_TITLE)); - EmbellishTitle(fonts_group_title_); - fonts_group_title_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(fonts_group_title_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - InitFontLayout(); - layout->AddView(fonts_contents_); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - // Encoding group. - encoding_group_title_ = new views::Label( - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SUB_DIALOG_ENCODING_TITLE)); - EmbellishTitle(encoding_group_title_); - encoding_group_title_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(encoding_group_title_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - InitEncodingLayout(); - layout->AddView(encoding_contents_); -} - -void FontsPageView::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kWebKitFixedFontFamily) { - fixed_width_font_size_pixel_ = fixed_width_size_.GetValue(); - fixed_width_font_display_view_->SetFontType( - UTF8ToWide(fixed_width_name_.GetValue()), - fixed_width_font_size_pixel_); - } - if (!pref_name || *pref_name == prefs::kWebKitSerifFontFamily) { - serif_font_size_pixel_ = serif_size_.GetValue(); - serif_font_display_view_->SetFontType( - UTF8ToWide(serif_name_.GetValue()), - serif_font_size_pixel_); - } - if (!pref_name || *pref_name == prefs::kWebKitSansSerifFontFamily) { - sans_serif_font_size_pixel_ = sans_serif_size_.GetValue(); - sans_serif_font_display_view_->SetFontType( - UTF8ToWide(sans_serif_name_.GetValue()), - sans_serif_font_size_pixel_); - } -} - -void FontsPageView::InitFontLayout() { - // Fixed width. - fixed_width_font_display_view_ = new FontDisplayView; - fixed_width_font_change_page_button_ = new views::NativeButton( - this, - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_BUTTON_LABEL)); - - fixed_width_font_label_ = new views::Label( - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_FIXED_WIDTH_LABEL)); - fixed_width_font_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - // Serif font. - serif_font_display_view_ = new FontDisplayView; - serif_font_change_page_button_ = new views::NativeButton( - this, - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_BUTTON_LABEL)); - - serif_font_label_ = new views::Label( - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SERIF_LABEL)); - serif_font_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - // Sans Serif font. - sans_serif_font_display_view_ = new FontDisplayView; - sans_serif_font_change_page_button_ = new views::NativeButton( - this, - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_BUTTON_LABEL)); - - sans_serif_font_label_ = new views::Label( - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SANS_SERIF_LABEL)); - sans_serif_font_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - // Now add the views. - using views::GridLayout; - using views::ColumnSet; - - fonts_contents_ = new views::View; - GridLayout* layout = new GridLayout(fonts_contents_); - fonts_contents_->SetLayoutManager(layout); - - const int triple_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(triple_column_view_set_id); - - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - // Serif font controls. - layout->StartRow(0, triple_column_view_set_id); - layout->AddView(serif_font_label_); - layout->AddView(serif_font_display_view_, 1, 1, - GridLayout::FILL, GridLayout::CENTER); - layout->AddView(serif_font_change_page_button_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Sans serif font controls. - layout->StartRow(0, triple_column_view_set_id); - layout->AddView(sans_serif_font_label_); - layout->AddView(sans_serif_font_display_view_, 1, 1, - GridLayout::FILL, GridLayout::CENTER); - layout->AddView(sans_serif_font_change_page_button_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Fixed-width font controls. - layout->StartRow(0, triple_column_view_set_id); - layout->AddView(fixed_width_font_label_); - layout->AddView(fixed_width_font_display_view_, 1, 1, - GridLayout::FILL, GridLayout::CENTER); - layout->AddView(fixed_width_font_change_page_button_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); -} - -void FontsPageView::InitEncodingLayout() { - default_encoding_combobox_label_ = new views::Label( - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_FONT_DEFAULT_ENCODING_SELECTOR_LABEL)); - default_encoding_combobox_model_.reset(new DefaultEncodingComboboxModel); - default_encoding_combobox_ = new views::Combobox( - default_encoding_combobox_model_.get()); - int selected_encoding_index = default_encoding_combobox_model_-> - GetSelectedEncodingIndex(profile()); - default_encoding_combobox_->SetSelectedItem(selected_encoding_index); - default_encoding_selected_ = default_encoding_combobox_model_-> - GetEncodingCharsetByIndex(selected_encoding_index); - default_encoding_combobox_->set_listener(this); - - // Now add the views. - using views::GridLayout; - using views::ColumnSet; - - encoding_contents_ = new views::View; - GridLayout* layout = new GridLayout(encoding_contents_); - encoding_contents_->SetLayoutManager(layout); - - // Double column. - const int double_column_view_set_id = 2; - ColumnSet* column_set = layout->AddColumnSet(double_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - // Add Encoding Combobox. - layout->StartRow(0, double_column_view_set_id); - layout->AddView(default_encoding_combobox_label_); - layout->AddView(default_encoding_combobox_, 1, 1, GridLayout::FILL, - GridLayout::CENTER); -} diff --git a/chrome/browser/views/options/fonts_page_view.h b/chrome/browser/views/options/fonts_page_view.h index 477bf91..22cad00 100644 --- a/chrome/browser/views/options/fonts_page_view.h +++ b/chrome/browser/views/options/fonts_page_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,125 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_FONTS_PAGE_VIEW_H_ #pragma once -#include <string> - -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/shell_dialogs.h" -#include "chrome/browser/views/options/options_page_view.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/button/button.h" -#include "views/view.h" - -namespace views { -class GroupboxView; -class Label; -class NativeButton; -class TableView; -} - -class DefaultEncodingComboboxModel; -class FontDisplayView; -class TableModel; - -/////////////////////////////////////////////////////////////////////////////// -// FontsPageView - -class FontsPageView : public OptionsPageView, - public views::Combobox::Listener, - public SelectFontDialog::Listener, - public views::ButtonListener { - public: - explicit FontsPageView(Profile* profile); - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::Combobox::Listener implementation: - virtual void ItemChanged(views::Combobox* combo_box, - int prev_index, - int new_index); - - // SelectFontDialog::Listener implementation: - virtual void FontSelected(const gfx::Font& font, void* params); - - // Save Changes made to relevent pref members associated with this tab. - // This is public since it is called by FontsLanguageWindowView in its - // Dialog Delegate Accept() method. - void SaveChanges(); - - protected: - // OptionsPageView implementation: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - private: - enum FontTypeBeingChanged { - NONE, - SERIF, - SANS_SERIF, - FIXED_WIDTH - }; - - virtual ~FontsPageView(); - - // Init Dialog controls. - void InitFontLayout(); - void InitEncodingLayout(); - - bool serif_button_pressed_; - bool sans_serif_button_pressed_; - bool fixed_width_button_pressed_; - bool encoding_dropdown_clicked_; - - views::Label* fonts_group_title_; - views::Label* encoding_group_title_; - - views::View* fonts_contents_; - views::View* encoding_contents_; - - // Fonts settings. - // Select Font dialogs. - scoped_refptr<SelectFontDialog> select_font_dialog_; - - // Buttons. - views::NativeButton* fixed_width_font_change_page_button_; - views::NativeButton* serif_font_change_page_button_; - views::NativeButton* sans_serif_font_change_page_button_; - - // FontDisplayView objects to display selected font. - FontDisplayView* fixed_width_font_display_view_; - FontDisplayView* serif_font_display_view_; - FontDisplayView* sans_serif_font_display_view_; - - // Labels to describe what is to be changed. - views::Label* fixed_width_font_label_; - views::Label* serif_font_label_; - views::Label* sans_serif_font_label_; - - // Advanced Font names and sizes as PrefMembers. - StringPrefMember serif_name_; - StringPrefMember sans_serif_name_; - StringPrefMember fixed_width_name_; - IntegerPrefMember serif_size_; - IntegerPrefMember sans_serif_size_; - IntegerPrefMember fixed_width_size_; - int serif_font_size_pixel_; - int sans_serif_font_size_pixel_; - int fixed_width_font_size_pixel_; - StringPrefMember default_encoding_; - bool font_changed_; - - // Windows font picker flag; - FontTypeBeingChanged font_type_being_changed_; - - // Default Encoding. - scoped_ptr<DefaultEncodingComboboxModel> default_encoding_combobox_model_; - views::Label* default_encoding_combobox_label_; - views::Combobox* default_encoding_combobox_; - std::string default_encoding_selected_; - bool default_encoding_changed_; - - DISALLOW_COPY_AND_ASSIGN(FontsPageView); -}; +#include "chrome/browser/ui/views/options/fonts_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_FONTS_PAGE_VIEW_H_ + diff --git a/chrome/browser/views/options/general_page_view.cc b/chrome/browser/views/options/general_page_view.cc deleted file mode 100644 index e7c4d3e..0000000 --- a/chrome/browser/views/options/general_page_view.cc +++ /dev/null @@ -1,883 +0,0 @@ -// 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/options/general_page_view.h" - -#include "app/combobox_model.h" -#include "app/l10n_util.h" -#include "base/callback.h" -#include "base/message_loop.h" -#include "base/string16.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/custom_home_pages_table_model.h" -#include "chrome/browser/dom_ui/new_tab_ui.h" -#include "chrome/browser/instant/instant_confirm_dialog.h" -#include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/search_engines/template_url_model_observer.h" -#include "chrome/browser/show_options_url.h" -#include "chrome/browser/views/keyword_editor_view.h" -#include "chrome/browser/views/options/managed_prefs_banner_view.h" -#include "chrome/browser/views/options/options_group_view.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/installer/util/browser_distribution.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "views/controls/button/radio_button.h" -#include "views/controls/label.h" -#include "views/controls/table/table_view.h" -#include "views/controls/textfield/textfield.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" - -namespace { - -// All the options pages are in the same view hierarchy. This means we need to -// make sure group identifiers don't collide across different pages. -const int kStartupRadioGroup = 101; -const int kHomePageRadioGroup = 102; -const SkColor kDefaultBrowserLabelColor = SkColorSetRGB(0, 135, 0); -const SkColor kNotDefaultBrowserLabelColor = SkColorSetRGB(135, 0, 0); -const int kHomePageTextfieldWidthChars = 40; - -bool IsNewTabUIURLString(const GURL& url) { - return url == GURL(chrome::kChromeUINewTabURL); -} -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// OptionsGroupContents -class OptionsGroupContents : public views::View { - public: - OptionsGroupContents() { } - - // views::View overrides: - virtual AccessibilityTypes::Role GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; - } - - private: - DISALLOW_COPY_AND_ASSIGN(OptionsGroupContents); -}; - -/////////////////////////////////////////////////////////////////////////////// -// SearchEngineListModel - -class SearchEngineListModel : public ComboboxModel, - public TemplateURLModelObserver { - public: - explicit SearchEngineListModel(Profile* profile); - virtual ~SearchEngineListModel(); - - // Sets the Combobox. SearchEngineListModel needs a handle to the Combobox - // so that when the TemplateURLModel changes the combobox can be updated. - void SetCombobox(views::Combobox* combobox); - - // ComboboxModel overrides: - virtual int GetItemCount(); - virtual string16 GetItemAt(int index); - - // Returns the TemplateURL at the specified index. - const TemplateURL* GetTemplateURLAt(int index); - - TemplateURLModel* model() { return template_url_model_; } - - private: - // TemplateURLModelObserver methods. - virtual void OnTemplateURLModelChanged(); - - // Recalculates the TemplateURLs to display and notifies the combobox. - void ResetContents(); - - // Resets the selection of the combobox based on the users selected search - // engine. - void ChangeComboboxSelection(); - - TemplateURLModel* template_url_model_; - - // The combobox hosting us. - views::Combobox* combobox_; - - // The TemplateURLs we're showing. - typedef std::vector<const TemplateURL*> TemplateURLs; - TemplateURLs template_urls_; - - DISALLOW_COPY_AND_ASSIGN(SearchEngineListModel); -}; - -SearchEngineListModel::SearchEngineListModel(Profile* profile) - : template_url_model_(profile->GetTemplateURLModel()), - combobox_(NULL) { - if (template_url_model_) { - template_url_model_->Load(); - template_url_model_->AddObserver(this); - } - ResetContents(); -} - -SearchEngineListModel::~SearchEngineListModel() { - if (template_url_model_) - template_url_model_->RemoveObserver(this); -} - -void SearchEngineListModel::SetCombobox(views::Combobox* combobox) { - combobox_ = combobox; - if (template_url_model_ && template_url_model_->loaded()) - ChangeComboboxSelection(); - else - combobox_->SetEnabled(false); -} - -int SearchEngineListModel::GetItemCount() { - return static_cast<int>(template_urls_.size()); -} - -string16 SearchEngineListModel::GetItemAt(int index) { - DCHECK(index < GetItemCount()); - return WideToUTF16Hack(template_urls_[index]->short_name()); -} - -const TemplateURL* SearchEngineListModel::GetTemplateURLAt(int index) { - DCHECK(index >= 0 && index < static_cast<int>(template_urls_.size())); - return template_urls_[static_cast<int>(index)]; -} - -void SearchEngineListModel::OnTemplateURLModelChanged() { - ResetContents(); -} - -void SearchEngineListModel::ResetContents() { - if (!template_url_model_ || !template_url_model_->loaded()) - return; - template_urls_.clear(); - TemplateURLs model_urls = template_url_model_->GetTemplateURLs(); - for (size_t i = 0; i < model_urls.size(); ++i) { - if (model_urls[i]->ShowInDefaultList()) - template_urls_.push_back(model_urls[i]); - } - - if (combobox_) { - combobox_->ModelChanged(); - ChangeComboboxSelection(); - } -} - -void SearchEngineListModel::ChangeComboboxSelection() { - if (template_urls_.size()) { - const TemplateURL* default_search_provider = - template_url_model_->GetDefaultSearchProvider(); - if (default_search_provider) { - TemplateURLs::iterator i = - find(template_urls_.begin(), template_urls_.end(), - default_search_provider); - if (i != template_urls_.end()) { - combobox_->SetSelectedItem( - static_cast<int>(i - template_urls_.begin())); - } - } else { - combobox_->SetSelectedItem(-1); - } - } - // If the default search is managed or there are no URLs, disable the control. - combobox_->SetEnabled(!template_urls_.empty() && - !template_url_model_->is_default_search_managed()); -} - -/////////////////////////////////////////////////////////////////////////////// -// GeneralPageView, public: - -GeneralPageView::GeneralPageView(Profile* profile) - : startup_group_(NULL), - startup_homepage_radio_(NULL), - startup_last_session_radio_(NULL), - startup_custom_radio_(NULL), - startup_add_custom_page_button_(NULL), - startup_remove_custom_page_button_(NULL), - startup_use_current_page_button_(NULL), - startup_custom_pages_table_(NULL), - homepage_group_(NULL), - homepage_use_newtab_radio_(NULL), - homepage_use_url_radio_(NULL), - homepage_use_url_textfield_(NULL), - homepage_show_home_button_checkbox_(NULL), - default_search_group_(NULL), - default_search_manage_engines_button_(NULL), - instant_checkbox_(NULL), - instant_link_(NULL), - default_browser_group_(NULL), - default_browser_status_label_(NULL), - default_browser_use_as_default_button_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST( - default_browser_worker_( - new ShellIntegration::DefaultBrowserWorker(this))), - OptionsPageView(profile) { -} - -GeneralPageView::~GeneralPageView() { - if (startup_custom_pages_table_) - startup_custom_pages_table_->SetModel(NULL); - default_browser_worker_->ObserverDestroyed(); -} - -/////////////////////////////////////////////////////////////////////////////// -// GeneralPageView, views::ButtonListener implementation: - -void GeneralPageView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == startup_homepage_radio_ || - sender == startup_last_session_radio_ || - sender == startup_custom_radio_) { - SaveStartupPref(); - if (sender == startup_homepage_radio_) { - UserMetricsRecordAction(UserMetricsAction("Options_Startup_Homepage"), - profile()->GetPrefs()); - } else if (sender == startup_last_session_radio_) { - UserMetricsRecordAction(UserMetricsAction("Options_Startup_LastSession"), - profile()->GetPrefs()); - } else if (sender == startup_custom_radio_) { - UserMetricsRecordAction(UserMetricsAction("Options_Startup_Custom"), - profile()->GetPrefs()); - } - } else if (sender == startup_add_custom_page_button_) { - AddURLToStartupURLs(); - } else if (sender == startup_remove_custom_page_button_) { - RemoveURLsFromStartupURLs(); - } else if (sender == startup_use_current_page_button_) { - SetStartupURLToCurrentPage(); - } else if (sender == homepage_use_newtab_radio_) { - UserMetricsRecordAction(UserMetricsAction("Options_Homepage_UseNewTab"), - profile()->GetPrefs()); - UpdateHomepagePrefs(); - EnableHomepageURLField(false); - } else if (sender == homepage_use_url_radio_) { - UserMetricsRecordAction(UserMetricsAction("Options_Homepage_UseURL"), - profile()->GetPrefs()); - UpdateHomepagePrefs(); - EnableHomepageURLField(true); - } else if (sender == homepage_show_home_button_checkbox_) { - bool show_button = homepage_show_home_button_checkbox_->checked(); - if (show_button) { - UserMetricsRecordAction( - UserMetricsAction("Options_Homepage_ShowHomeButton"), - profile()->GetPrefs()); - } else { - UserMetricsRecordAction( - UserMetricsAction("Options_Homepage_HideHomeButton"), - profile()->GetPrefs()); - } - show_home_button_.SetValue(show_button); - } else if (sender == default_browser_use_as_default_button_) { - default_browser_worker_->StartSetAsDefaultBrowser(); - UserMetricsRecordAction(UserMetricsAction("Options_SetAsDefaultBrowser"), - NULL); - // If the user made Chrome the default browser, then he/she arguably wants - // to be notified when that changes. - profile()->GetPrefs()->SetBoolean(prefs::kCheckDefaultBrowser, true); - } else if (sender == default_search_manage_engines_button_) { - UserMetricsRecordAction(UserMetricsAction("Options_ManageSearchEngines"), - NULL); - KeywordEditorView::Show(profile()); - } else if (sender == instant_checkbox_) { - if (instant_checkbox_->checked()) { - // Don't toggle immediately, instead let - // ShowInstantConfirmDialogIfNecessary do it. - instant_checkbox_->SetChecked(false); - browser::ShowInstantConfirmDialogIfNecessary( - GetWindow()->GetNativeWindow(), profile()); - } else { - profile()->GetPrefs()->SetBoolean(prefs::kInstantEnabled, false); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// GeneralPageView, views::Combobox::Listener implementation: - -void GeneralPageView::ItemChanged(views::Combobox* combobox, - int prev_index, int new_index) { - if (combobox == default_search_engine_combobox_) { - SetDefaultSearchProvider(); - UserMetricsRecordAction(UserMetricsAction("Options_SearchEngineChanged"), - NULL); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// GeneralPageView, views::Textfield::Controller implementation: - -void GeneralPageView::ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents) { - if (sender == homepage_use_url_textfield_) { - UpdateHomepagePrefs(); - } -} - -bool GeneralPageView::HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke&) { - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// GeneralPageView, OptionsPageView implementation: - -void GeneralPageView::InitControlLayout() { - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(5, 5, 5, 5); - SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView( - new ManagedPrefsBannerView(profile()->GetPrefs(), OPTIONS_PAGE_GENERAL)); - - layout->StartRow(0, single_column_view_set_id); - InitStartupGroup(); - layout->AddView(startup_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - InitHomepageGroup(); - layout->AddView(homepage_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - InitDefaultSearchGroup(); - layout->AddView(default_search_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - -#if !defined(OS_CHROMEOS) - layout->StartRow(0, single_column_view_set_id); - InitDefaultBrowserGroup(); - layout->AddView(default_browser_group_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); -#endif - - // Register pref observers that update the controls when a pref changes. - registrar_.Init(profile()->GetPrefs()); - registrar_.Add(prefs::kRestoreOnStartup, this); - registrar_.Add(prefs::kURLsToRestoreOnStartup, this); - registrar_.Add(prefs::kInstantEnabled, this); - - new_tab_page_is_home_page_.Init(prefs::kHomePageIsNewTabPage, - profile()->GetPrefs(), this); - homepage_.Init(prefs::kHomePage, profile()->GetPrefs(), this); - show_home_button_.Init(prefs::kShowHomeButton, profile()->GetPrefs(), this); -} - -void GeneralPageView::NotifyPrefChanged(const std::string* pref_name) { - PrefService* prefs = profile()->GetPrefs(); - if (!pref_name || - *pref_name == prefs::kRestoreOnStartup || - *pref_name == prefs::kURLsToRestoreOnStartup) { - const SessionStartupPref startup_pref = - SessionStartupPref::GetStartupPref(prefs); - bool radio_buttons_enabled = !SessionStartupPref::TypeIsManaged(prefs); - bool restore_urls_enabled = !SessionStartupPref::URLsAreManaged(prefs); - switch (startup_pref.type) { - case SessionStartupPref::DEFAULT: - startup_homepage_radio_->SetChecked(true); - restore_urls_enabled = false; - break; - - case SessionStartupPref::LAST: - startup_last_session_radio_->SetChecked(true); - restore_urls_enabled = false; - break; - - case SessionStartupPref::URLS: - startup_custom_radio_->SetChecked(true); - break; - } - startup_homepage_radio_->SetEnabled(radio_buttons_enabled); - startup_last_session_radio_->SetEnabled(radio_buttons_enabled); - startup_custom_radio_->SetEnabled(radio_buttons_enabled); - EnableCustomHomepagesControls(restore_urls_enabled); - startup_custom_pages_table_model_->SetURLs(startup_pref.urls); - } - - if (!pref_name || - *pref_name == prefs::kHomePageIsNewTabPage || - *pref_name == prefs::kHomePage) { - bool new_tab_page_is_home_page_managed = - new_tab_page_is_home_page_.IsManaged(); - bool homepage_managed = homepage_.IsManaged(); - bool homepage_url_is_new_tab = - IsNewTabUIURLString(GURL(homepage_.GetValue())); - bool homepage_is_new_tab = homepage_url_is_new_tab || - new_tab_page_is_home_page_.GetValue(); - // If HomepageIsNewTab is managed or - // Homepage is 'chrome://newtab' and managed, disable the radios. - bool disable_homepage_choice_buttons = - new_tab_page_is_home_page_managed || - homepage_managed && homepage_url_is_new_tab; - if (!homepage_url_is_new_tab) - homepage_use_url_textfield_->SetText(UTF8ToWide(homepage_.GetValue())); - UpdateHomepageIsNewTabRadio( - homepage_is_new_tab, !disable_homepage_choice_buttons); - EnableHomepageURLField(!homepage_is_new_tab); - } - - if (!pref_name || *pref_name == prefs::kShowHomeButton) { - homepage_show_home_button_checkbox_->SetChecked( - show_home_button_.GetValue()); - homepage_show_home_button_checkbox_->SetEnabled( - !show_home_button_.IsManaged()); - } - - if (!pref_name || *pref_name == prefs::kInstantEnabled) - instant_checkbox_->SetChecked(prefs->GetBoolean(prefs::kInstantEnabled)); -} - -void GeneralPageView::HighlightGroup(OptionsGroup highlight_group) { - if (highlight_group == OPTIONS_GROUP_DEFAULT_SEARCH) - default_search_group_->SetHighlighted(true); -} - -void GeneralPageView::LinkActivated(views::Link* source, int event_flags) { - DCHECK(source == instant_link_); - browser::ShowOptionsURL(profile(), - GURL(browser::kInstantLearnMoreURL)); -} - -/////////////////////////////////////////////////////////////////////////////// -// GeneralPageView, private: - -void GeneralPageView::SetDefaultBrowserUIState( - ShellIntegration::DefaultBrowserUIState state) { - bool button_enabled = state == ShellIntegration::STATE_NOT_DEFAULT; - default_browser_use_as_default_button_->SetEnabled(button_enabled); - default_browser_use_as_default_button_->SetNeedElevation(true); - if (state == ShellIntegration::STATE_IS_DEFAULT) { - default_browser_status_label_->SetText( - l10n_util::GetStringF(IDS_OPTIONS_DEFAULTBROWSER_DEFAULT, - l10n_util::GetString(IDS_PRODUCT_NAME))); - default_browser_status_label_->SetColor(kDefaultBrowserLabelColor); - Layout(); - } else if (state == ShellIntegration::STATE_NOT_DEFAULT) { - default_browser_status_label_->SetText( - l10n_util::GetStringF(IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT, - l10n_util::GetString(IDS_PRODUCT_NAME))); - default_browser_status_label_->SetColor(kNotDefaultBrowserLabelColor); - Layout(); - } else if (state == ShellIntegration::STATE_UNKNOWN) { - default_browser_status_label_->SetText( - l10n_util::GetStringF(IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN, - l10n_util::GetString(IDS_PRODUCT_NAME))); - default_browser_status_label_->SetColor(kNotDefaultBrowserLabelColor); - Layout(); - } -} - -void GeneralPageView::SetDefaultBrowserUIStateForSxS() { - default_browser_use_as_default_button_->SetEnabled(false); - default_browser_status_label_->SetText( - l10n_util::GetStringF(IDS_OPTIONS_DEFAULTBROWSER_SXS, - l10n_util::GetString(IDS_PRODUCT_NAME))); - default_browser_status_label_->SetColor(kNotDefaultBrowserLabelColor); - Layout(); -} - -void GeneralPageView::InitStartupGroup() { - startup_homepage_radio_ = new views::RadioButton( - l10n_util::GetString(IDS_OPTIONS_STARTUP_SHOW_DEFAULT_AND_NEWTAB), - kStartupRadioGroup); - startup_homepage_radio_->set_listener(this); - startup_last_session_radio_ = new views::RadioButton( - l10n_util::GetString(IDS_OPTIONS_STARTUP_SHOW_LAST_SESSION), - kStartupRadioGroup); - startup_last_session_radio_->set_listener(this); - startup_last_session_radio_->SetMultiLine(true); - startup_custom_radio_ = new views::RadioButton( - l10n_util::GetString(IDS_OPTIONS_STARTUP_SHOW_PAGES), - kStartupRadioGroup); - startup_custom_radio_->set_listener(this); - startup_add_custom_page_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_STARTUP_ADD_BUTTON)); - startup_remove_custom_page_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_STARTUP_REMOVE_BUTTON)); - startup_remove_custom_page_button_->SetEnabled(false); - startup_use_current_page_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_OPTIONS_STARTUP_USE_CURRENT)); - - startup_custom_pages_table_model_.reset( - new CustomHomePagesTableModel(profile())); - std::vector<TableColumn> columns; - columns.push_back(TableColumn()); - startup_custom_pages_table_ = new views::TableView( - startup_custom_pages_table_model_.get(), columns, - views::ICON_AND_TEXT, false, false, true); - startup_custom_pages_table_->SetObserver(this); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new OptionsGroupContents; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - const int double_column_view_set_id = 1; - column_set = layout->AddColumnSet(double_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(startup_homepage_radio_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(startup_last_session_radio_, 1, 1, - GridLayout::FILL, GridLayout::LEADING); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(startup_custom_radio_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, double_column_view_set_id); - layout->AddView(startup_custom_pages_table_, 1, 1, - GridLayout::FILL, GridLayout::FILL); - - views::View* button_stack = new views::View; - GridLayout* button_stack_layout = new GridLayout(button_stack); - button_stack->SetLayoutManager(button_stack_layout); - - column_set = button_stack_layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - button_stack_layout->StartRow(0, single_column_view_set_id); - button_stack_layout->AddView(startup_add_custom_page_button_, - 1, 1, GridLayout::FILL, GridLayout::CENTER); - button_stack_layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - button_stack_layout->StartRow(0, single_column_view_set_id); - button_stack_layout->AddView(startup_remove_custom_page_button_, - 1, 1, GridLayout::FILL, GridLayout::CENTER); - button_stack_layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - button_stack_layout->StartRow(0, single_column_view_set_id); - button_stack_layout->AddView(startup_use_current_page_button_, - 1, 1, GridLayout::FILL, GridLayout::CENTER); - layout->AddView(button_stack); - - startup_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_OPTIONS_STARTUP_GROUP_NAME), - std::wstring(), true); -} - -void GeneralPageView::InitHomepageGroup() { - homepage_use_newtab_radio_ = new views::RadioButton( - l10n_util::GetString(IDS_OPTIONS_HOMEPAGE_USE_NEWTAB), - kHomePageRadioGroup); - homepage_use_newtab_radio_->set_listener(this); - homepage_use_newtab_radio_->SetMultiLine(true); - homepage_use_url_radio_ = new views::RadioButton( - l10n_util::GetString(IDS_OPTIONS_HOMEPAGE_USE_URL), - kHomePageRadioGroup); - homepage_use_url_radio_->set_listener(this); - homepage_use_url_textfield_ = new views::Textfield; - homepage_use_url_textfield_->SetController(this); - homepage_use_url_textfield_->set_default_width_in_chars( - kHomePageTextfieldWidthChars); - homepage_show_home_button_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_HOMEPAGE_SHOW_BUTTON)); - homepage_show_home_button_checkbox_->set_listener(this); - homepage_show_home_button_checkbox_->SetMultiLine(true); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - const int double_column_view_set_id = 1; - column_set = layout->AddColumnSet(double_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(homepage_use_newtab_radio_, 1, 1, - GridLayout::FILL, GridLayout::LEADING); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, double_column_view_set_id); - layout->AddView(homepage_use_url_radio_); - layout->AddView(homepage_use_url_textfield_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(homepage_show_home_button_checkbox_, 1, 1, - GridLayout::FILL, GridLayout::LEADING); - - homepage_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_OPTIONS_HOMEPAGE_GROUP_NAME), - std::wstring(), true); -} - - -void GeneralPageView::InitDefaultSearchGroup() { - default_search_engines_model_.reset(new SearchEngineListModel(profile())); - default_search_engine_combobox_ = - new views::Combobox(default_search_engines_model_.get()); - default_search_engines_model_->SetCombobox(default_search_engine_combobox_); - default_search_engine_combobox_->set_listener(this); - - default_search_manage_engines_button_ = new views::NativeButton( - this, - l10n_util::GetString(IDS_OPTIONS_DEFAULTSEARCH_MANAGE_ENGINES_LINK)); - - instant_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_INSTANT_PREF)); - instant_checkbox_->SetMultiLine(true); - instant_checkbox_->set_listener(this); - - instant_link_ = new views::Link(l10n_util::GetString(IDS_LEARN_MORE)); - instant_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - instant_link_->SetController(this); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int double_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(double_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - const int single_column_view_set_id = 1; - column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - const int link_column_set_id = 2; - column_set = layout->AddColumnSet(link_column_set_id); - // TODO(sky): this isn't right, we need a method to determine real indent. - column_set->AddPaddingColumn(0, views::Checkbox::GetTextIndent() + 3); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, double_column_view_set_id); - layout->AddView(default_search_engine_combobox_); - layout->AddView(default_search_manage_engines_button_); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(instant_checkbox_); - layout->AddPaddingRow(0, 0); - - layout->StartRow(0, link_column_set_id); - layout->AddView( - new views::Label(l10n_util::GetString(IDS_INSTANT_PREF_WARNING))); - layout->AddView(instant_link_); - - default_search_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_OPTIONS_DEFAULTSEARCH_GROUP_NAME), - std::wstring(), true); -} - -void GeneralPageView::InitDefaultBrowserGroup() { - default_browser_status_label_ = new views::Label; - default_browser_status_label_->SetMultiLine(true); - default_browser_status_label_->SetHorizontalAlignment( - views::Label::ALIGN_LEFT); - default_browser_use_as_default_button_ = new views::NativeButton( - this, - l10n_util::GetStringF(IDS_OPTIONS_DEFAULTBROWSER_USEASDEFAULT, - l10n_util::GetString(IDS_PRODUCT_NAME))); - - using views::GridLayout; - using views::ColumnSet; - - views::View* contents = new views::View; - GridLayout* layout = new GridLayout(contents); - contents->SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, single_column_view_set_id); - layout->AddView(default_browser_status_label_, 1, 1, - GridLayout::FILL, GridLayout::LEADING); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(default_browser_use_as_default_button_); - - default_browser_group_ = new OptionsGroupView( - contents, l10n_util::GetString(IDS_OPTIONS_DEFAULTBROWSER_GROUP_NAME), - std::wstring(), false); - - if (BrowserDistribution::GetDistribution()->CanSetAsDefault()) - default_browser_worker_->StartCheckDefaultBrowser(); - else - SetDefaultBrowserUIStateForSxS(); -} - -void GeneralPageView::SaveStartupPref() { - SessionStartupPref pref; - - if (startup_last_session_radio_->checked()) { - pref.type = SessionStartupPref::LAST; - } else if (startup_custom_radio_->checked()) { - pref.type = SessionStartupPref::URLS; - } - - pref.urls = startup_custom_pages_table_model_->GetURLs(); - - SessionStartupPref::SetStartupPref(profile()->GetPrefs(), pref); -} - -void GeneralPageView::AddURLToStartupURLs() { - UrlPicker* dialog = new UrlPicker(this, profile()); - dialog->Show(GetWindow()->GetNativeWindow()); -} - -void GeneralPageView::RemoveURLsFromStartupURLs() { - int selected_row = 0; - for (views::TableView::iterator i = - startup_custom_pages_table_->SelectionBegin(); - i != startup_custom_pages_table_->SelectionEnd(); ++i) { - startup_custom_pages_table_model_->Remove(*i); - selected_row = *i; - } - int row_count = startup_custom_pages_table_->RowCount(); - if (selected_row >= row_count) - selected_row = row_count - 1; - if (selected_row >= 0) { - // Select the next row after the last row deleted, or the above item if the - // latest item was deleted or nothing when the table doesn't have any items. - startup_custom_pages_table_->Select(selected_row); - } - SaveStartupPref(); -} - -void GeneralPageView::SetStartupURLToCurrentPage() { - startup_custom_pages_table_model_->SetToCurrentlyOpenPages(); - - SaveStartupPref(); -} - -void GeneralPageView::EnableCustomHomepagesControls(bool enable) { - startup_add_custom_page_button_->SetEnabled(enable); - bool has_selected_rows = startup_custom_pages_table_->SelectedRowCount() > 0; - startup_remove_custom_page_button_->SetEnabled(enable && has_selected_rows); - startup_use_current_page_button_->SetEnabled(enable); - startup_custom_pages_table_->SetEnabled(enable); -} - -void GeneralPageView::AddBookmark(UrlPicker* dialog, - const std::wstring& title, - const GURL& url) { - // The restore URLs policy might have become managed while the dialog is - // displayed. While the model makes sure that no changes are made in this - // condition, we should still avoid changing the graphic elements. - if (SessionStartupPref::URLsAreManaged(profile()->GetPrefs())) - return; - int index = startup_custom_pages_table_->FirstSelectedRow(); - if (index == -1) - index = startup_custom_pages_table_model_->RowCount(); - else - index++; - startup_custom_pages_table_model_->Add(index, url); - startup_custom_pages_table_->Select(index); - - SaveStartupPref(); -} - -void GeneralPageView::UpdateHomepagePrefs() { - // If the text field contains a valid URL, sync it to prefs. We run it - // through the fixer upper to allow input like "google.com" to be converted - // to something valid ("http://google.com"). If the field contains an - // empty or null-host URL, a blank homepage is synced to prefs. - const GURL& homepage = - URLFixerUpper::FixupURL( - UTF16ToUTF8(homepage_use_url_textfield_->text()), std::string()); - bool new_tab_page_is_home_page = homepage_use_newtab_radio_->checked(); - if (IsNewTabUIURLString(homepage)) { // 'chrome://newtab/' - // This should be handled differently than invalid URLs. - // When the control arrives here, then |homepage| contains - // 'chrome://newtab/', and the homepage preference contains the previous - // valid content of the textfield (fixed up), most likely - // 'chrome://newta/'. This has to be cleared, because keeping it makes no - // sense to the user. - new_tab_page_is_home_page = true; - homepage_.SetValueIfNotManaged(std::string()); - } else if (!homepage.is_valid()) { - new_tab_page_is_home_page = true; - // The URL is invalid either with a host (e.g. http://chr%mium.org) - // or without a host (e.g. http://). In case there is a host, then - // the URL is not cleared, saving a fragment of the URL to the - // preferences (e.g. http://chr in case the characters of the above example - // were typed by the user one by one). - // See bug 40996. - if (!homepage.has_host()) - homepage_.SetValueIfNotManaged(std::string()); - } else { - homepage_.SetValueIfNotManaged(homepage.spec()); - } - new_tab_page_is_home_page_.SetValueIfNotManaged(new_tab_page_is_home_page); -} - -void GeneralPageView::UpdateHomepageIsNewTabRadio(bool homepage_is_new_tab, - bool enabled) { - homepage_use_newtab_radio_->SetChecked(homepage_is_new_tab); - homepage_use_url_radio_->SetChecked(!homepage_is_new_tab); - homepage_use_newtab_radio_->SetEnabled(enabled); - homepage_use_url_radio_->SetEnabled(enabled); -} - -void GeneralPageView::OnSelectionChanged() { - startup_remove_custom_page_button_->SetEnabled( - startup_custom_pages_table_->SelectedRowCount() > 0); -} - -void GeneralPageView::EnableHomepageURLField(bool enabled) { - if (homepage_.IsManaged()) { - enabled = false; - } - homepage_use_url_textfield_->SetEnabled(enabled); - homepage_use_url_textfield_->SetReadOnly(!enabled); -} - -void GeneralPageView::SetDefaultSearchProvider() { - const int index = default_search_engine_combobox_->selected_item(); - default_search_engines_model_->model()->SetDefaultSearchProvider( - default_search_engines_model_->GetTemplateURLAt(index)); -} diff --git a/chrome/browser/views/options/general_page_view.h b/chrome/browser/views/options/general_page_view.h index a663c82..f9072e1 100644 --- a/chrome/browser/views/options/general_page_view.h +++ b/chrome/browser/views/options/general_page_view.h @@ -6,167 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_GENERAL_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/prefs/pref_change_registrar.h" -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/shell_integration.h" -#include "chrome/browser/views/options/options_page_view.h" -#include "chrome/browser/views/url_picker.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/button/button.h" -#include "views/controls/link.h" -#include "views/controls/table/table_view_observer.h" -#include "views/view.h" - -namespace views { -class Checkbox; -class GroupboxView; -class Label; -class NativeButton; -class RadioButton; -class TableView; -class Textfield; -} -class CustomHomePagesTableModel; -class OptionsGroupView; -class SearchEngineListModel; -class TableModel; - -/////////////////////////////////////////////////////////////////////////////// -// GeneralPageView - -class GeneralPageView : public OptionsPageView, - public views::Combobox::Listener, - public views::ButtonListener, - public views::Textfield::Controller, - public UrlPickerDelegate, - public views::TableViewObserver, - public ShellIntegration::DefaultBrowserObserver, - public views::LinkController { - public: - explicit GeneralPageView(Profile* profile); - virtual ~GeneralPageView(); - - protected: - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::Combobox::Listener implementation: - virtual void ItemChanged(views::Combobox* combobox, - int prev_index, - int new_index); - - // views::Textfield::Controller implementation: - virtual void ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key); - - // OptionsPageView implementation: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - virtual void HighlightGroup(OptionsGroup highlight_group); - - // LinkController implementation: - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - // ShellIntegration::DefaultBrowserObserver implementation: - // Updates the UI state to reflect the current default browser state. - virtual void SetDefaultBrowserUIState( - ShellIntegration::DefaultBrowserUIState state); - - // For Side by Side installs, this will disable the Default Browser setting - // and display an explanitory message. - void SetDefaultBrowserUIStateForSxS(); - - // Init all the dialog controls - void InitStartupGroup(); - void InitHomepageGroup(); - void InitDefaultSearchGroup(); - void InitDefaultBrowserGroup(); - - // Saves the startup preference from that of the ui. - void SaveStartupPref(); - - // Shows a dialog allowing the user to add a new URL to the set of URLs - // launched on startup. - void AddURLToStartupURLs(); - - // Removes the selected URL from the list of startup urls. - void RemoveURLsFromStartupURLs(); - - // Resets the list of urls to launch on startup from the list of open - // browsers. - void SetStartupURLToCurrentPage(); - - // Enables/Disables the controls associated with the custom start pages - // option if that preference is not selected. - void EnableCustomHomepagesControls(bool enable); - - // UrlPickerDelegate. Adds the URL to the list of startup urls. - virtual void AddBookmark(UrlPicker* dialog, - const std::wstring& title, - const GURL& url); - - // Copies the home page preferences from the gui controls to - // kNewTabPageIsHomePage and kHomePage. If an empty or null-host - // URL is specified, then we revert to using NewTab page as the Homepage. - void UpdateHomepagePrefs(); - - // Invoked when the selection of the table view changes. Updates the enabled - // property of the remove button. - virtual void OnSelectionChanged(); - - // Enables or disables the field for entering a custom homepage URL. - void EnableHomepageURLField(bool enabled); - - // Sets the state and enables/disables the radio buttons that control - // if the home page is the new tab page. - void UpdateHomepageIsNewTabRadio(bool homepage_is_new_tab, bool enabled); - - // Sets the default search provider for the selected item in the combobox. - void SetDefaultSearchProvider(); - - // Controls for the Startup group - OptionsGroupView* startup_group_; - views::RadioButton* startup_homepage_radio_; - views::RadioButton* startup_last_session_radio_; - views::RadioButton* startup_custom_radio_; - views::NativeButton* startup_add_custom_page_button_; - views::NativeButton* startup_remove_custom_page_button_; - views::NativeButton* startup_use_current_page_button_; - views::TableView* startup_custom_pages_table_; - scoped_ptr<CustomHomePagesTableModel> startup_custom_pages_table_model_; - - // Controls for the Home Page group - OptionsGroupView* homepage_group_; - views::RadioButton* homepage_use_newtab_radio_; - views::RadioButton* homepage_use_url_radio_; - views::Textfield* homepage_use_url_textfield_; - views::Checkbox* homepage_show_home_button_checkbox_; - BooleanPrefMember new_tab_page_is_home_page_; - StringPrefMember homepage_; - BooleanPrefMember show_home_button_; - - // Controls for the Search group - OptionsGroupView* default_search_group_; - views::Combobox* default_search_engine_combobox_; - views::NativeButton* default_search_manage_engines_button_; - scoped_ptr<SearchEngineListModel> default_search_engines_model_; - views::Checkbox* instant_checkbox_; - views::Link* instant_link_; - - // Controls for the Default Browser group - OptionsGroupView* default_browser_group_; - views::Label* default_browser_status_label_; - views::NativeButton* default_browser_use_as_default_button_; - - // The helper object that performs default browser set/check tasks. - scoped_refptr<ShellIntegration::DefaultBrowserWorker> default_browser_worker_; - - PrefChangeRegistrar registrar_; - - DISALLOW_COPY_AND_ASSIGN(GeneralPageView); -}; +#include "chrome/browser/ui/views/options/general_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_GENERAL_PAGE_VIEW_H_ + diff --git a/chrome/browser/views/options/languages_page_view.cc b/chrome/browser/views/options/languages_page_view.cc deleted file mode 100644 index 207841c..0000000 --- a/chrome/browser/views/options/languages_page_view.cc +++ /dev/null @@ -1,579 +0,0 @@ -// 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 <windows.h> -#include <shlobj.h> -#include <vsstyle.h> -#include <vssym32.h> - -#include "chrome/browser/views/options/languages_page_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/command_line.h" -#include "base/file_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/language_combobox_model.h" -#include "chrome/browser/language_order_table_model.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/shell_dialogs.h" -#include "chrome/browser/views/restart_message_box.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/spellcheck_common.h" -#include "gfx/canvas.h" -#include "gfx/font.h" -#include "gfx/native_theme_win.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "unicode/uloc.h" -#include "views/controls/button/radio_button.h" -#include "views/controls/tabbed_pane/tabbed_pane.h" -#include "views/controls/table/table_view.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -/////////////////////////////////////////////////////////////////////////////// -// AddLanguageWindowView -// -// This opens another window from where a new accept language can be selected. -// -class AddLanguageWindowView : public views::View, - public views::Combobox::Listener, - public views::DialogDelegate { - public: - AddLanguageWindowView(LanguagesPageView* language_delegate, Profile* profile); - views::Window* container() const { return container_; } - void set_container(views::Window* container) { - container_ = container; - } - - // views::DialogDelegate methods. - virtual bool Accept(); - virtual std::wstring GetWindowTitle() const; - - // views::WindowDelegate method. - virtual bool IsModal() const { return true; } - virtual views::View* GetContentsView() { return this; } - - // views::Combobox::Listener implementation: - virtual void ItemChanged(views::Combobox* combobox, - int prev_index, - int new_index); - - // views::View overrides. - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - protected: - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - private: - void Init(); - - // The Options dialog window. - views::Window* container_; - - // Used for Call back to LanguagePageView that language has been selected. - LanguagesPageView* language_delegate_; - std::string accept_language_selected_; - - // Combobox and its corresponding model. - scoped_ptr<LanguageComboboxModel> accept_language_combobox_model_; - views::Combobox* accept_language_combobox_; - - // The Profile associated with this window. - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(AddLanguageWindowView); -}; - -static const int kDialogPadding = 7; -static int kDefaultWindowWidthChars = 60; -static int kDefaultWindowHeightLines = 3; - -AddLanguageWindowView::AddLanguageWindowView( - LanguagesPageView* language_delegate, - Profile* profile) - : profile_(profile->GetOriginalProfile()), - language_delegate_(language_delegate), - accept_language_combobox_(NULL) { - Init(); - - // Initialize accept_language_selected_ to the first index in drop down. - accept_language_selected_ = accept_language_combobox_model_-> - GetLocaleFromIndex(0); -} - -std::wstring AddLanguageWindowView::GetWindowTitle() const { - return l10n_util::GetString(IDS_FONT_LANGUAGE_SETTING_LANGUAGES_TAB_TITLE); -} - -bool AddLanguageWindowView::Accept() { - if (language_delegate_) { - language_delegate_->OnAddLanguage(accept_language_selected_); - } - return true; -} - -void AddLanguageWindowView::ItemChanged(views::Combobox* combobox, - int prev_index, - int new_index) { - accept_language_selected_ = accept_language_combobox_model_-> - GetLocaleFromIndex(new_index); -} - -void AddLanguageWindowView::Layout() { - gfx::Size sz = accept_language_combobox_->GetPreferredSize(); - accept_language_combobox_->SetBounds(kDialogPadding, kDialogPadding, - width() - 2*kDialogPadding, - sz.height()); -} - -gfx::Size AddLanguageWindowView::GetPreferredSize() { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& font = rb.GetFont(ResourceBundle::BaseFont); - return gfx::Size(font.GetAverageCharacterWidth() * kDefaultWindowWidthChars, - font.GetHeight() * kDefaultWindowHeightLines); -} - -void AddLanguageWindowView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - // Can't init before we're inserted into a Widget, because we require - // a HWND to parent native child controls to. - if (is_add && child == this) - Init(); -} - -void AddLanguageWindowView::Init() { - // Determine Locale Codes. - const std::string app_locale = g_browser_process->GetApplicationLocale(); - std::vector<std::string> locale_codes; - l10n_util::GetAcceptLanguagesForLocale(app_locale, &locale_codes); - - accept_language_combobox_model_.reset(new LanguageComboboxModel( - profile_, locale_codes)); - accept_language_combobox_ = new views::Combobox( - accept_language_combobox_model_.get()); - accept_language_combobox_->SetSelectedItem(0); - accept_language_combobox_->set_listener(this); - AddChildView(accept_language_combobox_); -} - -LanguagesPageView::LanguagesPageView(Profile* profile) - : languages_instructions_(NULL), - languages_contents_(NULL), - language_order_table_(NULL), - add_button_(NULL), - remove_button_(NULL), - move_up_button_(NULL), - move_down_button_(NULL), - button_stack_(NULL), - language_info_label_(NULL), - ui_language_label_(NULL), - change_ui_language_combobox_(NULL), - change_dictionary_language_combobox_(NULL), - enable_spellchecking_checkbox_(NULL), - enable_autospellcorrect_checkbox_(NULL), - dictionary_language_label_(NULL), - OptionsPageView(profile), - language_table_edited_(false), - language_warning_shown_(false), - enable_spellcheck_checkbox_clicked_(false), - enable_autospellcorrect_checkbox_clicked_(false), - spellcheck_language_index_selected_(-1), - ui_language_index_selected_(-1), - starting_ui_language_index_(-1) { - accept_languages_.Init(prefs::kAcceptLanguages, - profile->GetPrefs(), NULL); - enable_spellcheck_.Init(prefs::kEnableSpellCheck, - profile->GetPrefs(), NULL); - enable_autospellcorrect_.Init(prefs::kEnableAutoSpellCorrect, - profile->GetPrefs(), NULL); -} - -LanguagesPageView::~LanguagesPageView() { - if (language_order_table_) - language_order_table_->SetModel(NULL); -} - -void LanguagesPageView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (sender == move_up_button_) { - OnMoveUpLanguage(); - language_table_edited_ = true; - } else if (sender == move_down_button_) { - OnMoveDownLanguage(); - language_table_edited_ = true; - } else if (sender == remove_button_) { - OnRemoveLanguage(); - language_table_edited_ = true; - } else if (sender == add_button_) { - views::Window::CreateChromeWindow( - GetWindow()->GetNativeWindow(), - gfx::Rect(), - new AddLanguageWindowView(this, profile()))->Show(); - language_table_edited_ = true; - } else if (sender == enable_spellchecking_checkbox_) { - enable_spellcheck_checkbox_clicked_ = true; - } else if (sender == enable_autospellcorrect_checkbox_) { - enable_autospellcorrect_checkbox_clicked_ = true; - } -} - -void LanguagesPageView::OnAddLanguage(const std::string& new_language) { - if (language_order_table_model_->Add(new_language)) { - language_order_table_->Select(language_order_table_model_->RowCount() - 1); - OnSelectionChanged(); - } -} - -void LanguagesPageView::InitControlLayout() { - // Define the buttons. - add_button_ = new views::NativeButton(this, l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_ADD_BUTTON_LABEL)); - remove_button_ = new views::NativeButton(this, l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_REMOVE_BUTTON_LABEL)); - remove_button_->SetEnabled(false); - move_up_button_ = new views::NativeButton(this, l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEUP_BUTTON_LABEL)); - move_up_button_->SetEnabled(false); - move_down_button_ = new views::NativeButton(this, l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEDOWN_BUTTON_LABEL)); - move_down_button_->SetEnabled(false); - - languages_contents_ = new views::View; - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int single_column_view_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); - - // Add the instructions label. - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - languages_instructions_ = new views::Label( - l10n_util::GetString( - IDS_FONT_LANGUAGE_SETTING_LANGUAGES_INSTRUCTIONS)); - languages_instructions_->SetMultiLine(true); - languages_instructions_->SetHorizontalAlignment( - views::Label::ALIGN_LEFT); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(languages_instructions_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Add two columns - for table, and for button stack. - std::vector<TableColumn> columns; - columns.push_back(TableColumn()); - language_order_table_model_.reset(new LanguageOrderTableModel); - language_order_table_ = new views::TableView( - language_order_table_model_.get(), columns, - views::TEXT_ONLY, false, true, true); - language_order_table_->SetObserver(this); - - const int double_column_view_set_id = 1; - column_set = layout->AddColumnSet(double_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, double_column_view_set_id); - - // Add the table to the the first column. - layout->AddView(language_order_table_); - - // Now add the four buttons to the second column. - button_stack_ = new views::View; - GridLayout* button_stack_layout = new GridLayout(button_stack_); - button_stack_->SetLayoutManager(button_stack_layout); - - column_set = button_stack_layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - button_stack_layout->StartRow(0, single_column_view_set_id); - button_stack_layout->AddView(add_button_, 1, 1, GridLayout::FILL, - GridLayout::CENTER); - button_stack_layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - button_stack_layout->StartRow(0, single_column_view_set_id); - button_stack_layout->AddView(remove_button_, 1, 1, GridLayout::FILL, - GridLayout::CENTER); - button_stack_layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - button_stack_layout->StartRow(0, single_column_view_set_id); - button_stack_layout->AddView(move_up_button_, 1, 1, GridLayout::FILL, - GridLayout::CENTER); - button_stack_layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - button_stack_layout->StartRow(0, single_column_view_set_id); - button_stack_layout->AddView(move_down_button_, 1, 1, GridLayout::FILL, - GridLayout::CENTER); - - layout->AddView(button_stack_); - - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - language_info_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_CHROME_LANGUAGE_INFO)); - language_info_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - ui_language_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_CHROME_UI_LANGUAGE)); - ui_language_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - ui_language_model_.reset(new LanguageComboboxModel); - change_ui_language_combobox_ = - new views::Combobox(ui_language_model_.get()); - change_ui_language_combobox_->set_listener(this); - dictionary_language_label_ = new views::Label( - l10n_util::GetString(IDS_OPTIONS_CHROME_DICTIONARY_LANGUAGE)); - dictionary_language_label_->SetHorizontalAlignment( - views::Label::ALIGN_LEFT); - enable_spellchecking_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_ENABLE_SPELLCHECK)); - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kExperimentalSpellcheckerFeatures)) { - enable_autospellcorrect_checkbox_ = new views::Checkbox( - l10n_util::GetString(IDS_OPTIONS_ENABLE_AUTO_SPELL_CORRECTION)); - enable_autospellcorrect_checkbox_->set_listener(this); - } - enable_spellchecking_checkbox_->set_listener(this); - enable_spellchecking_checkbox_->SetMultiLine(true); - - // Determine Locale Codes. - std::vector<std::string> spell_check_languages; - SpellCheckCommon::SpellCheckLanguages(&spell_check_languages); - dictionary_language_model_.reset(new LanguageComboboxModel(profile(), - spell_check_languages)); - change_dictionary_language_combobox_ = - new views::Combobox(dictionary_language_model_.get()); - change_dictionary_language_combobox_->set_listener(this); - - // SpellCheck language settings. - layout->StartRow(0, single_column_view_set_id); - layout->AddView(enable_spellchecking_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - if (command_line.HasSwitch(switches::kExperimentalSpellcheckerFeatures)) { - layout->StartRow(0, single_column_view_set_id); - layout->AddView(enable_autospellcorrect_checkbox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - } - const int double_column_view_set_2_id = 2; - column_set = layout->AddColumnSet(double_column_view_set_2_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->StartRow(0, double_column_view_set_2_id); - layout->AddView(dictionary_language_label_); - layout->AddView(change_dictionary_language_combobox_); - - // UI language settings. - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - layout->StartRow(0, single_column_view_set_id); - layout->AddView(language_info_label_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(0, double_column_view_set_2_id); - layout->AddView(ui_language_label_); - layout->AddView(change_ui_language_combobox_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - // Init member prefs so we can update the controls if prefs change. - app_locale_.Init(prefs::kApplicationLocale, - g_browser_process->local_state(), this); - dictionary_language_.Init(prefs::kSpellCheckDictionary, - profile()->GetPrefs(), this); -} - -void LanguagesPageView::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kAcceptLanguages) { - language_order_table_model_->SetAcceptLanguagesString( - accept_languages_.GetValue()); - } - if (!pref_name || *pref_name == prefs::kApplicationLocale) { - int index = ui_language_model_->GetSelectedLanguageIndex( - prefs::kApplicationLocale); - if (-1 == index) { - // The pref value for locale isn't valid. Use the current app locale - // (which is what we're currently using). - index = ui_language_model_->GetIndexFromLocale( - g_browser_process->GetApplicationLocale()); - } - DCHECK(-1 != index); - change_ui_language_combobox_->SetSelectedItem(index); - starting_ui_language_index_ = index; - } - if (!pref_name || *pref_name == prefs::kSpellCheckDictionary) { - int index = dictionary_language_model_->GetSelectedLanguageIndex( - prefs::kSpellCheckDictionary); - - // If the index for the current language cannot be found, it is due to - // the fact that the pref-member value for the last dictionary language - // set by the user still uses the old format; i.e. language-region, even - // when region is not necessary. For example, if the user sets the - // dictionary language to be French, the pref-member value in the user - // profile is "fr-FR", whereas we now use only "fr". To resolve this issue, - // if "fr-FR" is read from the pref, the language code ("fr" here) is - // extracted, and re-written in the pref, so that the pref-member value for - // dictionary language in the user profile now correctly stores "fr" - // instead of "fr-FR". - if (index < 0) { - const std::string& lang_region = dictionary_language_.GetValue(); - dictionary_language_.SetValue( - SpellCheckCommon::GetLanguageFromLanguageRegion(lang_region)); - index = dictionary_language_model_->GetSelectedLanguageIndex( - prefs::kSpellCheckDictionary); - } - - change_dictionary_language_combobox_->SetSelectedItem(index); - spellcheck_language_index_selected_ = -1; - } - if (!pref_name || *pref_name == prefs::kEnableSpellCheck) { - enable_spellchecking_checkbox_->SetChecked( - enable_spellcheck_.GetValue()); - } - if (!pref_name || *pref_name == prefs::kEnableAutoSpellCorrect) { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kExperimentalSpellcheckerFeatures)) { - enable_autospellcorrect_checkbox_->SetChecked( - enable_autospellcorrect_.GetValue()); - } - } -} - -void LanguagesPageView::ItemChanged(views::Combobox* sender, - int prev_index, - int new_index) { - if (prev_index == new_index) - return; - - if (sender == change_ui_language_combobox_) { - if (new_index == starting_ui_language_index_) - ui_language_index_selected_ = -1; - else - ui_language_index_selected_ = new_index; - - if (!language_warning_shown_) { - RestartMessageBox::ShowMessageBox(GetWindow()->GetNativeWindow()); - language_warning_shown_ = true; - } - } else if (sender == change_dictionary_language_combobox_) { - // Set the spellcheck language selected. - spellcheck_language_index_selected_ = new_index; - - // Remove the previously added spell check language to the accept list. - if (!spellcheck_language_added_.empty()) { - int old_index = language_order_table_model_->GetIndex( - spellcheck_language_added_); - if (old_index > -1) - language_order_table_model_->Remove(old_index); - } - - // Add this new spell check language only if it is not already in the - // accept language list. - std::string language = - dictionary_language_model_->GetLocaleFromIndex(new_index); - int index = language_order_table_model_->GetIndex(language); - if (index == -1) { - // Add the new language. - OnAddLanguage(language); - language_table_edited_ = true; - spellcheck_language_added_ = language; - } else { - spellcheck_language_added_ = ""; - } - } -} - -void LanguagesPageView::OnSelectionChanged() { - move_up_button_->SetEnabled(language_order_table_->FirstSelectedRow() > 0 && - language_order_table_->SelectedRowCount() == 1); - move_down_button_->SetEnabled(language_order_table_->FirstSelectedRow() < - language_order_table_->RowCount() - 1 && - language_order_table_->SelectedRowCount() == - 1); - remove_button_->SetEnabled(language_order_table_->SelectedRowCount() > 0); -} - -void LanguagesPageView::OnRemoveLanguage() { - int item_selected = 0; - for (views::TableView::iterator i = - language_order_table_->SelectionBegin(); - i != language_order_table_->SelectionEnd(); ++i) { - language_order_table_model_->Remove(*i); - item_selected = *i; - } - - move_up_button_->SetEnabled(false); - move_down_button_->SetEnabled(false); - remove_button_->SetEnabled(false); - int items_left = language_order_table_model_->RowCount(); - if (items_left <= 0) - return; - if (item_selected > items_left - 1) - item_selected = items_left - 1; - language_order_table_->Select(item_selected); - OnSelectionChanged(); -} - -void LanguagesPageView::OnMoveDownLanguage() { - int item_selected = language_order_table_->FirstSelectedRow(); - language_order_table_model_->MoveDown(item_selected); - language_order_table_->Select(item_selected + 1); - OnSelectionChanged(); -} - -void LanguagesPageView::OnMoveUpLanguage() { - int item_selected = language_order_table_->FirstSelectedRow(); - language_order_table_model_->MoveUp(item_selected); - language_order_table_->Select(item_selected - 1); - - OnSelectionChanged(); -} - -void LanguagesPageView::SaveChanges() { - if (language_order_table_model_.get() && language_table_edited_) { - accept_languages_.SetValue( - language_order_table_model_->GetLanguageList()); - } - - if (ui_language_index_selected_ != -1) { - UserMetricsRecordAction(UserMetricsAction("Options_AppLanguage"), - g_browser_process->local_state()); - app_locale_.SetValue(ui_language_model_-> - GetLocaleFromIndex(ui_language_index_selected_)); - - // Remove pref values for spellcheck dictionaries forcefully. - PrefService* prefs = profile()->GetPrefs(); - if (prefs) - prefs->ClearPref(prefs::kSpellCheckDictionary); - } - - if (spellcheck_language_index_selected_ != -1) { - UserMetricsRecordAction(UserMetricsAction("Options_DictionaryLanguage"), - profile()->GetPrefs()); - dictionary_language_.SetValue(dictionary_language_model_-> - GetLocaleFromIndex(spellcheck_language_index_selected_)); - } - - if (enable_spellcheck_checkbox_clicked_) - enable_spellcheck_.SetValue(enable_spellchecking_checkbox_->checked()); - - if (enable_autospellcorrect_checkbox_clicked_) { - enable_autospellcorrect_.SetValue( - enable_autospellcorrect_checkbox_->checked()); - } -} diff --git a/chrome/browser/views/options/languages_page_view.h b/chrome/browser/views/options/languages_page_view.h index ace044e..722a893 100644 --- a/chrome/browser/views/options/languages_page_view.h +++ b/chrome/browser/views/options/languages_page_view.h @@ -2,118 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_OPTIONS_LANGUAGES_PAGE_VIEW_H__ -#define CHROME_BROWSER_VIEWS_OPTIONS_LANGUAGES_PAGE_VIEW_H__ +#ifndef CHROME_BROWSER_VIEWS_OPTIONS_LANGUAGES_PAGE_VIEW_H_ +#define CHROME_BROWSER_VIEWS_OPTIONS_LANGUAGES_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/views/options/options_page_view.h" -#include "views/controls/combobox/combobox.h" -#include "views/controls/button/button.h" -#include "views/controls/table/table_view_observer.h" -#include "views/view.h" +#include "chrome/browser/ui/views/options/languages_page_view.h" +// TODO(beng): remove this file once all includes have been updated. -namespace views { -class Checkbox; -class Label; -class NativeButton; -class TableView; -} +#endif // CHROME_BROWSER_VIEWS_OPTIONS_LANGUAGES_PAGE_VIEW_H_ -class AddLanguageView; -class LanguageComboboxModel; -class LanguageOrderTableModel; -class TableModel; - -/////////////////////////////////////////////////////////////////////////////// -// LanguagesPageView - -class LanguagesPageView : public OptionsPageView, - public views::ButtonListener, - public views::TableViewObserver, - public views::Combobox::Listener { - public: - explicit LanguagesPageView(Profile* profile); - virtual ~LanguagesPageView(); - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Save Changes made to relevant pref members associated with this tab. - // This is public since it is called by FontsLanguageWindowView in its - // Dialog Delegate Accept() method. - void SaveChanges(); - - // This is public because when user clicks OK in AddLanguageView dialog, - // this is called back in the LanguagePageView delegate in order to add - // this language to the table model in this tab. - void OnAddLanguage(const std::string& new_language); - - protected: - // OptionsPageView implementation: - virtual void InitControlLayout(); - virtual void NotifyPrefChanged(const std::string* pref_name); - - // views::Combobox::Listener implementation: - virtual void ItemChanged(views::Combobox* sender, - int prev_index, - int new_index); - - private: - // Invoked when the selection of the table view changes. Updates the enabled - // property of the remove button. - virtual void OnSelectionChanged(); - void OnRemoveLanguage(); - void OnMoveDownLanguage(); - void OnMoveUpLanguage(); - - views::Label* languages_instructions_; - views::View* languages_contents_; - views::View* button_stack_; - views::TableView* language_order_table_; - views::NativeButton* move_up_button_; - views::NativeButton* move_down_button_; - views::NativeButton* add_button_; - views::NativeButton* remove_button_; - views::Label* language_info_label_; - views::Label* ui_language_label_; - views::Combobox* change_ui_language_combobox_; - views::Combobox* change_dictionary_language_combobox_; - views::Checkbox* enable_autospellcorrect_checkbox_; - views::Checkbox* enable_spellchecking_checkbox_; - views::Label* dictionary_language_label_; - - scoped_ptr<LanguageOrderTableModel> language_order_table_model_; - AddLanguageView* add_language_instance_; - StringPrefMember accept_languages_; - - // The contents of the "user interface language" combobox. - scoped_ptr<LanguageComboboxModel> ui_language_model_; - StringPrefMember app_locale_; - int ui_language_index_selected_; - int starting_ui_language_index_; - - // The contents of the "dictionary language" combobox. - scoped_ptr<LanguageComboboxModel> dictionary_language_model_; - StringPrefMember dictionary_language_; - - // SpellChecker enable pref. - BooleanPrefMember enable_spellcheck_; - - // Auto spell correction pref. - BooleanPrefMember enable_autospellcorrect_; - - // This is assigned the new index of spellcheck language if the language - // is changed. Otherwise, it remains -1, and pref members are not updated. - int spellcheck_language_index_selected_; - std::string spellcheck_language_added_; - - bool language_table_edited_; - bool language_warning_shown_; - bool enable_spellcheck_checkbox_clicked_; - bool enable_autospellcorrect_checkbox_clicked_; - - DISALLOW_COPY_AND_ASSIGN(LanguagesPageView); -}; - -#endif // CHROME_BROWSER_VIEWS_OPTIONS_LANGUAGES_PAGE_VIEW_H__ diff --git a/chrome/browser/views/options/managed_prefs_banner_view.cc b/chrome/browser/views/options/managed_prefs_banner_view.cc deleted file mode 100644 index e063d14..0000000 --- a/chrome/browser/views/options/managed_prefs_banner_view.cc +++ /dev/null @@ -1,71 +0,0 @@ -// 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/options/managed_prefs_banner_view.h" - -#include "app/resource_bundle.h" -#include "gfx/color_utils.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/box_layout.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/standard_layout.h" - -// Spacing between the banner frame and its contents. -static const int kPrefsBannerPadding = 3; -// Width of the banner frame. -static const int kPrefsBannerBorderSize = 1; - -ManagedPrefsBannerView::ManagedPrefsBannerView(PrefService* prefs, - OptionsPage page) - : policy::ManagedPrefsBannerBase(prefs, page) { - content_ = new views::View; - SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); - views::Border* border = views::Border::CreateSolidBorder( - kPrefsBannerBorderSize, border_color); - content_->set_border(border); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - warning_image_ = new views::ImageView(); - warning_image_->SetImage(rb.GetBitmapNamed(IDR_WARNING)); - label_ = new views::Label(rb.GetLocalizedString(IDS_OPTIONS_MANAGED_PREFS)); -} - -void ManagedPrefsBannerView::Init() { - AddChildView(content_); - content_->SetLayoutManager( - new views::BoxLayout(views::BoxLayout::kHorizontal, - kPrefsBannerPadding, - kPrefsBannerPadding, - kRelatedControlSmallHorizontalSpacing)); - content_->AddChildView(warning_image_); - content_->AddChildView(label_); - OnUpdateVisibility(); -} - -gfx::Size ManagedPrefsBannerView::GetPreferredSize() { - if (!IsVisible()) - return gfx::Size(); - - // Add space below the banner. - gfx::Size size(content_->GetPreferredSize()); - size.Enlarge(0, kRelatedControlVerticalSpacing); - return size; -} - -void ManagedPrefsBannerView::Layout() { - content_->SetBounds(0, 0, width(), height() - kRelatedControlVerticalSpacing); -} - -void ManagedPrefsBannerView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -void ManagedPrefsBannerView::OnUpdateVisibility() { - SetVisible(DetermineVisibility()); -} diff --git a/chrome/browser/views/options/managed_prefs_banner_view.h b/chrome/browser/views/options/managed_prefs_banner_view.h index f34ab30..d1efb86 100644 --- a/chrome/browser/views/options/managed_prefs_banner_view.h +++ b/chrome/browser/views/options/managed_prefs_banner_view.h @@ -6,47 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_MANAGED_PREFS_BANNER_VIEW_H_ #pragma once -#include "chrome/browser/policy/managed_prefs_banner_base.h" -#include "views/view.h" - -namespace views { -class ImageView; -class Label; -} - -// Displays a banner showing a warning message that tells the user some options -// cannot be changed because the relevant preferences are managed by their -// system administrator. -class ManagedPrefsBannerView : public policy::ManagedPrefsBannerBase, - public views::View { - public: - // Initialize the banner. |page| is used to determine the names of the - // preferences that control the banner visibility through their managed flag. - ManagedPrefsBannerView(PrefService* pref_service, OptionsPage page); - virtual ~ManagedPrefsBannerView() {} - - private: - // Initialize contents and layout. - void Init(); - - // views::View overrides. - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // ManagedPrefsBannerBase override. - virtual void OnUpdateVisibility(); - - // Holds the warning icon image and text label and renders the border. - views::View* content_; - // Warning icon image. - views::ImageView* warning_image_; - // The label responsible for rendering the warning text. - views::Label* label_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ManagedPrefsBannerView); -}; +#include "chrome/browser/ui/views/options/managed_prefs_banner_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_MANAGED_PREFS_BANNER_VIEW_H_ + diff --git a/chrome/browser/views/options/options_group_view.cc b/chrome/browser/views/options/options_group_view.cc deleted file mode 100644 index ef3e5dd..0000000 --- a/chrome/browser/views/options/options_group_view.cc +++ /dev/null @@ -1,141 +0,0 @@ -// 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 <vsstyle.h> -#include <vssym32.h> - -#include "chrome/browser/views/options/options_group_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "gfx/canvas.h" -#include "gfx/font.h" -#include "gfx/native_theme_win.h" -#include "grit/locale_settings.h" -#include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/standard_layout.h" - -static const int kLeftColumnWidthChars = 20; -static const int kOptionsGroupViewColumnSpacing = 30; - -/////////////////////////////////////////////////////////////////////////////// -// OptionsGroupView, public: - -OptionsGroupView::OptionsGroupView(views::View* contents, - const std::wstring& title, - const std::wstring& description, - bool show_separator) - : contents_(contents), - title_label_(new views::Label(title)), - description_label_(new views::Label(description)), - separator_(NULL), - show_separator_(show_separator), - highlighted_(false) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& title_font = - rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); - title_label_->SetFont(title_font); - SkColor title_color = gfx::NativeTheme::instance()->GetThemeColorWithDefault( - gfx::NativeTheme::BUTTON, BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, - COLOR_WINDOWTEXT); - title_label_->SetColor(title_color); - title_label_->SetMultiLine(true); - title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - description_label_->SetMultiLine(true); - description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - - SetAccessibleName(title); - contents->SetAccessibleName(title); -} - -OptionsGroupView::~OptionsGroupView() { -} - -void OptionsGroupView::SetHighlighted(bool highlighted) { - highlighted_ = highlighted; - SchedulePaint(); -} - -int OptionsGroupView::GetContentsWidth() const { - return contents_->width(); -} - -/////////////////////////////////////////////////////////////////////////////// -// OptionsGroupView, views::View overrides: - -AccessibilityTypes::Role OptionsGroupView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -void OptionsGroupView::Paint(gfx::Canvas* canvas) { - if (highlighted_) { - COLORREF infocolor = GetSysColor(COLOR_INFOBK); - SkColor background_color = SkColorSetRGB(GetRValue(infocolor), - GetGValue(infocolor), - GetBValue(infocolor)); - int y_offset = kUnrelatedControlVerticalSpacing / 2; - canvas->FillRectInt(background_color, 0, 0, width(), - height() - y_offset); - } -} - -void OptionsGroupView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// OptionsGroupView, private: - -void OptionsGroupView::Init() { - using views::GridLayout; - using views::ColumnSet; - - GridLayout* layout = new GridLayout(this); - SetLayoutManager(layout); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& font = rb.GetFont(ResourceBundle::BaseFont); - std::wstring left_column_chars = - l10n_util::GetString(IDS_OPTIONS_DIALOG_LEFT_COLUMN_WIDTH_CHARS); - int left_column_width = - font.GetExpectedTextWidth(_wtoi(left_column_chars.c_str())); - - const int two_column_layout_id = 0; - ColumnSet* column_set = layout->AddColumnSet(two_column_layout_id); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, - GridLayout::FIXED, left_column_width, 0); - column_set->AddPaddingColumn(0, kOptionsGroupViewColumnSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(0, two_column_layout_id); - layout->AddView(title_label_, 1, 1, GridLayout::FILL, GridLayout::LEADING); - layout->AddView(contents_, 1, 3, GridLayout::FILL, GridLayout::FILL); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - layout->StartRow(1, two_column_layout_id); - layout->AddView(description_label_, 1, 1, - GridLayout::FILL, GridLayout::LEADING); - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - if (show_separator_) { - const int single_column_layout_id = 1; - column_set = layout->AddColumnSet(single_column_layout_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - separator_ = new views::Separator; - layout->StartRow(0, single_column_layout_id); - layout->AddView(separator_); - } -} diff --git a/chrome/browser/views/options/options_group_view.h b/chrome/browser/views/options/options_group_view.h index b79a36e..b3bf71b 100644 --- a/chrome/browser/views/options/options_group_view.h +++ b/chrome/browser/views/options/options_group_view.h @@ -2,62 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_GROUP_VIEW_H__ -#define CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_GROUP_VIEW_H__ +#ifndef CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_GROUP_VIEW_H_ +#define CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_GROUP_VIEW_H_ #pragma once -#include "views/view.h" +#include "chrome/browser/ui/views/options/options_group_view.h" +// TODO(beng): remove this file once all includes have been updated. -namespace views { -class Label; -class Separator; -}; +#endif // CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_GROUP_VIEW_H_ -/////////////////////////////////////////////////////////////////////////////// -// OptionsGroupView -// -// A helper View that gathers related options into groups with a title and -// optional description. -// -class OptionsGroupView : public views::View { - public: - OptionsGroupView(views::View* contents, - const std::wstring& title, - const std::wstring& description, - bool show_separator); - virtual ~OptionsGroupView(); - - // Sets the group as being highlighted to attract attention. - void SetHighlighted(bool highlighted); - - // Retrieves the width of the ContentsView. Used to help size wrapping items. - int GetContentsWidth() const; - - protected: - // views::View overrides: - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual void Paint(gfx::Canvas* canvas); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - private: - void Init(); - - views::View* contents_; - views::Label* title_label_; - views::Label* description_label_; - views::Separator* separator_; - - // True if we should show a separator line below the contents of this - // section. - bool show_separator_; - - // True if this section should have a highlighted treatment to draw the - // user's attention. - bool highlighted_; - - DISALLOW_COPY_AND_ASSIGN(OptionsGroupView); -}; - -#endif // CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_GROUP_VIEW_H__ diff --git a/chrome/browser/views/options/options_page_view.cc b/chrome/browser/views/options/options_page_view.cc deleted file mode 100644 index 6073442..0000000 --- a/chrome/browser/views/options/options_page_view.cc +++ /dev/null @@ -1,42 +0,0 @@ -// 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/options/options_page_view.h" - -#include "chrome/browser/browser_process.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/common/notification_service.h" -#include "views/widget/widget.h" - -/////////////////////////////////////////////////////////////////////////////// -// OptionsPageView - -OptionsPageView::OptionsPageView(Profile* profile) - : OptionsPageBase(profile), - initialized_(false) { -} - -OptionsPageView::~OptionsPageView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// OptionsPageView, views::View overrides: - -void OptionsPageView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (!initialized_ && is_add && GetWidget()) { - // It is important that this only get done _once_ otherwise we end up - // duplicating the view hierarchy when tabs are switched. - initialized_ = true; - InitControlLayout(); - NotifyPrefChanged(NULL); - } -} - -AccessibilityTypes::Role OptionsPageView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PAGETAB; -} - diff --git a/chrome/browser/views/options/options_page_view.h b/chrome/browser/views/options/options_page_view.h index 698cb99..2920edb 100644 --- a/chrome/browser/views/options/options_page_view.h +++ b/chrome/browser/views/options/options_page_view.h @@ -2,51 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_PAGE_VIEW_H__ -#define CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_PAGE_VIEW_H__ +#ifndef CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_PAGE_VIEW_H_ +#define CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/options_page_base.h" -#include "views/controls/link.h" -#include "views/controls/button/native_button.h" +#include "chrome/browser/ui/views/options/options_page_view.h" +// TODO(beng): remove this file once all includes have been updated. -class PrefService; +#endif // CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_PAGE_VIEW_H_ -/////////////////////////////////////////////////////////////////////////////// -// OptionsPageView -// -// A base class for Options dialog pages that handles ensuring control -// initialization is done just once. -// -class OptionsPageView : public views::View, - public OptionsPageBase { - public: - virtual ~OptionsPageView(); - - // Returns true if the window containing this view can be closed, given the - // current state of this view. This can be used to prevent the window from - // being closed when a modal dialog box is showing, for example. - virtual bool CanClose() const { return true; } - - protected: - // This class cannot be instantiated directly, but its constructor must be - // called by derived classes. - explicit OptionsPageView(Profile* profile); - - // Initializes the layout of the controls within the panel. - virtual void InitControlLayout() = 0; - - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - private: - // Whether or not the control layout has been initialized for this page. - bool initialized_; - - DISALLOW_COPY_AND_ASSIGN(OptionsPageView); -}; - -#endif // CHROME_BROWSER_VIEWS_OPTIONS_OPTIONS_PAGE_VIEW_H__ diff --git a/chrome/browser/views/options/options_window_view.cc b/chrome/browser/views/options/options_window_view.cc deleted file mode 100644 index 8201bd8..0000000 --- a/chrome/browser/views/options/options_window_view.cc +++ /dev/null @@ -1,244 +0,0 @@ -// 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/options_window.h" - -#include "app/l10n_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/views/options/advanced_page_view.h" -#include "chrome/browser/views/options/content_page_view.h" -#include "chrome/browser/views/options/general_page_view.h" -#include "chrome/browser/window_sizer.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/pref_names.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/tabbed_pane/tabbed_pane.h" -#include "views/widget/root_view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -/////////////////////////////////////////////////////////////////////////////// -// OptionsWindowView -// -// The contents of the Options dialog window. -// -class OptionsWindowView : public views::View, - public views::DialogDelegate, - public views::TabbedPane::Listener { - public: - explicit OptionsWindowView(Profile* profile); - virtual ~OptionsWindowView(); - - // Shows the Tab corresponding to the specified OptionsPage. - void ShowOptionsPage(OptionsPage page, OptionsGroup highlight_group); - - // views::DialogDelegate implementation: - virtual int GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - virtual std::wstring GetWindowTitle() const; - virtual std::wstring GetWindowName() const; - virtual void WindowClosing(); - virtual bool Cancel(); - virtual views::View* GetContentsView(); - virtual bool ShouldRestoreWindowSize() const; - - // views::TabbedPane::Listener implementation: - virtual void TabSelectedAt(int index); - - // views::View overrides: - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - protected: - // views::View overrides: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - private: - // Init the assorted Tabbed pages - void Init(); - - // Returns the currently selected OptionsPageView. - OptionsPageView* GetCurrentOptionsPageView() const; - - // The Tab view that contains all of the options pages. - views::TabbedPane* tabs_; - - // The Profile associated with these options. - Profile* profile_; - - // The last page the user was on when they opened the Options window. - IntegerPrefMember last_selected_page_; - - DISALLOW_COPY_AND_ASSIGN(OptionsWindowView); -}; - -// static -static OptionsWindowView* instance_ = NULL; -static const int kDialogPadding = 7; - -/////////////////////////////////////////////////////////////////////////////// -// OptionsWindowView, public: - -OptionsWindowView::OptionsWindowView(Profile* profile) - // Always show preferences for the original profile. Most state when off - // the record comes from the original profile, but we explicitly use - // the original profile to avoid potential problems. - : profile_(profile->GetOriginalProfile()) { - // We don't need to observe changes in this value. - last_selected_page_.Init(prefs::kOptionsWindowLastTabIndex, - g_browser_process->local_state(), NULL); -} - -OptionsWindowView::~OptionsWindowView() { -} - -void OptionsWindowView::ShowOptionsPage(OptionsPage page, - OptionsGroup highlight_group) { - // Positioning is handled by window_delegate. we just need to show the window. - // This will show invisible windows and bring visible windows to the front. - window()->Show(); - - if (page == OPTIONS_PAGE_DEFAULT) { - // Remember the last visited page from local state. - page = static_cast<OptionsPage>(last_selected_page_.GetValue()); - if (page == OPTIONS_PAGE_DEFAULT) - page = OPTIONS_PAGE_GENERAL; - } - // If the page number is out of bounds, reset to the first tab. - if (page < 0 || page >= tabs_->GetTabCount()) - page = OPTIONS_PAGE_GENERAL; - - tabs_->SelectTabAt(static_cast<int>(page)); - - GetCurrentOptionsPageView()->HighlightGroup(highlight_group); -} - -/////////////////////////////////////////////////////////////////////////////// -// OptionsWindowView, views::DialogDelegate implementation: - -std::wstring OptionsWindowView::GetWindowTitle() const { - return l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE, - l10n_util::GetString(IDS_PRODUCT_NAME)); -} - -std::wstring OptionsWindowView::GetWindowName() const { - return UTF8ToWide(prefs::kPreferencesWindowPlacement); -} - -void OptionsWindowView::WindowClosing() { - // Clear the static instance so that the next time ShowOptionsWindow() is - // called a new window is opened. - instance_ = NULL; -} - -bool OptionsWindowView::Cancel() { - return GetCurrentOptionsPageView()->CanClose(); -} - -views::View* OptionsWindowView::GetContentsView() { - return this; -} - -bool OptionsWindowView::ShouldRestoreWindowSize() const { - // By returning false the options window is always sized to its preferred - // size. - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// OptionsWindowView, views::TabbedPane::Listener implementation: - -void OptionsWindowView::TabSelectedAt(int index) { - DCHECK(index > OPTIONS_PAGE_DEFAULT && index < OPTIONS_PAGE_COUNT); - last_selected_page_.SetValue(index); -} - -/////////////////////////////////////////////////////////////////////////////// -// OptionsWindowView, views::View overrides: - -AccessibilityTypes::Role OptionsWindowView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_CLIENT; -} - -void OptionsWindowView::Layout() { - tabs_->SetBounds(kDialogPadding, kDialogPadding, - width() - (2 * kDialogPadding), - height() - (2 * kDialogPadding)); -} - -gfx::Size OptionsWindowView::GetPreferredSize() { - gfx::Size size(tabs_->GetPreferredSize()); - size.Enlarge(2 * kDialogPadding, 2 * kDialogPadding); - return size; -} - -void OptionsWindowView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - // Can't init before we're inserted into a Container, because we require a - // HWND to parent native child controls to. - if (is_add && child == this) - Init(); -} - -/////////////////////////////////////////////////////////////////////////////// -// OptionsWindowView, private: - -void OptionsWindowView::Init() { - tabs_ = new views::TabbedPane; - tabs_->SetAccessibleName(l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE, - l10n_util::GetString(IDS_PRODUCT_NAME))); - tabs_->SetListener(this); - AddChildView(tabs_); - - int tab_index = 0; - GeneralPageView* general_page = new GeneralPageView(profile_); - tabs_->AddTabAtIndex(tab_index++, - l10n_util::GetString(IDS_OPTIONS_GENERAL_TAB_LABEL), - general_page, false); - - ContentPageView* content_page = new ContentPageView(profile_); - tabs_->AddTabAtIndex(tab_index++, - l10n_util::GetString(IDS_OPTIONS_CONTENT_TAB_LABEL), - content_page, false); - - AdvancedPageView* advanced_page = new AdvancedPageView(profile_); - tabs_->AddTabAtIndex(tab_index++, - l10n_util::GetString(IDS_OPTIONS_ADVANCED_TAB_LABEL), - advanced_page, false); - - DCHECK(tabs_->GetTabCount() == OPTIONS_PAGE_COUNT); -} - -OptionsPageView* OptionsWindowView::GetCurrentOptionsPageView() const { - return static_cast<OptionsPageView*>(tabs_->GetSelectedTab()); -} - -/////////////////////////////////////////////////////////////////////////////// -// Factory/finder method: - -void ShowOptionsWindow(OptionsPage page, - OptionsGroup highlight_group, - Profile* profile) { - DCHECK(profile); - // If there's already an existing options window, activate it and switch to - // the specified page. - // TODO(beng): note this is not multi-simultaneous-profile-safe. When we care - // about this case this will have to be fixed. - if (!instance_) { - instance_ = new OptionsWindowView(profile); - views::Window::CreateChromeWindow(NULL, gfx::Rect(), instance_); - } - instance_->ShowOptionsPage(page, highlight_group); -} diff --git a/chrome/browser/views/options/passwords_exceptions_window_view.cc b/chrome/browser/views/options/passwords_exceptions_window_view.cc deleted file mode 100644 index 5c786ac..0000000 --- a/chrome/browser/views/options/passwords_exceptions_window_view.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2009 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/options/passwords_exceptions_window_view.h" - -#include "app/l10n_util.h" -#include "chrome/browser/views/options/passwords_page_view.h" -#include "chrome/browser/views/options/exceptions_page_view.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/tabbed_pane/tabbed_pane.h" -#include "views/window/window.h" - -// static -PasswordsExceptionsWindowView* PasswordsExceptionsWindowView::instance_ = NULL; - -static const int kDialogPadding = 7; - -namespace browser { - -// Declared in browser_dialogs.h so others don't have to depend on our header. -void ShowPasswordsExceptionsWindowView(Profile* profile) { - PasswordsExceptionsWindowView::Show(profile); -} - -} // namespace browser - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsExceptionsWindowView, public - -PasswordsExceptionsWindowView::PasswordsExceptionsWindowView(Profile* profile) - : tabs_(NULL), - passwords_page_view_(NULL), - exceptions_page_view_(NULL), - profile_(profile) { -} - -// static -void PasswordsExceptionsWindowView::Show(Profile* profile) { - DCHECK(profile); - if (!instance_) { - instance_ = new PasswordsExceptionsWindowView(profile); - - // |instance_| will get deleted once Close() is called. - views::Window::CreateChromeWindow(NULL, gfx::Rect(), instance_); - } - if (!instance_->window()->IsVisible()) { - instance_->window()->Show(); - } else { - instance_->window()->Activate(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// PasswordsExceptionsWindowView, views::View implementations - -void PasswordsExceptionsWindowView::Layout() { - tabs_->SetBounds(kDialogPadding, kDialogPadding, - width() - (2 * kDialogPadding), - height() - (2 * kDialogPadding)); -} - -gfx::Size PasswordsExceptionsWindowView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_PASSWORDS_DIALOG_WIDTH_CHARS, - IDS_PASSWORDS_DIALOG_HEIGHT_LINES)); -} - -void PasswordsExceptionsWindowView::ViewHierarchyChanged( - bool is_add, views::View* parent, views::View* child) { - if (is_add && child == this) - Init(); -} - -///////////////////////////////////////////////////////////////////////////// -// PasswordsExceptionsWindowView, views::DisloagDelegate implementations - -int PasswordsExceptionsWindowView::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring PasswordsExceptionsWindowView::GetWindowTitle() const { - return l10n_util::GetString(IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE); -} - -void PasswordsExceptionsWindowView::WindowClosing() { - // |instance_| is deleted once the window is closed, so we just have to set - // it to NULL. - instance_ = NULL; -} - -views::View* PasswordsExceptionsWindowView::GetContentsView() { - return this; -} - -///////////////////////////////////////////////////////////////////////////// -// PasswordsExceptionsWindowView, private - -void PasswordsExceptionsWindowView::Init() { - tabs_ = new views::TabbedPane(); - AddChildView(tabs_); - - passwords_page_view_ = new PasswordsPageView(profile_); - tabs_->AddTab(l10n_util::GetString( - IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE), passwords_page_view_); - - exceptions_page_view_ = new ExceptionsPageView(profile_); - tabs_->AddTab(l10n_util::GetString( - IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE), exceptions_page_view_); -} diff --git a/chrome/browser/views/options/passwords_exceptions_window_view.h b/chrome/browser/views/options/passwords_exceptions_window_view.h index df98697..7adbd5f 100644 --- a/chrome/browser/views/options/passwords_exceptions_window_view.h +++ b/chrome/browser/views/options/passwords_exceptions_window_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,62 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_PASSWORDS_EXCEPTIONS_WINDOW_VIEW_H_ #pragma once -#include "views/view.h" -#include "views/window/dialog_delegate.h" - -class Profile; -class PasswordsPageView; -class ExceptionsPageView; - -namespace views { -class TabbedPane; -} - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsExceptionsWindowView -// -// The contents of the "Save passwords and exceptions" dialog window. -// -class PasswordsExceptionsWindowView : public views::View, - public views::DialogDelegate { - public: - explicit PasswordsExceptionsWindowView(Profile* profile); - virtual ~PasswordsExceptionsWindowView() {} - - // Show the PasswordManagerExceptionsView for the given profile. - static void Show(Profile* profile); - - // views::View methods. - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - // views::DialogDelegate methods: - virtual int GetDialogButtons() const; - virtual bool CanResize() const { return true; } - virtual bool CanMaximize() const { return false; } - virtual bool IsAlwaysOnTop() const { return false; } - virtual bool HasAlwaysOnTopMenu() const { return false; } - virtual std::wstring GetWindowTitle() const; - virtual void WindowClosing(); - virtual views::View* GetContentsView(); - - private: - void Init(); - - // The Tab view that contains all of the options pages. - views::TabbedPane* tabs_; - - PasswordsPageView* passwords_page_view_; - - ExceptionsPageView* exceptions_page_view_; - - Profile* profile_; - - static PasswordsExceptionsWindowView* instance_; - - DISALLOW_COPY_AND_ASSIGN(PasswordsExceptionsWindowView); -}; +#include "chrome/browser/ui/views/options/passwords_exceptions_window_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_PASSWORDS_EXCEPTIONS_WINDOW_VIEW_H_ + diff --git a/chrome/browser/views/options/passwords_page_view.cc b/chrome/browser/views/options/passwords_page_view.cc deleted file mode 100644 index 6d22d5e..0000000 --- a/chrome/browser/views/options/passwords_page_view.cc +++ /dev/null @@ -1,367 +0,0 @@ -// 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/options/passwords_page_view.h" - -#include "app/l10n_util.h" -#include "base/i18n/rtl.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/password_manager/password_store.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/common/pref_names.h" -#include "grit/generated_resources.h" -#include "views/background.h" -#include "views/controls/button/native_button.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" - -using views::ColumnSet; -using views::GridLayout; -using webkit_glue::PasswordForm; - -/////////////////////////////////////////////////////////////////////////////// -// MultiLabelButtons -MultiLabelButtons::MultiLabelButtons(views::ButtonListener* listener, - const std::wstring& label, - const std::wstring& alt_label) - : NativeButton(listener, label), - label_(label), - alt_label_(alt_label) { -} - -gfx::Size MultiLabelButtons::GetPreferredSize() { - if (!IsVisible()) - return gfx::Size(); - - if (pref_size_.IsEmpty()) { - // Let's compute our preferred size. - std::wstring current_label = label(); - SetLabel(label_); - pref_size_ = NativeButton::GetPreferredSize(); - SetLabel(alt_label_); - gfx::Size alt_pref_size = NativeButton::GetPreferredSize(); - // Revert to the original label. - SetLabel(current_label); - pref_size_.SetSize(std::max(pref_size_.width(), alt_pref_size.width()), - std::max(pref_size_.height(), alt_pref_size.height())); - } - return gfx::Size(pref_size_.width(), pref_size_.height()); -} - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsTableModel, public -PasswordsTableModel::PasswordsTableModel(Profile* profile) - : observer_(NULL), - row_count_observer_(NULL), - pending_login_query_(NULL), - saved_signons_cleanup_(&saved_signons_), - profile_(profile) { - DCHECK(profile && profile->GetPasswordStore(Profile::EXPLICIT_ACCESS)); -} - -PasswordsTableModel::~PasswordsTableModel() { - CancelLoginsQuery(); -} - -int PasswordsTableModel::RowCount() { - return static_cast<int>(saved_signons_.size()); -} - -std::wstring PasswordsTableModel::GetText(int row, - int col_id) { - switch (col_id) { - case IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN: { // Site. - // Force URL to have LTR directionality. - std::wstring url(saved_signons_[row]->display_url.display_url()); - url = UTF16ToWide(base::i18n::GetDisplayStringInLTRDirectionality( - WideToUTF16(url))); - return url; - } - case IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN: { // Username. - std::wstring username = GetPasswordFormAt(row)->username_value; - base::i18n::AdjustStringForLocaleDirection(username, &username); - return username; - } - default: - NOTREACHED() << "Invalid column."; - return std::wstring(); - } -} - -int PasswordsTableModel::CompareValues(int row1, int row2, - int column_id) { - if (column_id == IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN) { - return saved_signons_[row1]->display_url.Compare( - saved_signons_[row2]->display_url, GetCollator()); - } - return TableModel::CompareValues(row1, row2, column_id); -} - -void PasswordsTableModel::SetObserver(TableModelObserver* observer) { - observer_ = observer; -} - -void PasswordsTableModel::GetAllSavedLoginsForProfile() { - DCHECK(!pending_login_query_); - pending_login_query_ = password_store()->GetAutofillableLogins(this); -} - -void PasswordsTableModel::OnPasswordStoreRequestDone( - int handle, const std::vector<PasswordForm*>& result) { - DCHECK_EQ(pending_login_query_, handle); - pending_login_query_ = NULL; - - STLDeleteElements<PasswordRows>(&saved_signons_); - saved_signons_.resize(result.size(), NULL); - std::wstring languages = - UTF8ToWide(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); - for (size_t i = 0; i < result.size(); ++i) { - saved_signons_[i] = new PasswordRow( - gfx::SortedDisplayURL(result[i]->origin, languages), result[i]); - } - if (observer_) - observer_->OnModelChanged(); - if (row_count_observer_) - row_count_observer_->OnRowCountChanged(RowCount()); -} - -PasswordForm* PasswordsTableModel::GetPasswordFormAt(int row) { - DCHECK(row >= 0 && row < RowCount()); - return saved_signons_[row]->form.get(); -} - -void PasswordsTableModel::ForgetAndRemoveSignon(int row) { - DCHECK(row >= 0 && row < RowCount()); - PasswordRows::iterator target_iter = saved_signons_.begin() + row; - // Remove from DB, memory, and vector. - PasswordRow* password_row = *target_iter; - password_store()->RemoveLogin(*(password_row->form.get())); - delete password_row; - saved_signons_.erase(target_iter); - if (observer_) - observer_->OnItemsRemoved(row, 1); - if (row_count_observer_) - row_count_observer_->OnRowCountChanged(RowCount()); -} - -void PasswordsTableModel::ForgetAndRemoveAllSignons() { - PasswordRows::iterator iter = saved_signons_.begin(); - while (iter != saved_signons_.end()) { - // Remove from DB, memory, and vector. - PasswordRow* row = *iter; - password_store()->RemoveLogin(*(row->form.get())); - delete row; - iter = saved_signons_.erase(iter); - } - if (observer_) - observer_->OnModelChanged(); - if (row_count_observer_) - row_count_observer_->OnRowCountChanged(RowCount()); -} - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsTableModel, private -void PasswordsTableModel::CancelLoginsQuery() { - if (pending_login_query_) { - password_store()->CancelLoginsQuery(pending_login_query_); - pending_login_query_ = NULL; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsPageView, public -PasswordsPageView::PasswordsPageView(Profile* profile) - : OptionsPageView(profile), - ALLOW_THIS_IN_INITIALIZER_LIST(show_button_( - this, - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON), - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON))), - ALLOW_THIS_IN_INITIALIZER_LIST(remove_button_( - this, - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON))), - ALLOW_THIS_IN_INITIALIZER_LIST(remove_all_button_( - this, - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON))), - table_model_(profile), - table_view_(NULL), - current_selected_password_(NULL) { - allow_show_passwords_.Init(prefs::kPasswordManagerAllowShowPasswords, - profile->GetPrefs(), - this); -} - -PasswordsPageView::~PasswordsPageView() { - // The model is going away, prevent the table from accessing it. - if (table_view_) - table_view_->SetModel(NULL); -} - -void PasswordsPageView::OnSelectionChanged() { - bool has_selection = table_view_->SelectedRowCount() > 0; - remove_button_.SetEnabled(has_selection); - - PasswordForm* selected = NULL; - if (has_selection) { - views::TableSelectionIterator iter = table_view_->SelectionBegin(); - selected = table_model_.GetPasswordFormAt(*iter); - DCHECK(++iter == table_view_->SelectionEnd()); - } - - if (selected != current_selected_password_) { - // Reset the password related views. - show_button_.SetLabel( - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON)); - show_button_.SetEnabled(has_selection); - password_label_.SetText(std::wstring()); - - current_selected_password_ = selected; - } -} - -void PasswordsPageView::ButtonPressed( - views::Button* sender, const views::Event& event) { - // Close will result in our destruction. - if (sender == &remove_all_button_) { - ConfirmMessageBoxDialog::Run( - GetWindow()->GetNativeWindow(), - this, - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS), - l10n_util::GetString( - IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS)); - return; - } - - // The following require a selection (and only one, since table is single- - // select only). - views::TableSelectionIterator iter = table_view_->SelectionBegin(); - int row = *iter; - PasswordForm* selected = table_model_.GetPasswordFormAt(row); - DCHECK(++iter == table_view_->SelectionEnd()); - - if (sender == &remove_button_) { - table_model_.ForgetAndRemoveSignon(row); - } else if (sender == &show_button_) { - if (password_label_.GetText().length() == 0 && - allow_show_passwords_.GetValue()) { - password_label_.SetText(selected->password_value); - show_button_.SetLabel( - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON)); - } else { - HidePassword(); - } - } else { - NOTREACHED() << "Invalid button."; - } -} - -void PasswordsPageView::OnRowCountChanged(size_t rows) { - remove_all_button_.SetEnabled(rows > 0); -} - -void PasswordsPageView::OnConfirmMessageAccept() { - table_model_.ForgetAndRemoveAllSignons(); -} - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsPageView, protected -void PasswordsPageView::InitControlLayout() { - SetupButtonsAndLabels(); - SetupTable(); - - // Do the layout thing. - const int top_column_set_id = 0; - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - // Design the grid. - ColumnSet* column_set = layout->AddColumnSet(top_column_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - // Fill the grid. - layout->StartRow(0, top_column_set_id); - layout->AddView(table_view_, 1, 8, GridLayout::FILL, - GridLayout::FILL); - layout->AddView(&remove_button_); - layout->StartRowWithPadding(0, top_column_set_id, 0, - kRelatedControlVerticalSpacing); - layout->SkipColumns(1); - layout->AddView(&remove_all_button_); - layout->StartRowWithPadding(0, top_column_set_id, 0, - kRelatedControlVerticalSpacing); - layout->SkipColumns(1); - layout->AddView(&show_button_); - layout->StartRowWithPadding(0, top_column_set_id, 0, - kRelatedControlVerticalSpacing); - layout->SkipColumns(1); - layout->AddView(&password_label_); - layout->AddPaddingRow(1, 0); - - // Ask the database for saved password data. - table_model_.GetAllSavedLoginsForProfile(); -} - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsPageView, private -void PasswordsPageView::SetupButtonsAndLabels() { - // Disable all buttons in the first place. - show_button_.set_parent_owned(false); - show_button_.SetEnabled(false); - - remove_button_.set_parent_owned(false); - remove_button_.SetEnabled(false); - - remove_all_button_.set_parent_owned(false); - remove_all_button_.SetEnabled(false); - - password_label_.set_parent_owned(false); -} - -void PasswordsPageView::SetupTable() { - // Tell the table model we are concern about how many rows it has. - table_model_.set_row_count_observer(this); - - // Creates the different columns for the table. - // The float resize values are the result of much tinkering. - std::vector<TableColumn> columns; - columns.push_back(TableColumn(IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN, - TableColumn::LEFT, -1, 0.55f)); - columns.back().sortable = true; - columns.push_back(TableColumn( - IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN, TableColumn::LEFT, - -1, 0.37f)); - columns.back().sortable = true; - table_view_ = new views::TableView(&table_model_, columns, views::TEXT_ONLY, - true, true, true); - // Make the table initially sorted by host. - views::TableView::SortDescriptors sort; - sort.push_back(views::TableView::SortDescriptor( - IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN, true)); - table_view_->SetSortDescriptors(sort); - table_view_->SetObserver(this); -} - -void PasswordsPageView::HidePassword() { - password_label_.SetText(L""); - show_button_.SetLabel( - l10n_util::GetString(IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON)); -} - -void PasswordsPageView::NotifyPrefChanged(const std::string* pref_name) { - if (!pref_name || *pref_name == prefs::kPasswordManagerAllowShowPasswords) { - bool show = allow_show_passwords_.GetValue(); - if (!show) - HidePassword(); - show_button_.SetVisible(show); - password_label_.SetVisible(show); - // Update the layout (it may depend on the button size). - show_button_.InvalidateLayout(); - Layout(); - } -} diff --git a/chrome/browser/views/options/passwords_page_view.h b/chrome/browser/views/options/passwords_page_view.h index 418fcbe..2c4612a 100644 --- a/chrome/browser/views/options/passwords_page_view.h +++ b/chrome/browser/views/options/passwords_page_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,195 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_PASSWORDS_PAGE_VIEW_H_ #pragma once -#include <vector> - -#include "app/table_model.h" -#include "app/text_elider.h" -#include "base/scoped_ptr.h" -#include "base/stl_util-inl.h" -#include "chrome/browser/password_manager/password_store.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/views/confirm_message_box_dialog.h" -#include "chrome/browser/views/options/options_page_view.h" -#include "views/controls/button/native_button.h" -#include "views/controls/label.h" -#include "views/controls/table/table_view.h" -#include "views/controls/table/table_view_observer.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" -#include "webkit/glue/password_form.h" - -/////////////////////////////////////////////////////////////////////////////// -// PasswordTableModelObserver -// An observer interface to notify change of row count in a table model. This -// allow the container view of TableView(i.e. PasswordsPageView and -// ExceptionsPageView), to be notified of row count changes directly -// from the TableModel. We have two different observers in -// PasswordsTableModel, namely TableModelObserver and -// PasswordsTableModelObserver, rather than adding this event to -// TableModelObserver because only container view of -// PasswordsTableModel cares about this event. -class PasswordsTableModelObserver { - public: - virtual void OnRowCountChanged(size_t rows) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// MultiLabelButtons -// A button that can have 2 different labels set on it and for which the -// preferred size is the size of the widest string. -class MultiLabelButtons : public views::NativeButton { - public: - MultiLabelButtons(views::ButtonListener* listener, - const std::wstring& label, - const std::wstring& alt_label); - - virtual gfx::Size GetPreferredSize(); - - private: - std::wstring label_; - std::wstring alt_label_; - gfx::Size pref_size_; - - DISALLOW_COPY_AND_ASSIGN(MultiLabelButtons); -}; - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsTableModel -class PasswordsTableModel : public TableModel, - public PasswordStoreConsumer { - public: - explicit PasswordsTableModel(Profile* profile); - virtual ~PasswordsTableModel(); - - // TableModel methods. - virtual int RowCount(); - virtual std::wstring GetText(int row, int column); - virtual int CompareValues(int row1, int row2, int column_id); - virtual void SetObserver(TableModelObserver* observer); - - // Delete the PasswordForm at specified row from the database (and remove - // from view). - void ForgetAndRemoveSignon(int row); - - // Delete all saved signons for the active profile (via web data service), - // and clear the view. - void ForgetAndRemoveAllSignons(); - - // PasswordStoreConsumer implementation. - virtual void OnPasswordStoreRequestDone( - int handle, const std::vector<webkit_glue::PasswordForm*>& result); - - // Request saved logins data. - void GetAllSavedLoginsForProfile(); - - // Return the PasswordForm at the specified index. - webkit_glue::PasswordForm* GetPasswordFormAt(int row); - - // Set the observer who concerns about how many rows are in the table. - void set_row_count_observer(PasswordsTableModelObserver* observer) { - row_count_observer_ = observer; - } - - protected: - // Wraps the PasswordForm from the database and caches the display URL for - // quick sorting. - struct PasswordRow { - PasswordRow(const gfx::SortedDisplayURL& url, - webkit_glue::PasswordForm* password_form) - : display_url(url), form(password_form) { - } - - // Contains the URL that is displayed along with the - gfx::SortedDisplayURL display_url; - - // The underlying PasswordForm. We own this. - scoped_ptr<webkit_glue::PasswordForm> form; - }; - - // The password store associated with the currently active profile. - PasswordStore* password_store() { - return profile_->GetPasswordStore(Profile::EXPLICIT_ACCESS); - } - - // The TableView observing this model. - TableModelObserver* observer_; - - // Dispatching row count events specific to this password manager table model - // to this observer. - PasswordsTableModelObserver* row_count_observer_; - - // Handle to any pending PasswordStore login lookup query. - int pending_login_query_; - - // The set of passwords we're showing. - typedef std::vector<PasswordRow*> PasswordRows; - PasswordRows saved_signons_; - STLElementDeleter<PasswordRows> saved_signons_cleanup_; - - Profile* profile_; - - private: - // Cancel any pending login query involving a callback. - void CancelLoginsQuery(); - - DISALLOW_COPY_AND_ASSIGN(PasswordsTableModel); -}; - -/////////////////////////////////////////////////////////////////////////////// -// PasswordsPageView -class PasswordsPageView : public OptionsPageView, - public views::TableViewObserver, - public views::ButtonListener, - public PasswordsTableModelObserver, - public ConfirmMessageBoxObserver { - public: - explicit PasswordsPageView(Profile* profile); - virtual ~PasswordsPageView(); - - // views::TableViewObserverImplementation. - virtual void OnSelectionChanged(); - - // views::ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // PasswordsTableModelObserver implementation. - virtual void OnRowCountChanged(size_t rows); - - // ConfirmMessageBoxObserver implementation. - virtual void OnConfirmMessageAccept(); - - protected: - virtual void InitControlLayout(); - - private: - // Helper to configure our buttons and labels. - void SetupButtonsAndLabels(); - - // Helper to configure our table view. - void SetupTable(); - - // Helper that hides the password. - void HidePassword(); - - // Handles changes to the observed preferences and updates the UI. - void NotifyPrefChanged(const std::string* pref_name); - - PasswordsTableModel table_model_; - views::TableView* table_view_; - - // The buttons and labels. - MultiLabelButtons show_button_; - views::NativeButton remove_button_; - views::NativeButton remove_all_button_; - views::Label password_label_; - webkit_glue::PasswordForm* current_selected_password_; - - // Tracks the preference that controls whether showing passwords is allowed. - BooleanPrefMember allow_show_passwords_; - - DISALLOW_COPY_AND_ASSIGN(PasswordsPageView); -}; +#include "chrome/browser/ui/views/options/passwords_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_PASSWORDS_PAGE_VIEW_H_ + diff --git a/chrome/browser/views/options/plugin_filter_page_view.cc b/chrome/browser/views/options/plugin_filter_page_view.cc deleted file mode 100644 index eeb5c6c..0000000 --- a/chrome/browser/views/options/plugin_filter_page_view.cc +++ /dev/null @@ -1,49 +0,0 @@ -// 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/options/plugin_filter_page_view.h" - -#include "app/l10n_util.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/show_options_url.h" -#include "chrome/common/url_constants.h" -#include "grit/generated_resources.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" - -PluginFilterPageView::PluginFilterPageView(Profile* profile) - : ContentFilterPageView(profile, CONTENT_SETTINGS_TYPE_PLUGINS) { -} - -PluginFilterPageView::~PluginFilterPageView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// PluginFilterPageView, ContentFilterPageView override: - -void PluginFilterPageView::InitControlLayout() { - ContentFilterPageView::InitControlLayout(); - - using views::GridLayout; - - GridLayout* layout = static_cast<GridLayout*>(GetLayoutManager()); - const int single_column_set_id = 0; - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - views::Link* plugins_page_link = new views::Link( - l10n_util::GetString(IDS_PLUGIN_SELECTIVE_DISABLE)); - plugins_page_link->SetController(this); - - layout->StartRow(0, single_column_set_id); - layout->AddView(plugins_page_link, 1, 1, GridLayout::LEADING, - GridLayout::FILL); -} - -/////////////////////////////////////////////////////////////////////////////// -// PluginFilterPageView, views::LinkController implementation: - -void PluginFilterPageView::LinkActivated(views::Link* source, - int event_flags) { - browser::ShowOptionsURL(profile(), GURL(chrome::kChromeUIPluginsURL)); -} diff --git a/chrome/browser/views/options/plugin_filter_page_view.h b/chrome/browser/views/options/plugin_filter_page_view.h index 6dc6af9..d1d4086 100644 --- a/chrome/browser/views/options/plugin_filter_page_view.h +++ b/chrome/browser/views/options/plugin_filter_page_view.h @@ -6,27 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_PLUGIN_FILTER_PAGE_VIEW_H_ #pragma once -#include "chrome/browser/views/options/content_filter_page_view.h" - -//////////////////////////////////////////////////////////////////////////////// -// PluginFilterPageView class is used to render the plugin content settings tab. - -class PluginFilterPageView : public ContentFilterPageView, - public views::LinkController { - public: - explicit PluginFilterPageView(Profile* profile); - virtual ~PluginFilterPageView(); - - private: - // Overridden from ContentFilterPageView: - virtual void InitControlLayout(); - - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(PluginFilterPageView); -}; +#include "chrome/browser/ui/views/options/plugin_filter_page_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_PLUGIN_FILTER_PAGE_VIEW_H_ diff --git a/chrome/browser/views/options/simple_content_exceptions_view.cc b/chrome/browser/views/options/simple_content_exceptions_view.cc deleted file mode 100644 index 5df84aa..0000000 --- a/chrome/browser/views/options/simple_content_exceptions_view.cc +++ /dev/null @@ -1,185 +0,0 @@ -// 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/options/simple_content_exceptions_view.h" - -#include <algorithm> -#include <vector> - -#include "app/l10n_util.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "gfx/rect.h" -#include "views/controls/button/native_button.h" -#include "views/controls/table/table_view.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/window/window.h" - -static const int kExceptionsViewInsetSize = 5; -static SimpleContentExceptionsView* instance = NULL; - -// static -void SimpleContentExceptionsView::ShowExceptionsWindow( - gfx::NativeWindow parent, - RemoveRowsTableModel* model, - int title_message_id) { - scoped_ptr<RemoveRowsTableModel> owned_model(model); - if (!instance) { - instance = new SimpleContentExceptionsView(owned_model.release(), - title_message_id); - views::Window::CreateChromeWindow(parent, gfx::Rect(), instance); - } - - // This will show invisible windows and bring visible windows to the front. - instance->window()->Show(); -} - -SimpleContentExceptionsView::~SimpleContentExceptionsView() { - instance = NULL; - table_->SetModel(NULL); -} - -void SimpleContentExceptionsView::OnSelectionChanged() { - UpdateButtonState(); -} - -void SimpleContentExceptionsView::OnTableViewDelete( - views::TableView* table_view) { - Remove(); -} - -void SimpleContentExceptionsView::ButtonPressed(views::Button* sender, - const views::Event& event) { - switch (sender->tag()) { - case IDS_EXCEPTIONS_REMOVEALL_BUTTON: - RemoveAll(); - break; - case IDS_EXCEPTIONS_REMOVE_BUTTON: - Remove(); - break; - default: - NOTREACHED(); - } -} - -void SimpleContentExceptionsView::Layout() { - views::NativeButton* buttons[] = { remove_button_, remove_all_button_ }; - - // The buttons are placed in the parent, but we need to lay them out. - int max_y = GetParent()->GetLocalBounds(false).bottom() - kButtonVEdgeMargin; - int x = kPanelHorizMargin; - - for (size_t i = 0; i < arraysize(buttons); ++i) { - gfx::Size pref = buttons[i]->GetPreferredSize(); - buttons[i]->SetBounds(x, max_y - pref.height(), pref.width(), - pref.height()); - x += pref.width() + kRelatedControlHorizontalSpacing; - } - - // Lay out the rest of this view. - View::Layout(); -} - -gfx::Size SimpleContentExceptionsView::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_SIMPLE_CONTENT_EXCEPTION_DIALOG_WIDTH_CHARS, - IDS_SIMPLE_CONTENT_EXCEPTION_DIALOG_HEIGHT_LINES)); -} - -void SimpleContentExceptionsView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - Init(); -} - -std::wstring SimpleContentExceptionsView::GetWindowTitle() const { - return l10n_util::GetString(title_message_id_); -} - -SimpleContentExceptionsView::SimpleContentExceptionsView( - RemoveRowsTableModel* model, - int title_message_id) - : model_(model), - table_(NULL), - remove_button_(NULL), - remove_all_button_(NULL), - title_message_id_(title_message_id) { -} - -void SimpleContentExceptionsView::Init() { - if (table_) - return; // We've already Init'd. - - using views::GridLayout; - - std::vector<TableColumn> columns; - columns.push_back( - TableColumn(IDS_EXCEPTIONS_HOSTNAME_HEADER, TableColumn::LEFT, -1, .75)); - columns.back().sortable = true; - columns.push_back( - TableColumn(IDS_EXCEPTIONS_ACTION_HEADER, TableColumn::LEFT, -1, .25)); - columns.back().sortable = true; - table_ = new views::TableView(model_.get(), columns, views::TEXT_ONLY, - false, true, false); - views::TableView::SortDescriptors sort; - sort.push_back( - views::TableView::SortDescriptor(IDS_EXCEPTIONS_HOSTNAME_HEADER, true)); - table_->SetSortDescriptors(sort); - table_->SetObserver(this); - - remove_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_EXCEPTIONS_REMOVE_BUTTON)); - remove_button_->set_tag(IDS_EXCEPTIONS_REMOVE_BUTTON); - remove_all_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_EXCEPTIONS_REMOVEALL_BUTTON)); - remove_all_button_->set_tag(IDS_EXCEPTIONS_REMOVEALL_BUTTON); - - View* parent = GetParent(); - parent->AddChildView(remove_button_); - parent->AddChildView(remove_all_button_); - - GridLayout* layout = new GridLayout(this); - layout->SetInsets(kExceptionsViewInsetSize, kExceptionsViewInsetSize, - kExceptionsViewInsetSize, kExceptionsViewInsetSize); - SetLayoutManager(layout); - - const int single_column_layout_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(1, single_column_layout_id); - layout->AddView(table_); - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - UpdateButtonState(); -} - -RemoveRowsTableModel::Rows - SimpleContentExceptionsView::GetSelectedRows() const { - RemoveRowsTableModel::Rows rows; - for (views::TableView::iterator i(table_->SelectionBegin()); - i != table_->SelectionEnd(); ++i) - rows.insert(*i); - return rows; -} - -void SimpleContentExceptionsView::UpdateButtonState() { - remove_button_->SetEnabled(model_->CanRemoveRows(GetSelectedRows())); - remove_all_button_->SetEnabled(model_->RowCount() > 0); -} - -void SimpleContentExceptionsView::Remove() { - model_->RemoveRows(GetSelectedRows()); - UpdateButtonState(); -} - -void SimpleContentExceptionsView::RemoveAll() { - model_->RemoveAll(); - UpdateButtonState(); -} diff --git a/chrome/browser/views/options/simple_content_exceptions_view.h b/chrome/browser/views/options/simple_content_exceptions_view.h index b0ab00a..6b89cd9 100644 --- a/chrome/browser/views/options/simple_content_exceptions_view.h +++ b/chrome/browser/views/options/simple_content_exceptions_view.h @@ -6,90 +6,8 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_SIMPLE_CONTENT_EXCEPTIONS_VIEW_H_ #pragma once -#include <string> - -#include "chrome/browser/remove_rows_table_model.h" -#include "chrome/common/content_settings.h" -#include "views/controls/button/button.h" -#include "views/controls/table/table_view_observer.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class NativeButton; -class TableView; -} - -// SimpleContentExceptionsView is responsible for showing the user the set of -// site-specific permissions. The exceptions are shown in a table view by way -// of a RemoveRowsTableModel. The user can remove exceptions. -// Use the ShowExceptionsWindow method to create and show a -// SimpleContentExceptionsView, which is deleted when the window closes. -class SimpleContentExceptionsView : public views::View, - public views::ButtonListener, - public views::DialogDelegate, - public views::TableViewObserver { - public: - // Shows the Exceptions window. Takes ownership of |model|. - static void ShowExceptionsWindow(gfx::NativeWindow parent, - RemoveRowsTableModel* model, - int title_message_id); - - virtual ~SimpleContentExceptionsView(); - - // TableViewObserver overrides: - virtual void OnSelectionChanged(); - virtual void OnTableViewDelete(views::TableView* table_view); - - // views::ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::View overrides: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // views::WindowDelegate implementation. - virtual int GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; - } - virtual bool CanResize() const { return true; } - virtual std::wstring GetWindowTitle() const; - virtual views::View* GetContentsView() { return this; } - - private: - // Takes ownership of |model|. - explicit SimpleContentExceptionsView(RemoveRowsTableModel* model, - int title_message_id); - - void Init(); - - // Resets the enabled state of the buttons from the model. - void UpdateButtonState(); - - // Returns the set of selected rows. - RemoveRowsTableModel::Rows GetSelectedRows() const; - - // Removes the selected item. - void Remove(); - - // Removes all. - void RemoveAll(); - - // The model displayed in the table. - scoped_ptr<RemoveRowsTableModel> model_; - - views::TableView* table_; - - views::NativeButton* remove_button_; - views::NativeButton* remove_all_button_; - - // The message id of the window title. - int title_message_id_; - - DISALLOW_COPY_AND_ASSIGN(SimpleContentExceptionsView); -}; +#include "chrome/browser/ui/views/options/simple_content_exceptions_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_OPTIONS_SIMPLE_CONTENT_EXCEPTIONS_VIEW_H_ diff --git a/chrome/browser/views/page_info_bubble_view.cc b/chrome/browser/views/page_info_bubble_view.cc deleted file mode 100644 index 90fa667..0000000 --- a/chrome/browser/views/page_info_bubble_view.cc +++ /dev/null @@ -1,352 +0,0 @@ -// 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/page_info_bubble_view.h" - -#include "app/l10n_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/cert_store.h" -#include "chrome/browser/certificate_viewer.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/info_bubble.h" -#include "chrome/browser/views/toolbar_view.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/grid_layout.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -namespace { - -// Layout constants. -const int kHGapToBorder = 11; -const int kVGapToImage = 10; -const int kVGapToHeadline = 7; -const int kHGapImageToDescription = 6; -const int kTextPaddingRight = 10; -const int kPaddingBelowSeparator = 4; -const int kPaddingAboveSeparator = 13; -const int kIconHorizontalOffset = 27; -const int kIconVerticalOffset = -7; - -// The duration of the animation that resizes the bubble once the async -// information is provided through the ModelChanged event. -const int kPageInfoSlideDuration = 300; - -// A section contains an image that shows a status (good or bad), a title, an -// optional head-line (in bold) and a description. -class Section : public views::View, - public views::LinkController { - public: - Section(PageInfoBubbleView* owner, - const PageInfoModel::SectionInfo& section_info, - const SkBitmap* status_icon, - bool show_cert); - virtual ~Section(); - - // views::View methods: - virtual int GetHeightForWidth(int w); - virtual void Layout(); - - // views::LinkController methods: - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - // Calculate the layout if |compute_bounds_only|, otherwise does Layout also. - gfx::Size LayoutItems(bool compute_bounds_only, int width); - - // The view that owns this Section object. - PageInfoBubbleView* owner_; - - // The information this view represents. - PageInfoModel::SectionInfo info_; - - views::ImageView* status_image_; - views::Label* headline_label_; - views::Label* description_label_; - views::Link* link_; - - DISALLOW_COPY_AND_ASSIGN(Section); -}; - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// PageInfoBubbleView - -PageInfoBubbleView::PageInfoBubbleView(gfx::NativeWindow parent_window, - Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - bool show_history) - : ALLOW_THIS_IN_INITIALIZER_LIST(model_(profile, url, ssl, - show_history, this)), - parent_window_(parent_window), - cert_id_(ssl.cert_id()), - info_bubble_(NULL), - help_center_link_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST(resize_animation_(this)), - animation_start_height_(0) { - if (cert_id_ > 0) { - scoped_refptr<net::X509Certificate> cert; - CertStore::GetSharedInstance()->RetrieveCert(cert_id_, &cert); - // When running with fake certificate (Chrome Frame) or Gears in offline - // mode, we have no os certificate, so there is no cert to show. Don't - // bother showing the cert info link in that case. - if (!cert.get() || !cert->os_cert_handle()) - cert_id_ = 0; - } - LayoutSections(); -} - -PageInfoBubbleView::~PageInfoBubbleView() { -} - -void PageInfoBubbleView::ShowCertDialog() { - ShowCertificateViewerByID(parent_window_, cert_id_); -} - -void PageInfoBubbleView::LayoutSections() { - // Remove all the existing sections. - RemoveAllChildViews(true); - - views::GridLayout* layout = new views::GridLayout(this); - SetLayoutManager(layout); - views::ColumnSet* columns = layout->AddColumnSet(0); - columns->AddColumn(views::GridLayout::FILL, // Horizontal resize. - views::GridLayout::FILL, // Vertical resize. - 1, // Resize weight. - views::GridLayout::USE_PREF, // Size type. - 0, // Ignored for USE_PREF. - 0); // Minimum size. - // Add a column set for aligning the text when it has no icons (such as the - // help center link). - columns = layout->AddColumnSet(1); - columns->AddPaddingColumn( - 0, kHGapToBorder + kIconHorizontalOffset + kHGapImageToDescription); - columns->AddColumn(views::GridLayout::LEADING, // Horizontal resize. - views::GridLayout::FILL, // Vertical resize. - 1, // Resize weight. - views::GridLayout::USE_PREF, // Size type. - 0, // Ignored for USE_PREF. - 0); // Minimum size. - - int count = model_.GetSectionCount(); - for (int i = 0; i < count; ++i) { - PageInfoModel::SectionInfo info = model_.GetSectionInfo(i); - layout->StartRow(0, 0); - const SkBitmap* icon = model_.GetIconImage(info.icon_id); - layout->AddView(new Section(this, info, icon, cert_id_ > 0)); - - // Add separator after all sections. - layout->AddPaddingRow(0, kPaddingAboveSeparator); - layout->StartRow(0, 0); - layout->AddView(new views::Separator()); - layout->AddPaddingRow(0, kPaddingBelowSeparator); - } - - // Then add the help center link at the bottom. - layout->StartRow(0, 1); - help_center_link_ = - new views::Link(l10n_util::GetString(IDS_PAGE_INFO_HELP_CENTER_LINK)); - help_center_link_->SetController(this); - layout->AddView(help_center_link_); -} - -gfx::Size PageInfoBubbleView::GetPreferredSize() { - gfx::Size size(views::Window::GetLocalizedContentsSize( - IDS_PAGEINFOBUBBLE_WIDTH_CHARS, IDS_PAGEINFOBUBBLE_HEIGHT_LINES)); - size.set_height(0); - - int count = model_.GetSectionCount(); - for (int i = 0; i < count; ++i) { - PageInfoModel::SectionInfo info = model_.GetSectionInfo(i); - const SkBitmap* icon = model_.GetIconImage(info.icon_id); - Section section(this, info, icon, cert_id_ > 0); - size.Enlarge(0, section.GetHeightForWidth(size.width())); - } - - // Calculate how much space the separators take up (with padding). - views::Separator separator; - gfx::Size separator_size = separator.GetPreferredSize(); - gfx::Size separator_plus_padding(0, separator_size.height() + - kPaddingAboveSeparator + - kPaddingBelowSeparator); - - // Account for the separators and padding within sections. - size.Enlarge(0, (count - 1) * separator_plus_padding.height()); - - // Account for the Help Center link and the separator above it. - gfx::Size link_size = help_center_link_->GetPreferredSize(); - size.Enlarge(0, separator_plus_padding.height() + - link_size.height()); - - if (!resize_animation_.is_animating()) - return size; - - // We are animating from animation_start_height_ to size. - int target_height = animation_start_height_ + static_cast<int>( - (size.height() - animation_start_height_) * - resize_animation_.GetCurrentValue()); - size.set_height(target_height); - return size; -} - -void PageInfoBubbleView::ModelChanged() { - animation_start_height_ = bounds().height(); - LayoutSections(); - resize_animation_.SetSlideDuration(kPageInfoSlideDuration); - resize_animation_.Show(); -} - -void PageInfoBubbleView::LinkActivated(views::Link* source, int event_flags) { - GURL url = GURL(l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER)); - Browser* browser = BrowserList::GetLastActive(); - browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); -} - -void PageInfoBubbleView::AnimationEnded(const Animation* animation) { - info_bubble_->SizeToContents(); -} - -void PageInfoBubbleView::AnimationProgressed(const Animation* animation) { - info_bubble_->SizeToContents(); -} - -//////////////////////////////////////////////////////////////////////////////// -// Section - -Section::Section(PageInfoBubbleView* owner, - const PageInfoModel::SectionInfo& section_info, - const SkBitmap* state_icon, - bool show_cert) - : owner_(owner), - info_(section_info), - status_image_(NULL), - link_(NULL) { - if (state_icon) { - status_image_ = new views::ImageView(); - status_image_->SetImage(*state_icon); - AddChildView(status_image_); - } - - headline_label_ = new views::Label(UTF16ToWideHack(info_.headline)); - headline_label_->SetFont( - headline_label_->font().DeriveFont(0, gfx::Font::BOLD)); - headline_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(headline_label_); - - description_label_ = new views::Label(UTF16ToWideHack(info_.description)); - description_label_->SetMultiLine(true); - description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - // Allow linebreaking in the middle of words if necessary, so that extremely - // long hostnames (longer than one line) will still be completely shown. - description_label_->SetAllowCharacterBreak(true); - AddChildView(description_label_); - - if (info_.type == PageInfoModel::SECTION_INFO_IDENTITY && show_cert) { - link_ = new views::Link( - l10n_util::GetString(IDS_PAGEINFO_CERT_INFO_BUTTON)); - link_->SetController(this); - AddChildView(link_); - } -} - -Section::~Section() { -} - -int Section::GetHeightForWidth(int width) { - return LayoutItems(true, width).height(); -} - -void Section::Layout() { - LayoutItems(false, width()); -} - -void Section::LinkActivated(views::Link* source, int event_flags) { - owner_->ShowCertDialog(); -} - -gfx::Size Section::LayoutItems(bool compute_bounds_only, int width) { - int x = kHGapToBorder; - int y = kVGapToImage; - - // Layout the image, head-line and description. - gfx::Size size; - if (status_image_) { - size = status_image_->GetPreferredSize(); - if (!compute_bounds_only) - status_image_->SetBounds(x, y, size.width(), size.height()); - } - int image_height = y + size.height(); - x += size.width() + kHGapImageToDescription; - int w = width - x - kTextPaddingRight; - y = kVGapToHeadline; - if (!headline_label_->GetText().empty()) { - size = headline_label_->GetPreferredSize(); - if (!compute_bounds_only) - headline_label_->SetBounds(x, y, w > 0 ? w : 0, size.height()); - y += size.height(); - } else { - if (!compute_bounds_only) - headline_label_->SetBounds(x, y, 0, 0); - } - if (w > 0) { - int height = description_label_->GetHeightForWidth(w); - if (!compute_bounds_only) - description_label_->SetBounds(x, y, w, height); - y += height; - } else { - if (!compute_bounds_only) - description_label_->SetBounds(x, y, 0, 0); - } - if (info_.type == PageInfoModel::SECTION_INFO_IDENTITY && link_) { - size = link_->GetPreferredSize(); - if (!compute_bounds_only) - link_->SetBounds(x, y, size.width(), size.height()); - y += size.height(); - } - - // Make sure the image is not truncated if the text doesn't contain much. - y = std::max(y, image_height); - return gfx::Size(width, y); -} - -namespace browser { - -void ShowPageInfoBubble(gfx::NativeWindow parent, - Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - bool show_history) { - // Find where to point the bubble at. - BrowserView* browser_view = - BrowserView::GetBrowserViewForNativeWindow(parent); - gfx::Point point; - if (base::i18n::IsRTL()) { - int width = browser_view->toolbar()->location_bar()->width(); - point = gfx::Point(width - kIconHorizontalOffset, 0); - } - point.Offset(0, kIconVerticalOffset); - views::View::ConvertPointToScreen(browser_view->toolbar()->location_bar(), - &point); - gfx::Rect bounds = browser_view->toolbar()->location_bar()->bounds(); - bounds.set_origin(point); - bounds.set_width(kIconHorizontalOffset); - - // Show the bubble. - PageInfoBubbleView* page_info_bubble = - new PageInfoBubbleView(parent, profile, url, ssl, show_history); - InfoBubble* info_bubble = - InfoBubble::Show(browser_view->GetWidget(), bounds, - BubbleBorder::TOP_LEFT, - page_info_bubble, page_info_bubble); - page_info_bubble->set_info_bubble(info_bubble); -} - -} diff --git a/chrome/browser/views/page_info_bubble_view.h b/chrome/browser/views/page_info_bubble_view.h index cc8d1f0..cb920bb 100644 --- a/chrome/browser/views/page_info_bubble_view.h +++ b/chrome/browser/views/page_info_bubble_view.h @@ -6,78 +6,8 @@ #define CHROME_BROWSER_VIEWS_PAGE_INFO_BUBBLE_VIEW_H_ #pragma once -#include "chrome/browser/page_info_model.h" -#include "chrome/browser/views/info_bubble.h" -#include "views/controls/link.h" -#include "views/view.h" - -namespace views { -class Label; -} - -class PageInfoBubbleView : public views::View, - public PageInfoModel::PageInfoModelObserver, - public InfoBubbleDelegate, - public views::LinkController, - public AnimationDelegate { - public: - PageInfoBubbleView(gfx::NativeWindow parent_window, - Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - bool show_history); - virtual ~PageInfoBubbleView(); - - // Show the certificate dialog. - void ShowCertDialog(); - - void set_info_bubble(InfoBubble* info_bubble) { info_bubble_ = info_bubble; } - - // View methods: - virtual gfx::Size GetPreferredSize(); - - // PageInfoModel::PageInfoModelObserver methods: - virtual void ModelChanged(); - - // InfoBubbleDelegate methods: - virtual void InfoBubbleClosing(InfoBubble* info_bubble, - bool closed_by_escape) {} - virtual bool CloseOnEscape() { return true; } - virtual bool FadeInOnShow() { return false; } - virtual std::wstring accessible_name() { return L"PageInfoBubble"; } - - // LinkController methods: - virtual void LinkActivated(views::Link* source, int event_flags); - - // Overridden from AnimationDelegate. - virtual void AnimationEnded(const Animation* animation); - virtual void AnimationProgressed(const Animation* animation); - - private: - // Layout the sections within the bubble. - void LayoutSections(); - - // The model providing the various section info. - PageInfoModel model_; - - // The parent window of the InfoBubble showing this view. - gfx::NativeWindow parent_window_; - - // The id of the certificate for this page. - int cert_id_; - - InfoBubble* info_bubble_; - - // The Help Center link at the bottom of the bubble. - views::Link* help_center_link_; - - // Animation that helps us change size smoothly as more data comes in. - SlideAnimation resize_animation_; - - // The height of the info bubble at the start of the resize animation. - int animation_start_height_; - - DISALLOW_COPY_AND_ASSIGN(PageInfoBubbleView); -}; +#include "chrome/browser/ui/views/page_info_bubble_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_PAGE_INFO_BUBBLE_VIEW_H_ + diff --git a/chrome/browser/views/pinned_contents_info_bubble.cc b/chrome/browser/views/pinned_contents_info_bubble.cc deleted file mode 100644 index c064c16..0000000 --- a/chrome/browser/views/pinned_contents_info_bubble.cc +++ /dev/null @@ -1,53 +0,0 @@ -// 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/pinned_contents_info_bubble.h" - -#include "chrome/browser/views/bubble_border.h" - -void PinnedContentsBorderContents::SizeAndGetBounds( - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - bool allow_bubble_offscreen, - const gfx::Size& contents_size, - gfx::Rect* contents_bounds, - gfx::Rect* window_bounds) { - // Arrow offset is calculated from the middle of the |position_relative_to|. - int offset = position_relative_to.x() + (position_relative_to.width() / 2); - offset -= bubble_anchor_.x(); - - gfx::Insets insets; - bubble_border_->GetInsets(&insets); - offset += kLeftMargin + insets.left() + 1; - bubble_border_->SetArrowOffset(offset, contents_size); - - BorderContents::SizeAndGetBounds( - position_relative_to, arrow_location, - true, // Don't move the bubble around if it does not fit on the screen. - contents_size, contents_bounds, window_bounds); - - // Now move the y position to make sure the bubble contents overlap the view. - window_bounds->Offset(0, -(kTopMargin + 1)); -} - -// InfoBubble ----------------------------------------------------------------- - -// static -PinnedContentsInfoBubble* PinnedContentsInfoBubble::Show( - views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - const gfx::Point& bubble_anchor, - views::View* contents, - InfoBubbleDelegate* delegate) { - PinnedContentsInfoBubble* window = - new PinnedContentsInfoBubble(bubble_anchor); - window->Init(parent, position_relative_to, arrow_location, - contents, delegate); - return window; -} - -BorderContents* PinnedContentsInfoBubble::CreateBorderContents() { - return new PinnedContentsBorderContents(bubble_anchor_); -} diff --git a/chrome/browser/views/pinned_contents_info_bubble.h b/chrome/browser/views/pinned_contents_info_bubble.h index 29cd5972..a2af973 100644 --- a/chrome/browser/views/pinned_contents_info_bubble.h +++ b/chrome/browser/views/pinned_contents_info_bubble.h @@ -6,63 +6,8 @@ #define CHROME_BROWSER_VIEWS_PINNED_CONTENTS_INFO_BUBBLE_H_ #pragma once -#include "chrome/browser/views/info_bubble.h" - -// This is a specialization of BorderContents, used to draw a border around -// an InfoBubble that has its contents pinned to a specific location. See -// base class for details. -class PinnedContentsBorderContents : public BorderContents { - public: - explicit PinnedContentsBorderContents(const gfx::Point& bubble_anchor) - : bubble_anchor_(bubble_anchor) {} - - // BorderContents overrides: - virtual void SizeAndGetBounds( - const gfx::Rect& position_relative_to, // In screen coordinates - BubbleBorder::ArrowLocation arrow_location, - bool allow_bubble_offscreen, - const gfx::Size& contents_size, - gfx::Rect* contents_bounds, // Returned in window coordinates - gfx::Rect* window_bounds); // Returned in screen coordinates - - private: - // The location of the pinned contents (in screen coordinates). - const gfx::Point bubble_anchor_; - - DISALLOW_COPY_AND_ASSIGN(PinnedContentsBorderContents); -}; - -// A specialization of the InfoBubble. Used to draw an InfoBubble which, in -// addition to having an arrow pointing to where the user clicked, also shifts -// the bubble horizontally to fix it to a specific location. See base class -// for details. -class PinnedContentsInfoBubble : public InfoBubble { - public: - // Shows the InfoBubble (see base class function for details). - // |bubble_anchor| specifies how far horizontally to shift the bubble in - // order to anchor its contents. Once the InfoBubble has been anchored its - // arrow may be pointing to a slightly different |y| location than specified - // in |position_relative_to|. - static PinnedContentsInfoBubble* Show( - views::Widget* parent, - const gfx::Rect& position_relative_to, - BubbleBorder::ArrowLocation arrow_location, - const gfx::Point& bubble_anchor_, - views::View* contents, - InfoBubbleDelegate* delegate); - - // InfoBubble overrides: - virtual BorderContents* CreateBorderContents(); - - private: - explicit PinnedContentsInfoBubble(const gfx::Point& bubble_anchor) - : bubble_anchor_(bubble_anchor) {} - virtual ~PinnedContentsInfoBubble() {} - - // The location of the pinned contents (in screen coordinates). - const gfx::Point bubble_anchor_; - - DISALLOW_COPY_AND_ASSIGN(PinnedContentsInfoBubble); -}; +#include "chrome/browser/ui/views/pinned_contents_info_bubble.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_PINNED_CONTENTS_INFO_BUBBLE_H_ + diff --git a/chrome/browser/views/reload_button.cc b/chrome/browser/views/reload_button.cc deleted file mode 100644 index 43015e7..0000000 --- a/chrome/browser/views/reload_button.cc +++ /dev/null @@ -1,137 +0,0 @@ -// 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/reload_button.h" - -#include "app/l10n_util.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/views/event_utils.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "grit/generated_resources.h" - -//////////////////////////////////////////////////////////////////////////////// -// ReloadButton, public: - -ReloadButton::ReloadButton(LocationBarView* location_bar, Browser* browser) - : ALLOW_THIS_IN_INITIALIZER_LIST(ToggleImageButton(this)), - location_bar_(location_bar), - browser_(browser), - intended_mode_(MODE_RELOAD), - visible_mode_(MODE_RELOAD), - double_click_timer_delay_( - base::TimeDelta::FromMilliseconds(GetDoubleClickTimeMS())), - stop_to_reload_timer_delay_(base::TimeDelta::FromMilliseconds(1350)), - testing_mouse_hovered_(false), - testing_reload_count_(0) { -} - -ReloadButton::~ReloadButton() { -} - -void ReloadButton::ChangeMode(Mode mode, bool force) { - intended_mode_ = mode; - - // If the change is forced, or the user isn't hovering the icon, or it's safe - // to change it to the other image type, make the change immediately; - // otherwise we'll let it happen later. - if (force || (!IsMouseHovered() && !testing_mouse_hovered_) || - ((mode == MODE_STOP) ? - !double_click_timer_.IsRunning() : (visible_mode_ != MODE_STOP))) { - double_click_timer_.Stop(); - stop_to_reload_timer_.Stop(); - SetToggled(mode == MODE_STOP); - visible_mode_ = mode; - SetEnabled(true); - - // We want to disable the button if we're preventing a change from stop to - // reload due to hovering, but not if we're preventing a change from reload to - // stop due to the double-click timer running. (There is no disabled reload - // state.) - } else if (visible_mode_ != MODE_RELOAD) { - SetEnabled(false); - - // Go ahead and change to reload after a bit, which allows repeated reloads - // without moving the mouse. - if (!stop_to_reload_timer_.IsRunning()) { - stop_to_reload_timer_.Start(stop_to_reload_timer_delay_, this, - &ReloadButton::OnStopToReloadTimer); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ReloadButton, views::ButtonListener implementation: - -void ReloadButton::ButtonPressed(views::Button* /* button */, - const views::Event& event) { - if (visible_mode_ == MODE_STOP) { - if (browser_) - browser_->Stop(); - // The user has clicked, so we can feel free to update the button, - // even if the mouse is still hovering. - ChangeMode(MODE_RELOAD, true); - } else if (!double_click_timer_.IsRunning()) { - // Shift-clicking or ctrl-clicking the reload button means we should ignore - // any cached content. - // TODO(avayvod): eliminate duplication of this logic in - // CompactLocationBarView. - int command; - int flags = mouse_event_flags(); - if (event.IsShiftDown() || event.IsControlDown()) { - command = IDC_RELOAD_IGNORING_CACHE; - // Mask off Shift and Control so they don't affect the disposition below. - flags &= ~(views::Event::EF_SHIFT_DOWN | views::Event::EF_CONTROL_DOWN); - } else { - command = IDC_RELOAD; - } - - WindowOpenDisposition disposition = - event_utils::DispositionFromEventFlags(flags); - if ((disposition == CURRENT_TAB) && location_bar_) { - // Forcibly reset the location bar, since otherwise it won't discard any - // ongoing user edits, since it doesn't realize this is a user-initiated - // action. - location_bar_->Revert(); - } - - // Start a timer - while this timer is running, the reload button cannot be - // changed to a stop button. We do not set |intended_mode_| to MODE_STOP - // here as the browser will do that when it actually starts loading (which - // may happen synchronously, thus the need to do this before telling the - // browser to execute the reload command). - double_click_timer_.Start(double_click_timer_delay_, this, - &ReloadButton::OnDoubleClickTimer); - - if (browser_) - browser_->ExecuteCommandWithDisposition(command, disposition); - ++testing_reload_count_; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ReloadButton, View overrides: - -void ReloadButton::OnMouseExited(const views::MouseEvent& e) { - ChangeMode(intended_mode_, true); - if (state() != BS_DISABLED) - SetState(BS_NORMAL); -} - -bool ReloadButton::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { - tooltip->assign(l10n_util::GetString((visible_mode_ == MODE_RELOAD) ? - IDS_TOOLTIP_RELOAD : IDS_TOOLTIP_STOP)); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// ReloadButton, private: - -void ReloadButton::OnDoubleClickTimer() { - ChangeMode(intended_mode_, false); -} - -void ReloadButton::OnStopToReloadTimer() { - ChangeMode(intended_mode_, true); -} diff --git a/chrome/browser/views/reload_button.h b/chrome/browser/views/reload_button.h index 0c253bf..71118e1 100644 --- a/chrome/browser/views/reload_button.h +++ b/chrome/browser/views/reload_button.h @@ -2,81 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_RELOAD_BUTTON_H__ -#define CHROME_BROWSER_VIEWS_RELOAD_BUTTON_H__ +#ifndef CHROME_BROWSER_VIEWS_RELOAD_BUTTON_H_ +#define CHROME_BROWSER_VIEWS_RELOAD_BUTTON_H_ #pragma once -#include "base/basictypes.h" -#include "base/gtest_prod_util.h" -#include "base/timer.h" -#include "views/controls/button/image_button.h" +#include "chrome/browser/ui/views/reload_button.h" +// TODO(beng): remove this file once all includes have been updated. -class Browser; -class LocationBarView; +#endif // CHROME_BROWSER_VIEWS_RELOAD_BUTTON_H_ -//////////////////////////////////////////////////////////////////////////////// -// -// ReloadButton -// -// The reload button in the toolbar, which changes to a stop button when a page -// load is in progress. Trickiness comes from the desire to have the 'stop' -// button not change back to 'reload' if the user's mouse is hovering over it -// (to prevent mis-clicks). -// -//////////////////////////////////////////////////////////////////////////////// - -class ReloadButton : public views::ToggleImageButton, - public views::ButtonListener { - public: - enum Mode { MODE_RELOAD = 0, MODE_STOP }; - - ReloadButton(LocationBarView* location_bar, Browser* Browser); - virtual ~ReloadButton(); - - // Ask for a specified button state. If |force| is true this will be applied - // immediately. - void ChangeMode(Mode mode, bool force); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* /* button */, - const views::Event& event); - - // Overridden from views::View: - virtual void OnMouseExited(const views::MouseEvent& e); - virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip); - - private: - friend class ReloadButtonTest; - - void OnDoubleClickTimer(); - void OnStopToReloadTimer(); - - base::OneShotTimer<ReloadButton> double_click_timer_; - base::OneShotTimer<ReloadButton> stop_to_reload_timer_; - - // These may be NULL when testing. - LocationBarView* location_bar_; - Browser* browser_; - - // The mode we should be in assuming no timers are running. - Mode intended_mode_; - - // The currently-visible mode - this may differ from the intended mode. - Mode visible_mode_; - - // The delay times for the timers. These are members so that tests can modify - // them. - base::TimeDelta double_click_timer_delay_; - base::TimeDelta stop_to_reload_timer_delay_; - - // TESTING ONLY - // True if we should pretend the button is hovered. - bool testing_mouse_hovered_; - // Increments when we would tell the browser to "reload", so - // test code can tell whether we did so (as there may be no |browser_|). - int testing_reload_count_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ReloadButton); -}; - -#endif // CHROME_BROWSER_VIEWS_RELOAD_BUTTON_H__ diff --git a/chrome/browser/views/reload_button_unittest.cc b/chrome/browser/views/reload_button_unittest.cc deleted file mode 100644 index 5f8255b..0000000 --- a/chrome/browser/views/reload_button_unittest.cc +++ /dev/null @@ -1,150 +0,0 @@ -// 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 "base/message_loop.h" -#include "chrome/browser/views/reload_button.h" -#include "testing/gtest/include/gtest/gtest.h" - -class ReloadButtonTest : public testing::Test { - public: - ReloadButtonTest(); - - void CheckState(bool enabled, - ReloadButton::Mode intended_mode, - ReloadButton::Mode visible_mode, - bool double_click_timer_running, - bool stop_to_reload_timer_running); - - // These accessors eliminate the need to declare each testcase as a friend. - void set_mouse_hovered(bool hovered) { - reload_.testing_mouse_hovered_ = hovered; - } - int reload_count() { return reload_.testing_reload_count_; } - - protected: - // We need a message loop for the timers to post events. - MessageLoop loop_; - - ReloadButton reload_; -}; - -ReloadButtonTest::ReloadButtonTest() : reload_(NULL, NULL) { - // Set the timer delays to 0 so that timers will fire as soon as we tell the - // message loop to run pending tasks. - reload_.double_click_timer_delay_ = base::TimeDelta(); - reload_.stop_to_reload_timer_delay_ = base::TimeDelta(); -} - -void ReloadButtonTest::CheckState(bool enabled, - ReloadButton::Mode intended_mode, - ReloadButton::Mode visible_mode, - bool double_click_timer_running, - bool stop_to_reload_timer_running) { - EXPECT_EQ(enabled, reload_.IsEnabled()); - EXPECT_EQ(intended_mode, reload_.intended_mode_); - EXPECT_EQ(visible_mode, reload_.visible_mode_); - EXPECT_EQ(double_click_timer_running, - reload_.double_click_timer_.IsRunning()); - EXPECT_EQ(stop_to_reload_timer_running, - reload_.stop_to_reload_timer_.IsRunning()); -} - -TEST_F(ReloadButtonTest, Basic) { - // The stop/reload button starts in the "enabled reload" state with no timers - // running. - CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, - false); - - // Press the button. This should start the double-click timer. - views::MouseEvent e(views::Event::ET_MOUSE_PRESSED, 0, 0, 0); - reload_.ButtonPressed(&reload_, e); - CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, true, - false); - - // Now change the mode (as if the browser had started loading the page). This - // should cancel the double-click timer since the button is not hovered. - reload_.ChangeMode(ReloadButton::MODE_STOP, false); - CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_STOP, false, - false); - - // Press the button again. This should change back to reload. - reload_.ButtonPressed(&reload_, e); - CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, - false); -} - -TEST_F(ReloadButtonTest, DoubleClickTimer) { - // Start by pressing the button. - views::MouseEvent e(views::Event::ET_MOUSE_PRESSED, 0, 0, 0); - reload_.ButtonPressed(&reload_, e); - - // Try to press the button again. This should do nothing because the timer is - // running. - int original_reload_count = reload_count(); - reload_.ButtonPressed(&reload_, e); - CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, true, - false); - EXPECT_EQ(original_reload_count, reload_count()); - - // Hover the button, and change mode. The visible mode should not change, - // again because the timer is running. - set_mouse_hovered(true); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); - CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_RELOAD, true, - false); - - // Now fire the timer. This should complete the mode change. - loop_.RunAllPending(); - CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_STOP, false, - false); -} - -TEST_F(ReloadButtonTest, DisableOnHover) { - // Change to stop and hover. - views::MouseEvent e(views::Event::ET_MOUSE_PRESSED, 0, 0, 0); - reload_.ButtonPressed(&reload_, e); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); - set_mouse_hovered(true); - - // Now change back to reload. This should result in a disabled stop button - // due to the hover. - reload_.ChangeMode(ReloadButton::MODE_RELOAD, false); - CheckState(false, ReloadButton::MODE_RELOAD, ReloadButton::MODE_STOP, false, - true); - - // Un-hover the button, which should allow it to reset. - set_mouse_hovered(false); - views::MouseEvent e2(views::Event::ET_MOUSE_MOVED, 0, 0, 0); - reload_.OnMouseExited(e2); - CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, - false); -} - -TEST_F(ReloadButtonTest, ResetOnClick) { - // Change to stop and hover. - views::MouseEvent e(views::Event::ET_MOUSE_PRESSED, 0, 0, 0); - reload_.ButtonPressed(&reload_, e); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); - set_mouse_hovered(true); - - // Press the button. This should change back to reload despite the hover, - // because it's a direct user action. - reload_.ButtonPressed(&reload_, e); - CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, - false); -} - -TEST_F(ReloadButtonTest, ResetOnTimer) { - // Change to stop, hover, and change back to reload. - views::MouseEvent e(views::Event::ET_MOUSE_PRESSED, 0, 0, 0); - reload_.ButtonPressed(&reload_, e); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); - set_mouse_hovered(true); - reload_.ChangeMode(ReloadButton::MODE_RELOAD, false); - - // Now fire the stop-to-reload timer. This should reset the button. - loop_.RunAllPending(); - CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, - false); -} diff --git a/chrome/browser/views/repost_form_warning_view.cc b/chrome/browser/views/repost_form_warning_view.cc deleted file mode 100644 index 7d7ed67..0000000 --- a/chrome/browser/views/repost_form_warning_view.cc +++ /dev/null @@ -1,82 +0,0 @@ -// 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/repost_form_warning_view.h" - -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/repost_form_warning_controller.h" -#include "chrome/browser/tab_contents/navigation_controller.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/notification_service.h" -#include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" -#include "views/window/window.h" - -namespace browser { - -// Declared in browser_dialogs.h so others don't have to depend on our header. -void ShowRepostFormWarningDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents) { - new RepostFormWarningView(parent_window, tab_contents); -} - -} // namespace browser - -////////////////////////////////////////////////////////////////////////////// -// RepostFormWarningView, constructor & destructor: - -RepostFormWarningView::RepostFormWarningView( - gfx::NativeWindow parent_window, - TabContents* tab_contents) - : controller_(new RepostFormWarningController(tab_contents)), - message_box_view_(NULL) { - message_box_view_ = new MessageBoxView( - MessageBoxFlags::kIsConfirmMessageBox, - l10n_util::GetString(IDS_HTTP_POST_WARNING), - std::wstring()); - controller_->Show(this); -} - -RepostFormWarningView::~RepostFormWarningView() { -} - -////////////////////////////////////////////////////////////////////////////// -// RepostFormWarningView, views::DialogDelegate implementation: - -std::wstring RepostFormWarningView::GetWindowTitle() const { - return l10n_util::GetString(IDS_HTTP_POST_WARNING_TITLE); -} - -std::wstring RepostFormWarningView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - return l10n_util::GetString(IDS_HTTP_POST_WARNING_RESEND); - if (button == MessageBoxFlags::DIALOGBUTTON_CANCEL) - return l10n_util::GetString(IDS_CANCEL); - return std::wstring(); -} - -views::View* RepostFormWarningView::GetContentsView() { - return message_box_view_; -} - -bool RepostFormWarningView::Cancel() { - controller_->Cancel(); - return true; -} - -bool RepostFormWarningView::Accept() { - controller_->Continue(); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// RepostFormWarningView, RepostFormWarning implementation: - -void RepostFormWarningView::DeleteDelegate() { - delete this; -} diff --git a/chrome/browser/views/repost_form_warning_view.h b/chrome/browser/views/repost_form_warning_view.h index b4e56a6..1dd6888 100644 --- a/chrome/browser/views/repost_form_warning_view.h +++ b/chrome/browser/views/repost_form_warning_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,52 +6,8 @@ #define CHROME_BROWSER_VIEWS_REPOST_FORM_WARNING_VIEW_H_ #pragma once -#include "chrome/browser/tab_contents/constrained_window.h" -#include "chrome/common/notification_registrar.h" -#include "gfx/native_widget_types.h" -#include "views/window/dialog_delegate.h" - -class ConstrainedWindow; -class MessageBoxView; -class NavigationController; -class RepostFormWarningController; -class TabContents; -namespace views { -class Window; -} - -// Displays a dialog that warns the user that they are about to resubmit -// a form. -// To display the dialog, allocate this object on the heap. It will open the -// dialog from its constructor and then delete itself when the user dismisses -// the dialog. -class RepostFormWarningView : public ConstrainedDialogDelegate { - public: - // Use BrowserWindow::ShowRepostFormWarningDialog to use. - RepostFormWarningView(gfx::NativeWindow parent_window, - TabContents* tab_contents); - - // views::DialogDelegate Methods: - virtual std::wstring GetWindowTitle() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual void DeleteDelegate(); - - virtual bool Cancel(); - virtual bool Accept(); - - // views::WindowDelegate Methods: - virtual views::View* GetContentsView(); - - private: - virtual ~RepostFormWarningView(); - - // The message box view whose commands we handle. - MessageBoxView* message_box_view_; - - scoped_ptr<RepostFormWarningController> controller_; - - DISALLOW_COPY_AND_ASSIGN(RepostFormWarningView); -}; +#include "chrome/browser/ui/views/repost_form_warning_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_REPOST_FORM_WARNING_VIEW_H_ + diff --git a/chrome/browser/views/restart_message_box.cc b/chrome/browser/views/restart_message_box.cc deleted file mode 100644 index c054098..0000000 --- a/chrome/browser/views/restart_message_box.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2006-2008 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/restart_message_box.h" - -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" -#include "views/window/window.h" - -//////////////////////////////////////////////////////////////////////////////// -// RestartMessageBox, public: - -// static -void RestartMessageBox::ShowMessageBox(gfx::NativeWindow parent_window) { - // When the window closes, it will delete itself. - new RestartMessageBox(parent_window); -} - -int RestartMessageBox::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_OK; -} - -std::wstring RestartMessageBox::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - DCHECK(button == MessageBoxFlags::DIALOGBUTTON_OK); - return l10n_util::GetString(IDS_OK); -} - -std::wstring RestartMessageBox::GetWindowTitle() const { - return l10n_util::GetString(IDS_PRODUCT_NAME); -} - -void RestartMessageBox::DeleteDelegate() { - delete this; -} - -bool RestartMessageBox::IsModal() const { - return true; -} - -views::View* RestartMessageBox::GetContentsView() { - return message_box_view_; -} - -//////////////////////////////////////////////////////////////////////////////// -// RestartMessageBox, private: - -RestartMessageBox::RestartMessageBox(gfx::NativeWindow parent_window) { - const int kDialogWidth = 400; - // Also deleted when the window closes. - message_box_view_ = new MessageBoxView( - MessageBoxFlags::kFlagHasMessage | MessageBoxFlags::kFlagHasOKButton, - l10n_util::GetString(IDS_OPTIONS_RESTART_REQUIRED).c_str(), - std::wstring(), - kDialogWidth); - views::Window::CreateChromeWindow(parent_window, gfx::Rect(), this)->Show(); -} - -RestartMessageBox::~RestartMessageBox() { -} diff --git a/chrome/browser/views/restart_message_box.h b/chrome/browser/views/restart_message_box.h index 816fe6c..1547e92 100644 --- a/chrome/browser/views/restart_message_box.h +++ b/chrome/browser/views/restart_message_box.h @@ -6,38 +6,8 @@ #define CHROME_BROWSER_VIEWS_RESTART_MESSAGE_BOX_H_ #pragma once -#include "base/basictypes.h" -#include "gfx/native_widget_types.h" -#include "views/window/dialog_delegate.h" - -class MessageBoxView; - -// A dialog box that tells the user that s/he needs to restart Chrome -// for a change to take effect. -class RestartMessageBox : public views::DialogDelegate { - public: - // This box is modal to |parent_window|. - static void ShowMessageBox(gfx::NativeWindow parent_window); - - protected: - // views::DialogDelegate: - virtual int GetDialogButtons() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual std::wstring GetWindowTitle() const; - - // views::WindowDelegate: - virtual void DeleteDelegate(); - virtual bool IsModal() const; - virtual views::View* GetContentsView(); - - private: - explicit RestartMessageBox(gfx::NativeWindow parent_window); - virtual ~RestartMessageBox(); - - MessageBoxView* message_box_view_; - - DISALLOW_COPY_AND_ASSIGN(RestartMessageBox); -}; +#include "chrome/browser/ui/views/restart_message_box.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_RESTART_MESSAGE_BOX_H_ + diff --git a/chrome/browser/views/sad_tab_view.cc b/chrome/browser/views/sad_tab_view.cc deleted file mode 100644 index 31f45fd..0000000 --- a/chrome/browser/views/sad_tab_view.cc +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2006-2008 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/sad_tab_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "gfx/canvas.h" -#include "gfx/canvas_skia.h" -#include "gfx/size.h" -#include "gfx/skia_util.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/effects/SkGradientShader.h" - -static const int kSadTabOffset = -64; -static const int kIconTitleSpacing = 20; -static const int kTitleMessageSpacing = 15; -static const int kMessageBottomMargin = 20; -static const float kMessageSize = 0.65f; -static const SkColor kTitleColor = SK_ColorWHITE; -static const SkColor kMessageColor = SK_ColorWHITE; -static const SkColor kLinkColor = SK_ColorWHITE; -static const SkColor kBackgroundColor = SkColorSetRGB(35, 48, 64); -static const SkColor kBackgroundEndColor = SkColorSetRGB(35, 48, 64); - -// static -SkBitmap* SadTabView::sad_tab_bitmap_ = NULL; -gfx::Font* SadTabView::title_font_ = NULL; -gfx::Font* SadTabView::message_font_ = NULL; -std::wstring SadTabView::title_; -std::wstring SadTabView::message_; -int SadTabView::title_width_; - -SadTabView::SadTabView(TabContents* tab_contents) - : tab_contents_(tab_contents), - learn_more_link_(NULL) { - DCHECK(tab_contents); - - InitClass(); - - if (tab_contents != NULL) { - learn_more_link_ = new views::Link(l10n_util::GetString(IDS_LEARN_MORE)); - learn_more_link_->SetFont(*message_font_); - learn_more_link_->SetNormalColor(kLinkColor); - learn_more_link_->SetController(this); - AddChildView(learn_more_link_); - } -} - -void SadTabView::Paint(gfx::Canvas* canvas) { - SkPaint paint; - SkSafeUnref(paint.setShader(gfx::CreateGradientShader(0, height(), - kBackgroundColor, - kBackgroundEndColor))); - paint.setStyle(SkPaint::kFill_Style); - canvas->AsCanvasSkia()->drawRectCoords( - 0, 0, SkIntToScalar(width()), SkIntToScalar(height()), paint); - - canvas->DrawBitmapInt(*sad_tab_bitmap_, icon_bounds_.x(), icon_bounds_.y()); - - canvas->DrawStringInt(title_, *title_font_, kTitleColor, title_bounds_.x(), - title_bounds_.y(), title_bounds_.width(), - title_bounds_.height(), - gfx::Canvas::TEXT_ALIGN_CENTER); - - canvas->DrawStringInt(message_, *message_font_, kMessageColor, - message_bounds_.x(), message_bounds_.y(), - message_bounds_.width(), message_bounds_.height(), - gfx::Canvas::MULTI_LINE); - - if (learn_more_link_ != NULL) - learn_more_link_->SetBounds(link_bounds_.x(), link_bounds_.y(), - link_bounds_.width(), link_bounds_.height()); -} - -void SadTabView::Layout() { - int icon_width = sad_tab_bitmap_->width(); - int icon_height = sad_tab_bitmap_->height(); - int icon_x = (width() - icon_width) / 2; - int icon_y = ((height() - icon_height) / 2) + kSadTabOffset; - icon_bounds_.SetRect(icon_x, icon_y, icon_width, icon_height); - - int title_x = (width() - title_width_) / 2; - int title_y = icon_bounds_.bottom() + kIconTitleSpacing; - int title_height = title_font_->GetHeight(); - title_bounds_.SetRect(title_x, title_y, title_width_, title_height); - - gfx::CanvasSkia cc(0, 0, true); - int message_width = static_cast<int>(width() * kMessageSize); - int message_height = 0; - cc.SizeStringInt(message_, *message_font_, &message_width, &message_height, - gfx::Canvas::MULTI_LINE); - int message_x = (width() - message_width) / 2; - int message_y = title_bounds_.bottom() + kTitleMessageSpacing; - message_bounds_.SetRect(message_x, message_y, message_width, message_height); - - if (learn_more_link_ != NULL) { - gfx::Size sz = learn_more_link_->GetPreferredSize(); - gfx::Insets insets = learn_more_link_->GetInsets(); - link_bounds_.SetRect((width() - sz.width()) / 2, - message_bounds_.bottom() + kTitleMessageSpacing - - insets.top(), sz.width(), sz.height()); - } -} - -void SadTabView::LinkActivated(views::Link* source, int event_flags) { - if (tab_contents_ != NULL && source == learn_more_link_) { - string16 url = l10n_util::GetStringUTF16(IDS_CRASH_REASON_URL); - WindowOpenDisposition disposition(CURRENT_TAB); -#if defined(OS_CHROMEOS) - if (tab_contents_->delegate() && - tab_contents_->delegate()->IsPopup(tab_contents_)) { - // Popup windows are generally too small to effectively show help, - // so open the help content in a new foregreound tab. - disposition = NEW_FOREGROUND_TAB; - } -#endif - tab_contents_->OpenURL(GURL(url), GURL(), disposition, - PageTransition::LINK); - } -} - -// static -void SadTabView::InitClass() { - static bool initialized = false; - if (!initialized) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - title_font_ = new gfx::Font( - rb.GetFont(ResourceBundle::BaseFont).DeriveFont(2, gfx::Font::BOLD)); - message_font_ = new gfx::Font( - rb.GetFont(ResourceBundle::BaseFont).DeriveFont(1)); - sad_tab_bitmap_ = rb.GetBitmapNamed(IDR_SAD_TAB); - - title_ = l10n_util::GetString(IDS_SAD_TAB_TITLE); - title_width_ = title_font_->GetStringWidth(title_); - message_ = l10n_util::GetString(IDS_SAD_TAB_MESSAGE); - - initialized = true; - } -} diff --git a/chrome/browser/views/sad_tab_view.h b/chrome/browser/views/sad_tab_view.h index 11f26265..f21d8e8 100644 --- a/chrome/browser/views/sad_tab_view.h +++ b/chrome/browser/views/sad_tab_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,57 +6,8 @@ #define CHROME_BROWSER_VIEWS_SAD_TAB_VIEW_H_ #pragma once -#include "base/basictypes.h" -#include "gfx/font.h" -#include "views/controls/link.h" -#include "views/view.h" +#include "chrome/browser/ui/views/sad_tab_view.h" +// TODO(beng): remove this file once all includes have been updated. -class SkBitmap; -class TabContents; +#endif // CHROME_BROWSER_VIEWS_SAD_TAB_VIEW_H_ -/////////////////////////////////////////////////////////////////////////////// -// -// SadTabView -// -// A views::View subclass used to render the presentation of the crashed -// "sad tab" in the browser window when a renderer is destroyed unnaturally. -// -/////////////////////////////////////////////////////////////////////////////// -class SadTabView : public views::View, - public views::LinkController { - public: - explicit SadTabView(TabContents* tab_contents); - virtual ~SadTabView() {} - - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - - // Overridden from views::LinkController: - virtual void LinkActivated(views::Link* source, int event_flags); - - private: - static void InitClass(); - - // Assorted resources for display. - static SkBitmap* sad_tab_bitmap_; - static gfx::Font* title_font_; - static gfx::Font* message_font_; - static std::wstring title_; - static std::wstring message_; - static int title_width_; - - TabContents* tab_contents_; - views::Link* learn_more_link_; - - // Regions within the display for different components, populated by - // Layout(). - gfx::Rect icon_bounds_; - gfx::Rect title_bounds_; - gfx::Rect message_bounds_; - gfx::Rect link_bounds_; - - DISALLOW_COPY_AND_ASSIGN(SadTabView); -}; - -#endif // CHROME_BROWSER_VIEWS_SAD_TAB_VIEW_H__ diff --git a/chrome/browser/views/select_file_dialog.cc b/chrome/browser/views/select_file_dialog.cc deleted file mode 100644 index da8427c..0000000 --- a/chrome/browser/views/select_file_dialog.cc +++ /dev/null @@ -1,483 +0,0 @@ -// 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/shell_dialogs.h" - -#include "app/l10n_util.h" -#include "base/callback.h" -#include "base/file_path.h" -#include "base/json/json_reader.h" -#include "base/scoped_ptr.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/dom_ui/html_dialog_ui.h" -#include "chrome/browser/profile_manager.h" -#include "chrome/browser/shell_dialogs.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "chrome/browser/views/html_dialog_view.h" -#include "chrome/common/url_constants.h" -#include "grit/generated_resources.h" -#include "views/window/non_client_view.h" -#include "views/window/window.h" - -namespace { - -const char kKeyNamePath[] = "path"; -const int kSaveCompletePageIndex = 2; - -} // namespace - -// Implementation of SelectFileDialog that shows an UI for choosing a file -// or folder using FileBrowseUI. -class SelectFileDialogImpl : public SelectFileDialog { - public: - explicit SelectFileDialogImpl(Listener* listener); - - // BaseShellDialog implementation. - virtual bool IsRunning(gfx::NativeWindow parent_window) const; - virtual void ListenerDestroyed(); - - // SelectFileDialog implementation. - // |params| is user data we pass back via the Listener interface. - virtual void SelectFile(Type type, - const string16& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const FilePath::StringType& default_extension, - gfx::NativeWindow owning_window, - void* params); - - virtual void set_browser_mode(bool value) { - browser_mode_ = value; - } - - private: - virtual ~SelectFileDialogImpl(); - - class FileBrowseDelegate : public HtmlDialogUIDelegate { - public: - FileBrowseDelegate(SelectFileDialogImpl* owner, - Type type, - const std::wstring& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const FilePath::StringType& default_extension, - gfx::NativeWindow parent, - void* params); - - // Owner of this FileBrowseDelegate. - scoped_refptr<SelectFileDialogImpl> owner_; - - // Parent window. - gfx::NativeWindow parent_; - - // The type of dialog we are showing the user. - Type type_; - - // The dialog title. - std::wstring title_; - - // Default path of the file dialog. - FilePath default_path_; - - // The file filters. - FileTypeInfo file_types_; - - // The index of the default selected file filter. - // Note: This starts from 1, not 0. - int file_type_index_; - - // Default extension to be added to file if user does not type one. - FilePath::StringType default_extension_; - - // Associated user data. - void* params_; - - private: - ~FileBrowseDelegate(); - - // Overridden from HtmlDialogUI::Delegate: - virtual bool IsDialogModal() const; - virtual std::wstring GetDialogTitle() const; - virtual GURL GetDialogContentURL() const; - virtual void GetDOMMessageHandlers( - std::vector<DOMMessageHandler*>* handlers) const; - virtual void GetDialogSize(gfx::Size* size) const; - virtual std::string GetDialogArgs() const; - virtual void OnDialogClosed(const std::string& json_retval); - virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) { - } - virtual bool ShouldShowDialogTitle() const { return true; } - - DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegate); - }; - - class FileBrowseDelegateHandler : public DOMMessageHandler { - public: - explicit FileBrowseDelegateHandler(FileBrowseDelegate* delegate); - - // DOMMessageHandler implementation. - virtual void RegisterMessages(); - - // Callback for the "setDialogTitle" message. - void HandleSetDialogTitle(const ListValue* args); - - private: - FileBrowseDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegateHandler); - }; - - // Notification from FileBrowseDelegate when file browse UI is dismissed. - void OnDialogClosed(FileBrowseDelegate* delegate, const std::string& json); - - // Callback method to open HTML - void OpenHtmlDialog(gfx::NativeWindow owning_window, - FileBrowseDelegate* file_browse_delegate); - - // The set of all parent windows for which we are currently running dialogs. - std::set<gfx::NativeWindow> parents_; - - // The set of all FileBrowseDelegate that we are currently running. - std::set<FileBrowseDelegate*> delegates_; - - // True when opening in browser, otherwise in OOBE/login mode. - bool browser_mode_; - - // The listener to be notified of selection completion. - Listener* listener_; - - DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); -}; - -// static -SelectFileDialog* SelectFileDialog::Create(Listener* listener) { - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE)); - return new SelectFileDialogImpl(listener); -} - -SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener) - : browser_mode_(true), - listener_(listener) { -} - -SelectFileDialogImpl::~SelectFileDialogImpl() { - // All dialogs should be dismissed by now. - DCHECK(parents_.empty() && delegates_.empty()); -} - -bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const { - return parent_window && parents_.find(parent_window) != parents_.end(); -} - -void SelectFileDialogImpl::ListenerDestroyed() { - listener_ = NULL; -} - -void SelectFileDialogImpl::SelectFile( - Type type, - const string16& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const FilePath::StringType& default_extension, - gfx::NativeWindow owning_window, - void* params) { - std::wstring title_string; - if (title.empty()) { - int string_id; - switch (type) { - case SELECT_FOLDER: - string_id = IDS_SELECT_FOLDER_DIALOG_TITLE; - break; - case SELECT_OPEN_FILE: - case SELECT_OPEN_MULTI_FILE: - string_id = IDS_OPEN_FILE_DIALOG_TITLE; - break; - case SELECT_SAVEAS_FILE: - string_id = IDS_SAVE_AS_DIALOG_TITLE; - break; - default: - NOTREACHED(); - return; - } - title_string = l10n_util::GetString(string_id); - } else { - title_string = UTF16ToWide(title); - } - - if (owning_window) - parents_.insert(owning_window); - - FileBrowseDelegate* file_browse_delegate = new FileBrowseDelegate(this, - type, title_string, default_path, file_types, file_type_index, - default_extension, owning_window, params); - delegates_.insert(file_browse_delegate); - - if (browser_mode_) { - Browser* browser = BrowserList::GetLastActive(); - DCHECK(browser); - browser->BrowserShowHtmlDialog(file_browse_delegate, owning_window); - } else { - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - NewRunnableMethod(this, - &SelectFileDialogImpl::OpenHtmlDialog, - owning_window, - file_browse_delegate)); - } -} - -void SelectFileDialogImpl::OnDialogClosed(FileBrowseDelegate* delegate, - const std::string& json) { - // Nothing to do if listener_ is gone. - - if (!listener_) - return; - - bool notification_fired = false; - - if (!json.empty()) { - scoped_ptr<Value> value(base::JSONReader::Read(json, false)); - if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) { - // Bad json value returned. - NOTREACHED(); - } else { - const DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); - if (delegate->type_ == SELECT_OPEN_FILE || - delegate->type_ == SELECT_SAVEAS_FILE || - delegate->type_ == SELECT_FOLDER) { - std::string path_string; - if (dict->HasKey(kKeyNamePath) && - dict->GetString(kKeyNamePath, &path_string)) { - FilePath path = FilePath::FromWStringHack(UTF8ToWide(path_string)); - - listener_->FileSelected(path, kSaveCompletePageIndex, - delegate->params_); - notification_fired = true; - } - } else if (delegate->type_ == SELECT_OPEN_MULTI_FILE) { - ListValue* paths_value = NULL; - if (dict->HasKey(kKeyNamePath) && - dict->GetList(kKeyNamePath, &paths_value) && - paths_value) { - std::vector<FilePath> paths; - paths.reserve(paths_value->GetSize()); - for (size_t i = 0; i < paths_value->GetSize(); ++i) { - std::string path_string; - if (paths_value->GetString(i, &path_string) && - !path_string.empty()) { - paths.push_back(FilePath::FromWStringHack( - UTF8ToWide(path_string))); - } - } - - listener_->MultiFilesSelected(paths, delegate->params_); - notification_fired = true; - } - } else { - NOTREACHED(); - } - } - } - - // Always notify listener when dialog is dismissed. - if (!notification_fired) - listener_->FileSelectionCanceled(delegate->params_); - - parents_.erase(delegate->parent_); - delegates_.erase(delegate); -} - -void SelectFileDialogImpl::OpenHtmlDialog( - gfx::NativeWindow owning_window, - FileBrowseDelegate* file_browse_delegate) { - browser::ShowHtmlDialogView(owning_window, - ProfileManager::GetDefaultProfile(), - file_browse_delegate); -} - -SelectFileDialogImpl::FileBrowseDelegate::FileBrowseDelegate( - SelectFileDialogImpl* owner, - Type type, - const std::wstring& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const FilePath::StringType& default_extension, - gfx::NativeWindow parent, - void* params) - : owner_(owner), - parent_(parent), - type_(type), - title_(title), - default_path_(default_path), - file_type_index_(file_type_index), - default_extension_(default_extension), - params_(params) { - if (file_types) - file_types_ = *file_types; - else - file_types_.include_all_files = true; -} - -SelectFileDialogImpl::FileBrowseDelegate::~FileBrowseDelegate() { -} - -bool SelectFileDialogImpl::FileBrowseDelegate::IsDialogModal() const { - return true; -} - -std::wstring SelectFileDialogImpl::FileBrowseDelegate::GetDialogTitle() const { - return title_; -} - -GURL SelectFileDialogImpl::FileBrowseDelegate::GetDialogContentURL() const { - std::string url_string(chrome::kChromeUIFileBrowseURL); - - return GURL(url_string); -} - -void SelectFileDialogImpl::FileBrowseDelegate::GetDOMMessageHandlers( - std::vector<DOMMessageHandler*>* handlers) const { - handlers->push_back(new FileBrowseDelegateHandler( - const_cast<FileBrowseDelegate*>(this))); - return; -} - -void SelectFileDialogImpl::FileBrowseDelegate::GetDialogSize( - gfx::Size* size) const { - size->SetSize(320, 240); -} - -std::string SelectFileDialogImpl::FileBrowseDelegate::GetDialogArgs() const { - // SelectFile inputs as json. - // { - // "type" : "open", // (or "open_multiple", "save", "folder" - // "all_files" : true, - // "file_types" : { - // "exts" : [ ["htm", "html"], ["txt"] ], - // "desc" : [ "HTML files", "Text files" ], - // }, - // "file_type_index" : 1, // 1-based file type index. - // } - // See browser/shell_dialogs.h for more details. - - std::string type_string; - switch (type_) { - case SELECT_FOLDER: - type_string = "folder"; - break; - case SELECT_OPEN_FILE: - type_string = "open"; - break; - case SELECT_OPEN_MULTI_FILE: - type_string = "open_multiple"; - break; - case SELECT_SAVEAS_FILE: - type_string = "save"; - break; - default: - NOTREACHED(); - return std::string(); - } - - std::string exts_list; - std::string desc_list; - for (size_t i = 0; i < file_types_.extensions.size(); ++i) { - DCHECK(!file_types_.extensions[i].empty()); - - std::string exts; - for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { - if (!exts.empty()) - exts.append(","); - StringAppendF(&exts, "\"%s\"", file_types_.extensions[i][j].c_str()); - } - - if (!exts_list.empty()) - exts_list.append(","); - StringAppendF(&exts_list, "[%s]", exts.c_str()); - - std::string desc; - if (i < file_types_.extension_description_overrides.size()) { - desc = UTF16ToUTF8(file_types_.extension_description_overrides[i]); - } else { -#if defined(OS_WIN) - desc = WideToUTF8(file_types_.extensions[i][0]); -#elif defined(OS_POSIX) - desc = file_types_.extensions[i][0]; -#else - NOTIMPLEMENTED(); -#endif - } - - if (!desc_list.empty()) - desc_list.append(","); - StringAppendF(&desc_list, "\"%s\"", desc.c_str()); - } - - std::string filename = default_path_.BaseName().value(); - - return StringPrintf("{" - "\"type\":\"%s\"," - "\"all_files\":%s," - "\"current_file\":\"%s\"," - "\"file_types\":{\"exts\":[%s],\"desc\":[%s]}," - "\"file_type_index\":%d" - "}", - type_string.c_str(), - file_types_.include_all_files ? "true" : "false", - filename.c_str(), - exts_list.c_str(), - desc_list.c_str(), - file_type_index_); -} - -void SelectFileDialogImpl::FileBrowseDelegate::OnDialogClosed( - const std::string& json_retval) { - owner_->OnDialogClosed(this, json_retval); - delete this; - return; -} - -SelectFileDialogImpl::FileBrowseDelegateHandler::FileBrowseDelegateHandler( - FileBrowseDelegate* delegate) - : delegate_(delegate) { -} - -void SelectFileDialogImpl::FileBrowseDelegateHandler::RegisterMessages() { - dom_ui_->RegisterMessageCallback("setDialogTitle", - NewCallback(this, &FileBrowseDelegateHandler::HandleSetDialogTitle)); -} - -void SelectFileDialogImpl::FileBrowseDelegateHandler::HandleSetDialogTitle( - const ListValue* args) { - std::wstring new_title = ExtractStringValue(args); - if (new_title != delegate_->title_) { - delegate_->title_ = new_title; - - // Notify the containing view about the title change. - // The current HtmlDialogUIDelegate and HtmlDialogView does not support - // dynamic title change. We hijacked the mechanism between HTMLDialogUI - // and HtmlDialogView to get the HtmlDialgoView and forced it to update - // its title. - // TODO(xiyuan): Change this when the infrastructure is improved. - HtmlDialogUIDelegate** delegate = HtmlDialogUI::GetPropertyAccessor(). - GetProperty(dom_ui_->tab_contents()->property_bag()); - HtmlDialogView* containing_view = static_cast<HtmlDialogView*>(*delegate); - DCHECK(containing_view); - - containing_view->GetWindow()->UpdateWindowTitle(); - containing_view->GetWindow()->GetNonClientView()->SchedulePaint(); - } -} diff --git a/chrome/browser/views/shell_dialogs_win.cc b/chrome/browser/views/shell_dialogs_win.cc deleted file mode 100644 index bc5f92b..0000000 --- a/chrome/browser/views/shell_dialogs_win.cc +++ /dev/null @@ -1,1130 +0,0 @@ -// 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/shell_dialogs.h" - -#include <windows.h> -#include <commdlg.h> -#include <shlobj.h> - -#include <algorithm> -#include <set> - -#include "app/l10n_util.h" -#include "base/file_util.h" -#include "base/message_loop.h" -#include "base/scoped_comptr_win.h" -#include "base/string_split.h" -#include "base/thread.h" -#include "base/utf_string_conversions.h" -#include "base/win/registry.h" -#include "base/win/windows_version.h" -#include "chrome/browser/browser_thread.h" -#include "gfx/font.h" -#include "grit/app_strings.h" -#include "grit/generated_resources.h" - -// This function takes the output of a SaveAs dialog: a filename, a filter and -// the extension originally suggested to the user (shown in the dialog box) and -// returns back the filename with the appropriate extension tacked on. If the -// user requests an unknown extension and is not using the 'All files' filter, -// the suggested extension will be appended, otherwise we will leave the -// filename unmodified. |filename| should contain the filename selected in the -// SaveAs dialog box and may include the path, |filter_selected| should be -// '*.something', for example '*.*' or it can be blank (which is treated as -// *.*). |suggested_ext| should contain the extension without the dot (.) in -// front, for example 'jpg'. -std::wstring AppendExtensionIfNeeded(const std::wstring& filename, - const std::wstring& filter_selected, - const std::wstring& suggested_ext) { - DCHECK(!filename.empty()); - std::wstring return_value = filename; - - // If we wanted a specific extension, but the user's filename deleted it or - // changed it to something that the system doesn't understand, re-append. - // Careful: Checking net::GetMimeTypeFromExtension() will only find - // extensions with a known MIME type, which many "known" extensions on Windows - // don't have. So we check directly for the "known extension" registry key. - std::wstring file_extension(file_util::GetFileExtensionFromPath(filename)); - std::wstring key(L"." + file_extension); - if (!(filter_selected.empty() || filter_selected == L"*.*") && - !base::win::RegKey(HKEY_CLASSES_ROOT, key.c_str(), KEY_READ).Valid() && - file_extension != suggested_ext) { - if (return_value[return_value.length() - 1] != L'.') - return_value.append(L"."); - return_value.append(suggested_ext); - } - - // Strip any trailing dots, which Windows doesn't allow. - size_t index = return_value.find_last_not_of(L'.'); - if (index < return_value.size() - 1) - return_value.resize(index + 1); - - return return_value; -} - -namespace { - -// Get the file type description from the registry. This will be "Text Document" -// for .txt files, "JPEG Image" for .jpg files, etc. If the registry doesn't -// have an entry for the file type, we return false, true if the description was -// found. 'file_ext' must be in form ".txt". -static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext, - std::wstring* reg_description) { - DCHECK(reg_description); - base::win::RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ); - std::wstring reg_app; - if (reg_ext.ReadValue(NULL, ®_app) && !reg_app.empty()) { - base::win::RegKey reg_link(HKEY_CLASSES_ROOT, reg_app.c_str(), KEY_READ); - if (reg_link.ReadValue(NULL, reg_description)) - return true; - } - return false; -} - -// Set up a filter for a Save/Open dialog, which will consist of |file_ext| file -// extensions (internally separated by semicolons), |ext_desc| as the text -// descriptions of the |file_ext| types (optional), and (optionally) the default -// 'All Files' view. The purpose of the filter is to show only files of a -// particular type in a Windows Save/Open dialog box. The resulting filter is -// returned. The filters created here are: -// 1. only files that have 'file_ext' as their extension -// 2. all files (only added if 'include_all_files' is true) -// Example: -// file_ext: { "*.txt", "*.htm;*.html" } -// ext_desc: { "Text Document" } -// returned: "Text Document\0*.txt\0HTML Document\0*.htm;*.html\0" -// "All Files\0*.*\0\0" (in one big string) -// If a description is not provided for a file extension, it will be retrieved -// from the registry. If the file extension does not exist in the registry, it -// will be omitted from the filter, as it is likely a bogus extension. -std::wstring FormatFilterForExtensions( - const std::vector<std::wstring>& file_ext, - const std::vector<std::wstring>& ext_desc, - bool include_all_files) { - const std::wstring all_ext = L"*.*"; - const std::wstring all_desc = l10n_util::GetString(IDS_APP_SAVEAS_ALL_FILES); - - DCHECK(file_ext.size() >= ext_desc.size()); - - std::wstring result; - - for (size_t i = 0; i < file_ext.size(); ++i) { - std::wstring ext = file_ext[i]; - std::wstring desc; - if (i < ext_desc.size()) - desc = ext_desc[i]; - - if (ext.empty()) { - // Force something reasonable to appear in the dialog box if there is no - // extension provided. - include_all_files = true; - continue; - } - - if (desc.empty()) { - DCHECK(ext.find(L'.') != std::wstring::npos); - std::wstring first_extension = ext.substr(ext.find(L'.')); - size_t first_separator_index = first_extension.find(L';'); - if (first_separator_index != std::wstring::npos) - first_extension = first_extension.substr(0, first_separator_index); - - // Find the extension name without the preceeding '.' character. - std::wstring ext_name = first_extension; - size_t ext_index = ext_name.find_first_not_of(L'.'); - if (ext_index != std::wstring::npos) - ext_name = ext_name.substr(ext_index); - - if (!GetRegistryDescriptionFromExtension(first_extension, &desc)) { - // The extension doesn't exist in the registry. Create a description - // based on the unknown extension type (i.e. if the extension is .qqq, - // the we create a description "QQQ File (.qqq)"). - include_all_files = true; - desc = l10n_util::GetStringF(IDS_APP_SAVEAS_EXTENSION_FORMAT, - l10n_util::ToUpper(ext_name), - ext_name); - } - if (desc.empty()) - desc = L"*." + ext_name; - } - - result.append(desc.c_str(), desc.size() + 1); // Append NULL too. - result.append(ext.c_str(), ext.size() + 1); - } - - if (include_all_files) { - result.append(all_desc.c_str(), all_desc.size() + 1); - result.append(all_ext.c_str(), all_ext.size() + 1); - } - - result.append(1, '\0'); // Double NULL required. - return result; -} - -// Enforce visible dialog box. -UINT_PTR CALLBACK SaveAsDialogHook(HWND dialog, UINT message, - WPARAM wparam, LPARAM lparam) { - static const UINT kPrivateMessage = 0x2F3F; - switch (message) { - case WM_INITDIALOG: { - // Do nothing here. Just post a message to defer actual processing. - PostMessage(dialog, kPrivateMessage, 0, 0); - return TRUE; - } - case kPrivateMessage: { - // The dialog box is the parent of the current handle. - HWND real_dialog = GetParent(dialog); - - // Retrieve the final size. - RECT dialog_rect; - GetWindowRect(real_dialog, &dialog_rect); - - // Verify that the upper left corner is visible. - POINT point = { dialog_rect.left, dialog_rect.top }; - HMONITOR monitor1 = MonitorFromPoint(point, MONITOR_DEFAULTTONULL); - point.x = dialog_rect.right; - point.y = dialog_rect.bottom; - - // Verify that the lower right corner is visible. - HMONITOR monitor2 = MonitorFromPoint(point, MONITOR_DEFAULTTONULL); - if (monitor1 && monitor2) - return 0; - - // Some part of the dialog box is not visible, fix it by moving is to the - // client rect position of the browser window. - HWND parent_window = GetParent(real_dialog); - if (!parent_window) - return 0; - WINDOWINFO parent_info; - parent_info.cbSize = sizeof(WINDOWINFO); - GetWindowInfo(parent_window, &parent_info); - SetWindowPos(real_dialog, NULL, - parent_info.rcClient.left, - parent_info.rcClient.top, - 0, 0, // Size. - SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | - SWP_NOZORDER); - - return 0; - } - } - return 0; -} - -// Prompt the user for location to save a file. -// Callers should provide the filter string, and also a filter index. -// The parameter |index| indicates the initial index of filter description -// and filter pattern for the dialog box. If |index| is zero or greater than -// the number of total filter types, the system uses the first filter in the -// |filter| buffer. |index| is used to specify the initial selected extension, -// and when done contains the extension the user chose. The parameter -// |final_name| returns the file name which contains the drive designator, -// path, file name, and extension of the user selected file name. |def_ext| is -// the default extension to give to the file if the user did not enter an -// extension. If |ignore_suggested_ext| is true, any file extension contained in -// |suggested_name| will not be used to generate the file name. This is useful -// in the case of saving web pages, where we know the extension type already and -// where |suggested_name| may contain a '.' character as a valid part of the -// name, thus confusing our extension detection code. -bool SaveFileAsWithFilter(HWND owner, - const std::wstring& suggested_name, - const std::wstring& filter, - const std::wstring& def_ext, - bool ignore_suggested_ext, - unsigned* index, - std::wstring* final_name) { - DCHECK(final_name); - // Having an empty filter makes for a bad user experience. We should always - // specify a filter when saving. - DCHECK(!filter.empty()); - std::wstring file_part = file_util::GetFilenameFromPath(suggested_name); - - // The size of the in/out buffer in number of characters we pass to win32 - // GetSaveFileName. From MSDN "The buffer must be large enough to store the - // path and file name string or strings, including the terminating NULL - // character. ... The buffer should be at least 256 characters long.". - // _IsValidPathComDlg does a copy expecting at most MAX_PATH, otherwise will - // result in an error of FNERR_INVALIDFILENAME. So we should only pass the - // API a buffer of at most MAX_PATH. - wchar_t file_name[MAX_PATH]; - base::wcslcpy(file_name, file_part.c_str(), arraysize(file_name)); - - OPENFILENAME save_as; - // We must do this otherwise the ofn's FlagsEx may be initialized to random - // junk in release builds which can cause the Places Bar not to show up! - ZeroMemory(&save_as, sizeof(save_as)); - save_as.lStructSize = sizeof(OPENFILENAME); - save_as.hwndOwner = owner; - save_as.hInstance = NULL; - - save_as.lpstrFilter = filter.empty() ? NULL : filter.c_str(); - - save_as.lpstrCustomFilter = NULL; - save_as.nMaxCustFilter = 0; - save_as.nFilterIndex = *index; - save_as.lpstrFile = file_name; - save_as.nMaxFile = arraysize(file_name); - save_as.lpstrFileTitle = NULL; - save_as.nMaxFileTitle = 0; - - // Set up the initial directory for the dialog. - std::wstring directory = file_util::GetDirectoryFromPath(suggested_name); - save_as.lpstrInitialDir = directory.c_str(); - save_as.lpstrTitle = NULL; - save_as.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING | - OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; - save_as.lpstrDefExt = &def_ext[0]; - save_as.lCustData = NULL; - - if (base::win::GetVersion() < base::win::VERSION_VISTA) { - // The save as on Windows XP remembers its last position, - // and if the screen resolution changed, it will be off screen. - save_as.Flags |= OFN_ENABLEHOOK; - save_as.lpfnHook = &SaveAsDialogHook; - } - - // Must be NULL or 0. - save_as.pvReserved = NULL; - save_as.dwReserved = 0; - - if (!GetSaveFileName(&save_as)) { - // Zero means the dialog was closed, otherwise we had an error. - DWORD error_code = CommDlgExtendedError(); - if (error_code != 0) { - NOTREACHED() << "GetSaveFileName failed with code: " << error_code; - } - return false; - } - - // Return the user's choice. - final_name->assign(save_as.lpstrFile); - *index = save_as.nFilterIndex; - - // Figure out what filter got selected from the vector with embedded nulls. - // NOTE: The filter contains a string with embedded nulls, such as: - // JPG Image\0*.jpg\0All files\0*.*\0\0 - // The filter index is 1-based index for which pair got selected. So, using - // the example above, if the first index was selected we need to skip 1 - // instance of null to get to "*.jpg". - std::vector<std::wstring> filters; - if (!filter.empty() && save_as.nFilterIndex > 0) - base::SplitString(filter, '\0', &filters); - std::wstring filter_selected; - if (!filters.empty()) - filter_selected = filters[(2 * (save_as.nFilterIndex - 1)) + 1]; - - // Get the extension that was suggested to the user (when the Save As dialog - // was opened). For saving web pages, we skip this step since there may be - // 'extension characters' in the title of the web page. - std::wstring suggested_ext; - if (!ignore_suggested_ext) - suggested_ext = file_util::GetFileExtensionFromPath(suggested_name); - - // If we can't get the extension from the suggested_name, we use the default - // extension passed in. This is to cover cases like when saving a web page, - // where we get passed in a name without an extension and a default extension - // along with it. - if (suggested_ext.empty()) - suggested_ext = def_ext; - - *final_name = - AppendExtensionIfNeeded(*final_name, filter_selected, suggested_ext); - return true; -} - -// Prompt the user for location to save a file. 'suggested_name' is a full path -// that gives the dialog box a hint as to how to initialize itself. -// For example, a 'suggested_name' of: -// "C:\Documents and Settings\jojo\My Documents\picture.png" -// will start the dialog in the "C:\Documents and Settings\jojo\My Documents\" -// directory, and filter for .png file types. -// 'owner' is the window to which the dialog box is modal, NULL for a modeless -// dialog box. -// On success, returns true and 'final_name' contains the full path of the file -// that the user chose. On error, returns false, and 'final_name' is not -// modified. -bool SaveFileAs(HWND owner, - const std::wstring& suggested_name, - std::wstring* final_name) { - std::wstring file_ext = file_util::GetFileExtensionFromPath(suggested_name); - file_ext.insert(0, L"*."); - std::wstring filter = FormatFilterForExtensions( - std::vector<std::wstring>(1, file_ext), - std::vector<std::wstring>(), - true); - unsigned index = 1; - return SaveFileAsWithFilter(owner, - suggested_name, - filter, - L"", - false, - &index, - final_name); -} - -} // namespace - -// Helpers to show certain types of Windows shell dialogs in a way that doesn't -// block the UI of the entire app. - -class ShellDialogThread : public base::Thread { - public: - ShellDialogThread() : base::Thread("Chrome_ShellDialogThread") { } - - protected: - void Init() { - // Initializes the COM library on the current thread. - CoInitialize(NULL); - } - - void CleanUp() { - // Closes the COM library on the current thread. CoInitialize must - // be balanced by a corresponding call to CoUninitialize. - CoUninitialize(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ShellDialogThread); -}; - -/////////////////////////////////////////////////////////////////////////////// -// A base class for all shell dialog implementations that handles showing a -// shell dialog modally on its own thread. -class BaseShellDialogImpl { - public: - BaseShellDialogImpl(); - virtual ~BaseShellDialogImpl(); - - protected: - // Represents a run of a dialog. - struct RunState { - // Owning HWND, may be null. - HWND owner; - - // Thread dialog is run on. - base::Thread* dialog_thread; - }; - - // Called at the beginning of a modal dialog run. Disables the owner window - // and tracks it. Returns the message loop of the thread that the dialog will - // be run on. - RunState BeginRun(HWND owner); - - // Cleans up after a dialog run. If the run_state has a valid HWND this makes - // sure that the window is enabled. This is essential because BeginRun - // aggressively guards against multiple modal dialogs per HWND. Must be called - // on the UI thread after the result of the dialog has been determined. - // - // In addition this deletes the Thread in RunState. - void EndRun(RunState run_state); - - // Returns true if a modal shell dialog is currently active for the specified - // owner. Must be called on the UI thread. - bool IsRunningDialogForOwner(HWND owner) const; - - // Disables the window |owner|. Can be run from either the ui or the dialog - // thread. Can be called on either the UI or the dialog thread. This function - // is called on the dialog thread after the modal Windows Common dialog - // functions return because Windows automatically re-enables the owning - // window when those functions return, but we don't actually want them to be - // re-enabled until the response of the dialog propagates back to the UI - // thread, so we disable the owner manually after the Common dialog function - // returns. - void DisableOwner(HWND owner); - - private: - // Creates a thread to run a shell dialog on. Each dialog requires its own - // thread otherwise in some situations where a singleton owns a single - // instance of this object we can have a situation where a modal dialog in - // one window blocks the appearance of a modal dialog in another. - static base::Thread* CreateDialogThread(); - - // Enables the window |owner_|. Can only be run from the ui thread. - void EnableOwner(HWND owner); - - // A list of windows that currently own active shell dialogs for this - // instance. For example, if the DownloadManager owns an instance of this - // object and there are two browser windows open both with Save As dialog - // boxes active, this list will consist of the two browser windows' HWNDs. - // The derived class must call EndRun once the dialog is done showing to - // remove the owning HWND from this list. - // This object is static since it is maintained for all instances of this - // object - i.e. you can't have a font picker and a file picker open for the - // same owner, even though they might be represented by different instances - // of this object. - // This set only contains non-null HWNDs. NULL hwnds are not added to this - // list. - typedef std::set<HWND> Owners; - static Owners owners_; - static int instance_count_; - - DISALLOW_COPY_AND_ASSIGN(BaseShellDialogImpl); -}; - -// static -BaseShellDialogImpl::Owners BaseShellDialogImpl::owners_; -int BaseShellDialogImpl::instance_count_ = 0; - -BaseShellDialogImpl::BaseShellDialogImpl() { - ++instance_count_; -} - -BaseShellDialogImpl::~BaseShellDialogImpl() { - // All runs should be complete by the time this is called! - if (--instance_count_ == 0) - DCHECK(owners_.empty()); -} - -BaseShellDialogImpl::RunState BaseShellDialogImpl::BeginRun(HWND owner) { - // Cannot run a modal shell dialog if one is already running for this owner. - DCHECK(!IsRunningDialogForOwner(owner)); - // The owner must be a top level window, otherwise we could end up with two - // entries in our map for the same top level window. - DCHECK(!owner || owner == GetAncestor(owner, GA_ROOT)); - RunState run_state; - run_state.dialog_thread = CreateDialogThread(); - run_state.owner = owner; - if (owner) { - owners_.insert(owner); - DisableOwner(owner); - } - return run_state; -} - -void BaseShellDialogImpl::EndRun(RunState run_state) { - if (run_state.owner) { - DCHECK(IsRunningDialogForOwner(run_state.owner)); - EnableOwner(run_state.owner); - DCHECK(owners_.find(run_state.owner) != owners_.end()); - owners_.erase(run_state.owner); - } - DCHECK(run_state.dialog_thread); - delete run_state.dialog_thread; -} - -bool BaseShellDialogImpl::IsRunningDialogForOwner(HWND owner) const { - return (owner && owners_.find(owner) != owners_.end()); -} - -void BaseShellDialogImpl::DisableOwner(HWND owner) { - if (IsWindow(owner)) - EnableWindow(owner, FALSE); -} - -// static -base::Thread* BaseShellDialogImpl::CreateDialogThread() { - base::Thread* thread = new ShellDialogThread; - bool started = thread->Start(); - DCHECK(started); - return thread; -} - -void BaseShellDialogImpl::EnableOwner(HWND owner) { - if (IsWindow(owner)) - EnableWindow(owner, TRUE); -} - -// Implementation of SelectFileDialog that shows a Windows common dialog for -// choosing a file or folder. -class SelectFileDialogImpl : public SelectFileDialog, - public BaseShellDialogImpl { - public: - explicit SelectFileDialogImpl(Listener* listener); - - // SelectFileDialog implementation: - virtual void SelectFile(Type type, - const string16& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const FilePath::StringType& default_extension, - gfx::NativeWindow owning_window, - void* params); - virtual bool IsRunning(HWND owning_hwnd) const; - virtual void ListenerDestroyed(); - - private: - virtual ~SelectFileDialogImpl(); - - // A struct for holding all the state necessary for displaying a Save dialog. - struct ExecuteSelectParams { - ExecuteSelectParams(Type type, - const std::wstring& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const std::wstring& default_extension, - RunState run_state, - HWND owner, - void* params) - : type(type), - title(title), - default_path(default_path), - file_type_index(file_type_index), - default_extension(default_extension), - run_state(run_state), - owner(owner), - params(params) { - if (file_types) { - this->file_types = *file_types; - } else { - this->file_types.include_all_files = true; - } - } - SelectFileDialog::Type type; - std::wstring title; - FilePath default_path; - FileTypeInfo file_types; - int file_type_index; - std::wstring default_extension; - RunState run_state; - HWND owner; - void* params; - }; - - // Shows the file selection dialog modal to |owner| and calls the result - // back on the ui thread. Run on the dialog thread. - void ExecuteSelectFile(const ExecuteSelectParams& params); - - // Notifies the listener that a folder was chosen. Run on the ui thread. - void FileSelected(const FilePath& path, int index, - void* params, RunState run_state); - - // Notifies listener that multiple files were chosen. Run on the ui thread. - void MultiFilesSelected(const std::vector<FilePath>& paths, void* params, - RunState run_state); - - // Notifies the listener that no file was chosen (the action was canceled). - // Run on the ui thread. - void FileNotSelected(void* params, RunState run_state); - - // Runs a Folder selection dialog box, passes back the selected folder in - // |path| and returns true if the user clicks OK. If the user cancels the - // dialog box the value in |path| is not modified and returns false. |title| - // is the user-supplied title text to show for the dialog box. Run on the - // dialog thread. - bool RunSelectFolderDialog(const std::wstring& title, - HWND owner, - FilePath* path); - - // Runs an Open file dialog box, with similar semantics for input paramaters - // as RunSelectFolderDialog. - bool RunOpenFileDialog(const std::wstring& title, - const std::wstring& filters, - HWND owner, - FilePath* path); - - // Runs an Open file dialog box that supports multi-select, with similar - // semantics for input paramaters as RunOpenFileDialog. - bool RunOpenMultiFileDialog(const std::wstring& title, - const std::wstring& filter, - HWND owner, - std::vector<FilePath>* paths); - - // The callback function for when the select folder dialog is opened. - static int CALLBACK BrowseCallbackProc(HWND window, UINT message, - LPARAM parameter, - LPARAM data); - - // The listener to be notified of selection completion. - Listener* listener_; - - DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); -}; - -SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener) - : listener_(listener), - BaseShellDialogImpl() { -} - -SelectFileDialogImpl::~SelectFileDialogImpl() { -} - -void SelectFileDialogImpl::SelectFile( - Type type, - const string16& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const FilePath::StringType& default_extension, - gfx::NativeWindow owning_window, - void* params) { - ExecuteSelectParams execute_params(type, UTF16ToWide(title), default_path, - file_types, file_type_index, - default_extension, BeginRun(owning_window), - owning_window, params); - execute_params.run_state.dialog_thread->message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(this, &SelectFileDialogImpl::ExecuteSelectFile, - execute_params)); -} - -bool SelectFileDialogImpl::IsRunning(HWND owning_hwnd) const { - return listener_ && IsRunningDialogForOwner(owning_hwnd); -} - -void SelectFileDialogImpl::ListenerDestroyed() { - // Our associated listener has gone away, so we shouldn't call back to it if - // our worker thread returns after the listener is dead. - listener_ = NULL; -} - -void SelectFileDialogImpl::ExecuteSelectFile( - const ExecuteSelectParams& params) { - std::vector<std::wstring> exts; - for (size_t i = 0; i < params.file_types.extensions.size(); ++i) { - const std::vector<std::wstring>& inner_exts = - params.file_types.extensions[i]; - std::wstring ext_string; - for (size_t j = 0; j < inner_exts.size(); ++j) { - if (!ext_string.empty()) - ext_string.push_back(L';'); - ext_string.append(L"*."); - ext_string.append(inner_exts[j]); - } - exts.push_back(ext_string); - } - std::wstring filter = FormatFilterForExtensions( - exts, - params.file_types.extension_description_overrides, - params.file_types.include_all_files); - - FilePath path = params.default_path; - bool success = false; - unsigned filter_index = params.file_type_index; - if (params.type == SELECT_FOLDER) { - success = RunSelectFolderDialog(params.title, - params.run_state.owner, - &path); - } else if (params.type == SELECT_SAVEAS_FILE) { - std::wstring path_as_wstring = path.ToWStringHack(); - success = SaveFileAsWithFilter(params.run_state.owner, - params.default_path.ToWStringHack(), filter, - params.default_extension, false, &filter_index, &path_as_wstring); - if (success) { - path = FilePath::FromWStringHack(path_as_wstring); - } - DisableOwner(params.run_state.owner); - } else if (params.type == SELECT_OPEN_FILE) { - success = RunOpenFileDialog(params.title, filter, - params.run_state.owner, &path); - } else if (params.type == SELECT_OPEN_MULTI_FILE) { - std::vector<FilePath> paths; - if (RunOpenMultiFileDialog(params.title, filter, - params.run_state.owner, &paths)) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - this, &SelectFileDialogImpl::MultiFilesSelected, paths, - params.params, params.run_state)); - return; - } - } - - if (success) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - this, &SelectFileDialogImpl::FileSelected, path, filter_index, - params.params, params.run_state)); - } else { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - this, &SelectFileDialogImpl::FileNotSelected, params.params, - params.run_state)); - } -} - -void SelectFileDialogImpl::FileSelected(const FilePath& selected_folder, - int index, - void* params, - RunState run_state) { - if (listener_) - listener_->FileSelected(selected_folder, index, params); - EndRun(run_state); -} - -void SelectFileDialogImpl::MultiFilesSelected( - const std::vector<FilePath>& selected_files, - void* params, - RunState run_state) { - if (listener_) - listener_->MultiFilesSelected(selected_files, params); - EndRun(run_state); -} - -void SelectFileDialogImpl::FileNotSelected(void* params, RunState run_state) { - if (listener_) - listener_->FileSelectionCanceled(params); - EndRun(run_state); -} - -int CALLBACK SelectFileDialogImpl::BrowseCallbackProc(HWND window, - UINT message, - LPARAM parameter, - LPARAM data) { - if (message == BFFM_INITIALIZED) { - // WParam is TRUE since passing a path. - // data lParam member of the BROWSEINFO structure. - SendMessage(window, BFFM_SETSELECTION, TRUE, (LPARAM)data); - } - return 0; -} - -bool SelectFileDialogImpl::RunSelectFolderDialog(const std::wstring& title, - HWND owner, - FilePath* path) { - DCHECK(path); - - wchar_t dir_buffer[MAX_PATH + 1]; - - bool result = false; - BROWSEINFO browse_info = {0}; - browse_info.hwndOwner = owner; - browse_info.lpszTitle = title.c_str(); - browse_info.pszDisplayName = dir_buffer; - browse_info.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS; - - if (path->value().length()) { - // Highlight the current value. - browse_info.lParam = (LPARAM)path->value().c_str(); - browse_info.lpfn = &BrowseCallbackProc; - } - - LPITEMIDLIST list = SHBrowseForFolder(&browse_info); - DisableOwner(owner); - if (list) { - STRRET out_dir_buffer; - ZeroMemory(&out_dir_buffer, sizeof(out_dir_buffer)); - out_dir_buffer.uType = STRRET_WSTR; - ScopedComPtr<IShellFolder> shell_folder; - if (SHGetDesktopFolder(shell_folder.Receive()) == NOERROR) { - HRESULT hr = shell_folder->GetDisplayNameOf(list, SHGDN_FORPARSING, - &out_dir_buffer); - if (SUCCEEDED(hr) && out_dir_buffer.uType == STRRET_WSTR) { - *path = FilePath(out_dir_buffer.pOleStr); - CoTaskMemFree(out_dir_buffer.pOleStr); - result = true; - } else { - // Use old way if we don't get what we want. - wchar_t old_out_dir_buffer[MAX_PATH + 1]; - if (SHGetPathFromIDList(list, old_out_dir_buffer)) { - *path = FilePath(old_out_dir_buffer); - result = true; - } - } - - // According to MSDN, win2000 will not resolve shortcuts, so we do it - // ourself. - file_util::ResolveShortcut(path); - } - CoTaskMemFree(list); - } - return result; -} - -bool SelectFileDialogImpl::RunOpenFileDialog( - const std::wstring& title, - const std::wstring& filter, - HWND owner, - FilePath* path) { - OPENFILENAME ofn; - // We must do this otherwise the ofn's FlagsEx may be initialized to random - // junk in release builds which can cause the Places Bar not to show up! - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = owner; - - wchar_t filename[MAX_PATH]; - // According to http://support.microsoft.com/?scid=kb;en-us;222003&x=8&y=12, - // The lpstrFile Buffer MUST be NULL Terminated. - filename[0] = 0; - // Define the dir in here to keep the string buffer pointer pointed to - // ofn.lpstrInitialDir available during the period of running the - // GetOpenFileName. - FilePath dir; - // Use lpstrInitialDir to specify the initial directory - if (!path->empty()) { - bool is_dir; - base::PlatformFileInfo file_info; - if (file_util::GetFileInfo(*path, &file_info)) - is_dir = file_info.is_directory; - else - is_dir = file_util::EndsWithSeparator(*path); - if (is_dir) { - ofn.lpstrInitialDir = path->value().c_str(); - } else { - dir = path->DirName(); - ofn.lpstrInitialDir = dir.value().c_str(); - // Only pure filename can be put in lpstrFile field. - base::wcslcpy(filename, path->BaseName().value().c_str(), - arraysize(filename)); - } - } - - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - - // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory - // without having to close Chrome first. - ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; - - if (!filter.empty()) - ofn.lpstrFilter = filter.c_str(); - bool success = !!GetOpenFileName(&ofn); - DisableOwner(owner); - if (success) - *path = FilePath(filename); - return success; -} - -bool SelectFileDialogImpl::RunOpenMultiFileDialog( - const std::wstring& title, - const std::wstring& filter, - HWND owner, - std::vector<FilePath>* paths) { - OPENFILENAME ofn; - // We must do this otherwise the ofn's FlagsEx may be initialized to random - // junk in release builds which can cause the Places Bar not to show up! - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = owner; - - scoped_array<wchar_t> filename(new wchar_t[UNICODE_STRING_MAX_CHARS]); - filename[0] = 0; - - ofn.lpstrFile = filename.get(); - ofn.nMaxFile = UNICODE_STRING_MAX_CHARS; - // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory - // without having to close Chrome first. - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER - | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT; - - if (!filter.empty()) { - ofn.lpstrFilter = filter.c_str(); - } - bool success = !!GetOpenFileName(&ofn); - DisableOwner(owner); - if (success) { - std::vector<FilePath> files; - const wchar_t* selection = ofn.lpstrFile; - while (*selection) { // Empty string indicates end of list. - files.push_back(FilePath(selection)); - // Skip over filename and null-terminator. - selection += files.back().value().length() + 1; - } - if (files.empty()) { - success = false; - } else if (files.size() == 1) { - // When there is one file, it contains the path and filename. - paths->swap(files); - } else { - // Otherwise, the first string is the path, and the remainder are - // filenames. - std::vector<FilePath>::iterator path = files.begin(); - for (std::vector<FilePath>::iterator file = path + 1; - file != files.end(); ++file) { - paths->push_back(path->Append(*file)); - } - } - } - return success; -} - -// static -SelectFileDialog* SelectFileDialog::Create(Listener* listener) { - return new SelectFileDialogImpl(listener); -} - -/////////////////////////////////////////////////////////////////////////////// -// SelectFontDialogImpl -// Implementation of SelectFontDialog that shows a Windows common dialog for -// choosing a font. -class SelectFontDialogImpl : public SelectFontDialog, - public BaseShellDialogImpl { - public: - explicit SelectFontDialogImpl(Listener* listener); - - // SelectFontDialog implementation: - virtual void SelectFont(HWND owning_hwnd, void* params); - virtual void SelectFont(HWND owning_hwnd, - void* params, - const std::wstring& font_name, - int font_size); - virtual bool IsRunning(HWND owning_hwnd) const; - virtual void ListenerDestroyed(); - - private: - virtual ~SelectFontDialogImpl(); - - // Shows the font selection dialog modal to |owner| and calls the result - // back on the ui thread. Run on the dialog thread. - void ExecuteSelectFont(RunState run_state, void* params); - - // Shows the font selection dialog modal to |owner| and calls the result - // back on the ui thread. Run on the dialog thread. - void ExecuteSelectFontWithNameSize(RunState run_state, - void* params, - const std::wstring& font_name, - int font_size); - - // Notifies the listener that a font was chosen. Run on the ui thread. - void FontSelected(LOGFONT logfont, void* params, RunState run_state); - - // Notifies the listener that no font was chosen (the action was canceled). - // Run on the ui thread. - void FontNotSelected(void* params, RunState run_state); - - // The listener to be notified of selection completion. - Listener* listener_; - - DISALLOW_COPY_AND_ASSIGN(SelectFontDialogImpl); -}; - -SelectFontDialogImpl::SelectFontDialogImpl(Listener* listener) - : listener_(listener), - BaseShellDialogImpl() { -} - -SelectFontDialogImpl::~SelectFontDialogImpl() { -} - -void SelectFontDialogImpl::SelectFont(HWND owner, void* params) { - RunState run_state = BeginRun(owner); - run_state.dialog_thread->message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(this, &SelectFontDialogImpl::ExecuteSelectFont, - run_state, params)); -} - -void SelectFontDialogImpl::SelectFont(HWND owner, void* params, - const std::wstring& font_name, - int font_size) { - RunState run_state = BeginRun(owner); - run_state.dialog_thread->message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(this, - &SelectFontDialogImpl::ExecuteSelectFontWithNameSize, run_state, - params, font_name, font_size)); -} - -bool SelectFontDialogImpl::IsRunning(HWND owning_hwnd) const { - return listener_ && IsRunningDialogForOwner(owning_hwnd); -} - -void SelectFontDialogImpl::ListenerDestroyed() { - // Our associated listener has gone away, so we shouldn't call back to it if - // our worker thread returns after the listener is dead. - listener_ = NULL; -} - -void SelectFontDialogImpl::ExecuteSelectFont(RunState run_state, void* params) { - LOGFONT logfont; - CHOOSEFONT cf; - cf.lStructSize = sizeof(cf); - cf.hwndOwner = run_state.owner; - cf.lpLogFont = &logfont; - cf.Flags = CF_SCREENFONTS; - bool success = !!ChooseFont(&cf); - DisableOwner(run_state.owner); - if (success) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - this, &SelectFontDialogImpl::FontSelected, logfont, params, - run_state)); - } else { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - this, &SelectFontDialogImpl::FontNotSelected, params, run_state)); - } -} - -void SelectFontDialogImpl::ExecuteSelectFontWithNameSize( - RunState run_state, void* params, const std::wstring& font_name, - int font_size) { - // Create the HFONT from font name and size. - HDC hdc = GetDC(NULL); - long lf_height = -MulDiv(font_size, GetDeviceCaps(hdc, LOGPIXELSY), 72); - ReleaseDC(NULL, hdc); - HFONT hf = ::CreateFont(lf_height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - font_name.c_str()); - LOGFONT logfont; - GetObject(hf, sizeof(LOGFONT), &logfont); - // Retrieve the localized face name of the above font and update the LOGFONT - // structure. When a font has a localized name matching to the system locale, - // GetTextFace() returns the localized name. We should pass this localized - // name to ChooseFont() so it can set the focus. - HDC memory_dc = CreateCompatibleDC(NULL); - if (memory_dc) { - wchar_t localized_font_name[LF_FACESIZE]; - HFONT original_font = reinterpret_cast<HFONT>(SelectObject(memory_dc, hf)); - int length = GetTextFace(memory_dc, arraysize(localized_font_name), - &localized_font_name[0]); - if (length > 0) { - memcpy(&logfont.lfFaceName[0], &localized_font_name[0], - sizeof(localized_font_name)); - } - SelectObject(memory_dc, original_font); - DeleteDC(memory_dc); - } - CHOOSEFONT cf; - cf.lStructSize = sizeof(cf); - cf.hwndOwner = run_state.owner; - cf.lpLogFont = &logfont; - // Limit the list to a reasonable subset of fonts. - // TODO : get rid of style selector and script selector - // 1. List only truetype font - // 2. Exclude vertical fonts (whose names begin with '@') - // 3. Exclude symbol and OEM fonts - // 4. Limit the size to [8, 40]. - // See http://msdn.microsoft.com/en-us/library/ms646832(VS.85).aspx - cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_TTONLY | - CF_NOVERTFONTS | CF_SCRIPTSONLY | CF_LIMITSIZE; - - // These limits are arbitrary and needs to be revisited. Is it bad - // to clamp the size at 40 from A11Y point of view? - cf.nSizeMin = 8; - cf.nSizeMax = 40; - - bool success = !!ChooseFont(&cf); - DisableOwner(run_state.owner); - if (success) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - this, &SelectFontDialogImpl::FontSelected, logfont, params, - run_state)); - } else { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, &SelectFontDialogImpl::FontNotSelected, params, - run_state)); - } -} - -void SelectFontDialogImpl::FontSelected(LOGFONT logfont, - void* params, - RunState run_state) { - if (listener_) { - HFONT font = CreateFontIndirect(&logfont); - if (font) { - listener_->FontSelected(gfx::Font(font), params); - DeleteObject(font); - } else { - listener_->FontSelectionCanceled(params); - } - } - EndRun(run_state); -} - -void SelectFontDialogImpl::FontNotSelected(void* params, RunState run_state) { - if (listener_) - listener_->FontSelectionCanceled(params); - EndRun(run_state); -} - -// static -SelectFontDialog* SelectFontDialog::Create(Listener* listener) { - return new SelectFontDialogImpl(listener); -} diff --git a/chrome/browser/views/shell_dialogs_win_unittest.cc b/chrome/browser/views/shell_dialogs_win_unittest.cc deleted file mode 100644 index 0c2cad5..0000000 --- a/chrome/browser/views/shell_dialogs_win_unittest.cc +++ /dev/null @@ -1,44 +0,0 @@ -// 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/shell_dialogs.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(ShellDialogsWin, AppendExtensionIfNeeded) { - struct AppendExtensionTestCase { - wchar_t* filename; - wchar_t* filter_selected; - wchar_t* suggested_ext; - wchar_t* expected_filename; - } test_cases[] = { - // Known extensions, with or without associated MIME types, should not get - // an extension appended. - { L"sample.html", L"*.txt", L"txt", L"sample.html" }, - { L"sample.reg", L"*.txt", L"txt", L"sample.reg" }, - - // An unknown extension, or no extension, should get the default extension - // appended. - { L"sample.unknown", L"*.txt", L"txt", L"sample.unknown.txt" }, - { L"sample", L"*.txt", L"txt", L"sample.txt" }, - // ...unless the unknown and default extensions match. - { L"sample.unknown", L"*.unknown", L"unknown", L"sample.unknown" }, - - // The extension alone should be treated like a filename with no extension. - { L"txt", L"*.txt", L"txt", L"txt.txt" }, - - // Trailing dots should cause us to append an extension. - { L"sample.txt.", L"*.txt", L"txt", L"sample.txt.txt" }, - { L"...", L"*.txt", L"txt", L"...txt" }, - - // If the filter is changed to "All files", we allow any filename. - { L"sample.unknown", L"*.*", L"", L"sample.unknown" }, - }; - - for (size_t i = 0; i < arraysize(test_cases); ++i) { - EXPECT_EQ(std::wstring(test_cases[i].expected_filename), - AppendExtensionIfNeeded(test_cases[i].filename, - test_cases[i].filter_selected, - test_cases[i].suggested_ext)); - } -} diff --git a/chrome/browser/views/ssl_client_certificate_selector_win.cc b/chrome/browser/views/ssl_client_certificate_selector_win.cc deleted file mode 100644 index 5eddcef..0000000 --- a/chrome/browser/views/ssl_client_certificate_selector_win.cc +++ /dev/null @@ -1,73 +0,0 @@ -// 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/ssl_client_certificate_selector.h" - -#include <windows.h> -#include <cryptuiapi.h> -#pragma comment(lib, "cryptui.lib") - -#include "app/l10n_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/ssl/ssl_client_auth_handler.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "grit/generated_resources.h" -#include "net/url_request/url_request.h" - -namespace browser { - -void ShowSSLClientCertificateSelector( - TabContents* parent, - net::SSLCertRequestInfo* cert_request_info, - SSLClientAuthHandler* delegate) { - // TODO(jcampan): replace this with our own cert selection dialog. - // CryptUIDlgSelectCertificateFromStore is blocking (but still processes - // Windows messages), which is scary. - // - // TODO(davidben): Make this dialog tab-modal to the - // TabContents. This depends on the above TODO. - HCERTSTORE client_certs = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, - 0, NULL); - BOOL ok; - for (size_t i = 0; i < cert_request_info->client_certs.size(); ++i) { - PCCERT_CONTEXT cc = cert_request_info->client_certs[i]->os_cert_handle(); - ok = CertAddCertificateContextToStore(client_certs, cc, - CERT_STORE_ADD_ALWAYS, NULL); - DCHECK(ok); - } - - std::wstring title = l10n_util::GetString(IDS_CLIENT_CERT_DIALOG_TITLE); - std::wstring text = l10n_util::GetStringF( - IDS_CLIENT_CERT_DIALOG_TEXT, - ASCIIToWide(cert_request_info->host_and_port)); - PCCERT_CONTEXT cert_context = CryptUIDlgSelectCertificateFromStore( - client_certs, parent->GetMessageBoxRootWindow(), - title.c_str(), text.c_str(), 0, 0, NULL); - - net::X509Certificate* cert = NULL; - if (cert_context) { - for (size_t i = 0; i < cert_request_info->client_certs.size(); ++i) { - net::X509Certificate* client_cert = cert_request_info->client_certs[i]; - if (net::X509Certificate::IsSameOSCert(cert_context, - client_cert->os_cert_handle())) { - cert = client_cert; - break; - } - } - DCHECK(cert != NULL); - net::X509Certificate::FreeOSCertHandle(cert_context); - } - - ok = CertCloseStore(client_certs, CERT_CLOSE_STORE_CHECK_FLAG); - DCHECK(ok); - - delegate->CertificateSelected(cert); -} - -} // namespace browser diff --git a/chrome/browser/views/status_bubble_views.cc b/chrome/browser/views/status_bubble_views.cc deleted file mode 100644 index 234b6f0..0000000 --- a/chrome/browser/views/status_bubble_views.cc +++ /dev/null @@ -1,835 +0,0 @@ -// 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/status_bubble_views.h" - -#include <algorithm> - -#include "app/linear_animation.h" -#include "app/resource_bundle.h" -#include "app/text_elider.h" -#include "base/i18n/rtl.h" -#include "base/message_loop.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "gfx/canvas_skia.h" -#include "gfx/point.h" -#include "googleurl/src/gurl.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "net/base/net_util.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "third_party/skia/include/core/SkPath.h" -#include "third_party/skia/include/core/SkRect.h" -#include "views/controls/label.h" -#include "views/controls/scrollbar/native_scroll_bar.h" -#include "views/screen.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -using views::Widget; - -// The alpha and color of the bubble's shadow. -static const SkColor kShadowColor = SkColorSetARGB(30, 0, 0, 0); - -// The roundedness of the edges of our bubble. -static const int kBubbleCornerRadius = 4; - -// How close the mouse can get to the infobubble before it starts sliding -// off-screen. -static const int kMousePadding = 20; - -// The horizontal offset of the text within the status bubble, not including the -// outer shadow ring. -static const int kTextPositionX = 3; - -// The minimum horizontal space between the (right) end of the text and the edge -// of the status bubble, not including the outer shadow ring. -static const int kTextHorizPadding = 1; - -// Delays before we start hiding or showing the bubble after we receive a -// show or hide request. -static const int kShowDelay = 80; -static const int kHideDelay = 250; - -// How long each fade should last for. -static const int kShowFadeDurationMS = 120; -static const int kHideFadeDurationMS = 200; -static const int kFramerate = 25; - -// How long each expansion step should take. -static const int kMinExpansionStepDurationMS = 20; -static const int kMaxExpansionStepDurationMS = 150; - -// View ----------------------------------------------------------------------- -// StatusView manages the display of the bubble, applying text changes and -// fading in or out the bubble as required. -class StatusBubbleViews::StatusView : public views::Label, - public LinearAnimation, - public AnimationDelegate { - public: - StatusView(StatusBubble* status_bubble, views::Widget* popup, - ThemeProvider* theme_provider) - : ALLOW_THIS_IN_INITIALIZER_LIST(LinearAnimation(kFramerate, this)), - stage_(BUBBLE_HIDDEN), - style_(STYLE_STANDARD), - ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)), - status_bubble_(status_bubble), - popup_(popup), - opacity_start_(0), - opacity_end_(0), - theme_provider_(theme_provider) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - gfx::Font font(rb.GetFont(ResourceBundle::BaseFont)); - SetFont(font); - } - - virtual ~StatusView() { - Stop(); - CancelTimer(); - } - - // The bubble can be in one of many stages: - enum BubbleStage { - BUBBLE_HIDDEN, // Entirely BUBBLE_HIDDEN. - BUBBLE_HIDING_FADE, // In a fade-out transition. - BUBBLE_HIDING_TIMER, // Waiting before a fade-out. - BUBBLE_SHOWING_TIMER, // Waiting before a fade-in. - BUBBLE_SHOWING_FADE, // In a fade-in transition. - BUBBLE_SHOWN // Fully visible. - }; - - enum BubbleStyle { - STYLE_BOTTOM, - STYLE_FLOATING, - STYLE_STANDARD, - STYLE_STANDARD_RIGHT - }; - - // Set the bubble text to a certain value, hides the bubble if text is - // an empty string. Trigger animation sequence to display if - // |should_animate_open|. - void SetText(const string16& text, bool should_animate_open); - - BubbleStage GetState() const { return stage_; } - - void SetStyle(BubbleStyle style); - - BubbleStyle GetStyle() const { return style_; } - - // Show the bubble instantly. - void Show(); - - // Hide the bubble instantly. - void Hide(); - - // Resets any timers we have. Typically called when the user moves a - // mouse. - void ResetTimer(); - - private: - class InitialTimer; - - // Manage the timers that control the delay before a fade begins or ends. - void StartTimer(int time); - void OnTimer(); - void CancelTimer(); - void RestartTimer(int delay); - - // Manage the fades and starting and stopping the animations correctly. - void StartFade(double start, double end, int duration); - void StartHiding(); - void StartShowing(); - - // Animation functions. - double GetCurrentOpacity(); - void SetOpacity(double opacity); - void AnimateToState(double state); - void AnimationEnded(const Animation* animation); - - virtual void Paint(gfx::Canvas* canvas); - - BubbleStage stage_; - BubbleStyle style_; - - ScopedRunnableMethodFactory<StatusBubbleViews::StatusView> timer_factory_; - - // Manager, owns us. - StatusBubble* status_bubble_; - - // Handle to the widget that contains us. - views::Widget* popup_; - - // The currently-displayed text. - string16 text_; - - // Start and end opacities for the current transition - note that as a - // fade-in can easily turn into a fade out, opacity_start_ is sometimes - // a value between 0 and 1. - double opacity_start_; - double opacity_end_; - - // Holds the theme provider of the frame that created us. - ThemeProvider* theme_provider_; -}; - -void StatusBubbleViews::StatusView::SetText(const string16& text, - bool should_animate_open) { - if (text.empty()) { - // The string was empty. - StartHiding(); - } else { - // We want to show the string. - text_ = text; - if (should_animate_open) - StartShowing(); - } - - SchedulePaint(); -} - -void StatusBubbleViews::StatusView::Show() { - Stop(); - CancelTimer(); - SetOpacity(1.0); - popup_->Show(); - stage_ = BUBBLE_SHOWN; - PaintNow(); -} - -void StatusBubbleViews::StatusView::Hide() { - Stop(); - CancelTimer(); - SetOpacity(0.0); - text_.clear(); - popup_->Hide(); - stage_ = BUBBLE_HIDDEN; -} - -void StatusBubbleViews::StatusView::StartTimer(int time) { - if (!timer_factory_.empty()) - timer_factory_.RevokeAll(); - - MessageLoop::current()->PostDelayedTask(FROM_HERE, - timer_factory_.NewRunnableMethod(&StatusBubbleViews::StatusView::OnTimer), - time); -} - -void StatusBubbleViews::StatusView::OnTimer() { - if (stage_ == BUBBLE_HIDING_TIMER) { - stage_ = BUBBLE_HIDING_FADE; - StartFade(1.0, 0.0, kHideFadeDurationMS); - } else if (stage_ == BUBBLE_SHOWING_TIMER) { - stage_ = BUBBLE_SHOWING_FADE; - StartFade(0.0, 1.0, kShowFadeDurationMS); - } -} - -void StatusBubbleViews::StatusView::CancelTimer() { - if (!timer_factory_.empty()) - timer_factory_.RevokeAll(); -} - -void StatusBubbleViews::StatusView::RestartTimer(int delay) { - CancelTimer(); - StartTimer(delay); -} - -void StatusBubbleViews::StatusView::ResetTimer() { - if (stage_ == BUBBLE_SHOWING_TIMER) { - // We hadn't yet begun showing anything when we received a new request - // for something to show, so we start from scratch. - RestartTimer(kShowDelay); - } -} - -void StatusBubbleViews::StatusView::StartFade(double start, - double end, - int duration) { - opacity_start_ = start; - opacity_end_ = end; - - // This will also reset the currently-occurring animation. - SetDuration(duration); - Start(); -} - -void StatusBubbleViews::StatusView::StartHiding() { - if (stage_ == BUBBLE_SHOWN) { - stage_ = BUBBLE_HIDING_TIMER; - StartTimer(kHideDelay); - } else if (stage_ == BUBBLE_SHOWING_TIMER) { - stage_ = BUBBLE_HIDDEN; - CancelTimer(); - } else if (stage_ == BUBBLE_SHOWING_FADE) { - stage_ = BUBBLE_HIDING_FADE; - // Figure out where we are in the current fade. - double current_opacity = GetCurrentOpacity(); - - // Start a fade in the opposite direction. - StartFade(current_opacity, 0.0, - static_cast<int>(kHideFadeDurationMS * current_opacity)); - } -} - -void StatusBubbleViews::StatusView::StartShowing() { - if (stage_ == BUBBLE_HIDDEN) { - popup_->Show(); - stage_ = BUBBLE_SHOWING_TIMER; - StartTimer(kShowDelay); - } else if (stage_ == BUBBLE_HIDING_TIMER) { - stage_ = BUBBLE_SHOWN; - CancelTimer(); - } else if (stage_ == BUBBLE_HIDING_FADE) { - // We're partway through a fade. - stage_ = BUBBLE_SHOWING_FADE; - - // Figure out where we are in the current fade. - double current_opacity = GetCurrentOpacity(); - - // Start a fade in the opposite direction. - StartFade(current_opacity, 1.0, - static_cast<int>(kShowFadeDurationMS * current_opacity)); - } else if (stage_ == BUBBLE_SHOWING_TIMER) { - // We hadn't yet begun showing anything when we received a new request - // for something to show, so we start from scratch. - ResetTimer(); - } -} - -// Animation functions. -double StatusBubbleViews::StatusView::GetCurrentOpacity() { - return opacity_start_ + (opacity_end_ - opacity_start_) * - LinearAnimation::GetCurrentValue(); -} - -void StatusBubbleViews::StatusView::SetOpacity(double opacity) { - popup_->SetOpacity(static_cast<unsigned char>(opacity * 255)); - SchedulePaint(); -} - -void StatusBubbleViews::StatusView::AnimateToState(double state) { - SetOpacity(GetCurrentOpacity()); -} - -void StatusBubbleViews::StatusView::AnimationEnded( - const Animation* animation) { - SetOpacity(opacity_end_); - - if (stage_ == BUBBLE_HIDING_FADE) { - stage_ = BUBBLE_HIDDEN; - popup_->Hide(); - } else if (stage_ == BUBBLE_SHOWING_FADE) { - stage_ = BUBBLE_SHOWN; - } -} - -void StatusBubbleViews::StatusView::SetStyle(BubbleStyle style) { - if (style_ != style) { - style_ = style; - SchedulePaint(); - } -} - -void StatusBubbleViews::StatusView::Paint(gfx::Canvas* canvas) { - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setFlags(SkPaint::kAntiAlias_Flag); - SkColor toolbar_color = - theme_provider_->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); - paint.setColor(toolbar_color); - - gfx::Rect popup_bounds; - popup_->GetBounds(&popup_bounds, true); - - // Figure out how to round the bubble's four corners. - SkScalar rad[8]; - - // Top Edges - if the bubble is in its bottom position (sticking downwards), - // then we square the top edges. Otherwise, we square the edges based on the - // position of the bubble within the window (the bubble is positioned in the - // southeast corner in RTL and in the southwest corner in LTR). - if (style_ == STYLE_BOTTOM) { - // Top Left corner. - rad[0] = 0; - rad[1] = 0; - - // Top Right corner. - rad[2] = 0; - rad[3] = 0; - } else { - if (base::i18n::IsRTL() != (style_ == STYLE_STANDARD_RIGHT)) { - // The text is RtL or the bubble is on the right side (but not both). - - // Top Left corner. - rad[0] = SkIntToScalar(kBubbleCornerRadius); - rad[1] = SkIntToScalar(kBubbleCornerRadius); - - // Top Right corner. - rad[2] = 0; - rad[3] = 0; - } else { - // Top Left corner. - rad[0] = 0; - rad[1] = 0; - - // Top Right corner. - rad[2] = SkIntToScalar(kBubbleCornerRadius); - rad[3] = SkIntToScalar(kBubbleCornerRadius); - } - } - - // Bottom edges - square these off if the bubble is in its standard position - // (sticking upward). - if (style_ == STYLE_STANDARD || style_ == STYLE_STANDARD_RIGHT) { - // Bottom Right Corner. - rad[4] = 0; - rad[5] = 0; - - // Bottom Left Corner. - rad[6] = 0; - rad[7] = 0; - } else { - // Bottom Right Corner. - rad[4] = SkIntToScalar(kBubbleCornerRadius); - rad[5] = SkIntToScalar(kBubbleCornerRadius); - - // Bottom Left Corner. - rad[6] = SkIntToScalar(kBubbleCornerRadius); - rad[7] = SkIntToScalar(kBubbleCornerRadius); - } - - // Draw the bubble's shadow. - int width = popup_bounds.width(); - int height = popup_bounds.height(); - SkRect rect; - rect.set(0, 0, - SkIntToScalar(width), - SkIntToScalar(height)); - SkPath shadow_path; - shadow_path.addRoundRect(rect, rad, SkPath::kCW_Direction); - SkPaint shadow_paint; - shadow_paint.setFlags(SkPaint::kAntiAlias_Flag); - shadow_paint.setColor(kShadowColor); - canvas->AsCanvasSkia()->drawPath(shadow_path, shadow_paint); - - // Draw the bubble. - rect.set(SkIntToScalar(kShadowThickness), - SkIntToScalar(kShadowThickness), - SkIntToScalar(width - kShadowThickness), - SkIntToScalar(height - kShadowThickness)); - SkPath path; - path.addRoundRect(rect, rad, SkPath::kCW_Direction); - canvas->AsCanvasSkia()->drawPath(path, paint); - - // Draw highlight text and then the text body. In order to make sure the text - // is aligned to the right on RTL UIs, we mirror the text bounds if the - // locale is RTL. - int text_width = std::min( - views::Label::font().GetStringWidth(UTF16ToWide(text_)), - width - (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding); - int text_height = height - (kShadowThickness * 2); - gfx::Rect body_bounds(kShadowThickness + kTextPositionX, - kShadowThickness, - std::max(0, text_width), - std::max(0, text_height)); - body_bounds.set_x(MirroredLeftPointForRect(body_bounds)); - SkColor text_color = - theme_provider_->GetColor(BrowserThemeProvider::COLOR_TAB_TEXT); - - // DrawStringInt doesn't handle alpha, so we'll do the blending ourselves. - text_color = SkColorSetARGB( - SkColorGetA(text_color), - (SkColorGetR(text_color) + SkColorGetR(toolbar_color)) / 2, - (SkColorGetG(text_color) + SkColorGetR(toolbar_color)) / 2, - (SkColorGetB(text_color) + SkColorGetR(toolbar_color)) / 2); - canvas->DrawStringInt(UTF16ToWide(text_), - views::Label::font(), - text_color, - body_bounds.x(), - body_bounds.y(), - body_bounds.width(), - body_bounds.height()); -} - -// StatusViewExpander --------------------------------------------------------- -// Manages the expansion and contraction of the status bubble as it accommodates -// URLs too long to fit in the standard bubble. Changes are passed through the -// StatusView to paint. -class StatusBubbleViews::StatusViewExpander : public LinearAnimation, - public AnimationDelegate { - public: - StatusViewExpander(StatusBubbleViews* status_bubble, - StatusView* status_view) - : ALLOW_THIS_IN_INITIALIZER_LIST(LinearAnimation(kFramerate, this)), - status_bubble_(status_bubble), - status_view_(status_view), - expansion_start_(0), - expansion_end_(0) { - } - - // Manage the expansion of the bubble. - void StartExpansion(string16 expanded_text, int current_width, - int expansion_end); - - // Set width of fully expanded bubble. - void SetExpandedWidth(int expanded_width); - - private: - // Animation functions. - int GetCurrentBubbleWidth(); - void SetBubbleWidth(int width); - void AnimateToState(double state); - void AnimationEnded(const Animation* animation); - - // Manager that owns us. - StatusBubbleViews* status_bubble_; - - // Change the bounds and text of this view. - StatusView* status_view_; - - // Text elided (if needed) to fit maximum status bar width. - string16 expanded_text_; - - // Widths at expansion start and end. - int expansion_start_; - int expansion_end_; -}; - -void StatusBubbleViews::StatusViewExpander::AnimateToState(double state) { - SetBubbleWidth(GetCurrentBubbleWidth()); -} - -void StatusBubbleViews::StatusViewExpander::AnimationEnded( - const Animation* animation) { - SetBubbleWidth(expansion_end_); - status_view_->SetText(expanded_text_, false); -} - -void StatusBubbleViews::StatusViewExpander::StartExpansion( - string16 expanded_text, int expansion_start, - int expansion_end) { - expanded_text_ = expanded_text; - expansion_start_ = expansion_start; - expansion_end_ = expansion_end; - int min_duration = std::max(kMinExpansionStepDurationMS, - static_cast<int>(kMaxExpansionStepDurationMS * - (expansion_end - expansion_start) / 100.0)); - SetDuration(std::min(kMaxExpansionStepDurationMS, min_duration)); - Start(); -} - -int StatusBubbleViews::StatusViewExpander::GetCurrentBubbleWidth() { - return static_cast<int>(expansion_start_ + - (expansion_end_ - expansion_start_) * LinearAnimation::GetCurrentValue()); -} - -void StatusBubbleViews::StatusViewExpander::SetBubbleWidth(int width) { - status_bubble_->SetBubbleWidth(width); - status_view_->SchedulePaint(); -} - -// StatusBubble --------------------------------------------------------------- - -const int StatusBubbleViews::kShadowThickness = 1; - -StatusBubbleViews::StatusBubbleViews(views::View* base_view) - : offset_(0), - popup_(NULL), - opacity_(0), - base_view_(base_view), - view_(NULL), - download_shelf_is_visible_(false), - is_expanded_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(expand_timer_factory_(this)) { - expand_view_.reset(); -} - -StatusBubbleViews::~StatusBubbleViews() { - CancelExpandTimer(); - if (popup_.get()) - popup_->CloseNow(); -} - -void StatusBubbleViews::Init() { - if (!popup_.get()) { - popup_.reset(Widget::CreatePopupWidget(Widget::Transparent, - Widget::NotAcceptEvents, - Widget::NotDeleteOnDestroy, - Widget::MirrorOriginInRTL)); - views::Widget* frame = base_view_->GetWidget(); - if (!view_) - view_ = new StatusView(this, popup_.get(), frame->GetThemeProvider()); - if (!expand_view_.get()) - expand_view_.reset(new StatusViewExpander(this, view_)); - popup_->SetOpacity(0x00); - popup_->Init(frame->GetNativeView(), gfx::Rect()); - popup_->SetContentsView(view_); - Reposition(); - popup_->Show(); - } -} - -void StatusBubbleViews::Reposition() { - if (popup_.get()) { - gfx::Point top_left; - views::View::ConvertPointToScreen(base_view_, &top_left); - - popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), - top_left.y() + position_.y(), - size_.width(), size_.height())); - } -} - -gfx::Size StatusBubbleViews::GetPreferredSize() { - return gfx::Size(0, ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont).GetHeight() + kTotalVerticalPadding); -} - -void StatusBubbleViews::SetBounds(int x, int y, int w, int h) { - original_position_.SetPoint(x, y); - position_.SetPoint(base_view_->MirroredXWithWidthInsideView(x, w), y); - size_.SetSize(w, h); - Reposition(); -} - -void StatusBubbleViews::SetStatus(const string16& status_text) { - if (size_.IsEmpty()) - return; // We have no bounds, don't attempt to show the popup. - - if (status_text_ == status_text && !status_text.empty()) - return; - - if (!IsFrameVisible()) - return; // Don't show anything if the parent isn't visible. - - Init(); - status_text_ = status_text; - if (!status_text_.empty()) { - view_->SetText(status_text, true); - view_->Show(); - } else if (!url_text_.empty()) { - view_->SetText(url_text_, true); - } else { - view_->SetText(string16(), true); - } -} - -void StatusBubbleViews::SetURL(const GURL& url, const string16& languages) { - languages_ = languages; - url_ = url; - if (size_.IsEmpty()) - return; // We have no bounds, don't attempt to show the popup. - - Init(); - - // If we want to clear a displayed URL but there is a status still to - // display, display that status instead. - if (url.is_empty() && !status_text_.empty()) { - url_text_ = string16(); - if (IsFrameVisible()) - view_->SetText(status_text_, true); - return; - } - - // Reset expansion state only when bubble is completely hidden. - if (view_->GetState() == StatusView::BUBBLE_HIDDEN) { - is_expanded_ = false; - SetBubbleWidth(GetStandardStatusBubbleWidth()); - } - - // Set Elided Text corresponding to the GURL object. - gfx::Rect popup_bounds; - popup_->GetBounds(&popup_bounds, true); - int text_width = static_cast<int>(popup_bounds.width() - - (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1); - url_text_ = gfx::ElideUrl(url, view_->Label::font(), - text_width, UTF16ToWideHack(languages)); - - std::wstring original_url_text = - UTF16ToWideHack(net::FormatUrl(url, UTF16ToUTF8(languages))); - - // An URL is always treated as a left-to-right string. On right-to-left UIs - // we need to explicitly mark the URL as LTR to make sure it is displayed - // correctly. - url_text_ = base::i18n::GetDisplayStringInLTRDirectionality(url_text_); - - if (IsFrameVisible()) { - view_->SetText(url_text_, true); - - CancelExpandTimer(); - - // If bubble is already in expanded state, shift to adjust to new text - // size (shrinking or expanding). Otherwise delay. - if (is_expanded_ && !url.is_empty()) - ExpandBubble(); - else if (original_url_text.length() > url_text_.length()) - MessageLoop::current()->PostDelayedTask(FROM_HERE, - expand_timer_factory_.NewRunnableMethod( - &StatusBubbleViews::ExpandBubble), kExpandHoverDelay); - } -} - -void StatusBubbleViews::Hide() { - status_text_ = string16(); - url_text_ = string16(); - if (view_) - view_->Hide(); -} - -void StatusBubbleViews::MouseMoved(const gfx::Point& location, - bool left_content) { - if (left_content) - return; - - if (view_) { - view_->ResetTimer(); - - if (view_->GetState() != StatusView::BUBBLE_HIDDEN && - view_->GetState() != StatusView::BUBBLE_HIDING_FADE && - view_->GetState() != StatusView::BUBBLE_HIDING_TIMER) { - AvoidMouse(location); - } - } -} - -void StatusBubbleViews::UpdateDownloadShelfVisibility(bool visible) { - download_shelf_is_visible_ = visible; -} - -void StatusBubbleViews::AvoidMouse(const gfx::Point& location) { - // Get the position of the frame. - gfx::Point top_left; - views::View::ConvertPointToScreen(base_view_, &top_left); - // Border included. - int window_width = base_view_->GetLocalBounds(true).width(); - - // Get the cursor position relative to the popup. - gfx::Point relative_location = location; - if (base::i18n::IsRTL()) { - int top_right_x = top_left.x() + window_width; - relative_location.set_x(top_right_x - relative_location.x()); - } else { - relative_location.set_x( - relative_location.x() - (top_left.x() + position_.x())); - } - relative_location.set_y( - relative_location.y() - (top_left.y() + position_.y())); - - // If the mouse is in a position where we think it would move the - // status bubble, figure out where and how the bubble should be moved. - if (relative_location.y() > -kMousePadding && - relative_location.x() < size_.width() + kMousePadding) { - int offset = kMousePadding + relative_location.y(); - - // Make the movement non-linear. - offset = offset * offset / kMousePadding; - - // When the mouse is entering from the right, we want the offset to be - // scaled by how horizontally far away the cursor is from the bubble. - if (relative_location.x() > size_.width()) { - offset = static_cast<int>(static_cast<float>(offset) * ( - static_cast<float>(kMousePadding - - (relative_location.x() - size_.width())) / - static_cast<float>(kMousePadding))); - } - - // Cap the offset and change the visual presentation of the bubble - // depending on where it ends up (so that rounded corners square off - // and mate to the edges of the tab content). - if (offset >= size_.height() - kShadowThickness * 2) { - offset = size_.height() - kShadowThickness * 2; - view_->SetStyle(StatusView::STYLE_BOTTOM); - } else if (offset > kBubbleCornerRadius / 2 - kShadowThickness) { - view_->SetStyle(StatusView::STYLE_FLOATING); - } else { - view_->SetStyle(StatusView::STYLE_STANDARD); - } - - // Check if the bubble sticks out from the monitor or will obscure - // download shelf. - gfx::NativeView widget = base_view_->GetWidget()->GetNativeView(); - gfx::Rect monitor_rect = - views::Screen::GetMonitorWorkAreaNearestWindow(widget); - const int bubble_bottom_y = top_left.y() + position_.y() + size_.height(); - - if (bubble_bottom_y + offset > monitor_rect.height() || - (download_shelf_is_visible_ && - (view_->GetStyle() == StatusView::STYLE_FLOATING || - view_->GetStyle() == StatusView::STYLE_BOTTOM))) { - // The offset is still too large. Move the bubble to the right and reset - // Y offset_ to zero. - view_->SetStyle(StatusView::STYLE_STANDARD_RIGHT); - offset_ = 0; - - // Subtract border width + bubble width. - int right_position_x = window_width - (position_.x() + size_.width()); - popup_->SetBounds(gfx::Rect(top_left.x() + right_position_x, - top_left.y() + position_.y(), - size_.width(), size_.height())); - } else { - offset_ = offset; - popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), - top_left.y() + position_.y() + offset_, - size_.width(), size_.height())); - } - } else if (offset_ != 0 || - view_->GetStyle() == StatusView::STYLE_STANDARD_RIGHT) { - offset_ = 0; - view_->SetStyle(StatusView::STYLE_STANDARD); - popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), - top_left.y() + position_.y(), - size_.width(), size_.height())); - } -} - -bool StatusBubbleViews::IsFrameVisible() { - views::Widget* frame = base_view_->GetWidget(); - if (!frame->IsVisible()) - return false; - - views::Window* window = frame->GetWindow(); - return !window || !window->IsMinimized(); -} - -void StatusBubbleViews::ExpandBubble() { - // Elide URL to maximum possible size, then check actual length (it may - // still be too long to fit) before expanding bubble. - gfx::Rect popup_bounds; - popup_->GetBounds(&popup_bounds, true); - int max_status_bubble_width = GetMaxStatusBubbleWidth(); - url_text_ = gfx::ElideUrl(url_, view_->Label::font(), - max_status_bubble_width, UTF16ToWideHack(languages_)); - int expanded_bubble_width =std::max(GetStandardStatusBubbleWidth(), - std::min(view_->Label::font().GetStringWidth(UTF16ToWide(url_text_)) + - (kShadowThickness * 2) + kTextPositionX + - kTextHorizPadding + 1, - max_status_bubble_width)); - is_expanded_ = true; - expand_view_->StartExpansion(url_text_, popup_bounds.width(), - expanded_bubble_width); -} - -int StatusBubbleViews::GetStandardStatusBubbleWidth() { - return base_view_->bounds().width() / 3; -} - -int StatusBubbleViews::GetMaxStatusBubbleWidth() { - return static_cast<int>(std::max(0, base_view_->bounds().width() - - (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1 - - views::NativeScrollBar::GetVerticalScrollBarWidth())); -} - -void StatusBubbleViews::SetBubbleWidth(int width) { - size_.set_width(width); - SetBounds(original_position_.x(), original_position_.y(), - size_.width(), size_.height()); -} - -void StatusBubbleViews::CancelExpandTimer() { - if (!expand_timer_factory_.empty()) - expand_timer_factory_.RevokeAll(); -} diff --git a/chrome/browser/views/status_bubble_views.h b/chrome/browser/views/status_bubble_views.h index 0cd685d..3d10bd4 100644 --- a/chrome/browser/views/status_bubble_views.h +++ b/chrome/browser/views/status_bubble_views.h @@ -6,131 +6,8 @@ #define CHROME_BROWSER_VIEWS_STATUS_BUBBLE_VIEWS_H_ #pragma once -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/string16.h" -#include "base/task.h" -#include "chrome/browser/status_bubble.h" -#include "googleurl/src/gurl.h" -#include "gfx/rect.h" - -class GURL; -namespace gfx { -class Point; -} -namespace views { -class View; -class Widget; -} - -// StatusBubble displays a bubble of text that fades in, hovers over the -// browser chrome and fades away when not needed. It is primarily designed -// to allow users to see where hovered links point to. -class StatusBubbleViews : public StatusBubble { - public: - // How wide the bubble's shadow is. - static const int kShadowThickness; - - // The combined vertical padding above and below the text. - static const int kTotalVerticalPadding = 7; - - // |base_view| is the view that this bubble is positioned relative to. - explicit StatusBubbleViews(views::View* base_view); - ~StatusBubbleViews(); - - views::View* base_view() { return base_view_; } - - // Reposition the bubble - as we are using a WS_POPUP for the bubble, - // we have to manually position it when the browser window moves. - void Reposition(); - - // The bubble only has a preferred height: the sum of the height of - // the font and kTotalVerticalPadding. - gfx::Size GetPreferredSize(); - - // Set the bounds of the bubble relative to |base_view_|. - void SetBounds(int x, int y, int w, int h); - - // Set bubble to new width. - void SetBubbleWidth(int width); - - // Overridden from StatusBubble: - virtual void SetStatus(const string16& status); - virtual void SetURL(const GURL& url, const string16& languages); - virtual void Hide(); - virtual void MouseMoved(const gfx::Point& location, bool left_content); - virtual void UpdateDownloadShelfVisibility(bool visible); - - private: - class StatusView; - class StatusViewExpander; - - // Initializes the popup and view. - void Init(); - - // Attempt to move the status bubble out of the way of the cursor, allowing - // users to see links in the region normally occupied by the status bubble. - void AvoidMouse(const gfx::Point& location); - - // Returns true if the base_view_'s widget is visible and not minimized. - bool IsFrameVisible(); - - // Expand bubble size to accommodate a long URL. - void ExpandBubble(); - - // Cancel all waiting expansion animations in the timer. - void CancelExpandTimer(); - - // Get the standard width for a status bubble in the current frame size. - int GetStandardStatusBubbleWidth(); - - // Get the maximum possible width for a status bubble in the current frame - // size. - int GetMaxStatusBubbleWidth(); - - // The status text we want to display when there are no URLs to display. - string16 status_text_; - - // The url we want to display when there is no status text to display. - string16 url_text_; - - // The original, non-elided URL. - GURL url_; - - // Used to elide the original URL again when we expand it. - string16 languages_; - - // Position relative to the base_view_. - gfx::Point original_position_; - // original_position_ adjusted according to the current RTL. - gfx::Point position_; - gfx::Size size_; - - // How vertically offset the bubble is from its root position_. - int offset_; - - // We use a HWND for the popup so that it may float above any HWNDs in our - // UI (the location bar, for example). - scoped_ptr<views::Widget> popup_; - double opacity_; - - views::View* base_view_; - StatusView* view_; - - // Manages the expansion of a status bubble to fit a long URL. - scoped_ptr<StatusViewExpander> expand_view_; - - // If the download shelf is visible, do not obscure it. - bool download_shelf_is_visible_; - - // If the bubble has already been expanded, and encounters a new URL, - // change size immediately, with no hover. - bool is_expanded_; - - // Times expansion of status bubble when URL is too long for standard width. - ScopedRunnableMethodFactory<StatusBubbleViews> expand_timer_factory_; - - DISALLOW_COPY_AND_ASSIGN(StatusBubbleViews); -}; +#include "chrome/browser/ui/views/status_bubble_views.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_STATUS_BUBBLE_VIEWS_H_ + diff --git a/chrome/browser/views/status_icons/status_icon_win.cc b/chrome/browser/views/status_icons/status_icon_win.cc deleted file mode 100644 index 5545560..0000000 --- a/chrome/browser/views/status_icons/status_icon_win.cc +++ /dev/null @@ -1,89 +0,0 @@ -// 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/status_icons/status_icon_win.h" - -#include "base/sys_string_conversions.h" -#include "gfx/icon_util.h" -#include "gfx/point.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "views/controls/menu/menu_2.h" - -StatusIconWin::StatusIconWin(UINT id, HWND window, UINT message) - : icon_id_(id), - window_(window), - message_id_(message) { - NOTIFYICONDATA icon_data; - InitIconData(&icon_data); - icon_data.uFlags = NIF_MESSAGE; - icon_data.uCallbackMessage = message_id_; - BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data); - DCHECK(result); -} - -StatusIconWin::~StatusIconWin() { - // Remove our icon. - NOTIFYICONDATA icon_data; - InitIconData(&icon_data); - Shell_NotifyIcon(NIM_DELETE, &icon_data); -} - -void StatusIconWin::SetImage(const SkBitmap& image) { - // Create the icon. - NOTIFYICONDATA icon_data; - InitIconData(&icon_data); - icon_data.uFlags = NIF_ICON; - icon_.Set(IconUtil::CreateHICONFromSkBitmap(image)); - icon_data.hIcon = icon_.Get(); - BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); - DCHECK(result); -} - -void StatusIconWin::SetPressedImage(const SkBitmap& image) { - // Ignore pressed images, since the standard on Windows is to not highlight - // pressed status icons. -} - -void StatusIconWin::SetToolTip(const string16& tool_tip) { - // Create the icon. - NOTIFYICONDATA icon_data; - InitIconData(&icon_data); - icon_data.uFlags = NIF_TIP; - wcscpy_s(icon_data.szTip, tool_tip.c_str()); - BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); - DCHECK(result); -} - -void StatusIconWin::InitIconData(NOTIFYICONDATA* icon_data) { - icon_data->cbSize = sizeof(icon_data); - icon_data->hWnd = window_; - icon_data->uID = icon_id_; -} - -void StatusIconWin::UpdatePlatformContextMenu(menus::MenuModel* menu) { - // If no items are passed, blow away our context menu. - if (!menu) { - context_menu_.reset(); - return; - } - - // Create context menu with the new contents. - context_menu_.reset(new views::Menu2(menu)); -} - -void StatusIconWin::HandleClickEvent(int x, int y, bool left_mouse_click) { - // Pass to the observer if appropriate. - if (left_mouse_click && HasObservers()) { - DispatchClickEvent(); - return; - } - - // Event not sent to the observer, so display the context menu if one exists. - if (context_menu_.get()) { - // Set our window as the foreground window, so the context menu closes when - // we click away from it. - SetForegroundWindow(window_); - context_menu_->RunContextMenuAt(gfx::Point(x, y)); - } -} diff --git a/chrome/browser/views/status_icons/status_icon_win.h b/chrome/browser/views/status_icons/status_icon_win.h index 08545ac..1f7ce62 100644 --- a/chrome/browser/views/status_icons/status_icon_win.h +++ b/chrome/browser/views/status_icons/status_icon_win.h @@ -6,60 +6,8 @@ #define CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_ #pragma once -#include <windows.h> -#include <shellapi.h> - -#include "base/scoped_handle_win.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/status_icons/status_icon.h" - -namespace views { -class Menu2; -} - -class StatusIconWin : public StatusIcon { - public: - // Constructor which provides this icon's unique ID and messaging window. - StatusIconWin(UINT id, HWND window, UINT message); - virtual ~StatusIconWin(); - - // Overridden from StatusIcon: - virtual void SetImage(const SkBitmap& image); - virtual void SetPressedImage(const SkBitmap& image); - virtual void SetToolTip(const string16& tool_tip); - - UINT icon_id() const { return icon_id_; } - - UINT message_id() const { return message_id_; } - - // Handles a click event from the user - if |left_button_click| is true and - // there is a registered observer, passes the click event to the observer, - // otherwise displays the context menu if there is one. - void HandleClickEvent(int x, int y, bool left_button_click); - - protected: - // Overridden from StatusIcon. - virtual void UpdatePlatformContextMenu(menus::MenuModel* menu); - - private: - void InitIconData(NOTIFYICONDATA* icon_data); - - // The unique ID corresponding to this icon. - UINT icon_id_; - - // Window used for processing messages from this icon. - HWND window_; - - // The message identifier used for status icon messages. - UINT message_id_; - - // The currently-displayed icon for the window. - ScopedHICON icon_; - - // Context menu associated with this icon (if any). - scoped_ptr<views::Menu2> context_menu_; - - DISALLOW_COPY_AND_ASSIGN(StatusIconWin); -}; +#include "chrome/browser/ui/views/status_icons/status_icon_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_ + diff --git a/chrome/browser/views/status_icons/status_tray_gtk.cc b/chrome/browser/views/status_icons/status_tray_gtk.cc deleted file mode 100644 index 7cd0666..0000000 --- a/chrome/browser/views/status_icons/status_tray_gtk.cc +++ /dev/null @@ -1,10 +0,0 @@ -// 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/status_icons/status_tray.h" - -// Status icons are not currently supported on linux/views. -StatusTray* StatusTray::Create() { - return NULL; -} diff --git a/chrome/browser/views/status_icons/status_tray_win.cc b/chrome/browser/views/status_icons/status_tray_win.cc deleted file mode 100644 index 29ed025..0000000 --- a/chrome/browser/views/status_icons/status_tray_win.cc +++ /dev/null @@ -1,81 +0,0 @@ -// 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/status_icons/status_tray_win.h" - -#include "base/win_util.h" -#include "chrome/browser/views/status_icons/status_icon_win.h" -#include "chrome/common/chrome_constants.h" - -static const UINT kStatusIconMessage = WM_APP + 1; - -StatusTrayWin::StatusTrayWin() - : next_icon_id_(1) { - // Register our window class - HINSTANCE hinst = GetModuleHandle(NULL); - WNDCLASSEX wc = {0}; - wc.cbSize = sizeof(wc); - wc.lpfnWndProc = StatusTrayWin::WndProcStatic; - wc.hInstance = hinst; - wc.lpszClassName = chrome::kStatusTrayWindowClass; - ATOM clazz = RegisterClassEx(&wc); - DCHECK(clazz); - - // Create an offscreen window for handling messages for the status icons. - window_ = CreateWindow(chrome::kStatusTrayWindowClass, - 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0); - win_util::SetWindowUserData(window_, this); -} - -LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam) { - StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>( - GetWindowLongPtr(hwnd, GWLP_USERDATA)); - return msg_wnd->WndProc(hwnd, message, wparam, lparam); -} - -LRESULT CALLBACK StatusTrayWin::WndProc(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam) { - switch (message) { - case kStatusIconMessage: - switch (lparam) { - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_CONTEXTMENU: - // Walk our icons, find which one was clicked on, and invoke its - // HandleClickEvent() method. - for (StatusIconList::const_iterator iter = status_icons().begin(); - iter != status_icons().end(); - ++iter) { - StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter); - if (win_icon->icon_id() == wparam) { - POINT p; - GetCursorPos(&p); - win_icon->HandleClickEvent(p.x, p.y, lparam == WM_LBUTTONDOWN); - } - } - return TRUE; - } - break; - } - return ::DefWindowProc(hwnd, message, wparam, lparam); -} - -StatusTrayWin::~StatusTrayWin() { - if (window_) - DestroyWindow(window_); - UnregisterClass(chrome::kStatusTrayWindowClass, GetModuleHandle(NULL)); -} - -StatusIcon* StatusTrayWin::CreatePlatformStatusIcon() { - return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage); -} - -StatusTray* StatusTray::Create() { - return new StatusTrayWin(); -} diff --git a/chrome/browser/views/status_icons/status_tray_win.h b/chrome/browser/views/status_icons/status_tray_win.h index a2e322c..7d7f301 100644 --- a/chrome/browser/views/status_icons/status_tray_win.h +++ b/chrome/browser/views/status_icons/status_tray_win.h @@ -6,38 +6,8 @@ #define CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_ #pragma once -#include <windows.h> - -#include "chrome/browser/status_icons/status_tray.h" - -class StatusTrayWin : public StatusTray { - public: - StatusTrayWin(); - ~StatusTrayWin(); - - // Exposed for testing. - LRESULT CALLBACK WndProc(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam); - protected: - // Overriden from StatusTray: - virtual StatusIcon* CreatePlatformStatusIcon(); - - private: - // Static callback invoked when a message comes in to our messaging window. - static LRESULT CALLBACK WndProcStatic(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam); - - // The unique icon ID we will assign to the next icon. - UINT next_icon_id_; - // The window used for processing events. - HWND window_; - - DISALLOW_COPY_AND_ASSIGN(StatusTrayWin); -}; +#include "chrome/browser/ui/views/status_icons/status_tray_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_ diff --git a/chrome/browser/views/status_icons/status_tray_win_unittest.cc b/chrome/browser/views/status_icons/status_tray_win_unittest.cc deleted file mode 100644 index c824755..0000000 --- a/chrome/browser/views/status_icons/status_tray_win_unittest.cc +++ /dev/null @@ -1,55 +0,0 @@ -// 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 "app/menus/simple_menu_model.h" -#include "app/resource_bundle.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/views/status_icons/status_icon_win.h" -#include "chrome/browser/views/status_icons/status_tray_win.h" -#include "grit/browser_resources.h" -#include "grit/theme_resources.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -class SkBitmap; - -class MockStatusIconObserver : public StatusIcon::Observer { - public: - MOCK_METHOD0(OnClicked, void()); -}; - -TEST(StatusTrayWinTest, CreateTray) { - // Just tests creation/destruction. - StatusTrayWin tray; -} - -TEST(StatusTrayWinTest, CreateIconAndMenu) { - // Create an icon, set the images, tooltip, and context menu, then shut it - // down. - StatusTrayWin tray; - StatusIcon* icon = tray.CreateStatusIcon(); - SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_STATUS_TRAY_ICON); - icon->SetImage(*bitmap); - icon->SetPressedImage(*bitmap); - icon->SetToolTip(ASCIIToUTF16("tool tip")); - menus::SimpleMenuModel* menu = new menus::SimpleMenuModel(NULL); - menu->AddItem(0, L"foo"); - icon->SetContextMenu(menu); -} - -TEST(StatusTrayWinTest, ClickOnIcon) { - // Create an icon, send a fake click event, make sure observer is called. - StatusTrayWin tray; - StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon()); - MockStatusIconObserver observer; - icon->AddObserver(&observer); - EXPECT_CALL(observer, OnClicked()); - // Mimic a click. - tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_LBUTTONDOWN); - // Mimic a right-click - observer should not be called. - tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_RBUTTONDOWN); - icon->RemoveObserver(&observer); -} diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container.h b/chrome/browser/views/tab_contents/native_tab_contents_container.h index 51e08af..7f2cdfc 100644 --- a/chrome/browser/views/tab_contents/native_tab_contents_container.h +++ b/chrome/browser/views/tab_contents/native_tab_contents_container.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,43 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_H_ #pragma once -class RenderViewHost; -class TabContents; -class TabContentsContainer; -namespace views { -class View; -} - -// An interface that the TabContentsContainer uses to talk to a platform- -// specific view that hosts the native handle of the TabContents' view. -class NativeTabContentsContainer { - public: - // Creates an appropriate native container for the current platform. - static NativeTabContentsContainer* CreateNativeContainer( - TabContentsContainer* container); - - // Attaches the new TabContents to the native container. - virtual void AttachContents(TabContents* contents) = 0; - - // Detaches the old TabContents from the native container. - virtual void DetachContents(TabContents* contents) = 0; - - // Tells the container to update less frequently during resizing operations - // so performance is better. - virtual void SetFastResize(bool fast_resize) = 0; - - // Tells the container that the RenderViewHost for the attached TabContents - // has changed and it should update focus. - virtual void RenderViewHostChanged(RenderViewHost* old_host, - RenderViewHost* new_host) = 0; - - // Tells the container that |tab_contents| got the focus. - virtual void TabContentsFocused(TabContents* tab_contents) = 0; - - // Retrieves the views::View that hosts the TabContents. - virtual views::View* GetView() = 0; - protected: - virtual ~NativeTabContentsContainer() {} -}; +#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_H_ + diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc deleted file mode 100644 index 0c07fa7..0000000 --- a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 2009 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/tab_contents/native_tab_contents_container_gtk.h" - -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/tab_contents/interstitial_page.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/tab_contents/tab_contents_container.h" -#include "views/focus/focus_manager.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainerGtk, public: - -NativeTabContentsContainerGtk::NativeTabContentsContainerGtk( - TabContentsContainer* container) - : container_(container), - focus_callback_id_(0) { - SetID(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); -} - -NativeTabContentsContainerGtk::~NativeTabContentsContainerGtk() { -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainerGtk, NativeTabContentsContainer overrides: - -void NativeTabContentsContainerGtk::AttachContents(TabContents* contents) { - Attach(contents->GetNativeView()); -} - -void NativeTabContentsContainerGtk::DetachContents(TabContents* contents) { - gtk_widget_hide(contents->GetNativeView()); - - // Now detach the TabContents. - Detach(); -} - -void NativeTabContentsContainerGtk::SetFastResize(bool fast_resize) { - set_fast_resize(fast_resize); -} - -void NativeTabContentsContainerGtk::RenderViewHostChanged( - RenderViewHost* old_host, - RenderViewHost* new_host) { - // If we are focused, we need to pass the focus to the new RenderViewHost. - views::FocusManager* focus_manager = GetFocusManager(); - if (focus_manager->GetFocusedView() == this) - Focus(); -} - -views::View* NativeTabContentsContainerGtk::GetView() { - return this; -} - -void NativeTabContentsContainerGtk::TabContentsFocused( - TabContents* tab_contents) { -#if !defined(TOUCH_UI) - // Called when the tab contents native view gets focused (typically through a - // user click). We make ourself the focused view, so the focus is restored - // properly when the browser window is deactivated/reactivated. - views::FocusManager* focus_manager = GetFocusManager(); - if (!focus_manager) { - NOTREACHED(); - return; - } - focus_manager->SetFocusedView(this); -#else - // no native views in TOUCH_UI, so don't steal the focus -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainerGtk, views::View overrides: - -bool NativeTabContentsContainerGtk::SkipDefaultKeyEventProcessing( - const views::KeyEvent& e) { - // Don't look-up accelerators or tab-traverse if we are showing a non-crashed - // TabContents. - // We'll first give the page a chance to process the key events. If it does - // not process them, they'll be returned to us and we'll treat them as - // accelerators then. - return container_->tab_contents() && - !container_->tab_contents()->is_crashed(); -} - -views::FocusTraversable* NativeTabContentsContainerGtk::GetFocusTraversable() { - return NULL; -} - -bool NativeTabContentsContainerGtk::IsFocusable() const { - // We need to be focusable when our contents is not a view hierarchy, as - // clicking on the contents needs to focus us. - return container_->tab_contents() != NULL; -} - -void NativeTabContentsContainerGtk::Focus() { - if (container_->tab_contents()) { - // Set the native focus on the actual content of the tab, that is the - // interstitial if one is showing. - if (container_->tab_contents()->interstitial_page()) { - container_->tab_contents()->interstitial_page()->Focus(); - return; - } - GtkWidget* widget = container_->tab_contents()->GetContentNativeView(); - if (widget) - gtk_widget_grab_focus(widget); - } -} - -void NativeTabContentsContainerGtk::RequestFocus() { - // This is a hack to circumvent the fact that a view does not explicitly get - // a call to set the focus if it already has the focus. This causes a problem - // with tabs such as the TabContents that instruct the RenderView that it got - // focus when they actually get the focus. When switching from one TabContents - // tab that has focus to another TabContents tab that had focus, since the - // TabContentsContainerView already has focus, Focus() would not be called and - // the RenderView would not get notified it got focused. - // By clearing the focused view before-hand, we ensure Focus() will be called. - GetRootView()->FocusView(NULL); - View::RequestFocus(); -} - -void NativeTabContentsContainerGtk::AboutToRequestFocusFromTabTraversal( - bool reverse) { - if (!container_->tab_contents()) - return; - // Give an opportunity to the tab to reset its focus. - if (container_->tab_contents()->interstitial_page()) { - container_->tab_contents()->interstitial_page()->FocusThroughTabTraversal( - reverse); - return; - } - container_->tab_contents()->FocusThroughTabTraversal(reverse); -} - -AccessibilityTypes::Role NativeTabContentsContainerGtk::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainer, public: - -// static -NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer( - TabContentsContainer* container) { - return new NativeTabContentsContainerGtk(container); -} diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h index 7de9e26..cab3c2b 100644 --- a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h +++ b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,41 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_GTK_H_ #pragma once -#include <gtk/gtk.h> - -#include "chrome/browser/views/tab_contents/native_tab_contents_container.h" -#include "views/controls/native/native_view_host.h" - -class NativeTabContentsContainerGtk : public NativeTabContentsContainer, - public views::NativeViewHost { - public: - explicit NativeTabContentsContainerGtk(TabContentsContainer* container); - virtual ~NativeTabContentsContainerGtk(); - - // Overridden from NativeTabContentsContainer: - virtual void AttachContents(TabContents* contents); - virtual void DetachContents(TabContents* contents); - virtual void SetFastResize(bool fast_resize); - virtual void RenderViewHostChanged(RenderViewHost* old_host, - RenderViewHost* new_host); - virtual void TabContentsFocused(TabContents* tab_contents); - virtual views::View* GetView(); - - // Overridden from views::View: - virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e); - virtual views::FocusTraversable* GetFocusTraversable(); - virtual bool IsFocusable() const; - virtual void Focus(); - virtual void RequestFocus(); - virtual void AboutToRequestFocusFromTabTraversal(bool reverse); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - private: - TabContentsContainer* container_; - - gulong focus_callback_id_; - - DISALLOW_COPY_AND_ASSIGN(NativeTabContentsContainerGtk); -}; +#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_GTK_H_ + diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc b/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc deleted file mode 100644 index eba411f..0000000 --- a/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2009 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/tab_contents/native_tab_contents_container_win.h" - -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/tab_contents/interstitial_page.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/tab_contents/tab_contents_container.h" -#include "chrome/browser/views/tab_contents/tab_contents_view_win.h" - -#include "views/focus/focus_manager.h" - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainerWin, public: - -NativeTabContentsContainerWin::NativeTabContentsContainerWin( - TabContentsContainer* container) - : container_(container) { - SetID(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); -} - -NativeTabContentsContainerWin::~NativeTabContentsContainerWin() { -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainerWin, NativeTabContentsContainer overrides: - -void NativeTabContentsContainerWin::AttachContents(TabContents* contents) { - // We need to register the tab contents window with the BrowserContainer so - // that the BrowserContainer is the focused view when the focus is on the - // TabContents window (for the TabContents case). - set_focus_view(this); - - Attach(contents->GetNativeView()); -} - -void NativeTabContentsContainerWin::DetachContents(TabContents* contents) { - // TODO(brettw) should this move to NativeViewHost::Detach which is called - // below? - // It needs cleanup regardless. - HWND container_hwnd = contents->GetNativeView(); - if (container_hwnd) { - // Hide the contents before adjusting its parent to avoid a full desktop - // flicker. - ShowWindow(container_hwnd, SW_HIDE); - - // Reset the parent to NULL to ensure hidden tabs don't receive messages. - static_cast<TabContentsViewWin*>(contents->view())->Unparent(); - } - - // Now detach the TabContents. - Detach(); -} - -void NativeTabContentsContainerWin::SetFastResize(bool fast_resize) { - set_fast_resize(fast_resize); -} - -void NativeTabContentsContainerWin::RenderViewHostChanged( - RenderViewHost* old_host, - RenderViewHost* new_host) { - // If we are focused, we need to pass the focus to the new RenderViewHost. - if (GetFocusManager()->GetFocusedView() == this) - Focus(); -} - -views::View* NativeTabContentsContainerWin::GetView() { - return this; -} - -void NativeTabContentsContainerWin::TabContentsFocused( - TabContents* tab_contents) { - views::FocusManager* focus_manager = GetFocusManager(); - if (!focus_manager) { - NOTREACHED(); - return; - } - focus_manager->SetFocusedView(this); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainerWin, views::View overrides: - -bool NativeTabContentsContainerWin::SkipDefaultKeyEventProcessing( - const views::KeyEvent& e) { - // Don't look-up accelerators or tab-traversal if we are showing a non-crashed - // TabContents. - // We'll first give the page a chance to process the key events. If it does - // not process them, they'll be returned to us and we'll treat them as - // accelerators then. - return container_->tab_contents() && - !container_->tab_contents()->is_crashed(); -} - -bool NativeTabContentsContainerWin::IsFocusable() const { - // We need to be focusable when our contents is not a view hierarchy, as - // clicking on the contents needs to focus us. - return container_->tab_contents() != NULL; -} - -void NativeTabContentsContainerWin::Focus() { - if (container_->tab_contents()) - container_->tab_contents()->Focus(); -} - -void NativeTabContentsContainerWin::RequestFocus() { - // This is a hack to circumvent the fact that a the Focus() method is not - // invoked when RequestFocus() is called on an already focused view. - // The TabContentsContainer is the view focused when the TabContents has - // focus. When switching between from one tab that has focus to another tab - // that should also have focus, RequestFocus() is invoked one the - // TabContentsContainer. In order to make sure Focus() is invoked we need to - // clear the focus before hands. - { - // Disable notifications. Clear focus will assign the focus to the main - // browser window. Because this change of focus was not user requested, - // don't send it to listeners. - views::AutoNativeNotificationDisabler local_notification_disabler; - GetFocusManager()->ClearFocus(); - } - View::RequestFocus(); -} - -void NativeTabContentsContainerWin::AboutToRequestFocusFromTabTraversal( - bool reverse) { - container_->tab_contents()->FocusThroughTabTraversal(reverse); -} - -AccessibilityTypes::Role NativeTabContentsContainerWin::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeTabContentsContainer, public: - -// static -NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer( - TabContentsContainer* container) { - return new NativeTabContentsContainerWin(container); -} diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_win.h b/chrome/browser/views/tab_contents/native_tab_contents_container_win.h index 916ce0f..5418181 100644 --- a/chrome/browser/views/tab_contents/native_tab_contents_container_win.h +++ b/chrome/browser/views/tab_contents/native_tab_contents_container_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,36 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_WIN_H_ #pragma once -#include "chrome/browser/views/tab_contents/native_tab_contents_container.h" -#include "views/controls/native/native_view_host.h" - -class NativeTabContentsContainerWin : public NativeTabContentsContainer, - public views::NativeViewHost { - public: - explicit NativeTabContentsContainerWin(TabContentsContainer* container); - virtual ~NativeTabContentsContainerWin(); - - // Overridden from NativeTabContentsContainer: - virtual void AttachContents(TabContents* contents); - virtual void DetachContents(TabContents* contents); - virtual void SetFastResize(bool fast_resize); - virtual void RenderViewHostChanged(RenderViewHost* old_host, - RenderViewHost* new_host); - virtual void TabContentsFocused(TabContents* tab_contents); - virtual views::View* GetView(); - - // Overridden from views::View: - virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e); - virtual bool IsFocusable() const; - virtual void Focus(); - virtual void RequestFocus(); - virtual void AboutToRequestFocusFromTabTraversal(bool reverse); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - private: - TabContentsContainer* container_; - - DISALLOW_COPY_AND_ASSIGN(NativeTabContentsContainerWin); -}; +#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_WIN_H_ + diff --git a/chrome/browser/views/tab_contents/render_view_context_menu_views.cc b/chrome/browser/views/tab_contents/render_view_context_menu_views.cc deleted file mode 100644 index e7ac1a6..0000000 --- a/chrome/browser/views/tab_contents/render_view_context_menu_views.cc +++ /dev/null @@ -1,98 +0,0 @@ -// 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/tab_contents/render_view_context_menu_views.h" - -#include "app/keyboard_codes.h" -#include "base/compiler_specific.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/profile.h" -#include "grit/generated_resources.h" -#include "views/accelerator.h" -#include "views/controls/menu/menu_2.h" - -//////////////////////////////////////////////////////////////////////////////// -// RenderViewContextMenuViews, public: - -RenderViewContextMenuViews::RenderViewContextMenuViews( - TabContents* tab_contents, - const ContextMenuParams& params) - : RenderViewContextMenu(tab_contents, params) { -} - -RenderViewContextMenuViews::~RenderViewContextMenuViews() { -} - -void RenderViewContextMenuViews::RunMenuAt(int x, int y) { - menu_->RunContextMenuAt(gfx::Point(x, y)); -} - -#if defined(OS_WIN) -void RenderViewContextMenuViews::SetExternal() { - external_ = true; -} -#endif - -void RenderViewContextMenuViews::UpdateMenuItemStates() { - menu_->UpdateStates(); -} - -//////////////////////////////////////////////////////////////////////////////// -// RenderViewContextMenuViews, protected: - -void RenderViewContextMenuViews::PlatformInit() { - menu_.reset(new views::Menu2(&menu_model_)); - -#if defined(OS_WIN) - if (external_) { - // The external tab container needs to be notified by command - // and not by index. So we are turning off the MNS_NOTIFYBYPOS - // style. - HMENU menu = GetMenuHandle(); - DCHECK(menu != NULL); - - MENUINFO mi = {0}; - mi.cbSize = sizeof(mi); - mi.fMask = MIM_STYLE | MIM_MENUDATA; - mi.dwMenuData = reinterpret_cast<ULONG_PTR>(this); - SetMenuInfo(menu, &mi); - } -#endif -} - -bool RenderViewContextMenuViews::GetAcceleratorForCommandId( - int command_id, - menus::Accelerator* accel) { - // There are no formally defined accelerators we can query so we assume - // that Ctrl+C, Ctrl+V, Ctrl+X, Ctrl-A, etc do what they normally do. - switch (command_id) { - case IDC_CONTENT_CONTEXT_UNDO: - *accel = views::Accelerator(app::VKEY_Z, false, true, false); - return true; - - case IDC_CONTENT_CONTEXT_REDO: - // TODO(jcampan): should it be Ctrl-Y? - *accel = views::Accelerator(app::VKEY_Z, true, true, false); - return true; - - case IDC_CONTENT_CONTEXT_CUT: - *accel = views::Accelerator(app::VKEY_X, false, true, false); - return true; - - case IDC_CONTENT_CONTEXT_COPY: - *accel = views::Accelerator(app::VKEY_C, false, true, false); - return true; - - case IDC_CONTENT_CONTEXT_PASTE: - *accel = views::Accelerator(app::VKEY_V, false, true, false); - return true; - - case IDC_CONTENT_CONTEXT_SELECTALL: - *accel = views::Accelerator(app::VKEY_A, false, true, false); - return true; - - default: - return false; - } -} diff --git a/chrome/browser/views/tab_contents/render_view_context_menu_views.h b/chrome/browser/views/tab_contents/render_view_context_menu_views.h index 048dfa9..98e610d 100644 --- a/chrome/browser/views/tab_contents/render_view_context_menu_views.h +++ b/chrome/browser/views/tab_contents/render_view_context_menu_views.h @@ -6,42 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_VIEWS_H_ #pragma once -#include "base/scoped_ptr.h" -#include "base/scoped_vector.h" -#include "chrome/browser/tab_contents/render_view_context_menu.h" -#include "views/controls/menu/menu_2.h" - -class RenderViewContextMenuViews : public RenderViewContextMenu { - public: - RenderViewContextMenuViews(TabContents* tab_contents, - const ContextMenuParams& params); - - virtual ~RenderViewContextMenuViews(); - - void RunMenuAt(int x, int y); - - gfx::NativeMenu GetMenuHandle() const { - return (menu_.get() ? menu_->GetNativeMenu() : NULL); - } - -#if defined(OS_WIN) - // Set this menu to show for an external tab contents. This - // only has an effect before Init() is called. - void SetExternal(); -#endif - - void UpdateMenuItemStates(); - - protected: - // RenderViewContextMenu implementation -------------------------------------- - virtual void PlatformInit(); - virtual bool GetAcceleratorForCommandId(int command_id, - menus::Accelerator* accelerator); - private: - // The context menu itself and its contents. - scoped_ptr<views::Menu2> menu_; - - DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenuViews); -}; +#include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_VIEWS_H_ + diff --git a/chrome/browser/views/tab_contents/tab_contents_container.cc b/chrome/browser/views/tab_contents/tab_contents_container.cc deleted file mode 100644 index a75743d..0000000 --- a/chrome/browser/views/tab_contents/tab_contents_container.cc +++ /dev/null @@ -1,121 +0,0 @@ -// 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/tab_contents/tab_contents_container.h" - -#include "chrome/browser/tab_contents/interstitial_page.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/tab_contents/native_tab_contents_container.h" -#include "chrome/common/notification_service.h" - -//////////////////////////////////////////////////////////////////////////////// -// TabContentsContainer, public: - -TabContentsContainer::TabContentsContainer() - : native_container_(NULL), - tab_contents_(NULL) { - SetID(VIEW_ID_TAB_CONTAINER); -} - -TabContentsContainer::~TabContentsContainer() { - if (tab_contents_) - RemoveObservers(); -} - -void TabContentsContainer::ChangeTabContents(TabContents* contents) { - if (tab_contents_) { - native_container_->DetachContents(tab_contents_); - tab_contents_->WasHidden(); - RemoveObservers(); - } - tab_contents_ = contents; - // When detaching the last tab of the browser ChangeTabContents is invoked - // with NULL. Don't attempt to do anything in that case. - if (tab_contents_) { - native_container_->AttachContents(tab_contents_); - AddObservers(); - } -} - -void TabContentsContainer::TabContentsFocused(TabContents* tab_contents) { - native_container_->TabContentsFocused(tab_contents); -} - -void TabContentsContainer::SetFastResize(bool fast_resize) { - native_container_->SetFastResize(fast_resize); -} - -//////////////////////////////////////////////////////////////////////////////// -// TabContentsContainer, NotificationObserver implementation: - -void TabContentsContainer::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) { - RenderViewHostSwitchedDetails* switched_details = - Details<RenderViewHostSwitchedDetails>(details).ptr(); - RenderViewHostChanged(switched_details->old_host, - switched_details->new_host); - } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) { - TabContentsDestroyed(Source<TabContents>(source).ptr()); - } else { - NOTREACHED(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// TabContentsContainer, View overrides: - -void TabContentsContainer::Layout() { - if (native_container_) { - native_container_->GetView()->SetBounds(0, 0, width(), height()); - native_container_->GetView()->Layout(); - } -} - -AccessibilityTypes::Role TabContentsContainer::GetAccessibleRole() { - return AccessibilityTypes::ROLE_WINDOW; -} - -void TabContentsContainer::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) { - native_container_ = NativeTabContentsContainer::CreateNativeContainer(this); - AddChildView(native_container_->GetView()); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// TabContentsContainer, private: - -void TabContentsContainer::AddObservers() { - // TabContents can change their RenderViewHost and hence the HWND that is - // shown and getting focused. We need to keep track of that so we install - // the focus subclass on the shown HWND so we intercept focus change events. - registrar_.Add(this, - NotificationType::RENDER_VIEW_HOST_CHANGED, - Source<NavigationController>(&tab_contents_->controller())); - - registrar_.Add(this, - NotificationType::TAB_CONTENTS_DESTROYED, - Source<TabContents>(tab_contents_)); -} - -void TabContentsContainer::RemoveObservers() { - registrar_.RemoveAll(); -} - -void TabContentsContainer::RenderViewHostChanged(RenderViewHost* old_host, - RenderViewHost* new_host) { - native_container_->RenderViewHostChanged(old_host, new_host); -} - -void TabContentsContainer::TabContentsDestroyed(TabContents* contents) { - // Sometimes, a TabContents is destroyed before we know about it. This allows - // us to clean up our state in case this happens. - DCHECK(contents == tab_contents_); - ChangeTabContents(NULL); -} diff --git a/chrome/browser/views/tab_contents/tab_contents_container.h b/chrome/browser/views/tab_contents/tab_contents_container.h index c5c2f1f..9039060 100644 --- a/chrome/browser/views/tab_contents/tab_contents_container.h +++ b/chrome/browser/views/tab_contents/tab_contents_container.h @@ -6,76 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_CONTAINER_H_ #pragma once -#include "chrome/browser/views/tab_contents/native_tab_contents_container.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "views/view.h" - -class NativeTabContentsContainer; -class RenderViewHost; -class TabContents; - -class TabContentsContainer : public views::View, - public NotificationObserver { - public: - TabContentsContainer(); - virtual ~TabContentsContainer(); - - // Changes the TabContents associated with this view. - void ChangeTabContents(TabContents* contents); - - View* GetFocusView() { return native_container_->GetView(); } - - // Accessor for |tab_contents_|. - TabContents* tab_contents() const { return tab_contents_; } - - // Called by the BrowserView to notify that |tab_contents| got the focus. - void TabContentsFocused(TabContents* tab_contents); - - // Tells the container to update less frequently during resizing operations - // so performance is better. - void SetFastResize(bool fast_resize); - - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Overridden from views::View: - virtual void Layout(); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - protected: - // Overridden from views::View: - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - private: - // Add or remove observers for events that we care about. - void AddObservers(); - void RemoveObservers(); - - // Called when the RenderViewHost of the hosted TabContents has changed, e.g. - // to show an interstitial page. - void RenderViewHostChanged(RenderViewHost* old_host, - RenderViewHost* new_host); - - // Called when a TabContents is destroyed. This gives us a chance to clean - // up our internal state if the TabContents is somehow destroyed before we - // get notified. - void TabContentsDestroyed(TabContents* contents); - - // An instance of a NativeTabContentsContainer object that holds the native - // view handle associated with the attached TabContents. - NativeTabContentsContainer* native_container_; - - // The attached TabContents. - TabContents* tab_contents_; - - // Handles registering for our notifications. - NotificationRegistrar registrar_; - - DISALLOW_COPY_AND_ASSIGN(TabContentsContainer); -}; +#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_CONTAINER_H_ + diff --git a/chrome/browser/views/tab_contents/tab_contents_drag_win.cc b/chrome/browser/views/tab_contents/tab_contents_drag_win.cc deleted file mode 100644 index 51d8f3a..0000000 --- a/chrome/browser/views/tab_contents/tab_contents_drag_win.cc +++ /dev/null @@ -1,367 +0,0 @@ -// 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/tab_contents/tab_contents_drag_win.h" - -#include <windows.h> - -#include <string> - -#include "base/file_path.h" -#include "base/message_loop.h" -#include "base/task.h" -#include "base/thread.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_drag_data.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/download/download_util.h" -#include "chrome/browser/download/drag_download_file.h" -#include "chrome/browser/download/drag_download_util.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/web_drag_source_win.h" -#include "chrome/browser/tab_contents/web_drag_utils_win.h" -#include "chrome/browser/tab_contents/web_drop_target_win.h" -#include "chrome/browser/views/tab_contents/tab_contents_view_win.h" -#include "chrome/common/url_constants.h" -#include "net/base/net_util.h" -#include "views/drag_utils.h" -#include "webkit/glue/webdropdata.h" - -using WebKit::WebDragOperationsMask; -using WebKit::WebDragOperationCopy; -using WebKit::WebDragOperationLink; -using WebKit::WebDragOperationMove; - -namespace { - -HHOOK msg_hook = NULL; -DWORD drag_out_thread_id = 0; -bool mouse_up_received = false; - -LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { - if (code == base::MessagePumpForUI::kMessageFilterCode && - !mouse_up_received) { - MSG* msg = reinterpret_cast<MSG*>(lparam); - // We do not care about WM_SYSKEYDOWN and WM_SYSKEYUP because when ALT key - // is pressed down on drag-and-drop, it means to create a link. - if (msg->message == WM_MOUSEMOVE || msg->message == WM_LBUTTONUP || - msg->message == WM_KEYDOWN || msg->message == WM_KEYUP) { - // Forward the message from the UI thread to the drag-and-drop thread. - PostThreadMessage(drag_out_thread_id, - msg->message, - msg->wParam, - msg->lParam); - - // If the left button is up, we do not need to forward the message any - // more. - if (msg->message == WM_LBUTTONUP || !(GetKeyState(VK_LBUTTON) & 0x8000)) - mouse_up_received = true; - - return TRUE; - } - } - return CallNextHookEx(msg_hook, code, wparam, lparam); -} - -} // namespace - -class DragDropThread : public base::Thread { - public: - explicit DragDropThread(TabContentsDragWin* drag_handler) - : base::Thread("Chrome_DragDropThread"), - drag_handler_(drag_handler) { - } - - virtual ~DragDropThread() { - Thread::Stop(); - } - - protected: - // base::Thread implementations: - virtual void Init() { - int ole_result = OleInitialize(NULL); - DCHECK(ole_result == S_OK); - } - - virtual void CleanUp() { - OleUninitialize(); - } - - private: - // Hold a reference count to TabContentsDragWin to make sure that it is always - // alive in the thread lifetime. - scoped_refptr<TabContentsDragWin> drag_handler_; - - DISALLOW_COPY_AND_ASSIGN(DragDropThread); -}; - -TabContentsDragWin::TabContentsDragWin(TabContentsViewWin* view) - : drag_drop_thread_id_(0), - view_(view), - drag_ended_(false), - old_drop_target_suspended_state_(false) { -} - -TabContentsDragWin::~TabContentsDragWin() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!drag_drop_thread_.get()); -} - -void TabContentsDragWin::StartDragging(const WebDropData& drop_data, - WebDragOperationsMask ops, - const SkBitmap& image, - const gfx::Point& image_offset) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - drag_source_ = new WebDragSource(view_->GetNativeView(), - view_->tab_contents()); - - const GURL& page_url = view_->tab_contents()->GetURL(); - const std::string& page_encoding = view_->tab_contents()->encoding(); - - // If it is not drag-out, do the drag-and-drop in the current UI thread. - if (drop_data.download_metadata.empty()) { - DoDragging(drop_data, ops, page_url, page_encoding, image, image_offset); - EndDragging(false); - return; - } - - // We do not want to drag and drop the download to itself. - old_drop_target_suspended_state_ = view_->drop_target()->suspended(); - view_->drop_target()->set_suspended(true); - - // Start a background thread to do the drag-and-drop. - DCHECK(!drag_drop_thread_.get()); - drag_drop_thread_.reset(new DragDropThread(this)); - base::Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_UI; - if (drag_drop_thread_->StartWithOptions(options)) { - drag_drop_thread_->message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &TabContentsDragWin::StartBackgroundDragging, - drop_data, - ops, - page_url, - page_encoding, - image, - image_offset)); - } - - // Install a hook procedure to monitor the messages so that we can forward - // the appropriate ones to the background thread. - drag_out_thread_id = drag_drop_thread_->thread_id(); - mouse_up_received = false; - DCHECK(!msg_hook); - msg_hook = SetWindowsHookEx(WH_MSGFILTER, - MsgFilterProc, - NULL, - GetCurrentThreadId()); - - // Attach the input state of the background thread to the UI thread so that - // SetCursor can work from the background thread. - AttachThreadInput(drag_out_thread_id, GetCurrentThreadId(), TRUE); -} - -void TabContentsDragWin::StartBackgroundDragging( - const WebDropData& drop_data, - WebDragOperationsMask ops, - const GURL& page_url, - const std::string& page_encoding, - const SkBitmap& image, - const gfx::Point& image_offset) { - drag_drop_thread_id_ = PlatformThread::CurrentId(); - - DoDragging(drop_data, ops, page_url, page_encoding, image, image_offset); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, &TabContentsDragWin::EndDragging, true)); -} - -void TabContentsDragWin::PrepareDragForDownload( - const WebDropData& drop_data, - OSExchangeData* data, - const GURL& page_url, - const std::string& page_encoding) { - // Parse the download metadata. - string16 mime_type; - FilePath file_name; - GURL download_url; - if (!drag_download_util::ParseDownloadMetadata(drop_data.download_metadata, - &mime_type, - &file_name, - &download_url)) - return; - - // Generate the download filename. - std::string content_disposition = - "attachment; filename=" + UTF16ToUTF8(file_name.value()); - FilePath generated_file_name; - download_util::GenerateFileName(download_url, - content_disposition, - std::string(), - UTF16ToUTF8(mime_type), - &generated_file_name); - - // Provide the data as file (CF_HDROP). A temporary download file with the - // Zone.Identifier ADS (Alternate Data Stream) attached will be created. - linked_ptr<net::FileStream> empty_file_stream; - scoped_refptr<DragDownloadFile> download_file = - new DragDownloadFile(generated_file_name, - empty_file_stream, - download_url, - page_url, - page_encoding, - view_->tab_contents()); - OSExchangeData::DownloadFileInfo file_download(FilePath(), - download_file.get()); - data->SetDownloadFileInfo(file_download); - - // Enable asynchronous operation. - OSExchangeDataProviderWin::GetIAsyncOperation(*data)->SetAsyncMode(TRUE); -} - -void TabContentsDragWin::PrepareDragForFileContents( - const WebDropData& drop_data, OSExchangeData* data) { - // Images without ALT text will only have a file extension so we need to - // synthesize one from the provided extension and URL. - FilePath file_name(drop_data.file_description_filename); - file_name = file_name.BaseName().RemoveExtension(); - if (file_name.value().empty()) { - // Retrieve the name from the URL. - file_name = net::GetSuggestedFilename(drop_data.url, "", "", FilePath()); - if (file_name.value().size() + drop_data.file_extension.size() + 1 > - MAX_PATH) { - file_name = FilePath(file_name.value().substr( - 0, MAX_PATH - drop_data.file_extension.size() - 2)); - } - } - file_name = file_name.ReplaceExtension(drop_data.file_extension); - data->SetFileContents(file_name.value(), drop_data.file_contents); -} - -void TabContentsDragWin::PrepareDragForUrl(const WebDropData& drop_data, - OSExchangeData* data) { - if (drop_data.url.SchemeIs(chrome::kJavaScriptScheme)) { - // We don't want to allow javascript URLs to be dragged to the desktop, - // but we do want to allow them to be added to the bookmarks bar - // (bookmarklets). So we create a fake bookmark entry (BookmarkDragData - // object) which explorer.exe cannot handle, and write the entry to data. - BookmarkDragData::Element bm_elt; - bm_elt.is_url = true; - bm_elt.url = drop_data.url; - bm_elt.title = drop_data.url_title; - - BookmarkDragData bm_drag_data; - bm_drag_data.elements.push_back(bm_elt); - - // Pass in NULL as the profile so that the bookmark always adds the url - // rather than trying to move an existing url. - bm_drag_data.Write(NULL, data); - } else { - data->SetURL(drop_data.url, drop_data.url_title); - } -} - -void TabContentsDragWin::DoDragging(const WebDropData& drop_data, - WebDragOperationsMask ops, - const GURL& page_url, - const std::string& page_encoding, - const SkBitmap& image, - const gfx::Point& image_offset) { - OSExchangeData data; - - if (!drop_data.download_metadata.empty()) { - PrepareDragForDownload(drop_data, &data, page_url, page_encoding); - - // Set the observer. - OSExchangeDataProviderWin::GetDataObjectImpl(data)->set_observer(this); - } else { - // We set the file contents before the URL because the URL also sets file - // contents (to a .URL shortcut). We want to prefer file content data over - // a shortcut so we add it first. - if (!drop_data.file_contents.empty()) - PrepareDragForFileContents(drop_data, &data); - if (!drop_data.text_html.empty()) - data.SetHtml(drop_data.text_html, drop_data.html_base_url); - // We set the text contents before the URL because the URL also sets text - // content. - if (!drop_data.plain_text.empty()) - data.SetString(drop_data.plain_text); - if (drop_data.url.is_valid()) - PrepareDragForUrl(drop_data, &data); - } - - // Set drag image. - if (!image.isNull()) { - drag_utils::SetDragImageOnDataObject( - image, gfx::Size(image.width(), image.height()), image_offset, &data); - } - - // We need to enable recursive tasks on the message loop so we can get - // updates while in the system DoDragDrop loop. - bool old_state = MessageLoop::current()->NestableTasksAllowed(); - MessageLoop::current()->SetNestableTasksAllowed(true); - DWORD effect; - DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source_, - web_drag_utils_win::WebDragOpMaskToWinDragOpMask(ops), &effect); - MessageLoop::current()->SetNestableTasksAllowed(old_state); - - // This works because WebDragSource::OnDragSourceDrop uses PostTask to - // dispatch the actual event. - drag_source_->set_effect(effect); -} - -void TabContentsDragWin::EndDragging(bool restore_suspended_state) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (drag_ended_) - return; - drag_ended_ = true; - - if (restore_suspended_state) - view_->drop_target()->set_suspended(old_drop_target_suspended_state_); - - if (msg_hook) { - AttachThreadInput(drag_out_thread_id, GetCurrentThreadId(), FALSE); - UnhookWindowsHookEx(msg_hook); - msg_hook = NULL; - } - - view_->EndDragging(); -} - -void TabContentsDragWin::CancelDrag() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - drag_source_->CancelDrag(); -} - -void TabContentsDragWin::CloseThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - drag_drop_thread_.reset(); -} - -void TabContentsDragWin::OnWaitForData() { - DCHECK(drag_drop_thread_id_ == PlatformThread::CurrentId()); - - // When the left button is release and we start to wait for the data, end - // the dragging before DoDragDrop returns. This makes the page leave the drag - // mode so that it can start to process the normal input events. - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, &TabContentsDragWin::EndDragging, true)); -} - -void TabContentsDragWin::OnDataObjectDisposed() { - DCHECK(drag_drop_thread_id_ == PlatformThread::CurrentId()); - - // The drag-and-drop thread is only closed after OLE is done with - // DataObjectImpl. - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, &TabContentsDragWin::CloseThread)); -} diff --git a/chrome/browser/views/tab_contents/tab_contents_drag_win.h b/chrome/browser/views/tab_contents/tab_contents_drag_win.h index 2fd29e8..79067eb 100644 --- a/chrome/browser/views/tab_contents/tab_contents_drag_win.h +++ b/chrome/browser/views/tab_contents/tab_contents_drag_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,95 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_DRAG_WIN_H_ #pragma once -#include "app/os_exchange_data_provider_win.h" -#include "base/platform_thread.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "gfx/point.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/WebKit/WebKit/chromium/public/WebDragOperation.h" - -class DragDropThread; -class TabContentsViewWin; -class WebDragSource; -struct WebDropData; - -// Windows-specific drag-and-drop handling in TabContentsView. -// If we are dragging a virtual file out of the browser, we use a background -// thread to do the drag-and-drop because we do not want to run nested -// message loop in the UI thread. For all other cases, the drag-and-drop happens -// in the UI thread. -class TabContentsDragWin - : public DataObjectImpl::Observer, - public base::RefCountedThreadSafe<TabContentsDragWin> { - public: - explicit TabContentsDragWin(TabContentsViewWin* view); - virtual ~TabContentsDragWin(); - - // Called on UI thread. - void StartDragging(const WebDropData& drop_data, - WebKit::WebDragOperationsMask ops, - const SkBitmap& image, - const gfx::Point& image_offset); - void CancelDrag(); - - // DataObjectImpl::Observer implementation. - // Called on drag-and-drop thread. - virtual void OnWaitForData(); - virtual void OnDataObjectDisposed(); - - private: - // Called on either UI thread or drag-and-drop thread. - void PrepareDragForDownload(const WebDropData& drop_data, - OSExchangeData* data, - const GURL& page_url, - const std::string& page_encoding); - void PrepareDragForFileContents(const WebDropData& drop_data, - OSExchangeData* data); - void PrepareDragForUrl(const WebDropData& drop_data, OSExchangeData* data); - void DoDragging(const WebDropData& drop_data, - WebKit::WebDragOperationsMask ops, - const GURL& page_url, - const std::string& page_encoding, - const SkBitmap& image, - const gfx::Point& image_offset); - - // Called on drag-and-drop thread. - void StartBackgroundDragging(const WebDropData& drop_data, - WebKit::WebDragOperationsMask ops, - const GURL& page_url, - const std::string& page_encoding, - const SkBitmap& image, - const gfx::Point& image_offset); - // Called on UI thread. - void EndDragging(bool restore_suspended_state); - void CloseThread(); - - // For debug check only. Access only on drag-and-drop thread. - PlatformThreadId drag_drop_thread_id_; - - // All the member variables below are accessed on UI thread. - - // Keep track of the TabContentsViewWin it is associated with. - TabContentsViewWin* view_; - - // |drag_source_| is our callback interface passed to the system when we - // want to initiate a drag and drop operation. We use it to tell if a - // drag operation is happening. - scoped_refptr<WebDragSource> drag_source_; - - // The thread used by the drag-out download. This is because we want to avoid - // running nested message loop in main UI thread. - scoped_ptr<DragDropThread> drag_drop_thread_; - - // The flag to guard that EndDragging is not called twice. - bool drag_ended_; - - // Keep track of the old suspended state of the drop target. - bool old_drop_target_suspended_state_; - - DISALLOW_COPY_AND_ASSIGN(TabContentsDragWin); -}; - +#include "chrome/browser/ui/views/tab_contents/tab_contents_drag_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_DRAG_WIN_H_ + diff --git a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc deleted file mode 100644 index 0a31684..0000000 --- a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc +++ /dev/null @@ -1,515 +0,0 @@ -// 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/tab_contents/tab_contents_view_gtk.h" - -#include <gdk/gdk.h> -#include <gtk/gtk.h> - -#include "base/string_util.h" -#include "build/build_config.h" -#include "chrome/browser/download/download_shelf.h" -#include "chrome/browser/gtk/constrained_window_gtk.h" -#include "chrome/browser/gtk/tab_contents_drag_source.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_view_host_factory.h" -#if defined(TOUCH_UI) -#include "chrome/browser/renderer_host/render_widget_host_view_views.h" -#else -#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" -#endif -#include "chrome/browser/tab_contents/interstitial_page.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/browser/tab_contents/web_drag_dest_gtk.h" -#include "chrome/browser/views/sad_tab_view.h" -#include "chrome/browser/views/tab_contents/render_view_context_menu_views.h" -#include "gfx/canvas_skia_paint.h" -#include "gfx/point.h" -#include "gfx/rect.h" -#include "gfx/size.h" -#include "views/controls/native/native_view_host.h" -#include "views/focus/view_storage.h" -#include "views/screen.h" -#include "views/widget/root_view.h" - -using WebKit::WebDragOperation; -using WebKit::WebDragOperationsMask; -using WebKit::WebInputEvent; - - -namespace { - -// Called when the content view gtk widget is tabbed to, or after the call to -// gtk_widget_child_focus() in TakeFocus(). We return true -// and grab focus if we don't have it. The call to -// FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to -// webkit. -gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus, - TabContents* tab_contents) { - // If we already have focus, let the next widget have a shot at it. We will - // reach this situation after the call to gtk_widget_child_focus() in - // TakeFocus(). - if (gtk_widget_is_focus(widget)) - return FALSE; - - gtk_widget_grab_focus(widget); - bool reverse = focus == GTK_DIR_TAB_BACKWARD; - tab_contents->FocusThroughTabTraversal(reverse); - return TRUE; -} - -// Called when the mouse leaves the widget. We notify our delegate. -// WidgetGtk also defines OnLeaveNotify, so we use the name OnLeaveNotify2 -// here. -gboolean OnLeaveNotify2(GtkWidget* widget, GdkEventCrossing* event, - TabContents* tab_contents) { - if (tab_contents->delegate()) - tab_contents->delegate()->ContentsMouseEvent( - tab_contents, views::Screen::GetCursorScreenPoint(), false); - return FALSE; -} - -// Called when the mouse moves within the widget. -gboolean CallMouseMove(GtkWidget* widget, GdkEventMotion* event, - TabContentsViewGtk* tab_contents_view) { - return tab_contents_view->OnMouseMove(widget, event); -} - -// See tab_contents_view_gtk.cc for discussion of mouse scroll zooming. -gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event, - TabContents* tab_contents) { - if ((event->state & gtk_accelerator_get_default_mod_mask()) == - GDK_CONTROL_MASK) { - if (tab_contents->delegate()) { - if (event->direction == GDK_SCROLL_DOWN) { - tab_contents->delegate()->ContentsZoomChange(false); - return TRUE; - } else if (event->direction == GDK_SCROLL_UP) { - tab_contents->delegate()->ContentsZoomChange(true); - return TRUE; - } - } - } - - return FALSE; -} - -} // namespace - -// static -TabContentsView* TabContentsView::Create(TabContents* tab_contents) { - return new TabContentsViewGtk(tab_contents); -} - -TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) - : TabContentsView(tab_contents), - views::WidgetGtk(TYPE_CHILD), - sad_tab_(NULL), - ignore_next_char_event_(false) { - drag_source_.reset(new TabContentsDragSource(this)); - last_focused_view_storage_id_ = - views::ViewStorage::GetSharedInstance()->CreateStorageID(); -} - -TabContentsViewGtk::~TabContentsViewGtk() { - // Make sure to remove any stored view we may still have in the ViewStorage. - // - // It is possible the view went away before us, so we only do this if the - // view is registered. - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) - view_storage->RemoveView(last_focused_view_storage_id_); - - // Just deleting the object doesn't destroy the GtkWidget. We need to do that - // manually, and synchronously, since subsequent signal handlers may expect - // to locate this object. - CloseNow(); -} - -void TabContentsViewGtk::AttachConstrainedWindow( - ConstrainedWindowGtk* constrained_window) { - DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(), - constrained_window) == constrained_windows_.end()); - - constrained_windows_.push_back(constrained_window); - AddChild(constrained_window->widget()); - - gfx::Rect bounds; - GetContainerBounds(&bounds); - SetFloatingPosition(bounds.size()); -} - -void TabContentsViewGtk::RemoveConstrainedWindow( - ConstrainedWindowGtk* constrained_window) { - std::vector<ConstrainedWindowGtk*>::iterator item = - find(constrained_windows_.begin(), constrained_windows_.end(), - constrained_window); - DCHECK(item != constrained_windows_.end()); - RemoveChild((*item)->widget()); - constrained_windows_.erase(item); -} - -void TabContentsViewGtk::CreateView(const gfx::Size& initial_size) { - set_delete_on_destroy(false); - WidgetGtk::Init(NULL, gfx::Rect(0, 0, initial_size.width(), - initial_size.height())); - // We need to own the widget in order to attach/detach the native view - // to container. - gtk_object_ref(GTK_OBJECT(GetNativeView())); -} - -RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget( - RenderWidgetHost* render_widget_host) { - if (render_widget_host->view()) { - // During testing, the view will already be set up in most cases to the - // test view, so we don't want to clobber it with a real one. To verify that - // this actually is happening (and somebody isn't accidentally creating the - // view twice), we check for the RVH Factory, which will be set when we're - // making special ones (which go along with the special views). - DCHECK(RenderViewHostFactory::has_factory()); - return render_widget_host->view(); - } - - // If we were showing sad tab, remove it now. - if (sad_tab_ != NULL) { - SetContentsView(new views::View()); - sad_tab_ = NULL; - } - -#if defined(TOUCH_UI) - RenderWidgetHostViewViews* view = - new RenderWidgetHostViewViews(render_widget_host); - SetContentsView(view); - view->Show(); - view->InitAsChild(); - - g_signal_connect(view->native_view(), "focus", - G_CALLBACK(OnFocus), tab_contents()); - g_signal_connect(view->native_view(), "leave-notify-event", - G_CALLBACK(OnLeaveNotify2), tab_contents()); - g_signal_connect(view->native_view(), "motion-notify-event", - G_CALLBACK(CallMouseMove), this); - g_signal_connect(view->native_view(), "scroll-event", - G_CALLBACK(OnMouseScroll), tab_contents()); - gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK | - GDK_POINTER_MOTION_MASK); - - // Renderer target DnD. - if (tab_contents()->ShouldAcceptDragAndDrop()) - drag_dest_.reset(new WebDragDestGtk(tab_contents(), view->native_view())); - - return view; -#else - RenderWidgetHostViewGtk* view = - new RenderWidgetHostViewGtk(render_widget_host); - view->InitAsChild(); - g_signal_connect(view->native_view(), "focus", - G_CALLBACK(OnFocus), tab_contents()); - g_signal_connect(view->native_view(), "leave-notify-event", - G_CALLBACK(OnLeaveNotify2), tab_contents()); - g_signal_connect(view->native_view(), "motion-notify-event", - G_CALLBACK(CallMouseMove), this); - g_signal_connect(view->native_view(), "scroll-event", - G_CALLBACK(OnMouseScroll), tab_contents()); - gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK | - GDK_POINTER_MOTION_MASK); - - // Renderer target DnD. - if (tab_contents()->ShouldAcceptDragAndDrop()) - drag_dest_.reset(new WebDragDestGtk(tab_contents(), view->native_view())); - - gtk_fixed_put(GTK_FIXED(GetNativeView()), view->native_view(), 0, 0); - return view; -#endif -} - -gfx::NativeView TabContentsViewGtk::GetNativeView() const { - return WidgetGtk::GetNativeView(); -} - -gfx::NativeView TabContentsViewGtk::GetContentNativeView() const { - RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); - if (!rwhv) - return NULL; - return rwhv->GetNativeView(); -} - -gfx::NativeWindow TabContentsViewGtk::GetTopLevelNativeWindow() const { - GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW); - return window ? GTK_WINDOW(window) : NULL; -} - -void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const { - // Callers expect the requested bounds not the actual bounds. For example, - // during init callers expect 0x0, but Gtk layout enforces a min size of 1x1. - GetBounds(out, false); - - gfx::Size size; - WidgetGtk::GetRequestedSize(&size); - out->set_size(size); -} - -void TabContentsViewGtk::StartDragging(const WebDropData& drop_data, - WebDragOperationsMask ops, - const SkBitmap& image, - const gfx::Point& image_offset) { - drag_source_->StartDragging(drop_data, ops, &last_mouse_down_, - image, image_offset); -} - -void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { - // Set the window name to include the page title so it's easier to spot - // when debugging (e.g. via xwininfo -tree). - gfx::NativeView content_view = GetContentNativeView(); - if (content_view && content_view->window) - gdk_window_set_title(content_view->window, WideToUTF8(title).c_str()); -} - -void TabContentsViewGtk::OnTabCrashed() { -} - -void TabContentsViewGtk::SizeContents(const gfx::Size& size) { - // TODO(brettw) this is a hack and should be removed. See tab_contents_view.h. - - // We're contained in a fixed. To have the fixed relay us out to |size|, set - // the size request, which triggers OnSizeAllocate. - gtk_widget_set_size_request(GetNativeView(), size.width(), size.height()); - - // We need to send this immediately. - RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); - if (rwhv) - rwhv->SetSize(size); -} - -void TabContentsViewGtk::Focus() { - if (tab_contents()->interstitial_page()) { - tab_contents()->interstitial_page()->Focus(); - return; - } - - if (tab_contents()->is_crashed() && sad_tab_ != NULL) { - sad_tab_->RequestFocus(); - return; - } - - RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); - gtk_widget_grab_focus(rwhv ? rwhv->GetNativeView() : GetNativeView()); -} - -void TabContentsViewGtk::SetInitialFocus() { - if (tab_contents()->FocusLocationBarByDefault()) - tab_contents()->SetFocusToLocationBar(false); - else - Focus(); -} - -void TabContentsViewGtk::StoreFocus() { - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - - if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) - view_storage->RemoveView(last_focused_view_storage_id_); - - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); - if (focus_manager) { - // |focus_manager| can be NULL if the tab has been detached but still - // exists. - views::View* focused_view = focus_manager->GetFocusedView(); - if (focused_view) - view_storage->StoreView(last_focused_view_storage_id_, focused_view); - } -} - -void TabContentsViewGtk::RestoreFocus() { - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - views::View* last_focused_view = - view_storage->RetrieveView(last_focused_view_storage_id_); - if (!last_focused_view) { - SetInitialFocus(); - } else { - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); - - // If you hit this DCHECK, please report it to Jay (jcampan). - DCHECK(focus_manager != NULL) << "No focus manager when restoring focus."; - - if (last_focused_view->IsFocusableInRootView() && focus_manager && - focus_manager->ContainsView(last_focused_view)) { - last_focused_view->RequestFocus(); - } else { - // The focused view may not belong to the same window hierarchy (e.g. - // if the location bar was focused and the tab is dragged out), or it may - // no longer be focusable (e.g. if the location bar was focused and then - // we switched to fullscreen mode). In that case we default to the - // default focus. - SetInitialFocus(); - } - view_storage->RemoveView(last_focused_view_storage_id_); - } -} - -void TabContentsViewGtk::UpdateDragCursor(WebDragOperation operation) { - if (drag_dest_.get()) - drag_dest_->UpdateDragStatus(operation); -} - -void TabContentsViewGtk::GotFocus() { - if (tab_contents()->delegate()) - tab_contents()->delegate()->TabContentsFocused(tab_contents()); -} - -void TabContentsViewGtk::TakeFocus(bool reverse) { - if (tab_contents()->delegate() && - !tab_contents()->delegate()->TakeFocus(reverse)) { - - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); - - // We may not have a focus manager if the tab has been switched before this - // message arrived. - if (focus_manager) - focus_manager->AdvanceFocus(reverse); - } -} - -void TabContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) { - // Allow delegates to handle the context menu operation first. - if (tab_contents()->delegate()->HandleContextMenu(params)) - return; - - context_menu_.reset(new RenderViewContextMenuViews(tab_contents(), params)); - context_menu_->Init(); - - gfx::Point screen_point(params.x, params.y); - views::View::ConvertPointToScreen(GetRootView(), &screen_point); - - // Enable recursive tasks on the message loop so we can get updates while - // the context menu is being displayed. - bool old_state = MessageLoop::current()->NestableTasksAllowed(); - MessageLoop::current()->SetNestableTasksAllowed(true); - context_menu_->RunMenuAt(screen_point.x(), screen_point.y()); - MessageLoop::current()->SetNestableTasksAllowed(old_state); -} - -void TabContentsViewGtk::ShowPopupMenu(const gfx::Rect& bounds, - int item_height, - double item_font_size, - int selected_item, - const std::vector<WebMenuItem>& items, - bool right_aligned) { - // External popup menus are only used on Mac. - NOTREACHED(); -} - -gboolean TabContentsViewGtk::OnButtonPress(GtkWidget* widget, - GdkEventButton* event) { - last_mouse_down_ = *event; - return views::WidgetGtk::OnButtonPress(widget, event); -} - -void TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget, - GtkAllocation* allocation) { - gfx::Size new_size(allocation->width, allocation->height); - - // Always call WasSized() to allow checking to make sure the - // RenderWidgetHostView is the right size. - WasSized(new_size); -} - -gboolean TabContentsViewGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { - if (tab_contents()->render_view_host() && - !tab_contents()->render_view_host()->IsRenderViewLive()) { - if (sad_tab_ == NULL) { - sad_tab_ = new SadTabView(tab_contents()); - SetContentsView(sad_tab_); - } - gfx::Rect bounds; - GetBounds(&bounds, true); - sad_tab_->SetBounds(gfx::Rect(0, 0, bounds.width(), bounds.height())); - gfx::CanvasSkiaPaint canvas(event); - sad_tab_->ProcessPaint(&canvas); - } else { -#if defined(TOUCH_UI) - // there's no native view, so just like sad tabs - // we need to pass on the message to paint the page - gfx::Rect bounds; - GetBounds(&bounds, true); - views::View *view = reinterpret_cast<RenderWidgetHostViewViews *> - (tab_contents()->render_view_host()->view()); - if (view) { - view->SetBounds(gfx::Rect(0, 0, bounds.width(), bounds.height())); - gfx::CanvasSkiaPaint canvas(event); - view->ProcessPaint(&canvas); - } -#endif - } - return false; // False indicates other widgets should get the event as well. -} - -void TabContentsViewGtk::OnShow(GtkWidget* widget) { - WasShown(); -} - -void TabContentsViewGtk::OnHide(GtkWidget* widget) { - WasHidden(); -} - -void TabContentsViewGtk::WasHidden() { - tab_contents()->HideContents(); -} - -void TabContentsViewGtk::WasShown() { - tab_contents()->ShowContents(); -} - -void TabContentsViewGtk::WasSized(const gfx::Size& size) { - // We have to check that the RenderWidgetHostView is the proper size. - // It can be wrong in cases where the renderer has died and the host - // view needed to be recreated. - bool needs_resize = size != size_; - - if (needs_resize) { - size_ = size; - if (tab_contents()->interstitial_page()) - tab_contents()->interstitial_page()->SetSize(size); - } - - RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); - if (rwhv && rwhv->GetViewBounds().size() != size) - rwhv->SetSize(size); - - if (needs_resize) - SetFloatingPosition(size); -} - -void TabContentsViewGtk::SetFloatingPosition(const gfx::Size& size) { - // Place each ConstrainedWindow in the center of the view. - int half_view_width = size.width() / 2; - - typedef std::vector<ConstrainedWindowGtk*>::iterator iterator; - - for (iterator f = constrained_windows_.begin(), - l = constrained_windows_.end(); f != l; ++f) { - GtkWidget* widget = (*f)->widget(); - - GtkRequisition requisition; - gtk_widget_size_request(widget, &requisition); - - int child_x = std::max(half_view_width - (requisition.width / 2), 0); - PositionChild(widget, child_x, 0, 0, 0); - } -} - -// Called when the mouse moves within the widget. We notify SadTabView if it's -// not NULL, else our delegate. -gboolean TabContentsViewGtk::OnMouseMove(GtkWidget* widget, - GdkEventMotion* event) { - if (sad_tab_ != NULL) - WidgetGtk::OnMotionNotify(widget, event); - else if (tab_contents()->delegate()) - tab_contents()->delegate()->ContentsMouseEvent( - tab_contents(), views::Screen::GetCursorScreenPoint(), true); - return FALSE; -} diff --git a/chrome/browser/views/tab_contents/tab_contents_view_gtk.h b/chrome/browser/views/tab_contents/tab_contents_view_gtk.h index 890c6b1..3ee3e9a 100644 --- a/chrome/browser/views/tab_contents/tab_contents_view_gtk.h +++ b/chrome/browser/views/tab_contents/tab_contents_view_gtk.h @@ -6,136 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_GTK_H_ #pragma once -#include <vector> - -#include "base/scoped_ptr.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "gfx/size.h" -#include "views/widget/widget_gtk.h" - -class ConstrainedWindowGtk; -typedef struct _GtkFloatingContainer GtkFloatingContainer; -class RenderViewContextMenuViews; -class SadTabView; -class SkBitmap; -class TabContentsDragSource; -class WebDragDestGtk; -namespace gfx { -class Point; -} -namespace views { -class NativeViewHost; -} - -// Gtk-specific implementation of the TabContentsView for the views-based front -// end. It is a WidgetGtk that contains all of the contents of the tab and -// associated child views. -class TabContentsViewGtk : public TabContentsView, - public views::WidgetGtk { - public: - // The corresponding TabContents is passed in the constructor, and manages our - // lifetime. This doesn't need to be the case, but is this way currently - // because that's what was easiest when they were split. - explicit TabContentsViewGtk(TabContents* tab_contents); - virtual ~TabContentsViewGtk(); - - // Unlike Windows, ConstrainedWindows need to collaborate with the - // TabContentsViewGtk to position the dialogs. - void AttachConstrainedWindow(ConstrainedWindowGtk* constrained_window); - void RemoveConstrainedWindow(ConstrainedWindowGtk* constrained_window); - - gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event); - - // TabContentsView implementation -------------------------------------------- - - virtual void CreateView(const gfx::Size& initial_size); - virtual RenderWidgetHostView* CreateViewForWidget( - RenderWidgetHost* render_widget_host); - virtual gfx::NativeView GetNativeView() const; - virtual gfx::NativeView GetContentNativeView() const; - virtual gfx::NativeWindow GetTopLevelNativeWindow() const; - virtual void GetContainerBounds(gfx::Rect* out) const; - virtual void SetPageTitle(const std::wstring& title); - virtual void OnTabCrashed(); - virtual void SizeContents(const gfx::Size& size); - virtual void Focus(); - virtual void SetInitialFocus(); - virtual void StoreFocus(); - virtual void RestoreFocus(); - - // Backend implementation of RenderViewHostDelegate::View. - virtual void ShowContextMenu(const ContextMenuParams& params); - virtual void ShowPopupMenu(const gfx::Rect& bounds, - int item_height, - double item_font_size, - int selected_item, - const std::vector<WebMenuItem>& items, - bool right_aligned); - virtual void StartDragging(const WebDropData& drop_data, - WebKit::WebDragOperationsMask ops_allowed, - const SkBitmap& image, - const gfx::Point& image_offset); - virtual void UpdateDragCursor(WebKit::WebDragOperation operation); - virtual void GotFocus(); - virtual void TakeFocus(bool reverse); - - private: - // Signal handlers ----------------------------------------------------------- - - // Overridden from views::WidgetGtk: - virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event); - virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation); - virtual gboolean OnPaint(GtkWidget* widget, GdkEventExpose* event); - virtual void OnShow(GtkWidget* widget); - virtual void OnHide(GtkWidget* widget); - - // Handles notifying the TabContents and other operations when the window was - // shown or hidden. - void WasHidden(); - void WasShown(); - - // Handles resizing of the contents. This will notify the RenderWidgetHostView - // of the change, reposition popups, and the find in page bar. - void WasSized(const gfx::Size& size); - - // For any floating views (ConstrainedDialogs) this function centers them - // within this view. It's called whem a ConstrainedDialog is attached and - // when this view is resized. - void SetFloatingPosition(const gfx::Size& size); - - // --------------------------------------------------------------------------- - - // Used to render the sad tab. This will be non-NULL only when the sad tab is - // visible. - SadTabView* sad_tab_; - - // Whether to ignore the next CHAR keyboard event. - bool ignore_next_char_event_; - - // The id used in the ViewStorage to store the last focused view. - int last_focused_view_storage_id_; - - // The context menu. Callbacks are asynchronous so we need to keep it around. - scoped_ptr<RenderViewContextMenuViews> context_menu_; - - // Handles drags from this TabContentsView. - scoped_ptr<TabContentsDragSource> drag_source_; - - // The event for the last mouse down we handled. We need this for drags. - GdkEventButton last_mouse_down_; - - // The helper object that handles drag destination related interactions with - // GTK. - scoped_ptr<WebDragDestGtk> drag_dest_; - - // Current size. See comment in WidgetGtk as to why this is cached. - gfx::Size size_; - - // Each individual UI for constrained dialogs currently displayed. The - // objects in this vector are owned by the TabContents, not the view. - std::vector<ConstrainedWindowGtk*> constrained_windows_; - - DISALLOW_COPY_AND_ASSIGN(TabContentsViewGtk); -}; +#include "chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_GTK_H_ + diff --git a/chrome/browser/views/tab_contents/tab_contents_view_win.cc b/chrome/browser/views/tab_contents/tab_contents_view_win.cc deleted file mode 100644 index f3126d1..0000000 --- a/chrome/browser/views/tab_contents/tab_contents_view_win.cc +++ /dev/null @@ -1,577 +0,0 @@ -// 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/tab_contents/tab_contents_view_win.h" - -#include <windows.h> - -#include "base/time.h" -#include "chrome/browser/browser.h" // TODO(beng): this dependency is awful. -#include "chrome/browser/browser_process.h" -#include "chrome/browser/download/download_request_limiter.h" -#include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_view_host_factory.h" -#include "chrome/browser/renderer_host/render_widget_host_view_win.h" -#include "chrome/browser/tab_contents/interstitial_page.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/browser/tab_contents/web_drop_target_win.h" -#include "chrome/browser/views/sad_tab_view.h" -#include "chrome/browser/views/tab_contents/render_view_context_menu_views.h" -#include "chrome/browser/views/tab_contents/tab_contents_drag_win.h" -#include "gfx/canvas_skia_paint.h" -#include "views/focus/view_storage.h" -#include "views/screen.h" -#include "views/widget/root_view.h" - -using WebKit::WebDragOperation; -using WebKit::WebDragOperationNone; -using WebKit::WebDragOperationsMask; -using WebKit::WebInputEvent; - -// static -TabContentsView* TabContentsView::Create(TabContents* tab_contents) { - return new TabContentsViewWin(tab_contents); -} - -TabContentsViewWin::TabContentsViewWin(TabContents* tab_contents) - : TabContentsView(tab_contents), - focus_manager_(NULL), - close_tab_after_drag_ends_(false), - sad_tab_(NULL) { - last_focused_view_storage_id_ = - views::ViewStorage::GetSharedInstance()->CreateStorageID(); -} - -TabContentsViewWin::~TabContentsViewWin() { - // Makes sure to remove any stored view we may still have in the ViewStorage. - // - // It is possible the view went away before us, so we only do this if the - // view is registered. - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) - view_storage->RemoveView(last_focused_view_storage_id_); -} - -void TabContentsViewWin::Unparent() { - // Remember who our FocusManager is, we won't be able to access it once - // unparented. - focus_manager_ = views::WidgetWin::GetFocusManager(); - // Note that we do not DCHECK on focus_manager_ as it may be NULL when used - // with an external tab container. - ::SetParent(GetNativeView(), NULL); -} - -void TabContentsViewWin::CreateView(const gfx::Size& initial_size) { - set_delete_on_destroy(false); - // Since we create these windows parented to the desktop window initially, we - // don't want to create them initially visible. - set_window_style(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - WidgetWin::Init(GetDesktopWindow(), gfx::Rect()); - - // Remove the root view drop target so we can register our own. - RevokeDragDrop(GetNativeView()); - drop_target_ = new WebDropTarget(GetNativeView(), tab_contents()); -} - -RenderWidgetHostView* TabContentsViewWin::CreateViewForWidget( - RenderWidgetHost* render_widget_host) { - if (render_widget_host->view()) { - // During testing, the view will already be set up in most cases to the - // test view, so we don't want to clobber it with a real one. To verify that - // this actually is happening (and somebody isn't accidentally creating the - // view twice), we check for the RVH Factory, which will be set when we're - // making special ones (which go along with the special views). - DCHECK(RenderViewHostFactory::has_factory()); - return render_widget_host->view(); - } - - // If we were showing sad tab, remove it now. - if (sad_tab_ != NULL) { - SetContentsView(new views::View()); - sad_tab_ = NULL; - } - - RenderWidgetHostViewWin* view = - new RenderWidgetHostViewWin(render_widget_host); - view->CreateWnd(GetNativeView()); - view->ShowWindow(SW_SHOW); - return view; -} - -gfx::NativeView TabContentsViewWin::GetNativeView() const { - return WidgetWin::GetNativeView(); -} - -gfx::NativeView TabContentsViewWin::GetContentNativeView() const { - RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); - if (!rwhv) - return NULL; - return rwhv->GetNativeView(); -} - -gfx::NativeWindow TabContentsViewWin::GetTopLevelNativeWindow() const { - return ::GetAncestor(GetNativeView(), GA_ROOT); -} - -void TabContentsViewWin::GetContainerBounds(gfx::Rect* out) const { - GetBounds(out, false); -} - -void TabContentsViewWin::StartDragging(const WebDropData& drop_data, - WebDragOperationsMask ops, - const SkBitmap& image, - const gfx::Point& image_offset) { - drag_handler_ = new TabContentsDragWin(this); - drag_handler_->StartDragging(drop_data, ops, image, image_offset); -} - -void TabContentsViewWin::EndDragging() { - if (close_tab_after_drag_ends_) { - close_tab_timer_.Start(base::TimeDelta::FromMilliseconds(0), this, - &TabContentsViewWin::CloseTab); - } - - if (tab_contents()->render_view_host()) - tab_contents()->render_view_host()->DragSourceSystemDragEnded(); - - drag_handler_ = NULL; -} - -void TabContentsViewWin::OnDestroy() { - if (drop_target_.get()) { - RevokeDragDrop(GetNativeView()); - drop_target_ = NULL; - } - - WidgetWin::OnDestroy(); -} - -void TabContentsViewWin::SetPageTitle(const std::wstring& title) { - if (GetNativeView()) { - // It's possible to get this after the hwnd has been destroyed. - ::SetWindowText(GetNativeView(), title.c_str()); - } -} - -void TabContentsViewWin::OnTabCrashed() { - // Force an invalidation to render sad tab. We will notice we crashed when we - // paint. - // Note that it's possible to get this message after the window was destroyed. - if (::IsWindow(GetNativeView())) - InvalidateRect(GetNativeView(), NULL, FALSE); -} - -void TabContentsViewWin::SizeContents(const gfx::Size& size) { - // TODO(brettw) this is a hack and should be removed. See tab_contents_view.h. - - gfx::Rect bounds; - GetContainerBounds(&bounds); - if (bounds.size() != size) { - // Our size really needs to change, invoke SetWindowPos so that we do a - // layout and all that good stuff. OnWindowPosChanged will invoke WasSized. - UINT swp_flags = SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE; - SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags); - } else { - // Our size isn't changing, which means SetWindowPos won't invoke - // OnWindowPosChanged. We need to invoke WasSized though as the renderer may - // need to be sized. - WasSized(bounds.size()); - } -} - -void TabContentsViewWin::Focus() { - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); - - if (tab_contents()->interstitial_page()) { - tab_contents()->interstitial_page()->Focus(); - return; - } - - if (tab_contents()->is_crashed() && sad_tab_ != NULL) { - sad_tab_->RequestFocus(); - return; - } - - RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); - if (rwhv) { - ::SetFocus(rwhv->GetNativeView()); - return; - } - - // Default to focusing our HWND. - ::SetFocus(GetNativeView()); -} - -void TabContentsViewWin::SetInitialFocus() { - if (tab_contents()->FocusLocationBarByDefault()) - tab_contents()->SetFocusToLocationBar(false); - else - Focus(); -} - -void TabContentsViewWin::StoreFocus() { - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - - if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) - view_storage->RemoveView(last_focused_view_storage_id_); - - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); - if (focus_manager) { - // |focus_manager| can be NULL if the tab has been detached but still - // exists. - views::View* focused_view = focus_manager->GetFocusedView(); - if (focused_view) - view_storage->StoreView(last_focused_view_storage_id_, focused_view); - - // If the focus was on the page, explicitly clear the focus so that we - // don't end up with the focused HWND not part of the window hierarchy. - // TODO(brettw) this should move to the view somehow. - HWND container_hwnd = GetNativeView(); - if (container_hwnd) { - views::View* focused_view = focus_manager->GetFocusedView(); - if (focused_view) { - HWND hwnd = focused_view->GetRootView()->GetWidget()->GetNativeView(); - if (container_hwnd == hwnd || ::IsChild(container_hwnd, hwnd)) - focus_manager->ClearFocus(); - } - } - } -} - -void TabContentsViewWin::RestoreFocus() { - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - views::View* last_focused_view = - view_storage->RetrieveView(last_focused_view_storage_id_); - - if (!last_focused_view) { - SetInitialFocus(); - } else { - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); - - // If you hit this DCHECK, please report it to Jay (jcampan). - DCHECK(focus_manager != NULL) << "No focus manager when restoring focus."; - - if (last_focused_view->IsFocusableInRootView() && focus_manager && - focus_manager->ContainsView(last_focused_view)) { - last_focused_view->RequestFocus(); - } else { - // The focused view may not belong to the same window hierarchy (e.g. - // if the location bar was focused and the tab is dragged out), or it may - // no longer be focusable (e.g. if the location bar was focused and then - // we switched to fullscreen mode). In that case we default to the - // default focus. - SetInitialFocus(); - } - view_storage->RemoveView(last_focused_view_storage_id_); - } -} - -bool TabContentsViewWin::IsDoingDrag() const { - return drag_handler_.get() != NULL; -} - -void TabContentsViewWin::CancelDragAndCloseTab() { - DCHECK(IsDoingDrag()); - // We can't close the tab while we're in the drag and - // |drag_handler_->CancelDrag()| is async. Instead, set a flag to cancel - // the drag and when the drag nested message loop ends, close the tab. - drag_handler_->CancelDrag(); - close_tab_after_drag_ends_ = true; -} - -void TabContentsViewWin::UpdateDragCursor(WebDragOperation operation) { - drop_target_->set_drag_cursor(operation); -} - -void TabContentsViewWin::GotFocus() { - if (tab_contents()->delegate()) - tab_contents()->delegate()->TabContentsFocused(tab_contents()); -} - -void TabContentsViewWin::TakeFocus(bool reverse) { - if (!tab_contents()->delegate()->TakeFocus(reverse)) { - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); - - // We may not have a focus manager if the tab has been switched before this - // message arrived. - if (focus_manager) - focus_manager->AdvanceFocus(reverse); - } -} - -views::FocusManager* TabContentsViewWin::GetFocusManager() { - views::FocusManager* focus_manager = WidgetWin::GetFocusManager(); - if (focus_manager) { - // If focus_manager_ is non NULL, it means we have been reparented, in which - // case its value may not be valid anymore. - focus_manager_ = NULL; - return focus_manager; - } - // TODO(jcampan): we should DCHECK on focus_manager_, as it should not be - // NULL. We are not doing it as it breaks some unit-tests. We should - // probably have an empty TabContentView implementation for the unit-tests, - // that would prevent that code being executed in the unit-test case. - // DCHECK(focus_manager_); - return focus_manager_; -} - -void TabContentsViewWin::CloseTab() { - tab_contents()->Close(tab_contents()->render_view_host()); -} - -void TabContentsViewWin::ShowContextMenu(const ContextMenuParams& params) { - // Allow delegates to handle the context menu operation first. - if (tab_contents()->delegate()->HandleContextMenu(params)) - return; - - context_menu_.reset(new RenderViewContextMenuViews(tab_contents(), params)); - context_menu_->Init(); - - POINT screen_pt = { params.x, params.y }; - MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1); - - // Enable recursive tasks on the message loop so we can get updates while - // the context menu is being displayed. - bool old_state = MessageLoop::current()->NestableTasksAllowed(); - MessageLoop::current()->SetNestableTasksAllowed(true); - context_menu_->RunMenuAt(screen_pt.x, screen_pt.y); - MessageLoop::current()->SetNestableTasksAllowed(old_state); -} - -void TabContentsViewWin::ShowPopupMenu(const gfx::Rect& bounds, - int item_height, - double item_font_size, - int selected_item, - const std::vector<WebMenuItem>& items, - bool right_aligned) { - // External popup menus are only used on Mac. - NOTREACHED(); -} - -void TabContentsViewWin::OnHScroll(int scroll_type, short position, - HWND scrollbar) { - ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar); -} - -void TabContentsViewWin::OnMouseLeave() { - // Let our delegate know that the mouse moved (useful for resetting status - // bubble state). - if (tab_contents()->delegate()) - tab_contents()->delegate()->ContentsMouseEvent( - tab_contents(), views::Screen::GetCursorScreenPoint(), false); - SetMsgHandled(FALSE); -} - -LRESULT TabContentsViewWin::OnMouseRange(UINT msg, - WPARAM w_param, LPARAM l_param) { - if (tab_contents()->is_crashed() && sad_tab_ != NULL) { - return WidgetWin::OnMouseRange(msg, w_param, l_param); - } - - switch (msg) { - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: { - // Make sure this TabContents is activated when it is clicked on. - if (tab_contents()->delegate()) - tab_contents()->delegate()->ActivateContents(tab_contents()); - break; - } - case WM_MOUSEMOVE: - // Let our delegate know that the mouse moved (useful for resetting status - // bubble state). - if (tab_contents()->delegate()) - tab_contents()->delegate()->ContentsMouseEvent( - tab_contents(), views::Screen::GetCursorScreenPoint(), true); - break; - default: - break; - } - - return 0; -} - -void TabContentsViewWin::OnPaint(HDC junk_dc) { - if (tab_contents()->render_view_host() && - !tab_contents()->render_view_host()->IsRenderViewLive()) { - if (sad_tab_ == NULL) { - sad_tab_ = new SadTabView(tab_contents()); - SetContentsView(sad_tab_); - } - CRect cr; - GetClientRect(&cr); - sad_tab_->SetBounds(gfx::Rect(cr)); - gfx::CanvasSkiaPaint canvas(GetNativeView(), true); - sad_tab_->ProcessPaint(&canvas); - return; - } - - // We need to do this to validate the dirty area so we don't end up in a - // WM_PAINTstorm that causes other mysterious bugs (such as WM_TIMERs not - // firing etc). It doesn't matter that we don't have any non-clipped area. - CPaintDC dc(GetNativeView()); - SetMsgHandled(FALSE); -} - -// A message is reflected here from view(). -// Return non-zero to indicate that it is handled here. -// Return 0 to allow view() to further process it. -LRESULT TabContentsViewWin::OnReflectedMessage(UINT msg, WPARAM w_param, - LPARAM l_param) { - MSG* message = reinterpret_cast<MSG*>(l_param); - switch (message->message) { - case WM_MOUSEWHEEL: - // This message is reflected from the view() to this window. - if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) { - WheelZoom(GET_WHEEL_DELTA_WPARAM(message->wParam)); - return 1; - } - break; - case WM_HSCROLL: - case WM_VSCROLL: - if (ScrollZoom(LOWORD(message->wParam))) - return 1; - default: - break; - } - - return 0; -} - -void TabContentsViewWin::OnVScroll(int scroll_type, short position, - HWND scrollbar) { - ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar); -} - -void TabContentsViewWin::OnWindowPosChanged(WINDOWPOS* window_pos) { - if (window_pos->flags & SWP_HIDEWINDOW) { - WasHidden(); - } else { - // The TabContents was shown by a means other than the user selecting a - // Tab, e.g. the window was minimized then restored. - if (window_pos->flags & SWP_SHOWWINDOW) - WasShown(); - - // Unless we were specifically told not to size, cause the renderer to be - // sized to the new bounds, which forces a repaint. Not required for the - // simple minimize-restore case described above, for example, since the - // size hasn't changed. - if (!(window_pos->flags & SWP_NOSIZE)) - WasSized(gfx::Size(window_pos->cx, window_pos->cy)); - } -} - -void TabContentsViewWin::OnSize(UINT param, const CSize& size) { - // NOTE: Because TabContentsViewWin handles OnWindowPosChanged without calling - // DefWindowProc, OnSize is NOT called on window resize. This handler - // is called only once when the window is created. - - // Don't call base class OnSize to avoid useless layout for 0x0 size. - // We will get OnWindowPosChanged later and layout root view in WasSized. - - // Hack for thinkpad touchpad driver. - // Set fake scrollbars so that we can get scroll messages, - SCROLLINFO si = {0}; - si.cbSize = sizeof(si); - si.fMask = SIF_ALL; - - si.nMin = 1; - si.nMax = 100; - si.nPage = 10; - si.nPos = 50; - - ::SetScrollInfo(GetNativeView(), SB_HORZ, &si, FALSE); - ::SetScrollInfo(GetNativeView(), SB_VERT, &si, FALSE); -} - -LRESULT TabContentsViewWin::OnNCCalcSize(BOOL w_param, LPARAM l_param) { - // Hack for thinkpad mouse wheel driver. We have set the fake scroll bars - // to receive scroll messages from thinkpad touchpad driver. Suppress - // painting of scrollbars by returning 0 size for them. - return 0; -} - -void TabContentsViewWin::OnNCPaint(HRGN rgn) { - // Suppress default WM_NCPAINT handling. We don't need to do anything - // here since the view will draw everything correctly. -} - -void TabContentsViewWin::ScrollCommon(UINT message, int scroll_type, - short position, HWND scrollbar) { - // This window can receive scroll events as a result of the ThinkPad's - // Trackpad scroll wheel emulation. - if (!ScrollZoom(scroll_type)) { - // Reflect scroll message to the view() to give it a chance - // to process scrolling. - SendMessage(GetContentNativeView(), message, - MAKELONG(scroll_type, position), - reinterpret_cast<LPARAM>(scrollbar)); - } -} - -void TabContentsViewWin::WasHidden() { - tab_contents()->HideContents(); -} - -void TabContentsViewWin::WasShown() { - tab_contents()->ShowContents(); -} - -void TabContentsViewWin::WasSized(const gfx::Size& size) { - if (tab_contents()->interstitial_page()) - tab_contents()->interstitial_page()->SetSize(size); - RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); - if (rwhv) - rwhv->SetSize(size); - - // We have to layout root view here because we handle OnWindowPosChanged - // without calling DefWindowProc (it sends OnSize and OnMove) so we don't - // receive OnSize. For performance reasons call SetBounds instead of - // LayoutRootView, we actually don't need paint event and we know new size. - GetRootView()->SetBounds(0, 0, size.width(), size.height()); -} - -bool TabContentsViewWin::ScrollZoom(int scroll_type) { - // If ctrl is held, zoom the UI. There are three issues with this: - // 1) Should the event be eaten or forwarded to content? We eat the event, - // which is like Firefox and unlike IE. - // 2) Should wheel up zoom in or out? We zoom in (increase font size), which - // is like IE and Google maps, but unlike Firefox. - // 3) Should the mouse have to be over the content area? We zoom as long as - // content has focus, although FF and IE require that the mouse is over - // content. This is because all events get forwarded when content has - // focus. - if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { - int distance = 0; - switch (scroll_type) { - case SB_LINEUP: - distance = WHEEL_DELTA; - break; - case SB_LINEDOWN: - distance = -WHEEL_DELTA; - break; - // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION, - // and SB_THUMBTRACK for completeness - default: - break; - } - - WheelZoom(distance); - return true; - } - return false; -} - -void TabContentsViewWin::WheelZoom(int distance) { - if (tab_contents()->delegate()) { - bool zoom_in = distance > 0; - tab_contents()->delegate()->ContentsZoomChange(zoom_in); - } -} diff --git a/chrome/browser/views/tab_contents/tab_contents_view_win.h b/chrome/browser/views/tab_contents/tab_contents_view_win.h index a42ffd7..49f6a13 100644 --- a/chrome/browser/views/tab_contents/tab_contents_view_win.h +++ b/chrome/browser/views/tab_contents/tab_contents_view_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,147 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_WIN_H_ #pragma once -#include "base/scoped_ptr.h" -#include "base/timer.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "gfx/size.h" -#include "views/widget/widget_win.h" - -class RenderViewContextMenuViews; -class SadTabView; -class SkBitmap; -class TabContentsDragWin; -struct WebDropData; -class WebDragSource; -class WebDropTarget; -namespace gfx { -class Point; -} - -// Windows-specific implementation of the TabContentsView. It is a HWND that -// contains all of the contents of the tab and associated child views. -class TabContentsViewWin : public TabContentsView, - public views::WidgetWin { - public: - // The corresponding TabContents is passed in the constructor, and manages our - // lifetime. This doesn't need to be the case, but is this way currently - // because that's what was easiest when they were split. - explicit TabContentsViewWin(TabContents* tab_contents); - virtual ~TabContentsViewWin(); - - // Reset the native parent of this view to NULL. Unparented windows should - // not receive any messages. - virtual void Unparent(); - - // TabContentsView implementation -------------------------------------------- - - virtual void CreateView(const gfx::Size& initial_size); - virtual RenderWidgetHostView* CreateViewForWidget( - RenderWidgetHost* render_widget_host); - virtual gfx::NativeView GetNativeView() const; - virtual gfx::NativeView GetContentNativeView() const; - virtual gfx::NativeWindow GetTopLevelNativeWindow() const; - virtual void GetContainerBounds(gfx::Rect* out) const; - virtual void SetPageTitle(const std::wstring& title); - virtual void OnTabCrashed(); - virtual void SizeContents(const gfx::Size& size); - virtual void Focus(); - virtual void SetInitialFocus(); - virtual void StoreFocus(); - virtual void RestoreFocus(); - virtual bool IsDoingDrag() const; - virtual void CancelDragAndCloseTab(); - - // Backend implementation of RenderViewHostDelegate::View. - virtual void ShowContextMenu(const ContextMenuParams& params); - virtual void ShowPopupMenu(const gfx::Rect& bounds, - int item_height, - double item_font_size, - int selected_item, - const std::vector<WebMenuItem>& items, - bool right_aligned); - virtual void StartDragging(const WebDropData& drop_data, - WebKit::WebDragOperationsMask operations, - const SkBitmap& image, - const gfx::Point& image_offset); - virtual void UpdateDragCursor(WebKit::WebDragOperation operation); - virtual void GotFocus(); - virtual void TakeFocus(bool reverse); - - // WidgetWin overridde. - virtual views::FocusManager* GetFocusManager(); - - void EndDragging(); - - WebDropTarget* drop_target() const { return drop_target_.get(); } - - private: - // A helper method for closing the tab. - void CloseTab(); - - // Windows events ------------------------------------------------------------ - - // Overrides from WidgetWin. - virtual void OnDestroy(); - virtual void OnHScroll(int scroll_type, short position, HWND scrollbar); - virtual void OnMouseLeave(); - virtual LRESULT OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param); - virtual void OnPaint(HDC junk_dc); - virtual LRESULT OnReflectedMessage(UINT msg, WPARAM w_param, LPARAM l_param); - virtual void OnVScroll(int scroll_type, short position, HWND scrollbar); - virtual void OnWindowPosChanged(WINDOWPOS* window_pos); - virtual void OnSize(UINT param, const WTL::CSize& size); - virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param); - virtual void OnNCPaint(HRGN rgn); - - // Backend for all scroll messages, the |message| parameter indicates which - // one it is. - void ScrollCommon(UINT message, int scroll_type, short position, - HWND scrollbar); - - // Handles notifying the TabContents and other operations when the window was - // shown or hidden. - void WasHidden(); - void WasShown(); - - // Handles resizing of the contents. This will notify the RenderWidgetHostView - // of the change, reposition popups, and the find in page bar. - void WasSized(const gfx::Size& size); - - // TODO(brettw) comment these. They're confusing. - bool ScrollZoom(int scroll_type); - void WheelZoom(int distance); - - // --------------------------------------------------------------------------- - - // A drop target object that handles drags over this TabContents. - scoped_refptr<WebDropTarget> drop_target_; - - // Used to render the sad tab. This will be non-NULL only when the sad tab is - // visible. - SadTabView* sad_tab_; - - // The id used in the ViewStorage to store the last focused view. - int last_focused_view_storage_id_; - - // The context menu. Callbacks are asynchronous so we need to keep it around. - scoped_ptr<RenderViewContextMenuViews> context_menu_; - - // The FocusManager associated with this tab. Stored as it is not directly - // accessible when unparented. - views::FocusManager* focus_manager_; - - // Set to true if we want to close the tab after the system drag operation - // has finished. - bool close_tab_after_drag_ends_; - - // Used to close the tab after the stack has unwound. - base::OneShotTimer<TabContentsViewWin> close_tab_timer_; - - // Used to handle the drag-and-drop. - scoped_refptr<TabContentsDragWin> drag_handler_; - - DISALLOW_COPY_AND_ASSIGN(TabContentsViewWin); -}; +#include "chrome/browser/ui/views/tab_contents/tab_contents_view_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_WIN_H_ + diff --git a/chrome/browser/views/tab_icon_view.cc b/chrome/browser/views/tab_icon_view.cc deleted file mode 100644 index 547b039..0000000 --- a/chrome/browser/views/tab_icon_view.cc +++ /dev/null @@ -1,156 +0,0 @@ -// 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/tab_icon_view.h" - -#if defined(OS_WIN) -#include <windows.h> -#include <shellapi.h> -#endif - -#include "app/resource_bundle.h" -#include "app/theme_provider.h" -#include "base/file_util.h" -#include "base/logging.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "gfx/canvas.h" -#include "gfx/favicon_size.h" -#include "grit/app_resources.h" -#include "grit/theme_resources.h" - -#if defined(OS_WIN) -#include "chrome/browser/app_icon_win.h" -#include "gfx/icon_util.h" -#endif - -static bool g_initialized = false; -static SkBitmap* g_default_fav_icon = NULL; - -// static -void TabIconView::InitializeIfNeeded() { - if (!g_initialized) { - g_initialized = true; - -#if defined(OS_WIN) - // The default window icon is the application icon, not the default - // favicon. - HICON app_icon = GetAppIcon(); - g_default_fav_icon = - IconUtil::CreateSkBitmapFromHICON(app_icon, gfx::Size(16, 16)); - DestroyIcon(app_icon); -#else - g_default_fav_icon = - ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_PRODUCT_LOGO_16); -#endif - } -} - -TabIconView::TabIconView(TabIconViewModel* model) - : model_(model), - throbber_running_(false), - is_light_(false), - throbber_frame_(0) { - InitializeIfNeeded(); -} - -TabIconView::~TabIconView() { -} - -void TabIconView::Update() { - static bool initialized = false; - static int throbber_frame_count = 0; - if (!initialized) { - initialized = true; - SkBitmap throbber( - *ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_THROBBER)); - throbber_frame_count = throbber.width() / throbber.height(); - } - - if (throbber_running_) { - // We think the tab is loading. - if (!model_->ShouldTabIconViewAnimate()) { - // Woops, tab is invalid or not loading, reset our status and schedule - // a paint. - throbber_running_ = false; - SchedulePaint(); - } else { - // The tab is still loading, increment the frame. - throbber_frame_ = (throbber_frame_ + 1) % throbber_frame_count; - SchedulePaint(); - } - } else if (model_->ShouldTabIconViewAnimate()) { - // We didn't think we were loading, but the tab is loading. Reset the - // frame and status and schedule a paint. - throbber_running_ = true; - throbber_frame_ = 0; - SchedulePaint(); - } -} - -void TabIconView::PaintThrobber(gfx::Canvas* canvas) { - SkBitmap throbber(*GetThemeProvider()->GetBitmapNamed( - is_light_ ? IDR_THROBBER_LIGHT : IDR_THROBBER)); - int image_size = throbber.height(); - PaintIcon(canvas, throbber, throbber_frame_ * image_size, 0, image_size, - image_size, false); -} - -void TabIconView::PaintFavIcon(gfx::Canvas* canvas, const SkBitmap& bitmap) { - PaintIcon(canvas, bitmap, 0, 0, bitmap.width(), bitmap.height(), true); -} - -void TabIconView::PaintIcon(gfx::Canvas* canvas, - const SkBitmap& bitmap, - int src_x, - int src_y, - int src_w, - int src_h, - bool filter) { - // For source images smaller than the favicon square, scale them as if they - // were padded to fit the favicon square, so we don't blow up tiny favicons - // into larger or nonproportional results. - float float_src_w = static_cast<float>(src_w); - float float_src_h = static_cast<float>(src_h); - float scalable_w, scalable_h; - if (src_w <= kFavIconSize && src_h <= kFavIconSize) { - scalable_w = scalable_h = kFavIconSize; - } else { - scalable_w = float_src_w; - scalable_h = float_src_h; - } - - // Scale proportionately. - float scale = std::min(static_cast<float>(width()) / scalable_w, - static_cast<float>(height()) / scalable_h); - int dest_w = static_cast<int>(float_src_w * scale); - int dest_h = static_cast<int>(float_src_h * scale); - - // Center the scaled image. - canvas->DrawBitmapInt(bitmap, src_x, src_y, src_w, src_h, - (width() - dest_w) / 2, (height() - dest_h) / 2, dest_w, - dest_h, filter); -} - -void TabIconView::Paint(gfx::Canvas* canvas) { - bool rendered = false; - - if (throbber_running_) { - rendered = true; - PaintThrobber(canvas); - } else { - SkBitmap favicon = model_->GetFavIconForTabIconView(); - if (!favicon.isNull()) { - rendered = true; - PaintFavIcon(canvas, favicon); - } - } - - if (!rendered) - PaintFavIcon(canvas, *g_default_fav_icon); -} - -gfx::Size TabIconView::GetPreferredSize() { - return gfx::Size(kFavIconSize, kFavIconSize); -} diff --git a/chrome/browser/views/tab_icon_view.h b/chrome/browser/views/tab_icon_view.h index ef42477..064c8a7 100644 --- a/chrome/browser/views/tab_icon_view.h +++ b/chrome/browser/views/tab_icon_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,68 +6,8 @@ #define CHROME_BROWSER_VIEWS_TAB_ICON_VIEW_H_ #pragma once -#include "views/view.h" - -class SkBitmap; -class TabContents; - -//////////////////////////////////////////////////////////////////////////////// -// -// A view to display a tab fav icon or a throbber. -// -//////////////////////////////////////////////////////////////////////////////// -class TabIconView : public views::View { - public: - // Classes implement this interface to provide state for the TabIconView. - class TabIconViewModel { - public: - // Returns true if the TabIconView should show a loading animation. - virtual bool ShouldTabIconViewAnimate() const = 0; - - // Returns the favicon to display in the icon view - virtual SkBitmap GetFavIconForTabIconView() = 0; - }; - - static void InitializeIfNeeded(); - - explicit TabIconView(TabIconViewModel* provider); - virtual ~TabIconView(); - - // Invoke whenever the tab state changes or the throbber should update. - void Update(); - - // Set the throbber to the light style (for use on dark backgrounds). - void set_is_light(bool is_light) { is_light_ = is_light; } - - // Overriden from View - virtual void Paint(gfx::Canvas* canvas); - virtual gfx::Size GetPreferredSize(); - - private: - void PaintThrobber(gfx::Canvas* canvas); - void PaintFavIcon(gfx::Canvas* canvas, const SkBitmap& bitmap); - void PaintIcon(gfx::Canvas* canvas, - const SkBitmap& bitmap, - int src_x, - int src_y, - int src_w, - int src_h, - bool filter); - - // Our model. - TabIconViewModel* model_; - - // Whether the throbber is running. - bool throbber_running_; - - // Whether we should display our light or dark style. - bool is_light_; - - // Current frame of the throbber being painted. This is only used if - // throbber_running_ is true. - int throbber_frame_; - - DISALLOW_COPY_AND_ASSIGN(TabIconView); -}; +#include "chrome/browser/ui/views/tab_icon_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TAB_ICON_VIEW_H_ + diff --git a/chrome/browser/views/tabs/base_tab.cc b/chrome/browser/views/tabs/base_tab.cc deleted file mode 100644 index fa752b3..0000000 --- a/chrome/browser/views/tabs/base_tab.cc +++ /dev/null @@ -1,480 +0,0 @@ -// 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/tabs/base_tab.h" - -#include <limits> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/slide_animation.h" -#include "app/theme_provider.h" -#include "app/throb_animation.h" -#include "base/command_line.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/views/tabs/tab_controller.h" -#include "chrome/browser/view_ids.h" -#include "chrome/common/chrome_switches.h" -#include "gfx/canvas_skia.h" -#include "gfx/favicon_size.h" -#include "gfx/font.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/image_button.h" - -#ifdef WIN32 -#include "app/win_util.h" -#endif - -// How long the pulse throb takes. -static const int kPulseDurationMs = 200; - -// How long the hover state takes. -static const int kHoverDurationMs = 90; - -namespace { - -//////////////////////////////////////////////////////////////////////////////// -// TabCloseButton -// -// This is a Button subclass that causes middle clicks to be forwarded to the -// parent View by explicitly not handling them in OnMousePressed. -class TabCloseButton : public views::ImageButton { - public: - explicit TabCloseButton(views::ButtonListener* listener) - : views::ImageButton(listener) { - } - virtual ~TabCloseButton() {} - - virtual bool OnMousePressed(const views::MouseEvent& event) { - bool handled = ImageButton::OnMousePressed(event); - // Explicitly mark midle-mouse clicks as non-handled to ensure the tab - // sees them. - return event.IsOnlyMiddleMouseButton() ? false : handled; - } - - // We need to let the parent know about mouse state so that it - // can highlight itself appropriately. Note that Exit events - // fire before Enter events, so this works. - virtual void OnMouseEntered(const views::MouseEvent& event) { - CustomButton::OnMouseEntered(event); - GetParent()->OnMouseEntered(event); - } - - virtual void OnMouseExited(const views::MouseEvent& event) { - CustomButton::OnMouseExited(event); - GetParent()->OnMouseExited(event); - } - - private: - DISALLOW_COPY_AND_ASSIGN(TabCloseButton); -}; - -} // namespace - -// static -gfx::Font* BaseTab::font_ = NULL; -// static -int BaseTab::font_height_ = 0; - -//////////////////////////////////////////////////////////////////////////////// -// FaviconCrashAnimation -// -// A custom animation subclass to manage the favicon crash animation. -class BaseTab::FavIconCrashAnimation : public LinearAnimation, - public AnimationDelegate { - public: - explicit FavIconCrashAnimation(BaseTab* target) - : ALLOW_THIS_IN_INITIALIZER_LIST(LinearAnimation(1000, 25, this)), - target_(target) { - } - virtual ~FavIconCrashAnimation() {} - - // Animation overrides: - virtual void AnimateToState(double state) { - const double kHidingOffset = 27; - - if (state < .5) { - target_->SetFavIconHidingOffset( - static_cast<int>(floor(kHidingOffset * 2.0 * state))); - } else { - target_->DisplayCrashedFavIcon(); - target_->SetFavIconHidingOffset( - static_cast<int>( - floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset)))); - } - } - - // AnimationDelegate overrides: - virtual void AnimationCanceled(const Animation* animation) { - target_->SetFavIconHidingOffset(0); - } - - private: - BaseTab* target_; - - DISALLOW_COPY_AND_ASSIGN(FavIconCrashAnimation); -}; - -BaseTab::BaseTab(TabController* controller) - : controller_(controller), - closing_(false), - dragging_(false), - loading_animation_frame_(0), - throbber_disabled_(false), - theme_provider_(NULL), - fav_icon_hiding_offset_(0), - should_display_crashed_favicon_(false) { - BaseTab::InitResources(); - - SetID(VIEW_ID_TAB); - - // Add the Close Button. - close_button_ = new TabCloseButton(this); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetBitmapNamed(IDR_TAB_CLOSE)); - close_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetBitmapNamed(IDR_TAB_CLOSE_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetBitmapNamed(IDR_TAB_CLOSE_P)); - close_button_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_CLOSE_TAB)); - close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); - // Disable animation so that the red danger sign shows up immediately - // to help avoid mis-clicks. - close_button_->SetAnimationDuration(0); - AddChildView(close_button_); - - SetContextMenuController(this); -} - -BaseTab::~BaseTab() { -} - -void BaseTab::SetData(const TabRendererData& data) { - TabRendererData old(data_); - data_ = data; - - if (data_.crashed) { - if (!should_display_crashed_favicon_ && !IsPerformingCrashAnimation()) - StartCrashAnimation(); - } else { - if (IsPerformingCrashAnimation()) - StopCrashAnimation(); - ResetCrashedFavIcon(); - } - - // Sets the accessible name for the tab. - SetAccessibleName(UTF16ToWide(data_.title)); - - DataChanged(old); - - Layout(); -} - -void BaseTab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { - // If this is an extension app and a command line flag is set, - // then disable the throbber. - throbber_disabled_ = data().app && - CommandLine::ForCurrentProcess()->HasSwitch(switches::kAppsNoThrob); - - if (throbber_disabled_) - return; - - if (state == data_.network_state && - state == TabRendererData::NETWORK_STATE_NONE) { - // If the network state is none and hasn't changed, do nothing. Otherwise we - // need to advance the animation frame. - return; - } - - TabRendererData::NetworkState old_state = data_.network_state; - data_.network_state = state; - AdvanceLoadingAnimation(old_state, state); -} - -void BaseTab::StartPulse() { - if (!pulse_animation_.get()) { - pulse_animation_.reset(new ThrobAnimation(this)); - pulse_animation_->SetSlideDuration(kPulseDurationMs); - if (animation_container_.get()) - pulse_animation_->SetContainer(animation_container_.get()); - } - pulse_animation_->Reset(); - pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); -} - -void BaseTab::StopPulse() { - if (!pulse_animation_.get()) - return; - - pulse_animation_->Stop(); // Do stop so we get notified. - pulse_animation_.reset(NULL); -} - -bool BaseTab::IsSelected() const { - return controller() ? controller()->IsTabSelected(this) : true; -} - -bool BaseTab::IsCloseable() const { - return controller() ? controller()->IsTabCloseable(this) : true; -} - -void BaseTab::OnMouseEntered(const views::MouseEvent& e) { - if (!hover_animation_.get()) { - hover_animation_.reset(new SlideAnimation(this)); - hover_animation_->SetContainer(animation_container_.get()); - hover_animation_->SetSlideDuration(kHoverDurationMs); - } - hover_animation_->SetTweenType(Tween::EASE_OUT); - hover_animation_->Show(); -} - -void BaseTab::OnMouseExited(const views::MouseEvent& e) { - hover_animation_->SetTweenType(Tween::EASE_IN); - hover_animation_->Hide(); -} - -bool BaseTab::OnMousePressed(const views::MouseEvent& event) { - if (!controller()) - return false; - - if (event.IsOnlyLeftMouseButton()) { - // Store whether or not we were selected just now... we only want to be - // able to drag foreground tabs, so we don't start dragging the tab if - // it was in the background. - bool just_selected = !IsSelected(); - if (just_selected) - controller()->SelectTab(this); - controller()->MaybeStartDrag(this, event); - } - return true; -} - -bool BaseTab::OnMouseDragged(const views::MouseEvent& event) { - if (controller()) - controller()->ContinueDrag(event); - return true; -} - -void BaseTab::OnMouseReleased(const views::MouseEvent& event, bool canceled) { - if (!controller()) - return; - - // Notify the drag helper that we're done with any potential drag operations. - // Clean up the drag helper, which is re-created on the next mouse press. - // In some cases, ending the drag will schedule the tab for destruction; if - // so, bail immediately, since our members are already dead and we shouldn't - // do anything else except drop the tab where it is. - if (controller()->EndDrag(canceled)) - return; - - // Close tab on middle click, but only if the button is released over the tab - // (normal windows behavior is to discard presses of a UI element where the - // releases happen off the element). - if (event.IsMiddleMouseButton()) { - if (HitTest(event.location())) { - controller()->CloseTab(this); - } else if (closing_) { - // We're animating closed and a middle mouse button was pushed on us but - // we don't contain the mouse anymore. We assume the user is clicking - // quicker than the animation and we should close the tab that falls under - // the mouse. - BaseTab* closest_tab = controller()->GetTabAt(this, event.location()); - if (closest_tab) - controller()->CloseTab(closest_tab); - } - } -} - -bool BaseTab::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { - if (data_.title.empty()) - return false; - - std::wstring title = UTF16ToWide(data_.title); - // Only show the tooltip if the title is truncated. - if (font_->GetStringWidth(title) > title_bounds().width()) { - *tooltip = title; - return true; - } - return false; -} - -AccessibilityTypes::Role BaseTab::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PAGETAB; -} - -ThemeProvider* BaseTab::GetThemeProvider() { - ThemeProvider* tp = View::GetThemeProvider(); - return tp ? tp : theme_provider_; -} - -void BaseTab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, - TabRendererData::NetworkState state) { - static bool initialized = false; - static int loading_animation_frame_count = 0; - static int waiting_animation_frame_count = 0; - static int waiting_to_loading_frame_count_ratio = 0; - if (!initialized) { - initialized = true; - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - SkBitmap loading_animation(*rb.GetBitmapNamed(IDR_THROBBER)); - loading_animation_frame_count = - loading_animation.width() / loading_animation.height(); - SkBitmap waiting_animation(*rb.GetBitmapNamed(IDR_THROBBER_WAITING)); - waiting_animation_frame_count = - waiting_animation.width() / waiting_animation.height(); - waiting_to_loading_frame_count_ratio = - waiting_animation_frame_count / loading_animation_frame_count; - } - - // The waiting animation is the reverse of the loading animation, but at a - // different rate - the following reverses and scales the animation_frame_ - // so that the frame is at an equivalent position when going from one - // animation to the other. - if (state != old_state) { - loading_animation_frame_ = loading_animation_frame_count - - (loading_animation_frame_ / waiting_to_loading_frame_count_ratio); - } - - if (state != TabRendererData::NETWORK_STATE_NONE) { - loading_animation_frame_ = (loading_animation_frame_ + 1) % - ((state == TabRendererData::NETWORK_STATE_WAITING) ? - waiting_animation_frame_count : loading_animation_frame_count); - } else { - loading_animation_frame_ = 0; - } - SchedulePaint(); -} - -void BaseTab::PaintIcon(gfx::Canvas* canvas, int x, int y) { - if (base::i18n::IsRTL()) { - x = width() - x - - (data().favicon.isNull() ? kFavIconSize : data().favicon.width()); - } - - int favicon_x = x; - if (!data().favicon.isNull() && data().favicon.width() != kFavIconSize) - favicon_x += (data().favicon.width() - kFavIconSize) / 2; - - if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { - ThemeProvider* tp = GetThemeProvider(); - SkBitmap frames(*tp->GetBitmapNamed( - (data().network_state == TabRendererData::NETWORK_STATE_WAITING) ? - IDR_THROBBER_WAITING : IDR_THROBBER)); - int image_size = frames.height(); - int image_offset = loading_animation_frame_ * image_size; - int dst_y = (height() - image_size) / 2; - canvas->DrawBitmapInt(frames, image_offset, 0, image_size, - image_size, favicon_x, dst_y, image_size, image_size, - false); - } else { - canvas->Save(); - canvas->ClipRectInt(0, 0, width(), height()); - if (should_display_crashed_favicon_) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - SkBitmap crashed_fav_icon(*rb.GetBitmapNamed(IDR_SAD_FAVICON)); - canvas->DrawBitmapInt(crashed_fav_icon, 0, 0, crashed_fav_icon.width(), - crashed_fav_icon.height(), favicon_x, - (height() - crashed_fav_icon.height()) / 2 + fav_icon_hiding_offset_, - kFavIconSize, kFavIconSize, true); - } else { - if (!data().favicon.isNull()) { - // TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch - // to using that class to render the favicon). - int size = data().favicon.width(); - canvas->DrawBitmapInt(data().favicon, 0, 0, - data().favicon.width(), - data().favicon.height(), - x, y + fav_icon_hiding_offset_, size, size, - true); - } - } - canvas->Restore(); - } -} - -void BaseTab::PaintTitle(gfx::Canvas* canvas, SkColor title_color) { - // Paint the Title. - string16 title = data().title; - if (title.empty()) { - title = data().loading ? - l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : - TabContents::GetDefaultTitle(); - } else { - Browser::FormatTitleForDisplay(&title); - } - - canvas->DrawStringInt(UTF16ToWideHack(title), *font_, title_color, - title_bounds().x(), title_bounds().y(), - title_bounds().width(), title_bounds().height()); -} - -void BaseTab::AnimationProgressed(const Animation* animation) { - SchedulePaint(); -} - -void BaseTab::AnimationCanceled(const Animation* animation) { - SchedulePaint(); -} - -void BaseTab::AnimationEnded(const Animation* animation) { - SchedulePaint(); -} - -void BaseTab::ButtonPressed(views::Button* sender, const views::Event& event) { - DCHECK(sender == close_button_); - controller()->CloseTab(this); -} - -void BaseTab::ShowContextMenu(views::View* source, - const gfx::Point& p, - bool is_mouse_gesture) { - if (controller()) - controller()->ShowContextMenu(this, p); -} - -void BaseTab::SetFavIconHidingOffset(int offset) { - fav_icon_hiding_offset_ = offset; - SchedulePaint(); -} - -void BaseTab::DisplayCrashedFavIcon() { - should_display_crashed_favicon_ = true; -} - -void BaseTab::ResetCrashedFavIcon() { - should_display_crashed_favicon_ = false; -} - -void BaseTab::StartCrashAnimation() { - if (!crash_animation_.get()) - crash_animation_.reset(new FavIconCrashAnimation(this)); - crash_animation_->Stop(); - crash_animation_->Start(); -} - -void BaseTab::StopCrashAnimation() { - if (!crash_animation_.get()) - return; - crash_animation_->Stop(); -} - -bool BaseTab::IsPerformingCrashAnimation() const { - return crash_animation_.get() && crash_animation_->is_animating(); -} - -// static -void BaseTab::InitResources() { - static bool initialized = false; - if (!initialized) { - initialized = true; - font_ = new gfx::Font( - ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont)); - font_height_ = font_->GetHeight(); - } -} diff --git a/chrome/browser/views/tabs/base_tab.h b/chrome/browser/views/tabs/base_tab.h index 9d6567b..e826fbf 100644 --- a/chrome/browser/views/tabs/base_tab.h +++ b/chrome/browser/views/tabs/base_tab.h @@ -6,199 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_BASE_TAB_H_ #pragma once -#include "app/animation.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/views/tabs/tab_renderer_data.h" -#include "views/controls/button/button.h" -#include "views/view.h" - -class AnimationContainer; -class BaseTab; -class SlideAnimation; -class TabController; -class ThrobAnimation; - -namespace gfx { -class Font; -} // namespace gfx - -namespace views { -class ImageButton; -} // namespace views - -// Base class for tab renderers. -class BaseTab : public AnimationDelegate, - public views::ButtonListener, - public views::ContextMenuController, - public views::View { - public: - explicit BaseTab(TabController* controller); - virtual ~BaseTab(); - - // Sets the data this tabs displays. Invokes DataChanged for subclasses to - // update themselves appropriately. - void SetData(const TabRendererData& data); - const TabRendererData& data() const { return data_; } - - // Sets the network state. If the network state changes NetworkStateChanged is - // invoked. - virtual void UpdateLoadingAnimation(TabRendererData::NetworkState state); - - // Starts/Stops a pulse animation. - void StartPulse(); - void StopPulse(); - - // Used to set/check whether this Tab is being animated closed. - void set_closing(bool closing) { closing_ = closing; } - bool closing() const { return closing_; } - - // See description above field. - void set_dragging(bool dragging) { dragging_ = dragging; } - bool dragging() const { return dragging_; } - - // Sets the container all animations run from. - void set_animation_container(AnimationContainer* container) { - animation_container_ = container; - } - AnimationContainer* animation_container() const { - return animation_container_.get(); - } - - // Set the theme provider - because we get detached, we are frequently - // outside of a hierarchy with a theme provider at the top. This should be - // called whenever we're detached or attached to a hierarchy. - void set_theme_provider(ThemeProvider* provider) { - theme_provider_ = provider; - } - - // Returns true if the tab is selected. - virtual bool IsSelected() const; - - // Returns true if the tab is closeable. - bool IsCloseable() const; - - // views::View overrides: - virtual void OnMouseEntered(const views::MouseEvent& event); - virtual void OnMouseExited(const views::MouseEvent& event); - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual bool OnMouseDragged(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, - bool canceled); - virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip); - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual ThemeProvider* GetThemeProvider(); - - protected: - // Invoked from SetData after |data_| has been updated to the new data. - virtual void DataChanged(const TabRendererData& old) {} - - // Invoked if data_.network_state changes, or the network_state is not none. - virtual void AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, - TabRendererData::NetworkState state); - - TabController* controller() const { return controller_; } - - // Returns the pulse animation. The pulse animation is non-null if StartPulse - // has been invoked. - ThrobAnimation* pulse_animation() const { return pulse_animation_.get(); } - - // Returns the hover animation. This may return null. - const SlideAnimation* hover_animation() const { - return hover_animation_.get(); - } - - views::ImageButton* close_button() const { return close_button_; } - - // Paints the icon at the specified coordinates, mirrored for RTL if needed. - void PaintIcon(gfx::Canvas* canvas, int x, int y); - void PaintTitle(gfx::Canvas* canvas, SkColor title_color); - - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation); - virtual void AnimationCanceled(const Animation* animation); - virtual void AnimationEnded(const Animation* animation); - - // views::ButtonListener overrides: - virtual void ButtonPressed(views::Button* sender, - const views::Event& event); - - // views::ContextMenuController overrides: - virtual void ShowContextMenu(views::View* source, - const gfx::Point& p, - bool is_mouse_gesture); - - // Returns the bounds of the title. - virtual const gfx::Rect& title_bounds() const = 0; - - static gfx::Font* font() { return font_; } - static int font_height() { return font_height_; } - - private: - // The animation object used to swap the favicon with the sad tab icon. - class FavIconCrashAnimation; - - // Set the temporary offset for the favicon. This is used during the crash - // animation. - void SetFavIconHidingOffset(int offset); - - void DisplayCrashedFavIcon(); - void ResetCrashedFavIcon(); - - // Starts/Stops the crash animation. - void StartCrashAnimation(); - void StopCrashAnimation(); - - // Return true if the crash animation is currently running. - bool IsPerformingCrashAnimation() const; - - static void InitResources(); - - // The controller. - // WARNING: this is null during detached tab dragging. - TabController* controller_; - - TabRendererData data_; - - // True if the tab is being animated closed. - bool closing_; - - // True if the tab is being dragged. - bool dragging_; - - // Pulse animation. - scoped_ptr<ThrobAnimation> pulse_animation_; - - // Hover animation. - scoped_ptr<SlideAnimation> hover_animation_; - - // Crash animation. - scoped_ptr<FavIconCrashAnimation> crash_animation_; - - scoped_refptr<AnimationContainer> animation_container_; - - views::ImageButton* close_button_; - - // The current index of the loading animation. - int loading_animation_frame_; - - // Whether to disable throbber animations. Only true if this is an app tab - // renderer and a command line flag has been passed in to disable the - // animations. - bool throbber_disabled_; - - ThemeProvider* theme_provider_; - - // The offset used to animate the favicon location. This is used when the tab - // crashes. - int fav_icon_hiding_offset_; - - bool should_display_crashed_favicon_; - - static gfx::Font* font_; - static int font_height_; - - DISALLOW_COPY_AND_ASSIGN(BaseTab); -}; +#include "chrome/browser/ui/views/tabs/base_tab.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_BASE_TAB_H_ + diff --git a/chrome/browser/views/tabs/base_tab_strip.cc b/chrome/browser/views/tabs/base_tab_strip.cc deleted file mode 100644 index 4f844ed..0000000 --- a/chrome/browser/views/tabs/base_tab_strip.cc +++ /dev/null @@ -1,473 +0,0 @@ -// 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/tabs/base_tab_strip.h" - -#include "base/logging.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/tabs/dragged_tab_controller.h" -#include "chrome/browser/views/tabs/tab_strip_controller.h" -#include "views/widget/root_view.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "app/win_util.h" -#include "views/widget/widget_win.h" -#endif - -namespace { - -// Animation delegate used when a dragged tab is released. When done sets the -// dragging state to false. -class ResetDraggingStateDelegate - : public views::BoundsAnimator::OwnedAnimationDelegate { - public: - explicit ResetDraggingStateDelegate(BaseTab* tab) : tab_(tab) { - } - - virtual void AnimationEnded(const Animation* animation) { - tab_->set_dragging(false); - } - - virtual void AnimationCanceled(const Animation* animation) { - tab_->set_dragging(false); - } - - private: - BaseTab* tab_; - - DISALLOW_COPY_AND_ASSIGN(ResetDraggingStateDelegate); -}; - -} // namespace - -// AnimationDelegate used when removing a tab. Does the necessary cleanup when -// done. -class BaseTabStrip::RemoveTabDelegate - : public views::BoundsAnimator::OwnedAnimationDelegate { - public: - RemoveTabDelegate(BaseTabStrip* tab_strip, BaseTab* tab) - : tabstrip_(tab_strip), - tab_(tab) { - } - - virtual void AnimationEnded(const Animation* animation) { - CompleteRemove(); - } - - virtual void AnimationCanceled(const Animation* animation) { - // We can be canceled for two interesting reasons: - // . The tab we reference was dragged back into the tab strip. In this case - // we don't want to remove the tab (closing is false). - // . The drag was completed before the animation completed - // (DestroyDraggedSourceTab). In this case we need to remove the tab - // (closing is true). - if (tab_->closing()) - CompleteRemove(); - } - - private: - void CompleteRemove() { - if (!tab_->closing()) { - // The tab was added back yet we weren't canceled. This shouldn't happen. - NOTREACHED(); - return; - } - tabstrip_->RemoveAndDeleteTab(tab_); - HighlightCloseButton(); - } - - // When the animation completes, we send the Container a message to simulate - // a mouse moved event at the current mouse position. This tickles the Tab - // the mouse is currently over to show the "hot" state of the close button. - void HighlightCloseButton() { - if (tabstrip_->IsDragSessionActive() || - !tabstrip_->ShouldHighlightCloseButtonAfterRemove()) { - // This function is not required (and indeed may crash!) for removes - // spawned by non-mouse closes and drag-detaches. - return; - } - -#if defined(OS_WIN) - views::Widget* widget = tabstrip_->GetWidget(); - // This can be null during shutdown. See http://crbug.com/42737. - if (!widget) - return; - // Force the close button (that slides under the mouse) to highlight by - // saying the mouse just moved, but sending the same coordinates. - DWORD pos = GetMessagePos(); - POINT cursor_point = {GET_X_LPARAM(pos), GET_Y_LPARAM(pos)}; - MapWindowPoints(NULL, widget->GetNativeView(), &cursor_point, 1); - - static_cast<views::WidgetWin*>(widget)->ResetLastMouseMoveFlag(); - // Return to message loop - otherwise we may disrupt some operation that's - // in progress. - SendMessage(widget->GetNativeView(), WM_MOUSEMOVE, 0, - MAKELPARAM(cursor_point.x, cursor_point.y)); -#else - NOTIMPLEMENTED(); -#endif - } - - BaseTabStrip* tabstrip_; - BaseTab* tab_; - - DISALLOW_COPY_AND_ASSIGN(RemoveTabDelegate); -}; - -BaseTabStrip::BaseTabStrip(TabStripController* controller, Type type) - : controller_(controller), - type_(type), - attaching_dragged_tab_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(bounds_animator_(this)) { -} - -BaseTabStrip::~BaseTabStrip() { -} - -void BaseTabStrip::UpdateLoadingAnimations() { - controller_->UpdateLoadingAnimations(); -} - -bool BaseTabStrip::IsAnimating() const { - return bounds_animator_.IsAnimating(); -} - -BaseTab* BaseTabStrip::GetSelectedBaseTab() const { - return GetBaseTabAtModelIndex(controller_->GetSelectedIndex()); -} - -void BaseTabStrip::AddTabAt(int model_index, - bool foreground, - const TabRendererData& data) { - BaseTab* tab = CreateTab(); - tab->SetData(data); - - TabData d = { tab, gfx::Rect() }; - tab_data_.insert(tab_data_.begin() + ModelIndexToTabIndex(model_index), d); - - AddChildView(tab); - - // Don't animate the first tab, it looks weird, and don't animate anything - // if the containing window isn't visible yet. - if (tab_count() > 1 && GetWindow() && GetWindow()->IsVisible()) - StartInsertTabAnimation(model_index, foreground); - else - DoLayout(); -} - -void BaseTabStrip::MoveTab(int from_model_index, int to_model_index) { - int from_tab_data_index = ModelIndexToTabIndex(from_model_index); - - BaseTab* tab = tab_data_[from_tab_data_index].tab; - tab_data_.erase(tab_data_.begin() + from_tab_data_index); - - TabData data = {tab, gfx::Rect()}; - - int to_tab_data_index = ModelIndexToTabIndex(to_model_index); - - tab_data_.insert(tab_data_.begin() + to_tab_data_index, data); - - StartMoveTabAnimation(); -} - -void BaseTabStrip::SetTabData(int model_index, const TabRendererData& data) { - BaseTab* tab = GetBaseTabAtModelIndex(model_index); - bool mini_state_changed = tab->data().mini != data.mini; - tab->SetData(data); - tab->SchedulePaint(); - - if (mini_state_changed) { - if (GetWindow() && GetWindow()->IsVisible()) - StartMiniTabAnimation(); - else - DoLayout(); - } -} - -BaseTab* BaseTabStrip::GetBaseTabAtModelIndex(int model_index) const { - return base_tab_at_tab_index(ModelIndexToTabIndex(model_index)); -} - -int BaseTabStrip::GetModelIndexOfBaseTab(const BaseTab* tab) const { - for (int i = 0, model_index = 0; i < tab_count(); ++i) { - BaseTab* current_tab = base_tab_at_tab_index(i); - if (!current_tab->closing()) { - if (current_tab == tab) - return model_index; - model_index++; - } - } - return -1; -} - -int BaseTabStrip::GetModelCount() const { - return controller_->GetCount(); -} - -bool BaseTabStrip::IsValidModelIndex(int model_index) const { - return controller_->IsValidIndex(model_index); -} - -int BaseTabStrip::ModelIndexToTabIndex(int model_index) const { - int current_model_index = 0; - for (int i = 0; i < tab_count(); ++i) { - if (!base_tab_at_tab_index(i)->closing()) { - if (current_model_index == model_index) - return i; - current_model_index++; - } - } - return static_cast<int>(tab_data_.size()); -} - -bool BaseTabStrip::IsDragSessionActive() const { - return drag_controller_.get() != NULL; -} - -void BaseTabStrip::SelectTab(BaseTab* tab) { - int model_index = GetModelIndexOfBaseTab(tab); - if (IsValidModelIndex(model_index)) - controller_->SelectTab(model_index); -} - -void BaseTabStrip::CloseTab(BaseTab* tab) { - // Find the closest model index. We do this so that the user can rapdily close - // tabs and have the close click close the next tab. - int model_index = 0; - for (int i = 0; i < tab_count(); ++i) { - BaseTab* current_tab = base_tab_at_tab_index(i); - if (current_tab == tab) - break; - if (!current_tab->closing()) - model_index++; - } - - if (IsValidModelIndex(model_index)) - controller_->CloseTab(model_index); -} - -void BaseTabStrip::ShowContextMenu(BaseTab* tab, const gfx::Point& p) { - controller_->ShowContextMenu(tab, p); -} - -bool BaseTabStrip::IsTabSelected(const BaseTab* tab) const { - int model_index = GetModelIndexOfBaseTab(tab); - return IsValidModelIndex(model_index) && - controller_->IsTabSelected(model_index); -} - -bool BaseTabStrip::IsTabPinned(const BaseTab* tab) const { - if (tab->closing()) - return false; - - int model_index = GetModelIndexOfBaseTab(tab); - return IsValidModelIndex(model_index) && - controller_->IsTabPinned(model_index); -} - -bool BaseTabStrip::IsTabCloseable(const BaseTab* tab) const { - int model_index = GetModelIndexOfBaseTab(tab); - return !IsValidModelIndex(model_index) || - controller_->IsTabCloseable(model_index); -} - -void BaseTabStrip::MaybeStartDrag(BaseTab* tab, - const views::MouseEvent& event) { - // Don't accidentally start any drag operations during animations if the - // mouse is down... during an animation tabs are being resized automatically, - // so the View system can misinterpret this easily if the mouse is down that - // the user is dragging. - if (IsAnimating() || tab->closing() || - controller_->HasAvailableDragActions() == 0) { - return; - } - int model_index = GetModelIndexOfBaseTab(tab); - if (!IsValidModelIndex(model_index)) { - CHECK(false); - return; - } - drag_controller_.reset(new DraggedTabController(tab, this)); - drag_controller_->CaptureDragInfo(tab, event.location()); -} - -void BaseTabStrip::ContinueDrag(const views::MouseEvent& event) { - // We can get called even if |MaybeStartDrag| wasn't called in the event of - // a TabStrip animation when the mouse button is down. In this case we should - // _not_ continue the drag because it can lead to weird bugs. - if (drag_controller_.get()) { - bool started_drag = drag_controller_->started_drag(); - drag_controller_->Drag(); - if (drag_controller_->started_drag() && !started_drag) { - // The drag just started. Redirect mouse events to us to that the tab that - // originated the drag can be safely deleted. - GetRootView()->SetMouseHandler(this); - } - } -} - -bool BaseTabStrip::EndDrag(bool canceled) { - if (!drag_controller_.get()) - return false; - bool started_drag = drag_controller_->started_drag(); - drag_controller_->EndDrag(canceled); - return started_drag; -} - -BaseTab* BaseTabStrip::GetTabAt(BaseTab* tab, - const gfx::Point& tab_in_tab_coordinates) { - gfx::Point local_point = tab_in_tab_coordinates; - ConvertPointToView(tab, this, &local_point); - views::View* view = GetViewForPoint(local_point); - if (!view) - return NULL; // No tab contains the point. - - // Walk up the view hierarchy until we find a tab, or the TabStrip. - while (view && view != this && view->GetID() != VIEW_ID_TAB) - view = view->GetParent(); - - return view && view->GetID() == VIEW_ID_TAB ? - static_cast<BaseTab*>(view) : NULL; -} - -void BaseTabStrip::Layout() { - // Only do a layout if our size changed. - if (last_layout_size_ == size()) - return; - DoLayout(); -} - -bool BaseTabStrip::OnMouseDragged(const views::MouseEvent& event) { - if (drag_controller_.get()) - drag_controller_->Drag(); - return true; -} - -void BaseTabStrip::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - EndDrag(canceled); -} - -void BaseTabStrip::StartRemoveTabAnimation(int model_index) { - PrepareForAnimation(); - - // Mark the tab as closing. - BaseTab* tab = GetBaseTabAtModelIndex(model_index); - tab->set_closing(true); - - // Start an animation for the tabs. - GenerateIdealBounds(); - AnimateToIdealBounds(); - - // Animate the tab being closed to 0x0. - gfx::Rect tab_bounds = tab->bounds(); - if (type() == HORIZONTAL_TAB_STRIP) - tab_bounds.set_width(0); - else - tab_bounds.set_height(0); - bounds_animator_.AnimateViewTo(tab, tab_bounds); - - // Register delegate to do cleanup when done, BoundsAnimator takes - // ownership of RemoveTabDelegate. - bounds_animator_.SetAnimationDelegate(tab, new RemoveTabDelegate(this, tab), - true); -} - -void BaseTabStrip::StartMiniTabAnimation() { - PrepareForAnimation(); - - GenerateIdealBounds(); - AnimateToIdealBounds(); -} - -void BaseTabStrip::RemoveAndDeleteTab(BaseTab* tab) { - int tab_data_index = TabIndexOfTab(tab); - - DCHECK(tab_data_index != -1); - - // Remove the Tab from the TabStrip's list... - tab_data_.erase(tab_data_.begin() + tab_data_index); - - delete tab; -} - -int BaseTabStrip::TabIndexOfTab(BaseTab* tab) const { - for (int i = 0; i < tab_count(); ++i) { - if (base_tab_at_tab_index(i) == tab) - return i; - } - return -1; -} - -void BaseTabStrip::DestroyDragController() { - if (IsDragSessionActive()) - drag_controller_.reset(NULL); -} - -void BaseTabStrip::StartedDraggingTab(BaseTab* tab) { - PrepareForAnimation(); - - // Reset the dragging state of all other tabs. We do this as the painting code - // only handles one tab being dragged at a time. If another tab is marked as - // dragging, it should also be closing. - for (int i = 0; i < tab_count(); ++i) - base_tab_at_tab_index(i)->set_dragging(false); - - tab->set_dragging(true); - - // Stop any animations on the tab. - bounds_animator_.StopAnimatingView(tab); - - // Move the tab to its ideal bounds. - GenerateIdealBounds(); - int tab_data_index = TabIndexOfTab(tab); - DCHECK(tab_data_index != -1); - tab->SetBounds(ideal_bounds(tab_data_index)); - SchedulePaint(); -} - -void BaseTabStrip::StoppedDraggingTab(BaseTab* tab) { - int tab_data_index = TabIndexOfTab(tab); - if (tab_data_index == -1) { - // The tab was removed before the drag completed. Don't do anything. - return; - } - - PrepareForAnimation(); - - // Animate the view back to its correct position. - GenerateIdealBounds(); - AnimateToIdealBounds(); - bounds_animator_.AnimateViewTo(tab, ideal_bounds(TabIndexOfTab(tab))); - - // Install a delegate to reset the dragging state when done. We have to leave - // dragging true for the tab otherwise it'll draw beneath the new tab button. - bounds_animator_.SetAnimationDelegate(tab, - new ResetDraggingStateDelegate(tab), - true); -} - -void BaseTabStrip::PrepareForAnimation() { - if (!IsDragSessionActive() && !DraggedTabController::IsAttachedTo(this)) { - for (int i = 0; i < tab_count(); ++i) - base_tab_at_tab_index(i)->set_dragging(false); - } -} - -AnimationDelegate* BaseTabStrip::CreateRemoveTabDelegate(BaseTab* tab) { - return new RemoveTabDelegate(this, tab); -} - -void BaseTabStrip::DoLayout() { - last_layout_size_ = size(); - - StopAnimating(false); - - GenerateIdealBounds(); - - for (int i = 0; i < tab_count(); ++i) - tab_data_[i].tab->SetBounds(tab_data_[i].ideal_bounds); - - SchedulePaint(); -} diff --git a/chrome/browser/views/tabs/base_tab_strip.h b/chrome/browser/views/tabs/base_tab_strip.h index e3f5231..603dcf9 100644 --- a/chrome/browser/views/tabs/base_tab_strip.h +++ b/chrome/browser/views/tabs/base_tab_strip.h @@ -6,261 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_BASE_TAB_STRIP_H_ #pragma once -#include <vector> - -#include "base/scoped_ptr.h" -#include "chrome/browser/views/tabs/base_tab.h" -#include "chrome/browser/views/tabs/tab_controller.h" -#include "views/animation/bounds_animator.h" -#include "views/view.h" - -class BaseTab; -class DraggedTabController; -class TabStrip; -class TabStripController; -class ThemeProvider; - -// Base class for the view tab strip implementations. -class BaseTabStrip : public views::View, - public TabController { - public: - enum Type { - HORIZONTAL_TAB_STRIP, - VERTICAL_TAB_STRIP - }; - - BaseTabStrip(TabStripController* controller, Type type); - virtual ~BaseTabStrip(); - - Type type() const { return type_; } - - // Returns the preferred height of this TabStrip. This is based on the - // typical height of its constituent tabs. - virtual int GetPreferredHeight() = 0; - - // Set the background offset used by inactive tabs to match the frame image. - virtual void SetBackgroundOffset(const gfx::Point& offset) = 0; - - // Returns true if the specified point(TabStrip coordinates) is - // in the window caption area of the browser window. - virtual bool IsPositionInWindowCaption(const gfx::Point& point) = 0; - - // Sets the bounds of the tab at the specified |tab_index|. |tab_bounds| are - // in TabStrip coordinates. - virtual void SetDraggedTabBounds(int tab_index, - const gfx::Rect& tab_bounds) = 0; - - // Updates the loading animations displayed by tabs in the tabstrip to the - // next frame. - void UpdateLoadingAnimations(); - - // Returns true if Tabs in this TabStrip are currently changing size or - // position. - virtual bool IsAnimating() const; - - // Returns this object as a TabStrip if it is one. - virtual TabStrip* AsTabStrip() = 0; - - // Starts highlighting the tab at the specified index. - virtual void StartHighlight(int model_index) = 0; - - // Stops all tab higlighting. - virtual void StopAllHighlighting() = 0; - - // Returns the selected tab. - virtual BaseTab* GetSelectedBaseTab() const; - - // Retrieves the ideal bounds for the Tab at the specified index. - const gfx::Rect& ideal_bounds(int tab_data_index) { - return tab_data_[tab_data_index].ideal_bounds; - } - - // Creates and returns a tab that can be used for dragging. Ownership passes - // to the caller. - virtual BaseTab* CreateTabForDragging() = 0; - - // Adds a tab at the specified index. - void AddTabAt(int model_index, - bool foreground, - const TabRendererData& data); - - // Invoked from the controller when the close initiates from the TabController - // (the user clicked the tab close button or middle clicked the tab). This is - // invoked from Close. Because of unload handlers Close is not always - // immediately followed by RemoveTabAt. - virtual void PrepareForCloseAt(int model_index) {} - - // Removes a tab at the specified index. - virtual void RemoveTabAt(int model_index) = 0; - - // Selects a tab at the specified index. |old_model_index| is the selected - // index prior to the selection change. - virtual void SelectTabAt(int old_model_index, int new_model_index) = 0; - - // Moves a tab. - virtual void MoveTab(int from_model_index, int to_model_index); - - // Invoked when the title of a tab changes and the tab isn't loading. - virtual void TabTitleChangedNotLoading(int model_index) = 0; - - // Sets the tab data at the specified model index. - virtual void SetTabData(int model_index, const TabRendererData& data); - - // Returns the tab at the specified model index. - virtual BaseTab* GetBaseTabAtModelIndex(int model_index) const; - - // Returns the tab at the specified tab index. - BaseTab* base_tab_at_tab_index(int tab_index) const { - return tab_data_[tab_index].tab; - } - - // Returns the index of the specified tab in the model coordiate system, or - // -1 if tab is closing or not valid. - virtual int GetModelIndexOfBaseTab(const BaseTab* tab) const; - - // Gets the number of Tabs in the tab strip. - // WARNING: this is the number of tabs displayed by the tabstrip, which if - // an animation is ongoing is not necessarily the same as the number of tabs - // in the model. - int tab_count() const { return static_cast<int>(tab_data_.size()); } - - // Cover method for TabStripController::GetCount. - int GetModelCount() const; - - // Cover method for TabStripController::IsValidIndex. - bool IsValidModelIndex(int model_index) const; - - // Returns the index into |tab_data_| corresponding to the index from the - // TabStripModel, or |tab_data_.size()| if there is no tab representing - // |model_index|. - int ModelIndexToTabIndex(int model_index) const; - - TabStripController* controller() const { return controller_.get(); } - - // Returns true if a drag session is currently active. - bool IsDragSessionActive() const; - - // TabController overrides: - virtual void SelectTab(BaseTab* tab); - virtual void CloseTab(BaseTab* tab); - virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p); - virtual bool IsTabSelected(const BaseTab* tab) const; - virtual bool IsTabPinned(const BaseTab* tab) const; - virtual bool IsTabCloseable(const BaseTab* tab) const; - virtual void MaybeStartDrag(BaseTab* tab, - const views::MouseEvent& event); - virtual void ContinueDrag(const views::MouseEvent& event); - virtual bool EndDrag(bool canceled); - virtual BaseTab* GetTabAt(BaseTab* tab, - const gfx::Point& tab_in_tab_coordinates); - - // View overrides: - virtual void Layout(); - - protected: - // The Tabs we contain, and their last generated "good" bounds. - struct TabData { - BaseTab* tab; - gfx::Rect ideal_bounds; - }; - - // View overrides. - virtual bool OnMouseDragged(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, - bool canceled); - - // Creates and returns a new tab. The caller owners the returned tab. - virtual BaseTab* CreateTab() = 0; - - // Invoked from |AddTabAt| after the newly created tab has been inserted. - // Subclasses should either start an animation, or layout. - virtual void StartInsertTabAnimation(int model_index, bool foreground) = 0; - - // Invoked from |MoveTab| after |tab_data_| has been updated to animate the - // move. - virtual void StartMoveTabAnimation() = 0; - - // Starts the remove tab animation. - virtual void StartRemoveTabAnimation(int model_index); - - // Starts the mini-tab animation. - virtual void StartMiniTabAnimation(); - - // Returns whether the highlight button should be highlighted after a remove. - virtual bool ShouldHighlightCloseButtonAfterRemove() { return true; } - - // Animates all the views to their ideal bounds. - // NOTE: this does *not* invoke GenerateIdealBounds, it uses the bounds - // currently set in ideal_bounds. - virtual void AnimateToIdealBounds() = 0; - - // Cleans up the Tab from the TabStrip. This is called from the tab animation - // code and is not a general-purpose method. - void RemoveAndDeleteTab(BaseTab* tab); - - // Resets the bounds of all non-closing tabs. - virtual void GenerateIdealBounds() = 0; - - void set_ideal_bounds(int index, const gfx::Rect& bounds) { - tab_data_[index].ideal_bounds = bounds; - } - - // Returns the index into |tab_data_| corresponding to the specified tab, or - // -1 if the tab isn't in |tab_data_|. - int TabIndexOfTab(BaseTab* tab) const; - - // Stops any ongoing animations. If |layout| is true and an animation is - // ongoing this does a layout. - virtual void StopAnimating(bool layout) = 0; - - // Destroys the active drag controller. - void DestroyDragController(); - - // Used by DraggedTabController when the user starts or stops dragging a tab. - void StartedDraggingTab(BaseTab* tab); - void StoppedDraggingTab(BaseTab* tab); - - // See description above field for details. - bool attaching_dragged_tab() const { return attaching_dragged_tab_; } - - views::BoundsAnimator& bounds_animator() { return bounds_animator_; } - - // Invoked prior to starting a new animation. - virtual void PrepareForAnimation(); - - // Creates an AnimationDelegate that resets state after a remove animation - // completes. The caller owns the returned object. - AnimationDelegate* CreateRemoveTabDelegate(BaseTab* tab); - - // Invoked from Layout if the size changes or layout is really needed. - virtual void DoLayout(); - - private: - class RemoveTabDelegate; - - friend class DraggedTabController; - - // See description above field for details. - void set_attaching_dragged_tab(bool value) { attaching_dragged_tab_ = value; } - - scoped_ptr<TabStripController> controller_; - - const Type type_; - - std::vector<TabData> tab_data_; - - // The controller for a drag initiated from a Tab. Valid for the lifetime of - // the drag session. - scoped_ptr<DraggedTabController> drag_controller_; - - // If true, the insert is a result of a drag attaching the tab back to the - // model. - bool attaching_dragged_tab_; - - views::BoundsAnimator bounds_animator_; - - // Size we last layed out at. - gfx::Size last_layout_size_; -}; +#include "chrome/browser/ui/views/tabs/base_tab_strip.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_BASE_TAB_STRIP_H_ + diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/views/tabs/browser_tab_strip_controller.cc deleted file mode 100644 index 78b1aa1..0000000 --- a/chrome/browser/views/tabs/browser_tab_strip_controller.cc +++ /dev/null @@ -1,428 +0,0 @@ -// 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/tabs/browser_tab_strip_controller.h" - -#include "base/auto_reset.h" -#include "base/command_line.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_menu_model.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/views/tabs/base_tab_strip.h" -#include "chrome/browser/views/tabs/tab_renderer_data.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/url_constants.h" -#include "views/controls/menu/menu_2.h" -#include "views/widget/widget.h" - -static TabRendererData::NetworkState TabContentsNetworkState( - TabContents* contents) { - if (!contents || !contents->is_loading()) - return TabRendererData::NETWORK_STATE_NONE; - if (contents->waiting_for_response()) - return TabRendererData::NETWORK_STATE_WAITING; - return TabRendererData::NETWORK_STATE_LOADING; -} - -class BrowserTabStripController::TabContextMenuContents - : public menus::SimpleMenuModel::Delegate { - public: - TabContextMenuContents(BaseTab* tab, - BrowserTabStripController* controller) - : ALLOW_THIS_IN_INITIALIZER_LIST( - model_(this, controller->IsTabPinned(tab))), - tab_(tab), - controller_(controller), - last_command_(TabStripModel::CommandFirst) { - Build(); - } - virtual ~TabContextMenuContents() { - menu_->CancelMenu(); - if (controller_) - controller_->tabstrip_->StopAllHighlighting(); - } - - void Cancel() { - controller_ = NULL; - } - - void RunMenuAt(const gfx::Point& point) { - BrowserTabStripController* controller = controller_; - menu_->RunMenuAt(point, views::Menu2::ALIGN_TOPLEFT); - // We could be gone now. Assume |this| is junk! - if (controller) - controller->tabstrip_->StopAllHighlighting(); - } - - // Overridden from menus::SimpleMenuModel::Delegate: - virtual bool IsCommandIdChecked(int command_id) const { - return controller_->IsCommandCheckedForTab( - static_cast<TabStripModel::ContextMenuCommand>(command_id), - tab_); - } - virtual bool IsCommandIdEnabled(int command_id) const { - return controller_->IsCommandEnabledForTab( - static_cast<TabStripModel::ContextMenuCommand>(command_id), - tab_); - } - virtual bool GetAcceleratorForCommandId( - int command_id, - menus::Accelerator* accelerator) { - return controller_->tabstrip_->GetWidget()->GetAccelerator(command_id, - accelerator); - } - virtual void CommandIdHighlighted(int command_id) { - controller_->StopHighlightTabsForCommand(last_command_, tab_); - last_command_ = static_cast<TabStripModel::ContextMenuCommand>(command_id); - controller_->StartHighlightTabsForCommand(last_command_, tab_); - } - virtual void ExecuteCommand(int command_id) { - controller_->ExecuteCommandForTab( - static_cast<TabStripModel::ContextMenuCommand>(command_id), - tab_); - } - - private: - void Build() { - menu_.reset(new views::Menu2(&model_)); - } - - TabMenuModel model_; - scoped_ptr<views::Menu2> menu_; - - // The tab we're showing a menu for. - BaseTab* tab_; - - // A pointer back to our hosting controller, for command state information. - BrowserTabStripController* controller_; - - // The last command that was selected, so that we can start/stop highlighting - // appropriately as the user moves through the menu. - TabStripModel::ContextMenuCommand last_command_; - - DISALLOW_COPY_AND_ASSIGN(TabContextMenuContents); -}; - -//////////////////////////////////////////////////////////////////////////////// -// BrowserTabStripController, public: - -BrowserTabStripController::BrowserTabStripController(Browser* browser, - TabStripModel* model) - : model_(model), - tabstrip_(NULL), - browser_(browser) { - model_->AddObserver(this); - - notification_registrar_.Add(this, - NotificationType::TAB_CLOSEABLE_STATE_CHANGED, - NotificationService::AllSources()); -} - -BrowserTabStripController::~BrowserTabStripController() { - // When we get here the TabStrip is being deleted. We need to explicitly - // cancel the menu, otherwise it may try to invoke something on the tabstrip - // from it's destructor. - if (context_menu_contents_.get()) - context_menu_contents_->Cancel(); - - model_->RemoveObserver(this); -} - -void BrowserTabStripController::InitFromModel(BaseTabStrip* tabstrip) { - tabstrip_ = tabstrip; - // Walk the model, calling our insertion observer method for each item within - // it. - for (int i = 0; i < model_->count(); ++i) { - TabInsertedAt(model_->GetTabContentsAt(i), i, - i == model_->selected_index()); - } -} - -bool BrowserTabStripController::IsCommandEnabledForTab( - TabStripModel::ContextMenuCommand command_id, - BaseTab* tab) const { - int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); - return model_->ContainsIndex(model_index) ? - model_->IsContextMenuCommandEnabled(model_index, command_id) : false; -} - -bool BrowserTabStripController::IsCommandCheckedForTab( - TabStripModel::ContextMenuCommand command_id, - BaseTab* tab) const { - int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); - return model_->ContainsIndex(model_index) ? - model_->IsContextMenuCommandChecked(model_index, command_id) : false; -} - -void BrowserTabStripController::ExecuteCommandForTab( - TabStripModel::ContextMenuCommand command_id, - BaseTab* tab) { - int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); - if (model_->ContainsIndex(model_index)) - model_->ExecuteContextMenuCommand(model_index, command_id); -} - -bool BrowserTabStripController::IsTabPinned(BaseTab* tab) { - return IsTabPinned(tabstrip_->GetModelIndexOfBaseTab(tab)); -} - -int BrowserTabStripController::GetCount() const { - return model_->count(); -} - -bool BrowserTabStripController::IsValidIndex(int index) const { - return model_->ContainsIndex(index); -} - -int BrowserTabStripController::GetSelectedIndex() const { - return model_->selected_index(); -} - -bool BrowserTabStripController::IsTabSelected(int model_index) const { - return model_->selected_index() == model_index; -} - -bool BrowserTabStripController::IsTabPinned(int model_index) const { - return model_->ContainsIndex(model_index) && model_->IsTabPinned(model_index); -} - -bool BrowserTabStripController::IsTabCloseable(int model_index) const { - return !model_->ContainsIndex(model_index) || - model_->delegate()->CanCloseTab(); -} - -bool BrowserTabStripController::IsNewTabPage(int model_index) const { - return model_->ContainsIndex(model_index) && - model_->GetTabContentsAt(model_index)->GetURL() == - GURL(chrome::kChromeUINewTabURL); -} - -void BrowserTabStripController::SelectTab(int model_index) { - model_->SelectTabContentsAt(model_index, true); -} - -void BrowserTabStripController::CloseTab(int model_index) { - tabstrip_->PrepareForCloseAt(model_index); - model_->CloseTabContentsAt(model_index, - TabStripModel::CLOSE_USER_GESTURE | - TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); -} - -void BrowserTabStripController::ShowContextMenu(BaseTab* tab, - const gfx::Point& p) { - context_menu_contents_.reset(new TabContextMenuContents(tab, this)); - context_menu_contents_->RunMenuAt(p); -} - -void BrowserTabStripController::UpdateLoadingAnimations() { - // Don't use the model count here as it's possible for this to be invoked - // before we've applied an update from the model (Browser::TabInsertedAt may - // be processed before us and invokes this). - for (int tab_index = 0, tab_count = tabstrip_->tab_count(); - tab_index < tab_count; ++tab_index) { - BaseTab* tab = tabstrip_->base_tab_at_tab_index(tab_index); - int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); - if (model_->ContainsIndex(model_index)) { - TabContents* contents = model_->GetTabContentsAt(model_index); - tab->UpdateLoadingAnimation(TabContentsNetworkState(contents)); - } - } -} - -int BrowserTabStripController::HasAvailableDragActions() const { - return model_->delegate()->GetDragActions(); -} - -void BrowserTabStripController::PerformDrop(bool drop_before, - int index, - const GURL& url) { - if (drop_before) { - UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLBetweenTabs"), - model_->profile()); - - // Insert a new tab. - TabContents* contents = model_->delegate()->CreateTabContentsForURL( - url, GURL(), model_->profile(), PageTransition::TYPED, false, NULL); - model_->AddTabContents(contents, index, PageTransition::GENERATED, - TabStripModel::ADD_SELECTED); - } else { - UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"), - model_->profile()); - - model_->GetTabContentsAt(index)->controller().LoadURL( - url, GURL(), PageTransition::GENERATED); - model_->SelectTabContentsAt(index, true); - } -} - -bool BrowserTabStripController::IsCompatibleWith(BaseTabStrip* other) const { - Profile* other_profile = - static_cast<BrowserTabStripController*>(other->controller())->profile(); - return other_profile == profile(); -} - -void BrowserTabStripController::CreateNewTab() { - UserMetrics::RecordAction(UserMetricsAction("NewTab_Button"), - model_->profile()); - - model_->delegate()->AddBlankTab(true); -} - -//////////////////////////////////////////////////////////////////////////////// -// BrowserTabStripController, TabStripModelObserver implementation: - -void BrowserTabStripController::TabInsertedAt(TabContents* contents, - int model_index, - bool foreground) { - DCHECK(contents); - DCHECK(model_index == TabStripModel::kNoTab || - model_->ContainsIndex(model_index)); - // This tab may be attached to another browser window, we should notify - // renderer. - contents->render_view_host()->UpdateBrowserWindowId( - contents->controller().window_id().id()); - - TabRendererData data; - SetTabRendererDataFromModel(contents, model_index, &data); - tabstrip_->AddTabAt(model_index, foreground, data); -} - -void BrowserTabStripController::TabDetachedAt(TabContents* contents, - int model_index) { - tabstrip_->RemoveTabAt(model_index); -} - -void BrowserTabStripController::TabSelectedAt(TabContents* old_contents, - TabContents* contents, - int model_index, - bool user_gesture) { - tabstrip_->SelectTabAt(model_->GetIndexOfTabContents(old_contents), - model_index); -} - -void BrowserTabStripController::TabMoved(TabContents* contents, - int from_model_index, - int to_model_index) { - // Update the data first as the pinned state may have changed. - TabRendererData data; - SetTabRendererDataFromModel(contents, to_model_index, &data); - tabstrip_->SetTabData(from_model_index, data); - - tabstrip_->MoveTab(from_model_index, to_model_index); -} - -void BrowserTabStripController::TabChangedAt(TabContents* contents, - int model_index, - TabChangeType change_type) { - if (change_type == TITLE_NOT_LOADING) { - tabstrip_->TabTitleChangedNotLoading(model_index); - // We'll receive another notification of the change asynchronously. - return; - } - - SetTabDataAt(contents, model_index); -} - -void BrowserTabStripController::TabReplacedAt(TabContents* old_contents, - TabContents* new_contents, - int model_index) { - SetTabDataAt(new_contents, model_index); -} - -void BrowserTabStripController::TabPinnedStateChanged(TabContents* contents, - int model_index) { - // Currently none of the renderers render pinned state differently. -} - -void BrowserTabStripController::TabMiniStateChanged( - TabContents* contents, - int model_index) { - SetTabDataAt(contents, model_index); -} - -void BrowserTabStripController::TabBlockedStateChanged(TabContents* contents, - int model_index) { - SetTabDataAt(contents, model_index); -} - -void BrowserTabStripController::SetTabDataAt(TabContents* contents, - int model_index) { - TabRendererData data; - SetTabRendererDataFromModel(contents, model_index, &data); - tabstrip_->SetTabData(model_index, data); -} - -void BrowserTabStripController::SetTabRendererDataFromModel( - TabContents* contents, - int model_index, - TabRendererData* data) { - SkBitmap* app_icon = NULL; - - // Extension App icons are slightly larger than favicons, so only allow - // them if permitted by the model. - if (model_->delegate()->LargeIconsPermitted()) - app_icon = contents->GetExtensionAppIcon(); - - if (app_icon) - data->favicon = *app_icon; - else - data->favicon = contents->GetFavIcon(); - data->network_state = TabContentsNetworkState(contents); - data->title = contents->GetTitle(); - data->loading = contents->is_loading(); - data->crashed = contents->is_crashed(); - data->off_the_record = contents->profile()->IsOffTheRecord(); - data->show_icon = contents->ShouldDisplayFavIcon(); - data->mini = model_->IsMiniTab(model_index); - data->blocked = model_->IsTabBlocked(model_index); - data->app = contents->is_app(); -} - -void BrowserTabStripController::StartHighlightTabsForCommand( - TabStripModel::ContextMenuCommand command_id, - BaseTab* tab) { - if (command_id == TabStripModel::CommandCloseOtherTabs || - command_id == TabStripModel::CommandCloseTabsToRight) { - int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); - if (IsValidIndex(model_index)) { - std::vector<int> indices = - model_->GetIndicesClosedByCommand(model_index, command_id); - for (std::vector<int>::const_iterator i = indices.begin(); - i != indices.end(); ++i) { - tabstrip_->StartHighlight(*i); - } - } - } -} - -void BrowserTabStripController::StopHighlightTabsForCommand( - TabStripModel::ContextMenuCommand command_id, - BaseTab* tab) { - if (command_id == TabStripModel::CommandCloseTabsToRight || - command_id == TabStripModel::CommandCloseOtherTabs) { - // Just tell all Tabs to stop pulsing - it's safe. - tabstrip_->StopAllHighlighting(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// BrowserTabStripController, NotificationObserver implementation: - -void BrowserTabStripController::Observe(NotificationType type, - const NotificationSource& source, const NotificationDetails& details) { - DCHECK(type.value == NotificationType::TAB_CLOSEABLE_STATE_CHANGED); - // Note that this notification may be fired during a model mutation and - // possibly before the tabstrip has processed the change. - // Here, we just re-layout each existing tab to reflect the change in its - // closeable state, and then schedule paint for entire tabstrip. - for (int i = 0; i < tabstrip_->tab_count(); ++i) { - tabstrip_->base_tab_at_tab_index(i)->Layout(); - } - tabstrip_->SchedulePaint(); -} diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.h b/chrome/browser/views/tabs/browser_tab_strip_controller.h index bbf1121..6606f28 100644 --- a/chrome/browser/views/tabs/browser_tab_strip_controller.h +++ b/chrome/browser/views/tabs/browser_tab_strip_controller.h @@ -6,116 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_BROWSER_TAB_STRIP_CONTROLLER_H_ #pragma once -#include "base/scoped_ptr.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/views/tabs/tab_strip_controller.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" - -class BaseTab; -class BaseTabStrip; -class Browser; - -struct TabRendererData; - -// An implementation of TabStripController that sources data from the -// TabContentses in a TabStripModel. -class BrowserTabStripController : public TabStripController, - public TabStripModelObserver, - public NotificationObserver { - public: - BrowserTabStripController(Browser* browser, TabStripModel* model); - virtual ~BrowserTabStripController(); - - void InitFromModel(BaseTabStrip* tabstrip); - - TabStripModel* model() const { return model_; } - - bool IsCommandEnabledForTab(TabStripModel::ContextMenuCommand command_id, - BaseTab* tab) const; - bool IsCommandCheckedForTab(TabStripModel::ContextMenuCommand command_id, - BaseTab* tab) const; - void ExecuteCommandForTab(TabStripModel::ContextMenuCommand command_id, - BaseTab* tab); - bool IsTabPinned(BaseTab* tab); - - // TabStripController implementation: - virtual int GetCount() const; - virtual bool IsValidIndex(int model_index) const; - virtual int GetSelectedIndex() const; - virtual bool IsTabSelected(int model_index) const; - virtual bool IsTabPinned(int model_index) const; - virtual bool IsTabCloseable(int model_index) const; - virtual bool IsNewTabPage(int model_index) const; - virtual void SelectTab(int model_index); - virtual void CloseTab(int model_index); - virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p); - virtual void UpdateLoadingAnimations(); - virtual int HasAvailableDragActions() const; - virtual void PerformDrop(bool drop_before, int index, const GURL& url); - virtual bool IsCompatibleWith(BaseTabStrip* other) const; - virtual void CreateNewTab(); - - // TabStripModelObserver implementation: - virtual void TabInsertedAt(TabContents* contents, - int model_index, - bool foreground); - virtual void TabDetachedAt(TabContents* contents, int model_index); - virtual void TabSelectedAt(TabContents* old_contents, - TabContents* contents, - int model_index, - bool user_gesture); - virtual void TabMoved(TabContents* contents, - int from_model_index, - int to_model_index); - virtual void TabChangedAt(TabContents* contents, - int model_index, - TabChangeType change_type); - virtual void TabReplacedAt(TabContents* old_contents, - TabContents* new_contents, - int model_index); - virtual void TabPinnedStateChanged(TabContents* contents, int model_index); - virtual void TabMiniStateChanged(TabContents* contents, int model_index); - virtual void TabBlockedStateChanged(TabContents* contents, int model_index); - - // NotificationObserver implementation: - virtual void Observe(NotificationType type, const NotificationSource& source, - const NotificationDetails& details); - - private: - class TabContextMenuContents; - - // Invokes tabstrip_->SetTabData. - void SetTabDataAt(TabContents* contents, int model_index); - - // Sets the TabRendererData from the TabStripModel. - void SetTabRendererDataFromModel(TabContents* contents, - int model_index, - TabRendererData* data); - - void StartHighlightTabsForCommand( - TabStripModel::ContextMenuCommand command_id, - BaseTab* tab); - void StopHighlightTabsForCommand( - TabStripModel::ContextMenuCommand command_id, - BaseTab* tab); - - Profile* profile() const { return model_->profile(); } - - TabStripModel* model_; - - BaseTabStrip* tabstrip_; - - // Non-owning pointer to the browser which is using this controller. - Browser* browser_; - - // If non-NULL it means we're showing a menu for the tab. - scoped_ptr<TabContextMenuContents> context_menu_contents_; - - NotificationRegistrar notification_registrar_; - - DISALLOW_COPY_AND_ASSIGN(BrowserTabStripController); -}; +#include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_BROWSER_TAB_STRIP_CONTROLLER_H_ diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc deleted file mode 100644 index 3798180..0000000 --- a/chrome/browser/views/tabs/dragged_tab_controller.cc +++ /dev/null @@ -1,1341 +0,0 @@ -// 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/tabs/dragged_tab_controller.h" - -#include <math.h> -#include <set> - -#include "app/animation.h" -#include "app/slide_animation.h" -#include "app/resource_bundle.h" -#include "base/callback.h" -#include "base/i18n/rtl.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/extensions/extension_function_dispatcher.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/tabs/base_tab.h" -#include "chrome/browser/views/tabs/base_tab_strip.h" -#include "chrome/browser/views/tabs/browser_tab_strip_controller.h" -#include "chrome/browser/views/tabs/dragged_tab_view.h" -#include "chrome/browser/views/tabs/native_view_photobooth.h" -#include "chrome/browser/views/tabs/side_tab.h" -#include "chrome/browser/views/tabs/side_tab_strip.h" -#include "chrome/browser/views/tabs/tab.h" -#include "chrome/browser/views/tabs/tab_strip.h" -#include "chrome/common/notification_service.h" -#include "gfx/canvas_skia.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "views/event.h" -#include "views/widget/root_view.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#endif - -#if defined(OS_LINUX) -#include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> -#endif - -static const int kHorizontalMoveThreshold = 16; // Pixels. - -// Distance in pixels the user must move the mouse before we consider moving -// an attached vertical tab. -static const int kVerticalMoveThreshold = 8; - -// If non-null there is a drag underway. -static DraggedTabController* instance_; - -namespace { - -// Delay, in ms, during dragging before we bring a window to front. -const int kBringToFrontDelay = 750; - -// Radius of the rect drawn by DockView. -const int kRoundedRectRadius = 4; - -// Spacing between tab icons when DockView is showing a docking location that -// contains more than one tab. -const int kTabSpacing = 4; - -// DockView is the view responsible for giving a visual indicator of where a -// dock is going to occur. - -class DockView : public views::View { - public: - explicit DockView(DockInfo::Type type) : type_(type) {} - - virtual gfx::Size GetPreferredSize() { - return gfx::Size(DockInfo::popup_width(), DockInfo::popup_height()); - } - - virtual void PaintBackground(gfx::Canvas* canvas) { - SkRect outer_rect = { SkIntToScalar(0), SkIntToScalar(0), - SkIntToScalar(width()), - SkIntToScalar(height()) }; - - // Fill the background rect. - SkPaint paint; - paint.setColor(SkColorSetRGB(108, 108, 108)); - paint.setStyle(SkPaint::kFill_Style); - canvas->AsCanvasSkia()->drawRoundRect( - outer_rect, SkIntToScalar(kRoundedRectRadius), - SkIntToScalar(kRoundedRectRadius), paint); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - SkBitmap* high_icon = rb.GetBitmapNamed(IDR_DOCK_HIGH); - SkBitmap* wide_icon = rb.GetBitmapNamed(IDR_DOCK_WIDE); - - canvas->Save(); - bool rtl_ui = base::i18n::IsRTL(); - if (rtl_ui) { - // Flip canvas to draw the mirrored tab images for RTL UI. - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } - int x_of_active_tab = width() / 2 + kTabSpacing / 2; - int x_of_inactive_tab = width() / 2 - high_icon->width() - kTabSpacing / 2; - switch (type_) { - case DockInfo::LEFT_OF_WINDOW: - case DockInfo::LEFT_HALF: - if (!rtl_ui) - std::swap(x_of_active_tab, x_of_inactive_tab); - canvas->DrawBitmapInt(*high_icon, x_of_active_tab, - (height() - high_icon->height()) / 2); - if (type_ == DockInfo::LEFT_OF_WINDOW) { - DrawBitmapWithAlpha(canvas, *high_icon, x_of_inactive_tab, - (height() - high_icon->height()) / 2); - } - break; - - - case DockInfo::RIGHT_OF_WINDOW: - case DockInfo::RIGHT_HALF: - if (rtl_ui) - std::swap(x_of_active_tab, x_of_inactive_tab); - canvas->DrawBitmapInt(*high_icon, x_of_active_tab, - (height() - high_icon->height()) / 2); - if (type_ == DockInfo::RIGHT_OF_WINDOW) { - DrawBitmapWithAlpha(canvas, *high_icon, x_of_inactive_tab, - (height() - high_icon->height()) / 2); - } - break; - - case DockInfo::TOP_OF_WINDOW: - canvas->DrawBitmapInt(*wide_icon, (width() - wide_icon->width()) / 2, - height() / 2 - high_icon->height()); - break; - - case DockInfo::MAXIMIZE: { - SkBitmap* max_icon = rb.GetBitmapNamed(IDR_DOCK_MAX); - canvas->DrawBitmapInt(*max_icon, (width() - max_icon->width()) / 2, - (height() - max_icon->height()) / 2); - break; - } - - case DockInfo::BOTTOM_HALF: - case DockInfo::BOTTOM_OF_WINDOW: - canvas->DrawBitmapInt(*wide_icon, (width() - wide_icon->width()) / 2, - height() / 2 + kTabSpacing / 2); - if (type_ == DockInfo::BOTTOM_OF_WINDOW) { - DrawBitmapWithAlpha(canvas, *wide_icon, - (width() - wide_icon->width()) / 2, - height() / 2 - kTabSpacing / 2 - wide_icon->height()); - } - break; - - default: - NOTREACHED(); - break; - } - canvas->Restore(); - } - - private: - void DrawBitmapWithAlpha(gfx::Canvas* canvas, const SkBitmap& image, - int x, int y) { - SkPaint paint; - paint.setAlpha(128); - canvas->DrawBitmapInt(image, x, y, paint); - } - - DockInfo::Type type_; - - DISALLOW_COPY_AND_ASSIGN(DockView); -}; - -gfx::Point ConvertScreenPointToTabStripPoint(BaseTabStrip* tabstrip, - const gfx::Point& screen_point) { - gfx::Point tabstrip_topleft; - views::View::ConvertPointToScreen(tabstrip, &tabstrip_topleft); - return gfx::Point(screen_point.x() - tabstrip_topleft.x(), - screen_point.y() - tabstrip_topleft.y()); -} - -// Returns the the x-coordinate of |point| if the type of tabstrip is horizontal -// otherwise returns the y-coordinate. -int MajorAxisValue(const gfx::Point& point, BaseTabStrip* tabstrip) { - return (tabstrip->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) ? - point.x() : point.y(); -} - -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// DockDisplayer - -// DockDisplayer is responsible for giving the user a visual indication of a -// possible dock position (as represented by DockInfo). DockDisplayer shows -// a window with a DockView in it. Two animations are used that correspond to -// the state of DockInfo::in_enable_area. -class DraggedTabController::DockDisplayer : public AnimationDelegate { - public: - DockDisplayer(DraggedTabController* controller, - const DockInfo& info) - : controller_(controller), - popup_(NULL), - popup_view_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)), - hidden_(false), - in_enable_area_(info.in_enable_area()) { -#if defined(OS_WIN) - views::WidgetWin* popup = new views::WidgetWin; - popup_ = popup; - popup->set_window_style(WS_POPUP); - popup->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | - WS_EX_TOPMOST); - popup->SetOpacity(0x00); - popup->Init(NULL, info.GetPopupRect()); - popup->SetContentsView(new DockView(info.type())); - if (info.in_enable_area()) - animation_.Reset(1); - else - animation_.Show(); - popup->SetWindowPos(HWND_TOP, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOMOVE | SWP_SHOWWINDOW); -#else - NOTIMPLEMENTED(); -#endif - popup_view_ = popup_->GetNativeView(); - } - - ~DockDisplayer() { - if (controller_) - controller_->DockDisplayerDestroyed(this); - } - - // Updates the state based on |in_enable_area|. - void UpdateInEnabledArea(bool in_enable_area) { - if (in_enable_area != in_enable_area_) { - in_enable_area_ = in_enable_area; - UpdateLayeredAlpha(); - } - } - - // Resets the reference to the hosting DraggedTabController. This is invoked - // when the DraggedTabController is destoryed. - void clear_controller() { controller_ = NULL; } - - // NativeView of the window we create. - gfx::NativeView popup_view() { return popup_view_; } - - // Starts the hide animation. When the window is closed the - // DraggedTabController is notified by way of the DockDisplayerDestroyed - // method - void Hide() { - if (hidden_) - return; - - if (!popup_) { - delete this; - return; - } - hidden_ = true; - animation_.Hide(); - } - - virtual void AnimationProgressed(const Animation* animation) { - UpdateLayeredAlpha(); - } - - virtual void AnimationEnded(const Animation* animation) { - if (!hidden_) - return; -#if defined(OS_WIN) - static_cast<views::WidgetWin*>(popup_)->Close(); -#else - NOTIMPLEMENTED(); -#endif - delete this; - } - - virtual void UpdateLayeredAlpha() { -#if defined(OS_WIN) - double scale = in_enable_area_ ? 1 : .5; - static_cast<views::WidgetWin*>(popup_)->SetOpacity( - static_cast<BYTE>(animation_.GetCurrentValue() * scale * 255.0)); - popup_->GetRootView()->SchedulePaint(); -#else - NOTIMPLEMENTED(); -#endif - } - - private: - // DraggedTabController that created us. - DraggedTabController* controller_; - - // Window we're showing. - views::Widget* popup_; - - // NativeView of |popup_|. We cache this to avoid the possibility of - // invoking a method on popup_ after we close it. - gfx::NativeView popup_view_; - - // Animation for when first made visible. - SlideAnimation animation_; - - // Have we been hidden? - bool hidden_; - - // Value of DockInfo::in_enable_area. - bool in_enable_area_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// DraggedTabController, public: - -DraggedTabController::DraggedTabController(BaseTab* source_tab, - BaseTabStrip* source_tabstrip) - : dragged_contents_(NULL), - original_delegate_(NULL), - source_tabstrip_(source_tabstrip), - source_model_index_(source_tabstrip->GetModelIndexOfBaseTab(source_tab)), - attached_tabstrip_(NULL), - attached_tab_(NULL), - offset_to_width_ratio_(0), - old_focused_view_(NULL), - last_move_screen_loc_(0), - mini_(source_tab->data().mini), - pinned_(source_tabstrip->IsTabPinned(source_tab)), - started_drag_(false), - active_(true) { - instance_ = this; - SetDraggedContents( - GetModel(source_tabstrip_)->GetTabContentsAt(source_model_index_)); - // Listen for Esc key presses. - MessageLoopForUI::current()->AddObserver(this); -} - -DraggedTabController::~DraggedTabController() { - if (instance_ == this) - instance_ = NULL; - - MessageLoopForUI::current()->RemoveObserver(this); - // Need to delete the view here manually _before_ we reset the dragged - // contents to NULL, otherwise if the view is animating to its destination - // bounds, it won't be able to clean up properly since its cleanup routine - // uses GetIndexForDraggedContents, which will be invalid. - view_.reset(NULL); - SetDraggedContents(NULL); // This removes our observer. -} - -// static -bool DraggedTabController::IsAttachedTo(BaseTabStrip* tab_strip) { - return instance_ && instance_->active_ && - instance_->attached_tabstrip_ == tab_strip; -} - -void DraggedTabController::CaptureDragInfo(views::View* tab, - const gfx::Point& mouse_offset) { - if (tab->width() > 0) { - offset_to_width_ratio_ = static_cast<float>(mouse_offset.x()) / - static_cast<float>(tab->width()); - } - start_screen_point_ = GetCursorScreenPoint(); - mouse_offset_ = mouse_offset; - InitWindowCreatePoint(); -} - -void DraggedTabController::Drag() { - bring_to_front_timer_.Stop(); - - // Before we get to dragging anywhere, ensure that we consider ourselves - // attached to the source tabstrip. - if (!started_drag_ && CanStartDrag()) { - started_drag_ = true; - SaveFocus(); - Attach(source_tabstrip_, gfx::Point()); - } - - if (started_drag_) - ContinueDragging(); -} - -void DraggedTabController::EndDrag(bool canceled) { - EndDragImpl(canceled ? CANCELED : NORMAL); -} - -/////////////////////////////////////////////////////////////////////////////// -// DraggedTabController, PageNavigator implementation: - -void DraggedTabController::OpenURLFromTab(TabContents* source, - const GURL& url, - const GURL& referrer, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - if (original_delegate_) { - if (disposition == CURRENT_TAB) - disposition = NEW_WINDOW; - - original_delegate_->OpenURLFromTab(source, url, referrer, - disposition, transition); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// DraggedTabController, TabContentsDelegate implementation: - -void DraggedTabController::NavigationStateChanged(const TabContents* source, - unsigned changed_flags) { - if (view_.get()) - view_->Update(); -} - -void DraggedTabController::AddNewContents(TabContents* source, - TabContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) { - DCHECK(disposition != CURRENT_TAB); - - // Theoretically could be called while dragging if the page tries to - // spawn a window. Route this message back to the browser in most cases. - if (original_delegate_) { - original_delegate_->AddNewContents(source, new_contents, disposition, - initial_pos, user_gesture); - } -} - -void DraggedTabController::ActivateContents(TabContents* contents) { - // Ignored. -} - -void DraggedTabController::DeactivateContents(TabContents* contents) { - // Ignored. -} - -void DraggedTabController::LoadingStateChanged(TabContents* source) { - // It would be nice to respond to this message by changing the - // screen shot in the dragged tab. - if (view_.get()) - view_->Update(); -} - -void DraggedTabController::CloseContents(TabContents* source) { - // Theoretically could be called by a window. Should be ignored - // because window.close() is ignored (usually, even though this - // method gets called.) -} - -void DraggedTabController::MoveContents(TabContents* source, - const gfx::Rect& pos) { - // Theoretically could be called by a web page trying to move its - // own window. Should be ignored since we're moving the window... -} - -void DraggedTabController::ToolbarSizeChanged(TabContents* source, - bool finished) { - // Dragged tabs don't care about this. -} - -void DraggedTabController::URLStarredChanged(TabContents* source, - bool starred) { - // Ignored. -} - -void DraggedTabController::UpdateTargetURL(TabContents* source, - const GURL& url) { - // Ignored. -} - -/////////////////////////////////////////////////////////////////////////////// -// DraggedTabController, NotificationObserver implementation: - -void DraggedTabController::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED); - DCHECK(Source<TabContents>(source).ptr() == dragged_contents_); - EndDragImpl(TAB_DESTROYED); -} - -/////////////////////////////////////////////////////////////////////////////// -// DraggedTabController, MessageLoop::Observer implementation: - -#if defined(OS_WIN) -void DraggedTabController::WillProcessMessage(const MSG& msg) { -} - -void DraggedTabController::DidProcessMessage(const MSG& msg) { - // If the user presses ESC during a drag, we need to abort and revert things - // to the way they were. This is the most reliable way to do this since no - // single view or window reliably receives events throughout all the various - // kinds of tab dragging. - if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) - EndDrag(true); -} -#else -void DraggedTabController::WillProcessEvent(GdkEvent* event) { -} - -void DraggedTabController::DidProcessEvent(GdkEvent* event) { - if (event->type == GDK_KEY_PRESS && - reinterpret_cast<GdkEventKey*>(event)->keyval == GDK_Escape) { - EndDrag(true); - } -} -#endif - -/////////////////////////////////////////////////////////////////////////////// -// DraggedTabController, private: - -void DraggedTabController::InitWindowCreatePoint() { - // window_create_point_ is only used in CompleteDrag() (through - // GetWindowCreatePoint() to get the start point of the docked window) when - // the attached_tabstrip_ is NULL and all the window's related bound - // information are obtained from source_tabstrip_. So, we need to get the - // first_tab based on source_tabstrip_, not attached_tabstrip_. Otherwise, - // the window_create_point_ is not in the correct coordinate system. Please - // refer to http://crbug.com/6223 comment #15 for detailed information. - views::View* first_tab = source_tabstrip_->base_tab_at_tab_index(0); - views::View::ConvertPointToWidget(first_tab, &first_source_tab_point_); - UpdateWindowCreatePoint(); -} - -void DraggedTabController::UpdateWindowCreatePoint() { - // See comments in InitWindowCreatePoint for details on this. - window_create_point_ = first_source_tab_point_; - window_create_point_.Offset(mouse_offset_.x(), mouse_offset_.y()); -} - -gfx::Point DraggedTabController::GetWindowCreatePoint() const { - gfx::Point cursor_point = GetCursorScreenPoint(); - if (dock_info_.type() != DockInfo::NONE) { - // If we're going to dock, we need to return the exact coordinate, - // otherwise we may attempt to maximize on the wrong monitor. - return cursor_point; - } - return gfx::Point(cursor_point.x() - window_create_point_.x(), - cursor_point.y() - window_create_point_.y()); -} - -void DraggedTabController::UpdateDockInfo(const gfx::Point& screen_point) { - // Update the DockInfo for the current mouse coordinates. - DockInfo dock_info = GetDockInfoAtPoint(screen_point); - if (source_tabstrip_->type() == BaseTabStrip::VERTICAL_TAB_STRIP && - ((dock_info.type() == DockInfo::LEFT_OF_WINDOW && - !base::i18n::IsRTL()) || - (dock_info.type() == DockInfo::RIGHT_OF_WINDOW && - base::i18n::IsRTL()))) { - // For side tabs it's way to easy to trigger to docking along the left/right - // edge, so we disable it. - dock_info = DockInfo(); - } - if (!dock_info.equals(dock_info_)) { - // DockInfo for current position differs. - if (dock_info_.type() != DockInfo::NONE && - !dock_controllers_.empty()) { - // Hide old visual indicator. - dock_controllers_.back()->Hide(); - } - dock_info_ = dock_info; - if (dock_info_.type() != DockInfo::NONE) { - // Show new docking position. - DockDisplayer* controller = new DockDisplayer(this, dock_info_); - if (controller->popup_view()) { - dock_controllers_.push_back(controller); - dock_windows_.insert(controller->popup_view()); - } else { - delete controller; - } - } - } else if (dock_info_.type() != DockInfo::NONE && - !dock_controllers_.empty()) { - // Current dock position is the same as last, update the controller's - // in_enable_area state as it may have changed. - dock_controllers_.back()->UpdateInEnabledArea(dock_info_.in_enable_area()); - } -} - -void DraggedTabController::SetDraggedContents(TabContents* new_contents) { - if (dragged_contents_) { - registrar_.Remove(this, - NotificationType::TAB_CONTENTS_DESTROYED, - Source<TabContents>(dragged_contents_)); - if (original_delegate_) - dragged_contents_->set_delegate(original_delegate_); - } - original_delegate_ = NULL; - dragged_contents_ = new_contents; - if (dragged_contents_) { - registrar_.Add(this, - NotificationType::TAB_CONTENTS_DESTROYED, - Source<TabContents>(dragged_contents_)); - - // We need to be the delegate so we receive messages about stuff, - // otherwise our dragged_contents() may be replaced and subsequently - // collected/destroyed while the drag is in process, leading to - // nasty crashes. - original_delegate_ = dragged_contents_->delegate(); - dragged_contents_->set_delegate(this); - } -} - -void DraggedTabController::SaveFocus() { - if (!old_focused_view_) { - old_focused_view_ = source_tabstrip_->GetRootView()->GetFocusedView(); - source_tabstrip_->GetRootView()->FocusView(source_tabstrip_); - } -} - -void DraggedTabController::RestoreFocus() { - if (old_focused_view_ && attached_tabstrip_ == source_tabstrip_) - old_focused_view_->GetRootView()->FocusView(old_focused_view_); - old_focused_view_ = NULL; -} - -bool DraggedTabController::CanStartDrag() const { - // Determine if the mouse has moved beyond a minimum elasticity distance in - // any direction from the starting point. - static const int kMinimumDragDistance = 10; - gfx::Point screen_point = GetCursorScreenPoint(); - int x_offset = abs(screen_point.x() - start_screen_point_.x()); - int y_offset = abs(screen_point.y() - start_screen_point_.y()); - return sqrt(pow(static_cast<float>(x_offset), 2) + - pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; -} - -void DraggedTabController::ContinueDragging() { - // Note that the coordinates given to us by |drag_event| are basically - // useless, since they're in source_tab_ coordinates. On the surface, you'd - // think we could just convert them to screen coordinates, however in the - // situation where we're dragging the last tab in a window when multiple - // windows are open, the coordinates of |source_tab_| are way off in - // hyperspace since the window was moved there instead of being closed so - // that we'd keep receiving events. And our ConvertPointToScreen methods - // aren't really multi-screen aware. So really it's just safer to get the - // actual position of the mouse cursor directly from Windows here, which is - // guaranteed to be correct regardless of monitor config. - gfx::Point screen_point = GetCursorScreenPoint(); - -#if defined(OS_CHROMEOS) - // We don't allow detaching in chrome os. - BaseTabStrip* target_tabstrip = source_tabstrip_; -#else - // Determine whether or not we have dragged over a compatible TabStrip in - // another browser window. If we have, we should attach to it and start - // dragging within it. - BaseTabStrip* target_tabstrip = GetTabStripForPoint(screen_point); -#endif - if (target_tabstrip != attached_tabstrip_) { - // Make sure we're fully detached from whatever TabStrip we're attached to - // (if any). - if (attached_tabstrip_) - Detach(); - if (target_tabstrip) - Attach(target_tabstrip, screen_point); - } - if (!target_tabstrip) { - bring_to_front_timer_.Start( - base::TimeDelta::FromMilliseconds(kBringToFrontDelay), this, - &DraggedTabController::BringWindowUnderMouseToFront); - } - - UpdateDockInfo(screen_point); - - if (attached_tabstrip_) - MoveAttachedTab(screen_point); - else - MoveDetachedTab(screen_point); -} - -void DraggedTabController::MoveAttachedTab(const gfx::Point& screen_point) { - DCHECK(attached_tabstrip_); - DCHECK(!view_.get()); - - gfx::Point dragged_view_point = GetAttachedTabDragPoint(screen_point); - TabStripModel* attached_model = GetModel(attached_tabstrip_); - int from_index = attached_model->GetIndexOfTabContents(dragged_contents_); - - int threshold = kVerticalMoveThreshold; - if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { - TabStrip* tab_strip = static_cast<TabStrip*>(attached_tabstrip_); - - // Determine the horizontal move threshold. This is dependent on the width - // of tabs. The smaller the tabs compared to the standard size, the smaller - // the threshold. - double unselected, selected; - tab_strip->GetCurrentTabWidths(&unselected, &selected); - double ratio = unselected / Tab::GetStandardSize().width(); - threshold = static_cast<int>(ratio * kHorizontalMoveThreshold); - } - - // Update the model, moving the TabContents from one index to another. Do this - // only if we have moved a minimum distance since the last reorder (to prevent - // jitter). - if (abs(MajorAxisValue(screen_point, attached_tabstrip_) - - last_move_screen_loc_) > threshold) { - gfx::Point dragged_view_screen_point(dragged_view_point); - views::View::ConvertPointToScreen(attached_tabstrip_, - &dragged_view_screen_point); - gfx::Rect bounds = GetDraggedViewTabStripBounds(dragged_view_screen_point); - int to_index = GetInsertionIndexForDraggedBounds(bounds, true); - to_index = NormalizeIndexToAttachedTabStrip(to_index); - if (from_index != to_index) { - last_move_screen_loc_ = MajorAxisValue(screen_point, attached_tabstrip_); - attached_model->MoveTabContentsAt(from_index, to_index, true); - } - } - - attached_tab_->SchedulePaint(); - attached_tab_->SetX(dragged_view_point.x()); - attached_tab_->SetX( - attached_tabstrip_->MirroredLeftPointForRect(attached_tab_->bounds())); - attached_tab_->SetY(dragged_view_point.y()); - attached_tab_->SchedulePaint(); -} - -void DraggedTabController::MoveDetachedTab(const gfx::Point& screen_point) { - DCHECK(!attached_tabstrip_); - DCHECK(view_.get()); - - int x = screen_point.x() - mouse_offset_.x(); - int y = screen_point.y() - mouse_offset_.y(); - - // Move the View. There are no changes to the model if we're detached. - view_->MoveTo(gfx::Point(x, y)); -} - -DockInfo DraggedTabController::GetDockInfoAtPoint( - const gfx::Point& screen_point) { - if (attached_tabstrip_) { - // If the mouse is over a tab strip, don't offer a dock position. - return DockInfo(); - } - - if (dock_info_.IsValidForPoint(screen_point)) { - // It's possible any given screen coordinate has multiple docking - // positions. Check the current info first to avoid having the docking - // position bounce around. - return dock_info_; - } - - gfx::NativeView dragged_hwnd = view_->GetWidget()->GetNativeView(); - dock_windows_.insert(dragged_hwnd); - DockInfo info = DockInfo::GetDockInfoAtPoint(screen_point, dock_windows_); - dock_windows_.erase(dragged_hwnd); - return info; -} - -BaseTabStrip* DraggedTabController::GetTabStripForPoint( - const gfx::Point& screen_point) { - gfx::NativeView dragged_view = NULL; - if (view_.get()) { - dragged_view = view_->GetWidget()->GetNativeView(); - dock_windows_.insert(dragged_view); - } - gfx::NativeWindow local_window = - DockInfo::GetLocalProcessWindowAtPoint(screen_point, dock_windows_); - if (dragged_view) - dock_windows_.erase(dragged_view); - if (!local_window) - return NULL; - BrowserView* browser = - BrowserView::GetBrowserViewForNativeWindow(local_window); - // We don't allow drops on windows that don't have tabstrips. - if (!browser || - !browser->browser()->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)) - return NULL; - - BaseTabStrip* other_tabstrip = browser->tabstrip(); - if (!other_tabstrip->controller()->IsCompatibleWith(source_tabstrip_)) - return NULL; - return GetTabStripIfItContains(other_tabstrip, screen_point); -} - -BaseTabStrip* DraggedTabController::GetTabStripIfItContains( - BaseTabStrip* tabstrip, const gfx::Point& screen_point) const { - static const int kVerticalDetachMagnetism = 15; - static const int kHorizontalDetachMagnetism = 15; - // Make sure the specified screen point is actually within the bounds of the - // specified tabstrip... - gfx::Rect tabstrip_bounds = GetViewScreenBounds(tabstrip); - if (tabstrip->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { - if (screen_point.x() < tabstrip_bounds.right() && - screen_point.x() >= tabstrip_bounds.x()) { - // TODO(beng): make this be relative to the start position of the mouse - // for the source TabStrip. - int upper_threshold = tabstrip_bounds.bottom() + kVerticalDetachMagnetism; - int lower_threshold = tabstrip_bounds.y() - kVerticalDetachMagnetism; - if (screen_point.y() >= lower_threshold && - screen_point.y() <= upper_threshold) { - return tabstrip; - } - } - } else { - if (screen_point.y() < tabstrip_bounds.bottom() && - screen_point.y() >= tabstrip_bounds.y()) { - int upper_threshold = tabstrip_bounds.right() + - kHorizontalDetachMagnetism; - int lower_threshold = tabstrip_bounds.x() - kHorizontalDetachMagnetism; - if (screen_point.x() >= lower_threshold && - screen_point.x() <= upper_threshold) { - return tabstrip; - } - } - } - return NULL; -} - -void DraggedTabController::Attach(BaseTabStrip* attached_tabstrip, - const gfx::Point& screen_point) { - DCHECK(!attached_tabstrip_); // We should already have detached by the time - // we get here. - DCHECK(!attached_tab_); // Similarly there should be no attached tab. - - attached_tabstrip_ = attached_tabstrip; - - // We don't need the photo-booth while we're attached. - photobooth_.reset(NULL); - - // And we don't need the dragged view. - view_.reset(); - - BaseTab* tab = GetTabMatchingDraggedContents(attached_tabstrip_); - - if (!tab) { - // There is no Tab in |attached_tabstrip| that corresponds to the dragged - // TabContents. We must now create one. - - // Remove ourselves as the delegate now that the dragged TabContents is - // being inserted back into a Browser. - dragged_contents_->set_delegate(NULL); - original_delegate_ = NULL; - - // Return the TabContents' to normalcy. - dragged_contents_->set_capturing_contents(false); - - // Inserting counts as a move. We don't want the tabs to jitter when the - // user moves the tab immediately after attaching it. - last_move_screen_loc_ = MajorAxisValue(screen_point, attached_tabstrip); - - // Figure out where to insert the tab based on the bounds of the dragged - // representation and the ideal bounds of the other Tabs already in the - // strip. ("ideal bounds" are stable even if the Tabs' actual bounds are - // changing due to animation). - gfx::Rect bounds = GetDraggedViewTabStripBounds(screen_point); - int index = GetInsertionIndexForDraggedBounds(bounds, false); - attached_tabstrip_->set_attaching_dragged_tab(true); - GetModel(attached_tabstrip_)->InsertTabContentsAt( - index, dragged_contents_, - TabStripModel::ADD_SELECTED | - (pinned_ ? TabStripModel::ADD_PINNED : 0)); - attached_tabstrip_->set_attaching_dragged_tab(false); - - tab = GetTabMatchingDraggedContents(attached_tabstrip_); - } - DCHECK(tab); // We should now have a tab. - attached_tab_ = tab; - attached_tabstrip_->StartedDraggingTab(tab); - - if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { - // The size of the dragged tab may have changed. Adjust the x offset so that - // ratio of mouse_offset_ to original width is maintained. - mouse_offset_.set_x(static_cast<int>(offset_to_width_ratio_ * - static_cast<int>(tab->width()))); - } - - // Move the corresponding window to the front. - attached_tabstrip_->GetWindow()->Activate(); -} - -void DraggedTabController::Detach() { - // Prevent the TabContents' HWND from being hidden by any of the model - // operations performed during the drag. - dragged_contents_->set_capturing_contents(true); - - // Update the Model. - TabRendererData tab_data = attached_tab_->data(); - TabStripModel* attached_model = GetModel(attached_tabstrip_); - int index = attached_model->GetIndexOfTabContents(dragged_contents_); - DCHECK(index != -1); - // Hide the tab so that the user doesn't see it animate closed. - attached_tab_->SetVisible(false); - int attached_tab_width = attached_tab_->width(); - attached_model->DetachTabContentsAt(index); - // Detaching may end up deleting the tab, drop references to it. - attached_tab_ = NULL; - - // If we've removed the last Tab from the TabStrip, hide the frame now. - if (attached_model->empty()) - HideFrame(); - - // Set up the photo booth to start capturing the contents of the dragged - // TabContents. - if (!photobooth_.get()) { - photobooth_.reset( - NativeViewPhotobooth::Create(dragged_contents_->GetNativeView())); - } - - // Create the dragged view. - EnsureDraggedView(tab_data); - view_->SetTabWidthAndUpdate(attached_tab_width, photobooth_.get()); - - // Detaching resets the delegate, but we still want to be the delegate. - dragged_contents_->set_delegate(this); - - attached_tabstrip_ = NULL; -} - -int DraggedTabController::GetInsertionIndexForDraggedBounds( - const gfx::Rect& dragged_bounds, - bool is_tab_attached) const { - int right_tab_x = 0; - int bottom_tab_y = 0; - - // If the UI layout of the tab strip is right-to-left, we need to mirror the - // bounds of the dragged tab before performing the drag/drop related - // calculations. We mirror the dragged bounds because we determine the - // position of each tab on the tab strip by calling GetBounds() (without the - // mirroring transformation flag) which effectively means that even though - // the tabs are rendered from right to left, the code performs the - // calculation as if the tabs are laid out from left to right. Mirroring the - // dragged bounds adjusts the coordinates of the tab we are dragging so that - // it uses the same orientation used by the tabs on the tab strip. - gfx::Rect adjusted_bounds(dragged_bounds); - adjusted_bounds.set_x( - attached_tabstrip_->MirroredLeftPointForRect(adjusted_bounds)); - - int index = -1; - for (int i = 0; i < attached_tabstrip_->tab_count(); ++i) { - const gfx::Rect& ideal_bounds = attached_tabstrip_->ideal_bounds(i); - if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { - gfx::Rect left_half = ideal_bounds; - left_half.set_width(left_half.width() / 2); - gfx::Rect right_half = ideal_bounds; - right_half.set_width(ideal_bounds.width() - left_half.width()); - right_half.set_x(left_half.right()); - right_tab_x = right_half.right(); - if (adjusted_bounds.x() >= right_half.x() && - adjusted_bounds.x() < right_half.right()) { - index = i + 1; - break; - } else if (adjusted_bounds.x() >= left_half.x() && - adjusted_bounds.x() < left_half.right()) { - index = i; - break; - } - } else { - // Vertical tab strip. - int max_y = ideal_bounds.bottom(); - int mid_y = ideal_bounds.y() + ideal_bounds.height() / 2; - bottom_tab_y = max_y; - if (adjusted_bounds.y() < mid_y) { - index = i; - break; - } else if (adjusted_bounds.y() >= mid_y && adjusted_bounds.y() < max_y) { - index = i + 1; - break; - } - } - } - if (index == -1) { - if ((attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP && - adjusted_bounds.right() > right_tab_x) || - (attached_tabstrip_->type() == BaseTabStrip::VERTICAL_TAB_STRIP && - adjusted_bounds.y() >= bottom_tab_y)) { - index = GetModel(attached_tabstrip_)->count(); - } else { - index = 0; - } - } - - index = GetModel(attached_tabstrip_)->ConstrainInsertionIndex(index, mini_); - if (is_tab_attached && mini_ && - index == GetModel(attached_tabstrip_)->IndexOfFirstNonMiniTab()) { - index--; - } - return index; -} - -gfx::Rect DraggedTabController::GetDraggedViewTabStripBounds( - const gfx::Point& screen_point) { - gfx::Point client_point = - ConvertScreenPointToTabStripPoint(attached_tabstrip_, screen_point); - // attached_tab_ is NULL when inserting into a new tabstrip. - if (attached_tab_) { - return gfx::Rect(client_point.x(), client_point.y(), - attached_tab_->width(), attached_tab_->height()); - } - - if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { - double sel_width, unselected_width; - static_cast<TabStrip*>(attached_tabstrip_)->GetCurrentTabWidths( - &sel_width, &unselected_width); - return gfx::Rect(client_point.x(), client_point.y(), - static_cast<int>(sel_width), - Tab::GetStandardSize().height()); - } - - return gfx::Rect(client_point.x(), client_point.y(), - attached_tabstrip_->width(), - SideTab::GetPreferredHeight()); -} - -gfx::Point DraggedTabController::GetAttachedTabDragPoint( - const gfx::Point& screen_point) { - DCHECK(attached_tabstrip_); // The tab must be attached. - - int x = screen_point.x() - mouse_offset_.x(); - int y = screen_point.y() - mouse_offset_.y(); - - gfx::Point tab_loc(x, y); - views::View::ConvertPointToView(NULL, attached_tabstrip_, &tab_loc); - - x = tab_loc.x(); - y = tab_loc.y(); - - const gfx::Size& tab_size = attached_tab_->bounds().size(); - - if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { - int max_x = attached_tabstrip_->bounds().right() - tab_size.width(); - x = std::min(std::max(x, 0), max_x); - y = 0; - } else { - x = SideTabStrip::kTabStripInset; - int max_y = attached_tabstrip_->bounds().bottom() - tab_size.height(); - y = std::min(std::max(y, SideTabStrip::kTabStripInset), max_y); - } - return gfx::Point(x, y); -} - -BaseTab* DraggedTabController::GetTabMatchingDraggedContents( - BaseTabStrip* tabstrip) const { - int model_index = - GetModel(tabstrip)->GetIndexOfTabContents(dragged_contents_); - return model_index == TabStripModel::kNoTab ? - NULL : tabstrip->GetBaseTabAtModelIndex(model_index); -} - -void DraggedTabController::EndDragImpl(EndDragType type) { - // WARNING: this may be invoked multiple times. In particular, if deletion - // occurs after a delay (as it does when the tab is released in the original - // tab strip) and the navigation controller/tab contents is deleted before - // the animation finishes, this is invoked twice. The second time through - // type == TAB_DESTROYED. - - active_ = false; - - bring_to_front_timer_.Stop(); - - // Hide the current dock controllers. - for (size_t i = 0; i < dock_controllers_.size(); ++i) { - // Be sure and clear the controller first, that way if Hide ends up - // deleting the controller it won't call us back. - dock_controllers_[i]->clear_controller(); - dock_controllers_[i]->Hide(); - } - dock_controllers_.clear(); - dock_windows_.clear(); - - if (type != TAB_DESTROYED) { - // We only finish up the drag if we were actually dragging. If start_drag_ - // is false, the user just clicked and released and didn't move the mouse - // enough to trigger a drag. - if (started_drag_) { - RestoreFocus(); - if (type == CANCELED) - RevertDrag(); - else - CompleteDrag(); - } - if (dragged_contents_ && dragged_contents_->delegate() == this) - dragged_contents_->set_delegate(original_delegate_); - } else { - // If we get here it means the NavigationController is going down. Don't - // attempt to do any cleanup other than resetting the delegate (if we're - // still the delegate). - if (dragged_contents_ && dragged_contents_->delegate() == this) - dragged_contents_->set_delegate(NULL); - dragged_contents_ = NULL; - } - - // The delegate of the dragged contents should have been reset. Unset the - // original delegate so that we don't attempt to reset the delegate when - // deleted. - DCHECK(!dragged_contents_ || dragged_contents_->delegate() != this); - original_delegate_ = NULL; - - source_tabstrip_->DestroyDragController(); -} - -void DraggedTabController::RevertDrag() { - DCHECK(started_drag_); - - // We save this here because code below will modify |attached_tabstrip_|. - bool restore_frame = attached_tabstrip_ != source_tabstrip_; - if (attached_tabstrip_) { - int index = GetModel(attached_tabstrip_)->GetIndexOfTabContents( - dragged_contents_); - if (attached_tabstrip_ != source_tabstrip_) { - // The Tab was inserted into another TabStrip. We need to put it back - // into the original one. - GetModel(attached_tabstrip_)->DetachTabContentsAt(index); - // TODO(beng): (Cleanup) seems like we should use Attach() for this - // somehow. - attached_tabstrip_ = source_tabstrip_; - GetModel(source_tabstrip_)->InsertTabContentsAt( - source_model_index_, dragged_contents_, - TabStripModel::ADD_SELECTED | - (pinned_ ? TabStripModel::ADD_PINNED : 0)); - } else { - // The Tab was moved within the TabStrip where the drag was initiated. - // Move it back to the starting location. - GetModel(source_tabstrip_)->MoveTabContentsAt(index, source_model_index_, - true); - source_tabstrip_->StoppedDraggingTab(attached_tab_); - } - } else { - // TODO(beng): (Cleanup) seems like we should use Attach() for this - // somehow. - attached_tabstrip_ = source_tabstrip_; - // The Tab was detached from the TabStrip where the drag began, and has not - // been attached to any other TabStrip. We need to put it back into the - // source TabStrip. - GetModel(source_tabstrip_)->InsertTabContentsAt( - source_model_index_, dragged_contents_, - TabStripModel::ADD_SELECTED | - (pinned_ ? TabStripModel::ADD_PINNED : 0)); - } - - // If we're not attached to any TabStrip, or attached to some other TabStrip, - // we need to restore the bounds of the original TabStrip's frame, in case - // it has been hidden. - if (restore_frame) { - if (!restore_bounds_.IsEmpty()) { -#if defined(OS_WIN) - HWND frame_hwnd = source_tabstrip_->GetWidget()->GetNativeView(); - MoveWindow(frame_hwnd, restore_bounds_.x(), restore_bounds_.y(), - restore_bounds_.width(), restore_bounds_.height(), TRUE); -#else - NOTIMPLEMENTED(); -#endif - } - } -} - -void DraggedTabController::CompleteDrag() { - DCHECK(started_drag_); - - if (attached_tabstrip_) { - attached_tabstrip_->StoppedDraggingTab(attached_tab_); - } else { - if (dock_info_.type() != DockInfo::NONE) { - Profile* profile = GetModel(source_tabstrip_)->profile(); - switch (dock_info_.type()) { - case DockInfo::LEFT_OF_WINDOW: - UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Left"), - profile); - break; - - case DockInfo::RIGHT_OF_WINDOW: - UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Right"), - profile); - break; - - case DockInfo::BOTTOM_OF_WINDOW: - UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Bottom"), - profile); - break; - - case DockInfo::TOP_OF_WINDOW: - UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Top"), - profile); - break; - - case DockInfo::MAXIMIZE: - UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Maximize"), - profile); - break; - - case DockInfo::LEFT_HALF: - UserMetrics::RecordAction(UserMetricsAction("DockingWindow_LeftHalf"), - profile); - break; - - case DockInfo::RIGHT_HALF: - UserMetrics::RecordAction( - UserMetricsAction("DockingWindow_RightHalf"), - profile); - break; - - case DockInfo::BOTTOM_HALF: - UserMetrics::RecordAction( - UserMetricsAction("DockingWindow_BottomHalf"), - profile); - break; - - default: - NOTREACHED(); - break; - } - } - // Compel the model to construct a new window for the detached TabContents. - views::Window* window = source_tabstrip_->GetWindow(); - gfx::Rect window_bounds(window->GetNormalBounds()); - window_bounds.set_origin(GetWindowCreatePoint()); - // When modifying the following if statement, please make sure not to - // introduce issue listed in http://crbug.com/6223 comment #11. - bool rtl_ui = base::i18n::IsRTL(); - bool has_dock_position = (dock_info_.type() != DockInfo::NONE); - if (rtl_ui && has_dock_position) { - // Mirror X axis so the docked tab is aligned using the mouse click as - // the top-right corner. - window_bounds.set_x(window_bounds.x() - window_bounds.width()); - } - Browser* new_browser = - GetModel(source_tabstrip_)->delegate()->CreateNewStripWithContents( - dragged_contents_, window_bounds, dock_info_, window->IsMaximized()); - TabStripModel* new_model = new_browser->tabstrip_model(); - new_model->SetTabPinned(new_model->GetIndexOfTabContents(dragged_contents_), - pinned_); - new_browser->window()->Show(); - } - - CleanUpHiddenFrame(); -} - -void DraggedTabController::EnsureDraggedView(const TabRendererData& data) { - if (!view_.get()) { - gfx::Rect tab_bounds; - dragged_contents_->GetContainerBounds(&tab_bounds); - BaseTab* renderer = source_tabstrip_->CreateTabForDragging(); - renderer->SetData(data); - // DraggedTabView takes ownership of renderer. - view_.reset(new DraggedTabView(renderer, mouse_offset_, - tab_bounds.size(), - Tab::GetMinimumSelectedSize())); - } -} - -gfx::Point DraggedTabController::GetCursorScreenPoint() const { -#if defined(OS_WIN) - DWORD pos = GetMessagePos(); - return gfx::Point(pos); -#else - gint x, y; - gdk_display_get_pointer(gdk_display_get_default(), NULL, &x, &y, NULL); - return gfx::Point(x, y); -#endif -} - -gfx::Rect DraggedTabController::GetViewScreenBounds(views::View* view) const { - gfx::Point view_topleft; - views::View::ConvertPointToScreen(view, &view_topleft); - gfx::Rect view_screen_bounds = view->GetLocalBounds(true); - view_screen_bounds.Offset(view_topleft.x(), view_topleft.y()); - return view_screen_bounds; -} - -int DraggedTabController::NormalizeIndexToAttachedTabStrip(int index) const { - DCHECK(attached_tabstrip_) << "Can only be called when attached!"; - TabStripModel* attached_model = GetModel(attached_tabstrip_); - if (index >= attached_model->count()) - return attached_model->count() - 1; - if (index == TabStripModel::kNoTab) - return 0; - return index; -} - -void DraggedTabController::HideFrame() { -#if defined(OS_WIN) - // We don't actually hide the window, rather we just move it way off-screen. - // If we actually hide it, we stop receiving drag events. - HWND frame_hwnd = source_tabstrip_->GetWidget()->GetNativeView(); - RECT wr; - GetWindowRect(frame_hwnd, &wr); - MoveWindow(frame_hwnd, 0xFFFF, 0xFFFF, wr.right - wr.left, - wr.bottom - wr.top, TRUE); - - // We also save the bounds of the window prior to it being moved, so that if - // the drag session is aborted we can restore them. - restore_bounds_ = gfx::Rect(wr); -#else - NOTIMPLEMENTED(); -#endif -} - -void DraggedTabController::CleanUpHiddenFrame() { - // If the model we started dragging from is now empty, we must ask the - // delegate to close the frame. - if (GetModel(source_tabstrip_)->empty()) - GetModel(source_tabstrip_)->delegate()->CloseFrameAfterDragSession(); -} - -void DraggedTabController::DockDisplayerDestroyed( - DockDisplayer* controller) { - DockWindows::iterator dock_i = - dock_windows_.find(controller->popup_view()); - if (dock_i != dock_windows_.end()) - dock_windows_.erase(dock_i); - else - NOTREACHED(); - - std::vector<DockDisplayer*>::iterator i = - std::find(dock_controllers_.begin(), dock_controllers_.end(), - controller); - if (i != dock_controllers_.end()) - dock_controllers_.erase(i); - else - NOTREACHED(); -} - -void DraggedTabController::BringWindowUnderMouseToFront() { - // If we're going to dock to another window, bring it to the front. - gfx::NativeWindow window = dock_info_.window(); - if (!window) { - gfx::NativeView dragged_view = view_->GetWidget()->GetNativeView(); - dock_windows_.insert(dragged_view); - window = DockInfo::GetLocalProcessWindowAtPoint(GetCursorScreenPoint(), - dock_windows_); - dock_windows_.erase(dragged_view); - } - if (window) { -#if defined(OS_WIN) - // Move the window to the front. - SetWindowPos(window, HWND_TOP, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - - // The previous call made the window appear on top of the dragged window, - // move the dragged window to the front. - SetWindowPos(view_->GetWidget()->GetNativeView(), HWND_TOP, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); -#else - NOTIMPLEMENTED(); -#endif - } -} - -TabStripModel* DraggedTabController::GetModel(BaseTabStrip* tabstrip) const { - return static_cast<BrowserTabStripController*>(tabstrip->controller())-> - model(); -} diff --git a/chrome/browser/views/tabs/dragged_tab_controller.h b/chrome/browser/views/tabs/dragged_tab_controller.h index 5c9c619..e445018 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.h +++ b/chrome/browser/views/tabs/dragged_tab_controller.h @@ -6,334 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_ #pragma once -#include "base/message_loop.h" -#include "base/scoped_ptr.h" -#include "base/timer.h" -#include "chrome/browser/dock_info.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "gfx/rect.h" - -namespace views { -class View; -} -class BaseTab; -class BaseTabStrip; -class DraggedTabView; -class NativeViewPhotobooth; -class TabStripModel; - -struct TabRendererData; - -/////////////////////////////////////////////////////////////////////////////// -// -// DraggedTabController -// -// An object that handles a drag session for an individual Tab within a -// TabStrip. This object is created whenever the mouse is pressed down on a -// Tab and destroyed when the mouse is released or the drag operation is -// aborted. The Tab that the user dragged (the "source tab") owns this object -// and must be the only one to destroy it (via |DestroyDragController|). -// -/////////////////////////////////////////////////////////////////////////////// -class DraggedTabController : public TabContentsDelegate, - public NotificationObserver, - public MessageLoopForUI::Observer { - public: - DraggedTabController(BaseTab* source_tab, - BaseTabStrip* source_tabstrip); - virtual ~DraggedTabController(); - - // Returns true if there is a drag underway and the drag is attached to - // |tab_strip|. - // NOTE: this returns false if the dragged tab controller is in the process - // of finishing the drag. - static bool IsAttachedTo(BaseTabStrip* tab_strip); - - // Capture information needed to be used during a drag session for this - // controller's associated source tab and BaseTabStrip. |mouse_offset| is the - // distance of the mouse pointer from the tab's origin. - void CaptureDragInfo(views::View* tab, const gfx::Point& mouse_offset); - - // Responds to drag events subsequent to StartDrag. If the mouse moves a - // sufficient distance before the mouse is released, a drag session is - // initiated. - void Drag(); - - // Complete the current drag session. If the drag session was canceled - // because the user pressed Escape or something interrupted it, |canceled| - // is true so the helper can revert the state to the world before the drag - // begun. - void EndDrag(bool canceled); - - TabContents* dragged_contents() { return dragged_contents_; } - - // Returns true if a drag started. - bool started_drag() const { return started_drag_; } - - private: - class DockDisplayer; - friend class DockDisplayer; - - typedef std::set<gfx::NativeView> DockWindows; - - // Enumeration of the ways a drag session can end. - enum EndDragType { - // Drag session exited normally: the user released the mouse. - NORMAL, - - // The drag session was canceled (alt-tab during drag, escape ...) - CANCELED, - - // The tab (NavigationController) was destroyed during the drag. - TAB_DESTROYED - }; - - // Overridden from TabContentsDelegate: - virtual void OpenURLFromTab(TabContents* source, - const GURL& url, - const GURL& referrer, - WindowOpenDisposition disposition, - PageTransition::Type transition); - virtual void NavigationStateChanged(const TabContents* source, - unsigned changed_flags); - virtual void AddNewContents(TabContents* source, - TabContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture); - virtual void ActivateContents(TabContents* contents); - virtual void DeactivateContents(TabContents* contents); - virtual void LoadingStateChanged(TabContents* source); - virtual void CloseContents(TabContents* source); - virtual void MoveContents(TabContents* source, const gfx::Rect& pos); - virtual void ToolbarSizeChanged(TabContents* source, bool is_animating); - virtual void URLStarredChanged(TabContents* source, bool starred); - virtual void UpdateTargetURL(TabContents* source, const GURL& url); - - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Overridden from MessageLoop::Observer: -#if defined(OS_WIN) - virtual void WillProcessMessage(const MSG& msg); - virtual void DidProcessMessage(const MSG& msg); -#else - virtual void WillProcessEvent(GdkEvent* event); - virtual void DidProcessEvent(GdkEvent* event); -#endif - - // Initialize the offset used to calculate the position to create windows - // in |GetWindowCreatePoint|. This should only be invoked from - // |CaptureDragInfo|. - void InitWindowCreatePoint(); - - // Updates the window create point from |mouse_offset_|. - void UpdateWindowCreatePoint(); - - // Returns the point where a detached window should be created given the - // current mouse position. - gfx::Point GetWindowCreatePoint() const; - - void UpdateDockInfo(const gfx::Point& screen_point); - - // Sets the TabContents being dragged with the specified |new_contents|. - void SetDraggedContents(TabContents* new_contents); - - // Saves focus in the window that the drag initiated from. Focus will be - // restored appropriately if the drag ends within this same window. - void SaveFocus(); - - // Restore focus to the View that had focus before the drag was started, if - // the drag ends within the same Window as it began. - void RestoreFocus(); - - // Tests whether the position of the mouse is past a minimum elasticity - // threshold required to start a drag. - bool CanStartDrag() const; - - // Move the DraggedTabView according to the current mouse screen position, - // potentially updating the source and other TabStrips. - void ContinueDragging(); - - // Handles dragging a tab while the tab is attached. - void MoveAttachedTab(const gfx::Point& screen_point); - - // Handles dragging while the tab is detached. - void MoveDetachedTab(const gfx::Point& screen_point); - - // Returns the compatible TabStrip that is under the specified point (screen - // coordinates), or NULL if there is none. - BaseTabStrip* GetTabStripForPoint(const gfx::Point& screen_point); - - DockInfo GetDockInfoAtPoint(const gfx::Point& screen_point); - - // Returns the specified |tabstrip| if it contains the specified point - // (screen coordinates), NULL if it does not. - BaseTabStrip* GetTabStripIfItContains(BaseTabStrip* tabstrip, - const gfx::Point& screen_point) const; - - // Attach the dragged Tab to the specified TabStrip. - void Attach(BaseTabStrip* attached_tabstrip, const gfx::Point& screen_point); - - // Detach the dragged Tab from the current TabStrip. - void Detach(); - - // Returns the index where the dragged TabContents should be inserted into - // the attached TabStripModel given the DraggedTabView's bounds - // |dragged_bounds| in coordinates relative to the attached TabStrip. - // |is_tab_attached| is true if the tab has already been added. - int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds, - bool is_tab_attached) const; - - // Retrieve the bounds of the DraggedTabView, relative to the attached - // TabStrip, given location of the dragged tab in screen coordinates. - gfx::Rect GetDraggedViewTabStripBounds(const gfx::Point& screen_point); - - // Get the position of the dragged tab view relative to the attached tab - // strip. - gfx::Point GetAttachedTabDragPoint(const gfx::Point& screen_point); - - // Finds the Tab within the specified TabStrip that corresponds to the - // dragged TabContents. - BaseTab* GetTabMatchingDraggedContents(BaseTabStrip* tabstrip) const; - - // Does the work for EndDrag. If we actually started a drag and |how_end| is - // not TAB_DESTROYED then one of EndDrag or RevertDrag is invoked. - void EndDragImpl(EndDragType how_end); - - // Reverts a cancelled drag operation. - void RevertDrag(); - - // Finishes a succesful drag operation. - void CompleteDrag(); - - // Create the DraggedTabView, if it does not yet exist. - void EnsureDraggedView(const TabRendererData& data); - - // Utility for getting the mouse position in screen coordinates. - gfx::Point GetCursorScreenPoint() const; - - // Returns the bounds (in screen coordinates) of the specified View. - gfx::Rect GetViewScreenBounds(views::View* tabstrip) const; - - // Utility to convert the specified TabStripModel index to something valid - // for the attached TabStrip. - int NormalizeIndexToAttachedTabStrip(int index) const; - - // Hides the frame for the window that contains the TabStrip the current - // drag session was initiated from. - void HideFrame(); - - // Closes a hidden frame at the end of a drag session. - void CleanUpHiddenFrame(); - - void DockDisplayerDestroyed(DockDisplayer* controller); - - void BringWindowUnderMouseToFront(); - - // Returns the TabStripModel for the specified tabstrip. - TabStripModel* GetModel(BaseTabStrip* tabstrip) const; - - // Handles registering for notifications. - NotificationRegistrar registrar_; - - // The TabContents being dragged. - TabContents* dragged_contents_; - - // The original TabContentsDelegate of |dragged_contents_|, before it was - // detached from the browser window. We store this so that we can forward - // certain delegate notifications back to it if we can't handle them locally. - TabContentsDelegate* original_delegate_; - - // The TabStrip |source_tab_| originated from. - BaseTabStrip* source_tabstrip_; - - // This is the index of the |source_tab_| in |source_tabstrip_| when the drag - // began. This is used to restore the previous state if the drag is aborted. - int source_model_index_; - - // The TabStrip the dragged Tab is currently attached to, or NULL if the - // dragged Tab is detached. - BaseTabStrip* attached_tabstrip_; - - // If attached this is the tab we're dragging. - BaseTab* attached_tab_; - - // The visual representation of the dragged Tab. - scoped_ptr<DraggedTabView> view_; - - // The photo-booth the TabContents sits in when the Tab is detached, to - // obtain screen shots. - scoped_ptr<NativeViewPhotobooth> photobooth_; - - // The position of the mouse (in screen coordinates) at the start of the drag - // operation. This is used to calculate minimum elasticity before a - // DraggedTabView is constructed. - gfx::Point start_screen_point_; - - // This is the offset of the mouse from the top left of the Tab where - // dragging begun. This is used to ensure that the dragged view is always - // positioned at the correct location during the drag, and to ensure that the - // detached window is created at the right location. - gfx::Point mouse_offset_; - - // Ratio of the x-coordinate of the mouse offset to the width of the tab. - float offset_to_width_ratio_; - - // A hint to use when positioning new windows created by detaching Tabs. This - // is the distance of the mouse from the top left of the dragged tab as if it - // were the distance of the mouse from the top left of the first tab in the - // attached TabStrip from the top left of the window. - gfx::Point window_create_point_; - - // Location of the first tab in the source tabstrip in screen coordinates. - // This is used to calculate window_create_point_. - gfx::Point first_source_tab_point_; - - // The bounds of the browser window before the last Tab was detached. When - // the last Tab is detached, rather than destroying the frame (which would - // abort the drag session), the frame is moved off-screen. If the drag is - // aborted (e.g. by the user pressing Esc, or capture being lost), the Tab is - // attached to the hidden frame and the frame moved back to these bounds. - gfx::Rect restore_bounds_; - - // The last view that had focus in the window containing |source_tab_|. This - // is saved so that focus can be restored properly when a drag begins and - // ends within this same window. - views::View* old_focused_view_; - - // The position along the major axis of the mouse cursor in screen coordinates - // at the time of the last re-order event. - int last_move_screen_loc_; - - DockInfo dock_info_; - - DockWindows dock_windows_; - - std::vector<DockDisplayer*> dock_controllers_; - - // Is the tab mini? - const bool mini_; - - // Is the tab pinned? - const bool pinned_; - - // Timer used to bring the window under the cursor to front. If the user - // stops moving the mouse for a brief time over a browser window, it is - // brought to front. - base::OneShotTimer<DraggedTabController> bring_to_front_timer_; - - // Did the mouse move enough that we started a drag? - bool started_drag_; - - // Is the drag active? - bool active_; - - DISALLOW_COPY_AND_ASSIGN(DraggedTabController); -}; +#include "chrome/browser/ui/views/tabs/dragged_tab_controller.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_ + diff --git a/chrome/browser/views/tabs/dragged_tab_view.cc b/chrome/browser/views/tabs/dragged_tab_view.cc deleted file mode 100644 index 8f77a87..0000000 --- a/chrome/browser/views/tabs/dragged_tab_view.cc +++ /dev/null @@ -1,222 +0,0 @@ -// 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/tabs/dragged_tab_view.h" - -#include "chrome/browser/views/tabs/native_view_photobooth.h" -#include "gfx/canvas_skia.h" -#include "third_party/skia/include/core/SkShader.h" -#include "views/widget/widget.h" - -#if defined(OS_WIN) -#include "views/widget/widget_win.h" -#elif defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -static const int kTransparentAlpha = 200; -static const int kOpaqueAlpha = 255; -static const int kDragFrameBorderSize = 2; -static const int kTwiceDragFrameBorderSize = 2 * kDragFrameBorderSize; -static const float kScalingFactor = 0.5; -static const SkColor kDraggedTabBorderColor = SkColorSetRGB(103, 129, 162); - -//////////////////////////////////////////////////////////////////////////////// -// DraggedTabView, public: - -DraggedTabView::DraggedTabView(views::View* renderer, - const gfx::Point& mouse_tab_offset, - const gfx::Size& contents_size, - const gfx::Size& min_size) - : renderer_(renderer), - show_contents_on_drag_(true), - mouse_tab_offset_(mouse_tab_offset), - tab_size_(min_size), - photobooth_(NULL), - contents_size_(contents_size) { - set_parent_owned(false); - -#if defined(OS_WIN) - container_.reset(new views::WidgetWin); - container_->set_delete_on_destroy(false); - container_->set_window_style(WS_POPUP); - container_->set_window_ex_style( - WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW); - container_->set_can_update_layered_window(false); - container_->Init(NULL, gfx::Rect(0, 0, 0, 0)); - container_->SetContentsView(this); - - BOOL drag; - if ((::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &drag, 0) != 0) && - (drag == FALSE)) { - show_contents_on_drag_ = false; - } -#else - container_.reset(new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP)); - container_->MakeTransparent(); - container_->set_delete_on_destroy(false); - container_->Init(NULL, gfx::Rect(0, 0, 0, 0)); - container_->SetContentsView(this); -#endif -} - -DraggedTabView::~DraggedTabView() { - GetParent()->RemoveChildView(this); - container_->CloseNow(); -} - -void DraggedTabView::MoveTo(const gfx::Point& screen_point) { - int x; - if (base::i18n::IsRTL()) { - // On RTL locales, a dragged tab (when it is not attached to a tab strip) - // is rendered using a right-to-left orientation so we should calculate the - // window position differently. - gfx::Size ps = GetPreferredSize(); - x = screen_point.x() - ScaleValue(ps.width()) + mouse_tab_offset_.x() + - ScaleValue( - renderer_->MirroredXCoordinateInsideView(mouse_tab_offset_.x())); - } else { - x = screen_point.x() + mouse_tab_offset_.x() - - ScaleValue(mouse_tab_offset_.x()); - } - int y = screen_point.y() + mouse_tab_offset_.y() - - ScaleValue(mouse_tab_offset_.y()); - -#if defined(OS_WIN) - int show_flags = container_->IsVisible() ? SWP_NOZORDER : SWP_SHOWWINDOW; - - container_->SetWindowPos(HWND_TOP, x, y, 0, 0, - SWP_NOSIZE | SWP_NOACTIVATE | show_flags); -#else - gfx::Rect bounds; - container_->GetBounds(&bounds, true); - container_->SetBounds(gfx::Rect(x, y, bounds.width(), bounds.height())); - if (!container_->IsVisible()) - container_->Show(); -#endif -} - -void DraggedTabView::SetTabWidthAndUpdate(int width, - NativeViewPhotobooth* photobooth) { - tab_size_.set_width(width); - photobooth_ = photobooth; -#if defined(OS_WIN) - container_->SetOpacity(kTransparentAlpha); -#endif - ResizeContainer(); - Update(); -} - -void DraggedTabView::Update() { -#if defined(OS_WIN) - container_->set_can_update_layered_window(true); - SchedulePaint(); - container_->PaintNow(gfx::Rect()); - container_->set_can_update_layered_window(false); -#else - SchedulePaint(); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -// DraggedTabView, views::View overrides: - -void DraggedTabView::Paint(gfx::Canvas* canvas) { - if (show_contents_on_drag_) - PaintDetachedView(canvas); - else - PaintFocusRect(canvas); -} - -void DraggedTabView::Layout() { - int left = 0; - if (base::i18n::IsRTL()) - left = GetPreferredSize().width() - tab_size_.width(); - // The renderer_'s width should be tab_size_.width() in both LTR and RTL - // locales. Wrong width will cause the wrong positioning of the tab view in - // dragging. Please refer to http://crbug.com/6223 for details. - renderer_->SetBounds(left, 0, tab_size_.width(), tab_size_.height()); -} - -gfx::Size DraggedTabView::GetPreferredSize() { - int width = std::max(tab_size_.width(), contents_size_.width()) + - kTwiceDragFrameBorderSize; - int height = tab_size_.height() + kDragFrameBorderSize + - contents_size_.height(); - return gfx::Size(width, height); -} - -//////////////////////////////////////////////////////////////////////////////// -// DraggedTabView, private: - -void DraggedTabView::PaintDetachedView(gfx::Canvas* canvas) { - gfx::Size ps = GetPreferredSize(); - gfx::CanvasSkia scale_canvas(ps.width(), ps.height(), false); - SkBitmap& bitmap_device = const_cast<SkBitmap&>( - scale_canvas.getTopPlatformDevice().accessBitmap(true)); - bitmap_device.eraseARGB(0, 0, 0, 0); - - scale_canvas.FillRectInt(kDraggedTabBorderColor, 0, - tab_size_.height() - kDragFrameBorderSize, - ps.width(), ps.height() - tab_size_.height()); - int image_x = kDragFrameBorderSize; - int image_y = tab_size_.height(); - int image_w = ps.width() - kTwiceDragFrameBorderSize; - int image_h = contents_size_.height(); - scale_canvas.FillRectInt(SK_ColorBLACK, image_x, image_y, image_w, image_h); - photobooth_->PaintScreenshotIntoCanvas( - &scale_canvas, - gfx::Rect(image_x, image_y, image_w, image_h)); - renderer_->ProcessPaint(&scale_canvas); - - SkIRect subset; - subset.set(0, 0, ps.width(), ps.height()); - SkBitmap mipmap = scale_canvas.ExtractBitmap(); - mipmap.buildMipMap(true); - - SkShader* bitmap_shader = - SkShader::CreateBitmapShader(mipmap, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode); - - SkMatrix shader_scale; - shader_scale.setScale(kScalingFactor, kScalingFactor); - bitmap_shader->setLocalMatrix(shader_scale); - - SkPaint paint; - paint.setShader(bitmap_shader); - paint.setAntiAlias(true); - bitmap_shader->unref(); - - SkRect rc; - rc.fLeft = 0; - rc.fTop = 0; - rc.fRight = SkIntToScalar(ps.width()); - rc.fBottom = SkIntToScalar(ps.height()); - canvas->AsCanvasSkia()->drawRect(rc, paint); -} - -void DraggedTabView::PaintFocusRect(gfx::Canvas* canvas) { - gfx::Size ps = GetPreferredSize(); - canvas->DrawFocusRect(0, 0, - static_cast<int>(ps.width() * kScalingFactor), - static_cast<int>(ps.height() * kScalingFactor)); -} - -void DraggedTabView::ResizeContainer() { - gfx::Size ps = GetPreferredSize(); - int w = ScaleValue(ps.width()); - int h = ScaleValue(ps.height()); -#if defined(OS_WIN) - SetWindowPos(container_->GetNativeView(), HWND_TOPMOST, 0, 0, w, h, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); -#else - gfx::Rect bounds; - container_->GetBounds(&bounds, true); - container_->SetBounds(gfx::Rect(bounds.x(), bounds.y(), w, h)); -#endif -} - -int DraggedTabView::ScaleValue(int value) { - return static_cast<int>(value * kScalingFactor); -} diff --git a/chrome/browser/views/tabs/dragged_tab_view.h b/chrome/browser/views/tabs/dragged_tab_view.h index 0432d46..2848baf 100644 --- a/chrome/browser/views/tabs/dragged_tab_view.h +++ b/chrome/browser/views/tabs/dragged_tab_view.h @@ -6,98 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_VIEW_H_ #pragma once -#include "build/build_config.h" -#include "gfx/point.h" -#include "gfx/size.h" -#include "views/view.h" - -namespace views { -#if defined(OS_WIN) -class WidgetWin; -#elif defined(OS_LINUX) -class WidgetGtk; -#endif -} -namespace gfx { -class Point; -} -class NativeViewPhotobooth; -class Tab; -class TabRenderer; - -class DraggedTabView : public views::View { - public: - // Creates a new DraggedTabView using |renderer| as the View. DraggedTabView - // takes ownership of |renderer|. - DraggedTabView(views::View* renderer, - const gfx::Point& mouse_tab_offset, - const gfx::Size& contents_size, - const gfx::Size& min_size); - virtual ~DraggedTabView(); - - // Moves the DraggedTabView to the appropriate location given the mouse - // pointer at |screen_point|. - void MoveTo(const gfx::Point& screen_point); - - // Sets the offset of the mouse from the upper left corner of the tab. - void set_mouse_tab_offset(const gfx::Point& offset) { - mouse_tab_offset_ = offset; - } - - // Sets the width of the dragged tab and updates the dragged image. - void SetTabWidthAndUpdate(int width, NativeViewPhotobooth* photobooth); - - // Notifies the DraggedTabView that it should update itself. - void Update(); - - private: - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - // Paint the view, when it's not attached to any TabStrip. - void PaintDetachedView(gfx::Canvas* canvas); - - // Paint the view, when "Show window contents while dragging" is disabled. - void PaintFocusRect(gfx::Canvas* canvas); - - // Resizes the container to fit the content for the current attachment mode. - void ResizeContainer(); - - // Utility for scaling a size by the current scaling factor. - int ScaleValue(int value); - - // The window that contains the DraggedTabView. -#if defined(OS_WIN) - scoped_ptr<views::WidgetWin> container_; -#elif defined(OS_LINUX) - scoped_ptr<views::WidgetGtk> container_; -#endif - - // The renderer that paints the Tab shape. - scoped_ptr<views::View> renderer_; - - // True if "Show window contents while dragging" is enabled. - bool show_contents_on_drag_; - - // The unscaled offset of the mouse from the top left of the dragged Tab. - // This is used to maintain an appropriate offset for the mouse pointer when - // dragging scaled and unscaled representations, and also to calculate the - // position of detached windows. - gfx::Point mouse_tab_offset_; - - // The size of the tab renderer. - gfx::Size tab_size_; - - // A handle to the DIB containing the current screenshot of the TabContents - // we are dragging. - NativeViewPhotobooth* photobooth_; - - // Size of the TabContents being dragged. - gfx::Size contents_size_; - - DISALLOW_COPY_AND_ASSIGN(DraggedTabView); -}; +#include "chrome/browser/ui/views/tabs/dragged_tab_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_VIEW_H_ + diff --git a/chrome/browser/views/tabs/native_view_photobooth.h b/chrome/browser/views/tabs/native_view_photobooth.h index 0eba321..1a954e5 100644 --- a/chrome/browser/views/tabs/native_view_photobooth.h +++ b/chrome/browser/views/tabs/native_view_photobooth.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,39 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_H_ #pragma once -#include "gfx/native_widget_types.h" - -namespace gfx { -class Canvas; -class Rect; -} -/////////////////////////////////////////////////////////////////////////////// -// NativeViewPhotobooth -// -// An object that a NativeView "steps into" to have its picture taken. This is -// used to generate a full size screen shot of the contents of a NativeView -// including any child windows. -// -// Implementation note: This causes the NativeView to be re-parented to a -// mostly off-screen layered window. -// -class NativeViewPhotobooth { - public: - // Creates the photo booth. Constructs a nearly off-screen window, parents - // the view, then shows it. The caller is responsible for destroying this - // photo-booth, since the photo-booth will detach it before it is destroyed. - static NativeViewPhotobooth* Create(gfx::NativeView initial_view); - - // Destroys the photo booth window. - virtual ~NativeViewPhotobooth() {} - - // Replaces the view in the photo booth with the specified one. - virtual void Replace(gfx::NativeView new_view) = 0; - - // Paints the current display image of the window into |canvas|, clipped to - // |target_bounds|. - virtual void PaintScreenshotIntoCanvas(gfx::Canvas* canvas, - const gfx::Rect& target_bounds) = 0; -}; +#include "chrome/browser/ui/views/tabs/native_view_photobooth.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_H_ + diff --git a/chrome/browser/views/tabs/native_view_photobooth_gtk.cc b/chrome/browser/views/tabs/native_view_photobooth_gtk.cc deleted file mode 100644 index a307112..0000000 --- a/chrome/browser/views/tabs/native_view_photobooth_gtk.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2009 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/tabs/native_view_photobooth_gtk.h" - -#include "base/logging.h" -#include "gfx/canvas.h" - -/////////////////////////////////////////////////////////////////////////////// -// NativeViewPhotoboothGtk, public: - -// static -NativeViewPhotobooth* NativeViewPhotobooth::Create( - gfx::NativeView initial_view) { - return new NativeViewPhotoboothGtk(initial_view); -} - -NativeViewPhotoboothGtk::NativeViewPhotoboothGtk( - gfx::NativeView initial_view) { -} - -NativeViewPhotoboothGtk::~NativeViewPhotoboothGtk() { -} - -void NativeViewPhotoboothGtk::Replace(gfx::NativeView new_view) { - NOTIMPLEMENTED(); -} - -void NativeViewPhotoboothGtk::PaintScreenshotIntoCanvas( - gfx::Canvas* canvas, - const gfx::Rect& target_bounds) { - NOTIMPLEMENTED(); -} diff --git a/chrome/browser/views/tabs/native_view_photobooth_gtk.h b/chrome/browser/views/tabs/native_view_photobooth_gtk.h index 8bc74063..22c3901 100644 --- a/chrome/browser/views/tabs/native_view_photobooth_gtk.h +++ b/chrome/browser/views/tabs/native_view_photobooth_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,25 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_GTK_H_ #pragma once -#include "chrome/browser/views/tabs/native_view_photobooth.h" - -class NativeViewPhotoboothGtk : public NativeViewPhotobooth { - public: - explicit NativeViewPhotoboothGtk(gfx::NativeView new_view); - - // Destroys the photo booth window. - virtual ~NativeViewPhotoboothGtk(); - - // Replaces the view in the photo booth with the specified one. - virtual void Replace(gfx::NativeView new_view); - - // Paints the current display image of the window into |canvas|, clipped to - // |target_bounds|. - virtual void PaintScreenshotIntoCanvas(gfx::Canvas* canvas, - const gfx::Rect& target_bounds); - - private: - DISALLOW_COPY_AND_ASSIGN(NativeViewPhotoboothGtk); -}; +#include "chrome/browser/ui/views/tabs/native_view_photobooth_gtk.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_GTK_H_ + diff --git a/chrome/browser/views/tabs/native_view_photobooth_win.cc b/chrome/browser/views/tabs/native_view_photobooth_win.cc deleted file mode 100644 index d749ea0..0000000 --- a/chrome/browser/views/tabs/native_view_photobooth_win.cc +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) 2006-2008 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/tabs/native_view_photobooth_win.h" - -#include "chrome/browser/tab_contents/tab_contents.h" -#include "gfx/canvas_skia.h" -#include "gfx/point.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "views/widget/widget_win.h" - -namespace { - -static BOOL CALLBACK MonitorEnumProc(HMONITOR monitor, HDC monitor_dc, - RECT* monitor_rect, LPARAM data) { - gfx::Point* point = reinterpret_cast<gfx::Point*>(data); - if (monitor_rect->right > point->x() && monitor_rect->bottom > point->y()) { - point->set_x(monitor_rect->right); - point->set_y(monitor_rect->bottom); - } - return TRUE; -} - -gfx::Point GetCaptureWindowPosition() { - // Since the capture window must be visible to be painted, it must be opened - // off screen to avoid flashing. But if it is opened completely off-screen - // (e.g. at 0xFFFFx0xFFFF) then on Windows Vista it will not paint even if it - // _is_ visible. So we need to find the right/bottommost monitor, and - // position it so that 1x1 pixel is on-screen on that monitor which is enough - // to convince Vista to paint it. Don't ask why this is so - this appears to - // be a regression over XP. - gfx::Point point(0, 0); - EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc, - reinterpret_cast<LPARAM>(&point)); - return gfx::Point(point.x() - 1, point.y() - 1); -} - -} - -/////////////////////////////////////////////////////////////////////////////// -// NativeViewPhotoboothWin, public: - -// static -NativeViewPhotobooth* NativeViewPhotobooth::Create( - gfx::NativeView initial_view) { - return new NativeViewPhotoboothWin(initial_view); -} - -NativeViewPhotoboothWin::NativeViewPhotoboothWin(HWND initial_hwnd) - : capture_window_(NULL), - current_hwnd_(initial_hwnd) { - DCHECK(IsWindow(current_hwnd_)); - CreateCaptureWindow(initial_hwnd); -} - -NativeViewPhotoboothWin::~NativeViewPhotoboothWin() { - // Detach the attached HWND. The creator of the photo-booth is responsible - // for destroying it. - Replace(NULL); - capture_window_->Close(); -} - -void NativeViewPhotoboothWin::Replace(HWND new_hwnd) { - if (IsWindow(current_hwnd_) && - GetParent(current_hwnd_) == capture_window_->GetNativeView()) { - // We need to hide the window too, so it doesn't show up in the TaskBar or - // be parented to the desktop. - ShowWindow(current_hwnd_, SW_HIDE); - SetParent(current_hwnd_, NULL); - } - current_hwnd_ = new_hwnd; - - if (IsWindow(new_hwnd)) { - // Insert the TabContents into the capture window. - SetParent(current_hwnd_, capture_window_->GetNativeView()); - - // Show the window (it may not be visible). This is the only safe way of - // doing this. ShowWindow does not work. - SetWindowPos(current_hwnd_, NULL, 0, 0, 0, 0, - SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOCOPYBITS | - SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER | - SWP_SHOWWINDOW | SWP_NOSIZE); - } -} - -void NativeViewPhotoboothWin::PaintScreenshotIntoCanvas( - gfx::Canvas* canvas, - const gfx::Rect& target_bounds) { - // Our contained window may have been re-parented. Make sure it belongs to - // us until someone calls Replace(NULL). - if (IsWindow(current_hwnd_) && - GetParent(current_hwnd_) != capture_window_->GetNativeView()) { - Replace(current_hwnd_); - } - - // We compel the contained HWND to paint now, synchronously. We do this to - // populate the device context with valid and current data. - RedrawWindow(current_hwnd_, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); - - // Transfer the contents of the layered capture window to the screen-shot - // canvas' DIB. - HDC target_dc = canvas->BeginPlatformPaint(); - HDC source_dc = GetDC(current_hwnd_); - RECT window_rect = {0}; - GetWindowRect(current_hwnd_, &window_rect); - BitBlt(target_dc, target_bounds.x(), target_bounds.y(), - target_bounds.width(), target_bounds.height(), source_dc, 0, 0, - SRCCOPY); - // Windows screws up the alpha channel on all text it draws, and so we need - // to call makeOpaque _after_ the blit to correct for this. - canvas->AsCanvasSkia()->getTopPlatformDevice().makeOpaque( - target_bounds.x(), target_bounds.y(), target_bounds.width(), - target_bounds.height()); - ReleaseDC(current_hwnd_, source_dc); - canvas->EndPlatformPaint(); -} - -/////////////////////////////////////////////////////////////////////////////// -// NativeViewPhotoboothWin, private: - -void NativeViewPhotoboothWin::CreateCaptureWindow(HWND initial_hwnd) { - // Snapshotting a HWND is tricky - if the HWND is clipped (e.g. positioned - // partially off-screen) then just blitting from the HWND' DC to the capture - // bitmap would be incorrect, since the capture bitmap would show only the - // visible area of the HWND. - // - // The approach turns out to be to create a second layered window in - // hyperspace the to act as a "photo booth." The window is created with the - // size of the unclipped HWND, and we attach the HWND as a child, refresh the - // HWND' by calling |Paint| on it, and then blitting from the HWND's DC to - // the capture bitmap. This results in the entire unclipped HWND display - // bitmap being captured. - // - // The capture window must be layered so that Windows generates a backing - // store for it, so that blitting from a child window's DC produces data. If - // the window is not layered, because it is off-screen Windows does not - // retain its contents and blitting results in blank data. The capture window - // is a "basic" (1 level of alpha) layered window because that is the mode - // that supports having child windows (variable alpha layered windows do not - // support child HWNDs). - // - // This function sets up the off-screen capture window, and attaches the - // associated HWND to it. Note that the details are important here, see below - // for further comments. - // - CRect contents_rect; - GetClientRect(initial_hwnd, &contents_rect); - gfx::Point window_position = GetCaptureWindowPosition(); - gfx::Rect capture_bounds(window_position.x(), window_position.y(), - contents_rect.Width(), contents_rect.Height()); - capture_window_ = new views::WidgetWin; - capture_window_->set_window_style(WS_POPUP); - // WS_EX_TOOLWINDOW ensures the capture window doesn't produce a Taskbar - // button. - capture_window_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW); - capture_window_->Init(NULL, capture_bounds); - // If the capture window isn't visible, blitting from the TabContents' - // HWND's DC to the capture bitmap produces blankness. - capture_window_->Show(); - SetLayeredWindowAttributes( - capture_window_->GetNativeView(), RGB(0xFF, 0xFF, 0xFF), 0xFF, LWA_ALPHA); - - Replace(initial_hwnd); -} diff --git a/chrome/browser/views/tabs/native_view_photobooth_win.h b/chrome/browser/views/tabs/native_view_photobooth_win.h index 4ed4016..2cd2a4b 100644 --- a/chrome/browser/views/tabs/native_view_photobooth_win.h +++ b/chrome/browser/views/tabs/native_view_photobooth_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -6,53 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_WIN_H_ #pragma once -#include "chrome/browser/views/tabs/native_view_photobooth.h" - -namespace views { -class WidgetWin; -} - -/////////////////////////////////////////////////////////////////////////////// -// HWNDPhotobooth -// -// An object that a HWND "steps into" to have its picture taken. This is used -// to generate a full size screen shot of the contents of a HWND including -// any child windows. -// -// Implementation note: This causes the HWND to be re-parented to a mostly -// off-screen layered window. -// -class NativeViewPhotoboothWin : public NativeViewPhotobooth { - public: - // Creates the photo booth. Constructs a nearly off-screen window, parents - // the HWND, then shows it. The caller is responsible for destroying this - // window, since the photo-booth will detach it before it is destroyed. - // |canvas| is a canvas to paint the contents into, and dest_bounds is the - // target area in |canvas| to which painted contents will be clipped. - explicit NativeViewPhotoboothWin(gfx::NativeView initial_view); - - // Destroys the photo booth window. - virtual ~NativeViewPhotoboothWin(); - - // Replaces the view in the photo booth with the specified one. - virtual void Replace(gfx::NativeView new_view); - - // Paints the current display image of the window into |canvas|, clipped to - // |target_bounds|. - virtual void PaintScreenshotIntoCanvas(gfx::Canvas* canvas, - const gfx::Rect& target_bounds); - - private: - // Creates a mostly off-screen window to contain the HWND to be captured. - void CreateCaptureWindow(HWND initial_hwnd); - - // The nearly off-screen photo-booth layered window used to hold the HWND. - views::WidgetWin* capture_window_; - - // The current HWND being captured. - HWND current_hwnd_; - - DISALLOW_COPY_AND_ASSIGN(NativeViewPhotoboothWin); -}; +#include "chrome/browser/ui/views/tabs/native_view_photobooth_win.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_WIN_H_ + diff --git a/chrome/browser/views/tabs/side_tab.cc b/chrome/browser/views/tabs/side_tab.cc deleted file mode 100644 index b42bca0..0000000 --- a/chrome/browser/views/tabs/side_tab.cc +++ /dev/null @@ -1,114 +0,0 @@ -// 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/tabs/side_tab.h" - -#include "app/resource_bundle.h" -#include "base/utf_string_conversions.h" -#include "gfx/canvas_skia.h" -#include "gfx/favicon_size.h" -#include "gfx/path.h" -#include "gfx/skia_util.h" -#include "grit/app_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/image_button.h" - -namespace { -const int kVerticalTabHeight = 27; -const int kTitleCloseSpacing = 4; -const SkScalar kRoundRectRadius = 4; -const SkColor kTabBackgroundColor = SK_ColorWHITE; -const SkColor kTextColor = SK_ColorBLACK; - -// Padding between the edge and the icon. -const int kIconLeftPadding = 5; - -// Location the title starts at. -const int kTitleX = kIconLeftPadding + kFavIconSize + 5; -}; - -//////////////////////////////////////////////////////////////////////////////// -// SideTab, public: - -SideTab::SideTab(TabController* controller) - : BaseTab(controller) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - close_button()->SetBackground(kTextColor, - rb.GetBitmapNamed(IDR_TAB_CLOSE), - rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK)); -} - -SideTab::~SideTab() { -} - -// static -int SideTab::GetPreferredHeight() { - return 27; -} - -//////////////////////////////////////////////////////////////////////////////// -// SideTab, views::View overrides: - -void SideTab::Layout() { - if (ShouldShowIcon()) { - int icon_x = kIconLeftPadding; - int icon_y = (height() - kFavIconSize) / 2; - int icon_size = - !data().favicon.empty() ? data().favicon.width() : kFavIconSize; - if (icon_size != kFavIconSize) { - icon_x -= (icon_size - kFavIconSize) / 2; - icon_y -= (icon_size - kFavIconSize) / 2; - } - icon_bounds_.SetRect(icon_x, icon_y, icon_size, icon_size); - } else { - icon_bounds_ = gfx::Rect(); - } - - gfx::Size ps = close_button()->GetPreferredSize(); - int close_y = (height() - ps.height()) / 2; - close_button()->SetBounds( - std::max(0, width() - ps.width() - - (GetPreferredHeight() - ps.height()) / 2), - close_y, - ps.width(), - ps.height()); - - int title_y = (height() - font_height()) / 2; - title_bounds_.SetRect( - kTitleX, - title_y, - std::max(0, close_button()->x() - kTitleCloseSpacing - kTitleX), - font_height()); -} - -void SideTab::Paint(gfx::Canvas* canvas) { - if (ShouldPaintHighlight()) { - SkPaint paint; - paint.setColor(kTabBackgroundColor); - paint.setAntiAlias(true); - SkRect border_rect = { SkIntToScalar(0), SkIntToScalar(0), - SkIntToScalar(width()), SkIntToScalar(height()) }; - canvas->AsCanvasSkia()->drawRoundRect(border_rect, - SkIntToScalar(kRoundRectRadius), - SkIntToScalar(kRoundRectRadius), - paint); - } - - if (ShouldShowIcon()) - PaintIcon(canvas, icon_bounds_.x(), icon_bounds_.y()); - - PaintTitle(canvas, kTextColor); -} - -gfx::Size SideTab::GetPreferredSize() { - return gfx::Size(0, GetPreferredHeight()); -} - -bool SideTab::ShouldPaintHighlight() const { - return IsSelected() || !controller(); -} - -bool SideTab::ShouldShowIcon() const { - return data().mini || data().show_icon; -} diff --git a/chrome/browser/views/tabs/side_tab.h b/chrome/browser/views/tabs/side_tab.h index 6cff764..5d27ce3 100644 --- a/chrome/browser/views/tabs/side_tab.h +++ b/chrome/browser/views/tabs/side_tab.h @@ -6,39 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_H_ #pragma once -#include "chrome/browser/views/tabs/base_tab.h" -#include "gfx/font.h" - -class SideTab; -class TabStripController; - -class SideTab : public BaseTab { - public: - explicit SideTab(TabController* controller); - virtual ~SideTab(); - - // Returns the preferred height of side tabs. - static int GetPreferredHeight(); - - // views::View Overrides: - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - virtual gfx::Size GetPreferredSize(); - - protected: - virtual const gfx::Rect& title_bounds() const { return title_bounds_; } - - // Returns true if the selected highlight should be rendered. - virtual bool ShouldPaintHighlight() const; - - private: - // Returns true if the icon should be shown. - bool ShouldShowIcon() const; - - gfx::Rect icon_bounds_; - gfx::Rect title_bounds_; - - DISALLOW_COPY_AND_ASSIGN(SideTab); -}; +#include "chrome/browser/ui/views/tabs/side_tab.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_H_ + diff --git a/chrome/browser/views/tabs/side_tab_strip.cc b/chrome/browser/views/tabs/side_tab_strip.cc deleted file mode 100644 index 84e8082..0000000 --- a/chrome/browser/views/tabs/side_tab_strip.cc +++ /dev/null @@ -1,260 +0,0 @@ -// 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/tabs/side_tab_strip.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/browser/views/tabs/side_tab.h" -#include "chrome/browser/views/tabs/tab_strip_controller.h" -#include "chrome/browser/view_ids.h" -#include "gfx/canvas.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/background.h" -#include "views/controls/button/image_button.h" - -namespace { -const int kVerticalTabSpacing = 2; -const int kTabStripWidth = 140; -const SkColor kBackgroundColor = SkColorSetARGB(255, 209, 220, 248); -const SkColor kSeparatorColor = SkColorSetARGB(255, 151, 159, 179); - -// Height of the separator. -const int kSeparatorHeight = 1; - -// The new tab button is rendered using a SideTab. -class SideTabNewTabButton : public SideTab { - public: - explicit SideTabNewTabButton(TabStripController* controller); - - virtual bool ShouldPaintHighlight() const { return false; } - virtual bool IsSelected() const { return false; } - bool OnMousePressed(const views::MouseEvent& event); - void OnMouseReleased(const views::MouseEvent& event, bool canceled); - - private: - TabStripController* controller_; - - DISALLOW_COPY_AND_ASSIGN(SideTabNewTabButton); -}; - -SideTabNewTabButton::SideTabNewTabButton(TabStripController* controller) - : SideTab(NULL), - controller_(controller) { - // Never show a close button for the new tab button. - close_button()->SetVisible(false); - TabRendererData data; - data.favicon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_SIDETABS_NEW_TAB); - data.title = l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE); - SetData(data); -} - -bool SideTabNewTabButton::OnMousePressed(const views::MouseEvent& event) { - return true; -} - -void SideTabNewTabButton::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - if (!canceled && event.IsOnlyLeftMouseButton() && HitTest(event.location())) - controller_->CreateNewTab(); -} - -} // namespace - -// static -const int SideTabStrip::kTabStripInset = 3; - -//////////////////////////////////////////////////////////////////////////////// -// SideTabStrip, public: - -SideTabStrip::SideTabStrip(TabStripController* controller) - : BaseTabStrip(controller, BaseTabStrip::VERTICAL_TAB_STRIP), - newtab_button_(new SideTabNewTabButton(controller)), - separator_(new views::View()) { - SetID(VIEW_ID_TAB_STRIP); - set_background(views::Background::CreateSolidBackground(kBackgroundColor)); - AddChildView(newtab_button_); - separator_->set_background( - views::Background::CreateSolidBackground(kSeparatorColor)); - AddChildView(separator_); -} - -SideTabStrip::~SideTabStrip() { - DestroyDragController(); -} - -//////////////////////////////////////////////////////////////////////////////// -// SideTabStrip, BaseTabStrip implementation: - -int SideTabStrip::GetPreferredHeight() { - return 0; -} - -void SideTabStrip::SetBackgroundOffset(const gfx::Point& offset) { -} - -bool SideTabStrip::IsPositionInWindowCaption(const gfx::Point& point) { - return GetViewForPoint(point) == this; -} - -void SideTabStrip::SetDraggedTabBounds(int tab_index, - const gfx::Rect& tab_bounds) { -} - -TabStrip* SideTabStrip::AsTabStrip() { - return NULL; -} - -void SideTabStrip::StartHighlight(int model_index) { -} - -void SideTabStrip::StopAllHighlighting() { -} - -BaseTab* SideTabStrip::CreateTabForDragging() { - SideTab* tab = new SideTab(NULL); - // Make sure the dragged tab shares our theme provider. We need to explicitly - // do this as during dragging there isn't a theme provider. - tab->set_theme_provider(GetThemeProvider()); - return tab; -} - -void SideTabStrip::RemoveTabAt(int model_index) { - StartRemoveTabAnimation(model_index); -} - -void SideTabStrip::SelectTabAt(int old_model_index, int new_model_index) { - GetBaseTabAtModelIndex(new_model_index)->SchedulePaint(); -} - -void SideTabStrip::TabTitleChangedNotLoading(int model_index) { -} - -gfx::Size SideTabStrip::GetPreferredSize() { - return gfx::Size(kTabStripWidth, 0); -} - -void SideTabStrip::PaintChildren(gfx::Canvas* canvas) { - // Make sure the dragged tab appears on top of all others by paint it last. - BaseTab* dragging_tab = NULL; - - // Paint the new tab and separator first so that any tabs animating appear on - // top. - separator_->ProcessPaint(canvas); - newtab_button_->ProcessPaint(canvas); - - for (int i = tab_count() - 1; i >= 0; --i) { - BaseTab* tab = base_tab_at_tab_index(i); - if (tab->dragging()) - dragging_tab = tab; - else - tab->ProcessPaint(canvas); - } - - if (dragging_tab) - dragging_tab->ProcessPaint(canvas); -} - -BaseTab* SideTabStrip::CreateTab() { - return new SideTab(this); -} - -void SideTabStrip::GenerateIdealBounds() { - gfx::Rect layout_rect = GetLocalBounds(false); - layout_rect.Inset(kTabStripInset, kTabStripInset); - - int y = layout_rect.y(); - bool last_was_mini = true; - bool has_non_closing_tab = false; - separator_bounds_.SetRect(0, -kSeparatorHeight, width(), kSeparatorHeight); - for (int i = 0; i < tab_count(); ++i) { - BaseTab* tab = base_tab_at_tab_index(i); - if (!tab->closing()) { - if (last_was_mini != tab->data().mini) { - if (has_non_closing_tab) { - separator_bounds_.SetRect(0, y, width(), kSeparatorHeight); - y += kSeparatorHeight + kVerticalTabSpacing; - } - newtab_button_bounds_.SetRect( - layout_rect.x(), y, layout_rect.width(), - newtab_button_->GetPreferredSize().height()); - y = newtab_button_bounds_.bottom() + kVerticalTabSpacing; - last_was_mini = tab->data().mini; - } - gfx::Rect bounds = gfx::Rect(layout_rect.x(), y, layout_rect.width(), - tab->GetPreferredSize().height()); - set_ideal_bounds(i, bounds); - y = bounds.bottom() + kVerticalTabSpacing; - has_non_closing_tab = true; - } - } - - if (last_was_mini) { - if (has_non_closing_tab) { - separator_bounds_.SetRect(0, y, width(), kSeparatorHeight); - y += kSeparatorHeight + kVerticalTabSpacing; - } - newtab_button_bounds_ = - gfx::Rect(layout_rect.x(), y, layout_rect.width(), - newtab_button_->GetPreferredSize().height()); - } -} - -void SideTabStrip::StartInsertTabAnimation(int model_index, bool foreground) { - PrepareForAnimation(); - - GenerateIdealBounds(); - - int tab_data_index = ModelIndexToTabIndex(model_index); - BaseTab* tab = base_tab_at_tab_index(tab_data_index); - if (model_index == 0) { - tab->SetBounds(ideal_bounds(tab_data_index).x(), 0, - ideal_bounds(tab_data_index).width(), 0); - } else { - BaseTab* last_tab = base_tab_at_tab_index(tab_data_index - 1); - tab->SetBounds(last_tab->x(), last_tab->bounds().bottom(), - ideal_bounds(tab_data_index).width(), 0); - } - - AnimateToIdealBounds(); -} - -void SideTabStrip::StartMoveTabAnimation() { - PrepareForAnimation(); - - GenerateIdealBounds(); - AnimateToIdealBounds(); -} - -void SideTabStrip::StopAnimating(bool layout) { - if (!IsAnimating()) - return; - - bounds_animator().Cancel(); - - if (layout) - DoLayout(); -} - -void SideTabStrip::AnimateToIdealBounds() { - for (int i = 0; i < tab_count(); ++i) { - BaseTab* tab = base_tab_at_tab_index(i); - if (!tab->closing() && !tab->dragging()) - bounds_animator().AnimateViewTo(tab, ideal_bounds(i)); - } - - bounds_animator().AnimateViewTo(newtab_button_, newtab_button_bounds_); - - bounds_animator().AnimateViewTo(separator_, separator_bounds_); -} - -void SideTabStrip::DoLayout() { - BaseTabStrip::DoLayout(); - - newtab_button_->SetBounds(newtab_button_bounds_); - - separator_->SetBounds(separator_bounds_); -} diff --git a/chrome/browser/views/tabs/side_tab_strip.h b/chrome/browser/views/tabs/side_tab_strip.h index c847077..cbecf20 100644 --- a/chrome/browser/views/tabs/side_tab_strip.h +++ b/chrome/browser/views/tabs/side_tab_strip.h @@ -6,62 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_H_ #pragma once -#include "chrome/browser/views/tabs/base_tab_strip.h" - -struct TabRendererData; - -class SideTabStrip : public BaseTabStrip { - public: - // The tabs are inset by this much along all axis. - static const int kTabStripInset; - - explicit SideTabStrip(TabStripController* controller); - virtual ~SideTabStrip(); - - // BaseTabStrip implementation: - virtual int GetPreferredHeight(); - virtual void SetBackgroundOffset(const gfx::Point& offset); - virtual bool IsPositionInWindowCaption(const gfx::Point& point); - virtual void SetDraggedTabBounds(int tab_index, - const gfx::Rect& tab_bounds); - virtual TabStrip* AsTabStrip(); - - virtual void StartHighlight(int model_index); - virtual void StopAllHighlighting(); - virtual BaseTab* CreateTabForDragging(); - virtual void RemoveTabAt(int model_index); - virtual void SelectTabAt(int old_model_index, int new_model_index); - virtual void TabTitleChangedNotLoading(int model_index); - - // views::View overrides: - virtual gfx::Size GetPreferredSize(); - virtual void PaintChildren(gfx::Canvas* canvas); - - protected: - // BaseTabStrip overrides: - virtual BaseTab* CreateTab(); - virtual void GenerateIdealBounds(); - virtual void StartInsertTabAnimation(int model_index, bool foreground); - virtual void StartMoveTabAnimation(); - virtual void StopAnimating(bool layout); - virtual void AnimateToIdealBounds(); - virtual void DoLayout(); - - private: - // The "New Tab" button. - views::View* newtab_button_; - - // Ideal bounds of the new tab button. - gfx::Rect newtab_button_bounds_; - - // Separator between mini-tabs and the new tab button. The separator is - // positioned above the visible area if there are no mini-tabs. - views::View* separator_; - - // Bounds of the sepatator. - gfx::Rect separator_bounds_; - - DISALLOW_COPY_AND_ASSIGN(SideTabStrip); -}; +#include "chrome/browser/ui/views/tabs/side_tab_strip.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_H_ + diff --git a/chrome/browser/views/tabs/tab.cc b/chrome/browser/views/tabs/tab.cc deleted file mode 100644 index dda22fb..0000000 --- a/chrome/browser/views/tabs/tab.cc +++ /dev/null @@ -1,610 +0,0 @@ -// 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/tabs/tab.h" - -#include <limits> - -#include "app/multi_animation.h" -#include "app/resource_bundle.h" -#include "app/slide_animation.h" -#include "app/throb_animation.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/defaults.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "gfx/canvas_skia.h" -#include "gfx/favicon_size.h" -#include "gfx/font.h" -#include "gfx/path.h" -#include "gfx/skbitmap_operations.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/effects/SkGradientShader.h" -#include "views/controls/button/image_button.h" -#include "views/widget/tooltip_manager.h" -#include "views/widget/widget.h" -#include "views/window/non_client_view.h" -#include "views/window/window.h" - -static const int kLeftPadding = 16; -static const int kTopPadding = 6; -static const int kRightPadding = 15; -static const int kBottomPadding = 5; -static const int kDropShadowHeight = 2; -static const int kToolbarOverlap = 1; -static const int kFavIconTitleSpacing = 4; -static const int kTitleCloseButtonSpacing = 5; -static const int kStandardTitleWidth = 175; -static const int kCloseButtonVertFuzz = 0; -static const int kCloseButtonHorzFuzz = 5; - -// Vertical adjustment to the favicon when the tab has a large icon. -static const int kAppTapFaviconVerticalAdjustment = 2; - -// When a non-mini-tab becomes a mini-tab the width of the tab animates. If -// the width of a mini-tab is >= kMiniTabRendererAsNormalTabWidth then the tab -// is rendered as a normal tab. This is done to avoid having the title -// immediately disappear when transitioning a tab from normal to mini-tab. -static const int kMiniTabRendererAsNormalTabWidth = - browser_defaults::kMiniTabWidth + 30; - -// How opaque to make the hover state (out of 1). -static const double kHoverOpacity = 0.33; - -Tab::TabImage Tab::tab_alpha = {0}; -Tab::TabImage Tab::tab_active = {0}; -Tab::TabImage Tab::tab_inactive = {0}; - -// Durations for the various parts of the mini tab title animation. -static const int kMiniTitleChangeAnimationDuration1MS = 1600; -static const int kMiniTitleChangeAnimationStart1MS = 0; -static const int kMiniTitleChangeAnimationEnd1MS = 1900; -static const int kMiniTitleChangeAnimationDuration2MS = 0; -static const int kMiniTitleChangeAnimationDuration3MS = 550; -static const int kMiniTitleChangeAnimationStart3MS = 150; -static const int kMiniTitleChangeAnimationEnd3MS = 800; - -// Offset from the right edge for the start of the mini title change animation. -static const int kMiniTitleChangeInitialXOffset = 6; - -// Radius of the radial gradient used for mini title change animation. -static const int kMiniTitleChangeGradientRadius = 20; - -// Colors of the gradient used during the mini title change animation. -static const SkColor kMiniTitleChangeGradientColor1 = SK_ColorWHITE; -static const SkColor kMiniTitleChangeGradientColor2 = - SkColorSetARGB(0, 255, 255, 255); - -// Hit mask constants. -static const SkScalar kTabCapWidth = 15; -static const SkScalar kTabTopCurveWidth = 4; -static const SkScalar kTabBottomCurveWidth = 3; - -namespace { - -void InitTabResources() { - static bool initialized = false; - if (initialized) - return; - - initialized = true; - Tab::LoadTabImages(); -} - -} // namespace - -// static -const char Tab::kViewClassName[] = "browser/tabs/Tab"; - -//////////////////////////////////////////////////////////////////////////////// -// Tab, public: - -Tab::Tab(TabController* controller) - : BaseTab(controller), - showing_icon_(false), - showing_close_button_(false), - close_button_color_(NULL) { - InitTabResources(); -} - -Tab::~Tab() { -} - -void Tab::StartMiniTabTitleAnimation() { - if (!mini_title_animation_.get()) { - MultiAnimation::Parts parts; - parts.push_back(MultiAnimation::Part(kMiniTitleChangeAnimationDuration1MS, - Tween::EASE_OUT)); - parts.push_back(MultiAnimation::Part(kMiniTitleChangeAnimationDuration2MS, - Tween::ZERO)); - parts.push_back(MultiAnimation::Part(kMiniTitleChangeAnimationDuration3MS, - Tween::EASE_IN)); - parts[0].start_time_ms = kMiniTitleChangeAnimationStart1MS; - parts[0].end_time_ms = kMiniTitleChangeAnimationEnd1MS; - parts[2].start_time_ms = kMiniTitleChangeAnimationStart3MS; - parts[2].end_time_ms = kMiniTitleChangeAnimationEnd3MS; - mini_title_animation_.reset(new MultiAnimation(parts)); - mini_title_animation_->SetContainer(animation_container()); - mini_title_animation_->set_delegate(this); - } - mini_title_animation_->Start(); -} - -void Tab::StopMiniTabTitleAnimation() { - if (mini_title_animation_.get()) - mini_title_animation_->Stop(); -} - -void Tab::PaintIcon(gfx::Canvas* canvas) { - BaseTab::PaintIcon(canvas, favicon_bounds_.x(), favicon_bounds_.y()); -} - -// static -gfx::Size Tab::GetMinimumUnselectedSize() { - InitTabResources(); - - gfx::Size minimum_size; - minimum_size.set_width(kLeftPadding + kRightPadding); - // Since we use bitmap images, the real minimum height of the image is - // defined most accurately by the height of the end cap images. - minimum_size.set_height(tab_active.image_l->height()); - return minimum_size; -} - -// static -gfx::Size Tab::GetMinimumSelectedSize() { - gfx::Size minimum_size = GetMinimumUnselectedSize(); - minimum_size.set_width(kLeftPadding + kFavIconSize + kRightPadding); - return minimum_size; -} - -// static -gfx::Size Tab::GetStandardSize() { - gfx::Size standard_size = GetMinimumUnselectedSize(); - standard_size.set_width( - standard_size.width() + kFavIconTitleSpacing + kStandardTitleWidth); - return standard_size; -} - -// static -int Tab::GetMiniWidth() { - return browser_defaults::kMiniTabWidth; -} - -//////////////////////////////////////////////////////////////////////////////// -// Tab, protected: - -void Tab::DataChanged(const TabRendererData& old) { - if (data().blocked == old.blocked) - return; - - if (data().blocked) - StartPulse(); - else - StopPulse(); -} - -//////////////////////////////////////////////////////////////////////////////// -// Tab, views::View overrides: - -void Tab::Paint(gfx::Canvas* canvas) { - // Don't paint if we're narrower than we can render correctly. (This should - // only happen during animations). - if (width() < GetMinimumUnselectedSize().width() && !data().mini) - return; - - // See if the model changes whether the icons should be painted. - const bool show_icon = ShouldShowIcon(); - const bool show_close_button = ShouldShowCloseBox(); - if (show_icon != showing_icon_ || show_close_button != showing_close_button_) - Layout(); - - PaintTabBackground(canvas); - - SkColor title_color = GetThemeProvider()-> - GetColor(IsSelected() ? - BrowserThemeProvider::COLOR_TAB_TEXT : - BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT); - - if (!data().mini || width() > kMiniTabRendererAsNormalTabWidth) - PaintTitle(canvas, title_color); - - if (show_icon) - PaintIcon(canvas); - - // If the close button color has changed, generate a new one. - if (!close_button_color_ || title_color != close_button_color_) { - close_button_color_ = title_color; - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - close_button()->SetBackground(close_button_color_, - rb.GetBitmapNamed(IDR_TAB_CLOSE), - rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK)); - } -} - -void Tab::Layout() { - gfx::Rect lb = GetLocalBounds(false); - if (lb.IsEmpty()) - return; - lb.Inset(kLeftPadding, kTopPadding, kRightPadding, kBottomPadding); - - // The height of the content of the Tab is the largest of the favicon, - // the title text and the close button graphic. - int content_height = std::max(kFavIconSize, font_height()); - gfx::Size close_button_size(close_button()->GetPreferredSize()); - content_height = std::max(content_height, close_button_size.height()); - - // Size the Favicon. - showing_icon_ = ShouldShowIcon(); - if (showing_icon_) { - // Use the size of the favicon as apps use a bigger favicon size. - int favicon_size = - !data().favicon.empty() ? data().favicon.width() : kFavIconSize; - int favicon_top = kTopPadding + content_height / 2 - favicon_size / 2; - int favicon_left = lb.x(); - if (favicon_size != kFavIconSize) { - favicon_left -= (favicon_size - kFavIconSize) / 2; - favicon_top -= kAppTapFaviconVerticalAdjustment; - } - favicon_bounds_.SetRect(favicon_left, favicon_top, - favicon_size, favicon_size); - if (data().mini && width() < kMiniTabRendererAsNormalTabWidth) { - // Adjust the location of the favicon when transitioning from a normal - // tab to a mini-tab. - int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth(); - int ideal_delta = width() - GetMiniWidth(); - if (ideal_delta < mini_delta) { - int ideal_x = (GetMiniWidth() - favicon_size) / 2; - int x = favicon_bounds_.x() + static_cast<int>( - (1 - static_cast<float>(ideal_delta) / - static_cast<float>(mini_delta)) * - (ideal_x - favicon_bounds_.x())); - favicon_bounds_.set_x(x); - } - } - } else { - favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0); - } - - // Size the Close button. - showing_close_button_ = ShouldShowCloseBox(); - if (showing_close_button_) { - int close_button_top = kTopPadding + kCloseButtonVertFuzz + - (content_height - close_button_size.height()) / 2; - // If the ratio of the close button size to tab width exceeds the maximum. - close_button()->SetBounds(lb.width() + kCloseButtonHorzFuzz, - close_button_top, close_button_size.width(), - close_button_size.height()); - close_button()->SetVisible(true); - } else { - close_button()->SetBounds(0, 0, 0, 0); - close_button()->SetVisible(false); - } - - int title_left = favicon_bounds_.right() + kFavIconTitleSpacing; - int title_top = kTopPadding + (content_height - font_height()) / 2; - // Size the Title text to fill the remaining space. - if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) { - // If the user has big fonts, the title will appear rendered too far down - // on the y-axis if we use the regular top padding, so we need to adjust it - // so that the text appears centered. - gfx::Size minimum_size = GetMinimumUnselectedSize(); - int text_height = title_top + font_height() + kBottomPadding; - if (text_height > minimum_size.height()) - title_top -= (text_height - minimum_size.height()) / 2; - - int title_width; - if (close_button()->IsVisible()) { - title_width = std::max(close_button()->x() - - kTitleCloseButtonSpacing - title_left, 0); - } else { - title_width = std::max(lb.width() - title_left, 0); - } - title_bounds_.SetRect(title_left, title_top, title_width, font_height()); - } else { - title_bounds_.SetRect(title_left, title_top, 0, 0); - } - - // Certain UI elements within the Tab (the favicon, etc.) are not represented - // as child Views (which is the preferred method). Instead, these UI elements - // are drawn directly on the canvas from within Tab::Paint(). The Tab's child - // Views (for example, the Tab's close button which is a views::Button - // instance) are automatically mirrored by the mirroring infrastructure in - // views. The elements Tab draws directly on the canvas need to be manually - // mirrored if the View's layout is right-to-left. - title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_)); -} - -void Tab::OnThemeChanged() { - Tab::LoadTabImages(); -} - -bool Tab::HasHitTestMask() const { - return true; -} - -void Tab::GetHitTestMask(gfx::Path* path) const { - DCHECK(path); - - SkScalar h = SkIntToScalar(height()); - SkScalar w = SkIntToScalar(width()); - - path->moveTo(0, h); - - // Left end cap. - path->lineTo(kTabBottomCurveWidth, h - kTabBottomCurveWidth); - path->lineTo(kTabCapWidth - kTabTopCurveWidth, kTabTopCurveWidth); - path->lineTo(kTabCapWidth, 0); - - // Connect to the right cap. - path->lineTo(w - kTabCapWidth, 0); - - // Right end cap. - path->lineTo(w - kTabCapWidth + kTabTopCurveWidth, kTabTopCurveWidth); - path->lineTo(w - kTabBottomCurveWidth, h - kTabBottomCurveWidth); - path->lineTo(w, h); - - // Close out the path. - path->lineTo(0, h); - path->close(); -} - -bool Tab::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* origin) { - origin->set_x(title_bounds().x() + 10); - origin->set_y(-views::TooltipManager::GetTooltipHeight() - 4); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// Tab, private - -void Tab::PaintTabBackground(gfx::Canvas* canvas) { - if (IsSelected()) { - PaintActiveTabBackground(canvas); - } else { - if (mini_title_animation_.get() && mini_title_animation_->is_animating()) - PaintInactiveTabBackgroundWithTitleChange(canvas); - else - PaintInactiveTabBackground(canvas); - - double throb_value = GetThrobValue(); - if (throb_value > 0) { - canvas->SaveLayerAlpha(static_cast<int>(throb_value * 0xff), - gfx::Rect(width(), height())); - canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, - SkXfermode::kClear_Mode); - PaintActiveTabBackground(canvas); - canvas->Restore(); - } - } -} - -void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) { - // Render the inactive tab background. We'll use this for clipping. - gfx::CanvasSkia background_canvas(width(), height(), false); - PaintInactiveTabBackground(&background_canvas); - - SkBitmap background_image = background_canvas.ExtractBitmap(); - - // Draw a radial gradient to hover_canvas. - gfx::CanvasSkia hover_canvas(width(), height(), false); - int radius = kMiniTitleChangeGradientRadius; - int x0 = width() + radius - kMiniTitleChangeInitialXOffset; - int x1 = radius; - int x2 = -radius; - int x; - if (mini_title_animation_->current_part_index() == 0) { - x = mini_title_animation_->CurrentValueBetween(x0, x1); - } else if (mini_title_animation_->current_part_index() == 1) { - x = x1; - } else { - x = mini_title_animation_->CurrentValueBetween(x1, x2); - } - SkPaint paint; - SkPoint loc = { SkIntToScalar(x), SkIntToScalar(0) }; - SkColor colors[2]; - colors[0] = kMiniTitleChangeGradientColor1; - colors[1] = kMiniTitleChangeGradientColor2; - SkShader* shader = SkGradientShader::CreateRadial( - loc, - SkIntToScalar(radius), - colors, - NULL, - 2, - SkShader::kClamp_TileMode); - paint.setShader(shader); - shader->unref(); - hover_canvas.DrawRectInt(x - radius, -radius, radius * 2, radius * 2, paint); - - // Draw the radial gradient clipped to the background into hover_image. - SkBitmap hover_image = SkBitmapOperations::CreateMaskedBitmap( - hover_canvas.ExtractBitmap(), background_image); - - // Draw the tab background to the canvas. - canvas->DrawBitmapInt(background_image, 0, 0); - - // And then the gradient on top of that. - if (mini_title_animation_->current_part_index() == 2) { - canvas->SaveLayerAlpha(mini_title_animation_->CurrentValueBetween(255, 0)); - canvas->DrawBitmapInt(hover_image, 0, 0); - canvas->Restore(); - } else { - canvas->DrawBitmapInt(hover_image, 0, 0); - } -} - -void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { - bool is_otr = data().off_the_record; - - // The tab image needs to be lined up with the background image - // so that it feels partially transparent. These offsets represent the tab - // position within the frame background image. - int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) + - background_offset_.x(); - - int tab_id; - if (GetWidget() && - GetWidget()->GetWindow()->GetNonClientView()->UseNativeFrame()) { - tab_id = IDR_THEME_TAB_BACKGROUND_V; - } else { - tab_id = is_otr ? IDR_THEME_TAB_BACKGROUND_INCOGNITO : - IDR_THEME_TAB_BACKGROUND; - } - - SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(tab_id); - - TabImage* tab_image = &tab_active; - TabImage* tab_inactive_image = &tab_inactive; - TabImage* alpha = &tab_alpha; - - // If the theme is providing a custom background image, then its top edge - // should be at the top of the tab. Otherwise, we assume that the background - // image is a composited foreground + frame image. - int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ? - 0 : background_offset_.y(); - - // Draw left edge. Don't draw over the toolbar, as we're not the foreground - // tab. - SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap( - *tab_bg, offset, bg_offset_y, tab_image->l_width, height()); - SkBitmap theme_l = - SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l); - canvas->DrawBitmapInt(theme_l, - 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap, - 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap, - false); - - // Draw right edge. Again, don't draw over the toolbar. - SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg, - offset + width() - tab_image->r_width, bg_offset_y, - tab_image->r_width, height()); - SkBitmap theme_r = - SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r); - canvas->DrawBitmapInt(theme_r, - 0, 0, theme_r.width(), theme_r.height() - kToolbarOverlap, - width() - theme_r.width(), 0, theme_r.width(), - theme_r.height() - kToolbarOverlap, false); - - // Draw center. Instead of masking out the top portion we simply skip over - // it by incrementing by kDropShadowHeight, since it's a simple rectangle. - // And again, don't draw over the toolbar. - canvas->TileImageInt(*tab_bg, - offset + tab_image->l_width, - bg_offset_y + kDropShadowHeight + tab_image->y_offset, - tab_image->l_width, - kDropShadowHeight + tab_image->y_offset, - width() - tab_image->l_width - tab_image->r_width, - height() - kDropShadowHeight - kToolbarOverlap - tab_image->y_offset); - - // Now draw the highlights/shadows around the tab edge. - canvas->DrawBitmapInt(*tab_inactive_image->image_l, 0, 0); - canvas->TileImageInt(*tab_inactive_image->image_c, - tab_inactive_image->l_width, 0, - width() - tab_inactive_image->l_width - - tab_inactive_image->r_width, - height()); - canvas->DrawBitmapInt(*tab_inactive_image->image_r, - width() - tab_inactive_image->r_width, 0); -} - -void Tab::PaintActiveTabBackground(gfx::Canvas* canvas) { - int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) + - background_offset_.x(); - ThemeProvider* tp = GetThemeProvider(); - if (!tp) - NOTREACHED() << "Unable to get theme provider"; - - SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(IDR_THEME_TOOLBAR); - - TabImage* tab_image = &tab_active; - TabImage* alpha = &tab_alpha; - - // Draw left edge. - SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap( - *tab_bg, offset, 0, tab_image->l_width, height()); - SkBitmap theme_l = - SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l); - canvas->DrawBitmapInt(theme_l, 0, 0); - - // Draw right edge. - SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg, - offset + width() - tab_image->r_width, 0, tab_image->r_width, height()); - SkBitmap theme_r = - SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r); - canvas->DrawBitmapInt(theme_r, width() - tab_image->r_width, 0); - - // Draw center. Instead of masking out the top portion we simply skip over it - // by incrementing by kDropShadowHeight, since it's a simple rectangle. - canvas->TileImageInt(*tab_bg, - offset + tab_image->l_width, - kDropShadowHeight + tab_image->y_offset, - tab_image->l_width, - kDropShadowHeight + tab_image->y_offset, - width() - tab_image->l_width - tab_image->r_width, - height() - kDropShadowHeight - tab_image->y_offset); - - // Now draw the highlights/shadows around the tab edge. - canvas->DrawBitmapInt(*tab_image->image_l, 0, 0); - canvas->TileImageInt(*tab_image->image_c, tab_image->l_width, 0, - width() - tab_image->l_width - tab_image->r_width, height()); - canvas->DrawBitmapInt(*tab_image->image_r, width() - tab_image->r_width, 0); -} - -int Tab::IconCapacity() const { - if (height() < GetMinimumUnselectedSize().height()) - return 0; - return (width() - kLeftPadding - kRightPadding) / kFavIconSize; -} - -bool Tab::ShouldShowIcon() const { - if (data().mini && height() >= GetMinimumUnselectedSize().height()) - return true; - if (!data().show_icon) { - return false; - } else if (IsSelected()) { - // The selected tab clips favicon before close button. - return IconCapacity() >= 2; - } - // Non-selected tabs clip close button before favicon. - return IconCapacity() >= 1; -} - -bool Tab::ShouldShowCloseBox() const { - // The selected tab never clips close button. - return !data().mini && IsCloseable() && - (IsSelected() || IconCapacity() >= 3); -} - -double Tab::GetThrobValue() { - if (pulse_animation() && pulse_animation()->is_animating()) - return pulse_animation()->GetCurrentValue() * kHoverOpacity; - - return hover_animation() ? - kHoverOpacity * hover_animation()->GetCurrentValue() : 0; -} - -//////////////////////////////////////////////////////////////////////////////// -// Tab, private: - -// static -void Tab::LoadTabImages() { - // We're not letting people override tab images just yet. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - tab_alpha.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT); - tab_alpha.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT); - - tab_active.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT); - tab_active.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER); - tab_active.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT); - tab_active.l_width = tab_active.image_l->width(); - tab_active.r_width = tab_active.image_r->width(); - - tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT); - tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER); - tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT); - tab_inactive.l_width = tab_inactive.image_l->width(); - tab_inactive.r_width = tab_inactive.image_r->width(); -} diff --git a/chrome/browser/views/tabs/tab.h b/chrome/browser/views/tabs/tab.h index e99a8fd..11076c1 100644 --- a/chrome/browser/views/tabs/tab.h +++ b/chrome/browser/views/tabs/tab.h @@ -6,136 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_TAB_H_ #pragma once -#include <string> - -#include "base/scoped_ptr.h" -#include "chrome/browser/views/tabs/base_tab.h" -#include "gfx/point.h" - -class MultiAnimation; -class SlideAnimation; - -/////////////////////////////////////////////////////////////////////////////// -// -// TabRenderer -// -// A View that renders a Tab, either in a TabStrip or in a DraggedTabView. -// -/////////////////////////////////////////////////////////////////////////////// -class Tab : public BaseTab { - public: - // The menu button's class name. - static const char kViewClassName[]; - - explicit Tab(TabController* controller); - virtual ~Tab(); - - // Start/stop the mini-tab title animation. - void StartMiniTabTitleAnimation(); - void StopMiniTabTitleAnimation(); - - // Set the background offset used to match the image in the inactive tab - // to the frame image. - void SetBackgroundOffset(const gfx::Point& offset) { - background_offset_ = offset; - } - - // Paints the icon. Most of the time you'll want to invoke Paint directly, but - // in certain situations this invoked outside of Paint. - void PaintIcon(gfx::Canvas* canvas); - - // Returns the minimum possible size of a single unselected Tab. - static gfx::Size GetMinimumUnselectedSize(); - // Returns the minimum possible size of a selected Tab. Selected tabs must - // always show a close button and have a larger minimum size than unselected - // tabs. - static gfx::Size GetMinimumSelectedSize(); - // Returns the preferred size of a single Tab, assuming space is - // available. - static gfx::Size GetStandardSize(); - - // Returns the width for mini-tabs. Mini-tabs always have this width. - static int GetMiniWidth(); - - // Loads the images to be used for the tab background. - static void LoadTabImages(); - - protected: - virtual const gfx::Rect& title_bounds() const { return title_bounds_; } - - // BaseTab overrides: - virtual void DataChanged(const TabRendererData& old); - - private: - // Overridden from views::View: - virtual void Paint(gfx::Canvas* canvas); - virtual void Layout(); - virtual void OnThemeChanged(); - virtual std::string GetClassName() const { return kViewClassName; } - virtual bool HasHitTestMask() const; - virtual void GetHitTestMask(gfx::Path* path) const; - virtual bool GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* origin); - - // Paint various portions of the Tab - void PaintTabBackground(gfx::Canvas* canvas); - void PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas); - void PaintInactiveTabBackground(gfx::Canvas* canvas); - void PaintActiveTabBackground(gfx::Canvas* canvas); - - // Returns the number of favicon-size elements that can fit in the tab's - // current size. - int IconCapacity() const; - - // Returns whether the Tab should display a favicon. - bool ShouldShowIcon() const; - - // Returns whether the Tab should display a close button. - bool ShouldShowCloseBox() const; - - // Gets the throb value for the tab. When a tab is not selected the - // active background is drawn at |GetThrobValue()|%. This is used for hover, - // mini tab title change and pulsing. - double GetThrobValue(); - - // The bounds of various sections of the display. - gfx::Rect favicon_bounds_; - gfx::Rect title_bounds_; - - // The offset used to paint the inactive background image. - gfx::Point background_offset_; - - // Hover animation. - scoped_ptr<SlideAnimation> hover_animation_; - - // Animation used when the title of an inactive mini tab changes. - scoped_ptr<MultiAnimation> mini_title_animation_; - - struct TabImage { - SkBitmap* image_l; - SkBitmap* image_c; - SkBitmap* image_r; - int l_width; - int r_width; - int y_offset; - }; - static TabImage tab_active; - static TabImage tab_inactive; - static TabImage tab_alpha; - - // Whether we're showing the icon. It is cached so that we can detect when it - // changes and layout appropriately. - bool showing_icon_; - - // Whether we are showing the close button. It is cached so that we can - // detect when it changes and layout appropriately. - bool showing_close_button_; - - // The current color of the close button. - SkColor close_button_color_; - - static bool initialized_; - - DISALLOW_COPY_AND_ASSIGN(Tab); -}; +#include "chrome/browser/ui/views/tabs/tab.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_TAB_H_ + diff --git a/chrome/browser/views/tabs/tab_controller.h b/chrome/browser/views/tabs/tab_controller.h index abaaf0f..5205f5e 100644 --- a/chrome/browser/views/tabs/tab_controller.h +++ b/chrome/browser/views/tabs/tab_controller.h @@ -6,54 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_TAB_CONTROLLER_H_ #pragma once -class BaseTab; - -namespace gfx { -class Point; -} -namespace views { -class MouseEvent; -} - -// Controller for tabs. -class TabController { - public: - // Selects the tab. - virtual void SelectTab(BaseTab* tab) = 0; - - // Closes the tab. - virtual void CloseTab(BaseTab* tab) = 0; - - // Shows a context menu for the tab at the specified point in screen coords. - virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p) = 0; - - // Returns true if the specified Tab is selected. - virtual bool IsTabSelected(const BaseTab* tab) const = 0; - - // Returns true if the specified Tab is pinned. - virtual bool IsTabPinned(const BaseTab* tab) const = 0; - - // Returns true if the specified Tab is closeable. - virtual bool IsTabCloseable(const BaseTab* tab) const = 0; - - // Potentially starts a drag for the specified Tab. - virtual void MaybeStartDrag(BaseTab* tab, const views::MouseEvent& event) = 0; - - // Continues dragging a Tab. - virtual void ContinueDrag(const views::MouseEvent& event) = 0; - - // Ends dragging a Tab. |canceled| is true if the drag was aborted in a way - // other than the user releasing the mouse. Returns whether the tab has been - // destroyed. - virtual bool EndDrag(bool canceled) = 0; - - // Returns the tab that contains the specified coordinates, in terms of |tab|, - // or NULL if there is no tab that contains the specified point. - virtual BaseTab* GetTabAt(BaseTab* tab, - const gfx::Point& tab_in_tab_coordinates) = 0; - - protected: - virtual ~TabController() {} -}; +#include "chrome/browser/ui/views/tabs/tab_controller.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_TAB_CONTROLLER_H_ + diff --git a/chrome/browser/views/tabs/tab_dragging_test.cc b/chrome/browser/views/tabs/tab_dragging_test.cc deleted file mode 100644 index 2cb0171..0000000 --- a/chrome/browser/views/tabs/tab_dragging_test.cc +++ /dev/null @@ -1,515 +0,0 @@ -// 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 "base/command_line.h" -#include "base/file_util.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/view_ids.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/automation/tab_proxy.h" -#include "chrome/test/automation/browser_proxy.h" -#include "chrome/test/automation/window_proxy.h" -#include "chrome/test/ui/ui_test.h" -#include "gfx/rect.h" -#include "googleurl/src/gurl.h" -#include "net/base/net_util.h" -#include "views/event.h" - -#if defined(OS_LINUX) -// This test doesn't make sense on chromeos as chromeos doesn't allow dragging -// tabs out. -#define MAYBE_Tab2OutOfTabStrip DISABLED_Tab2OutOfTabStrip -#else -// Flaky, http://crbug.com/62311. -#define MAYBE_Tab2OutOfTabStrip FLAKY_Tab2OutOfTabStrip -#endif - -#if defined(OS_LINUX) -// Disabled on Toolkit views bot. See http://crbug.com/42614 -#define MAYBE_Tab1Tab3Escape DISABLED_Tab1Tab3Escape -#elif defined(OS_WIN) -// Disabled on Windows. See http://crbug.com/57687 -#define MAYBE_Tab1Tab3Escape DISABLED_Tab1Tab3Escape -#else -#define MAYBE_Tab1Tab3Escape Tab1Tab3Escape -#endif - -// These tests fail on Linux because we haven't implemented all of tab dragging -// (it's not needed on chromeos). See http://crbug.com/10941 -#if defined(OS_LINUX) -#define MAYBE_Tab1Tab2 DISABLED_Tab1Tab2 -#define MAYBE_Tab1Tab3 DISABLED_Tab1Tab3 -#else -// Flaky, http://crbug.com/62311. -#define MAYBE_Tab1Tab2 FLAKY_Tab1Tab2 -#define MAYBE_Tab1Tab3 FLAKY_Tab1Tab3 -#endif - -class TabDraggingTest : public UITest { - protected: - TabDraggingTest() { - show_window_ = true; - } -}; - -// Automated UI test to open three tabs in a new window, and drag Tab_1 into -// the position of Tab_2. -TEST_F(TabDraggingTest, MAYBE_Tab1Tab2) { - scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser.get()); - scoped_refptr<WindowProxy> window(browser->GetWindow()); - ASSERT_TRUE(window.get()); - - // Get initial tab count. - int initial_tab_count = 0; - ASSERT_TRUE(browser->GetTabCount(&initial_tab_count)); - ASSERT_TRUE(1 == initial_tab_count); - - // Get Tab_1 which comes with the browser window. - scoped_refptr<TabProxy> tab1(browser->GetTab(0)); - ASSERT_TRUE(tab1.get()); - GURL tab1_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url)); - - // Add Tab_2. - GURL tab2_url("about:"); - ASSERT_TRUE(browser->AppendTab(tab2_url)); - scoped_refptr<TabProxy> tab2(browser->GetTab(1)); - ASSERT_TRUE(tab2.get()); - - // Add Tab_3. - GURL tab3_url("about:plugins"); - ASSERT_TRUE(browser->AppendTab(tab3_url)); - scoped_refptr<TabProxy> tab3(browser->GetTab(2)); - ASSERT_TRUE(tab3.get()); - - // Make sure 3 tabs are open. - ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2)); - - // Get bounds for the tabs. - gfx::Rect bounds1; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false)); - EXPECT_LT(0, bounds1.x()); - EXPECT_LT(0, bounds1.width()); - EXPECT_LT(0, bounds1.height()); - - gfx::Rect bounds2; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false)); - EXPECT_LT(0, bounds2.width()); - EXPECT_LT(0, bounds2.height()); - EXPECT_LT(bounds1.x(), bounds2.x()); - EXPECT_EQ(bounds2.y(), bounds1.y()); - - gfx::Rect bounds3; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false)); - EXPECT_LT(0, bounds3.width()); - EXPECT_LT(0, bounds3.height()); - EXPECT_LT(bounds2.x(), bounds3.x()); - EXPECT_EQ(bounds3.y(), bounds2.y()); - - // Get url Bar bounds. - gfx::Rect urlbar_bounds; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds, - false)); - EXPECT_LT(0, urlbar_bounds.x()); - EXPECT_LT(0, urlbar_bounds.y()); - EXPECT_LT(0, urlbar_bounds.width()); - EXPECT_LT(0, urlbar_bounds.height()); - - /* - TEST: Move Tab_1 to the position of Tab_2 - ____________ ____________ ____________ - / \ / \ / \ - | Tab_1 | Tab_2 | Tab_3 | - ---- ---- ---- ---- ---- ---- ---- ---- ---- - x---- ----> - ____________ - / X \ - | Tab_1 | - ---- ---- ---- - */ - - gfx::Point start(bounds1.x() + bounds1.width() / 2, - bounds1.y() + bounds1.height() / 2); - gfx::Point end(start.x() + 2 * bounds1.width() / 3, start.y()); - ASSERT_TRUE(browser->SimulateDrag(start, end, - views::Event::EF_LEFT_BUTTON_DOWN, - false)); - - // Now check for expected results. - tab1 = browser->GetTab(0); - ASSERT_TRUE(tab1.get()); - GURL tab1_new_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url)); - - tab2 = browser->GetTab(1); - ASSERT_TRUE(tab2.get()); - GURL tab2_new_url; - ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url)); - - EXPECT_EQ(tab1_url.spec(), tab2_new_url.spec()); - EXPECT_EQ(tab2_url.spec(), tab1_new_url.spec()); -} - -// Drag Tab_1 into the position of Tab_3. -TEST_F(TabDraggingTest, MAYBE_Tab1Tab3) { - scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser.get()); - scoped_refptr<WindowProxy> window(browser->GetWindow()); - ASSERT_TRUE(window.get()); - - // Get initial tab count. - int initial_tab_count = 0; - ASSERT_TRUE(browser->GetTabCount(&initial_tab_count)); - ASSERT_TRUE(1 == initial_tab_count); - - // Get Tab_1 which comes with the browser window. - scoped_refptr<TabProxy> tab1(browser->GetTab(0)); - ASSERT_TRUE(tab1.get()); - GURL tab1_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url)); - - // Add Tab_2. - GURL tab2_url("about:"); - ASSERT_TRUE(browser->AppendTab(tab2_url)); - scoped_refptr<TabProxy> tab2(browser->GetTab(1)); - ASSERT_TRUE(tab2.get()); - - // Add Tab_3. - GURL tab3_url("about:plugins"); - ASSERT_TRUE(browser->AppendTab(tab3_url)); - scoped_refptr<TabProxy> tab3(browser->GetTab(2)); - ASSERT_TRUE(tab3.get()); - - // Make sure 3 tabs are open. - ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2)); - - // Get bounds for the tabs. - gfx::Rect bounds1; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false)); - EXPECT_LT(0, bounds1.x()); - EXPECT_LT(0, bounds1.width()); - EXPECT_LT(0, bounds1.height()); - - gfx::Rect bounds2; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false)); - EXPECT_LT(0, bounds2.width()); - EXPECT_LT(0, bounds2.height()); - EXPECT_LT(bounds1.x(), bounds2.x()); - EXPECT_EQ(bounds2.y(), bounds1.y()); - - gfx::Rect bounds3; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false)); - EXPECT_LT(0, bounds3.width()); - EXPECT_LT(0, bounds3.height()); - EXPECT_LT(bounds2.x(), bounds3.x()); - EXPECT_EQ(bounds3.y(), bounds2.y()); - - // Get url Bar bounds. - gfx::Rect urlbar_bounds; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds, - false)); - EXPECT_LT(0, urlbar_bounds.x()); - EXPECT_LT(0, urlbar_bounds.y()); - EXPECT_LT(0, urlbar_bounds.width()); - EXPECT_LT(0, urlbar_bounds.height()); - - /* - TEST: Move Tab_1 to the middle position of Tab_3 - ____________ ____________ ____________ - / \ / \ / \ - | Tab_1 | Tab_2 | Tab_3 | - ---- ---- ---- ---- ---- ---- ---- ---- ---- - x---- ---- ---- ---- ---- ----> - ____________ - / X \ - | Tab_1 | - ---- ---- ---- - */ - - gfx::Point start(bounds1.x() + bounds1.width() / 2, - bounds1.y() + bounds1.height() / 2); - gfx::Point end(start.x() + bounds1.width() / 2 + bounds2.width() + - bounds3.width() / 2, - start.y()); - ASSERT_TRUE(browser->SimulateDrag(start, end, - views::Event::EF_LEFT_BUTTON_DOWN, - false)); - - // Now check for expected results. - tab1 = browser->GetTab(0); - ASSERT_TRUE(tab1.get()); - GURL tab1_new_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url)); - - tab2 = browser->GetTab(1); - ASSERT_TRUE(tab2.get()); - GURL tab2_new_url; - ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url)); - - tab3 = browser->GetTab(2); - ASSERT_TRUE(tab3.get()); - GURL tab3_new_url; - ASSERT_TRUE(tab3->GetCurrentURL(&tab3_new_url)); - - EXPECT_EQ(tab1_new_url.spec(), tab2_url.spec()); - EXPECT_EQ(tab2_new_url.spec(), tab3_url.spec()); - EXPECT_EQ(tab3_new_url.spec(), tab1_url.spec()); -} - -// Drag Tab_1 into the position of Tab_3, and press ESCAPE before releasing the -// left mouse button. -TEST_F(TabDraggingTest, MAYBE_Tab1Tab3Escape) { - scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser.get()); - scoped_refptr<WindowProxy> window(browser->GetWindow()); - ASSERT_TRUE(window.get()); - - // Get initial tab count. - int initial_tab_count = 0; - ASSERT_TRUE(browser->GetTabCount(&initial_tab_count)); - ASSERT_TRUE(1 == initial_tab_count); - - // Get Tab_1 which comes with the browser window. - scoped_refptr<TabProxy> tab1(browser->GetTab(0)); - ASSERT_TRUE(tab1.get()); - GURL tab1_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url)); - - // Add Tab_2. - GURL tab2_url("about:blank"); - ASSERT_TRUE(browser->AppendTab(tab2_url)); - scoped_refptr<TabProxy> tab2(browser->GetTab(1)); - ASSERT_TRUE(tab2.get()); - - // Add Tab_3. - GURL tab3_url("about:plugins"); - ASSERT_TRUE(browser->AppendTab(tab3_url)); - scoped_refptr<TabProxy> tab3(browser->GetTab(2)); - ASSERT_TRUE(tab3.get()); - - // Make sure 3 tabs are open. - ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2)); - - // Get bounds for the tabs. - gfx::Rect bounds1; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false)); - EXPECT_LT(0, bounds1.x()); - EXPECT_LT(0, bounds1.width()); - EXPECT_LT(0, bounds1.height()); - - gfx::Rect bounds2; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false)); - EXPECT_LT(0, bounds2.width()); - EXPECT_LT(0, bounds2.height()); - EXPECT_LT(bounds1.x(), bounds2.x()); - EXPECT_EQ(bounds2.y(), bounds1.y()); - - gfx::Rect bounds3; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false)); - EXPECT_LT(0, bounds3.width()); - EXPECT_LT(0, bounds3.height()); - EXPECT_LT(bounds2.x(), bounds3.x()); - EXPECT_EQ(bounds3.y(), bounds2.y()); - - // Get url Bar bounds. - gfx::Rect urlbar_bounds; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds, - false)); - EXPECT_LT(0, urlbar_bounds.x()); - EXPECT_LT(0, urlbar_bounds.y()); - EXPECT_LT(0, urlbar_bounds.width()); - EXPECT_LT(0, urlbar_bounds.height()); - - /* - TEST: Move Tab_1 to the middle position of Tab_3 - ____________ ____________ ____________ - / \ / \ / \ - | Tab_1 | Tab_2 | Tab_3 | - ---- ---- ---- ---- ---- ---- ---- ---- ---- - x---- ---- ---- ---- ---- ----> + ESCAPE - ____________ - / X \ - | Tab_1 | - ---- ---- ---- - */ - - gfx::Point start(bounds1.x() + bounds1.width() / 2, - bounds1.y() + bounds1.height() / 2); - gfx::Point end(start.x() + bounds1.width() / 2 + bounds2.width() + - bounds3.width() / 2, - start.y()); - - // Simulate drag with 'true' as the last parameter. This will interrupt - // in-flight with Escape. - ASSERT_TRUE(browser->SimulateDrag(start, end, - views::Event::EF_LEFT_BUTTON_DOWN, - true)); - - // Now check for expected results. - tab1 = browser->GetTab(0); - ASSERT_TRUE(tab1.get()); - GURL tab1_new_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url)); - - tab2 = browser->GetTab(1); - ASSERT_TRUE(tab2.get()); - GURL tab2_new_url; - ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url)); - - tab3 = browser->GetTab(2); - ASSERT_TRUE(tab3.get()); - GURL tab3_new_url; - ASSERT_TRUE(tab3->GetCurrentURL(&tab3_new_url)); - - // The tabs should be in their original positions. - EXPECT_EQ(tab1_new_url.spec(), tab1_url.spec()); - EXPECT_EQ(tab2_new_url.spec(), tab2_url.spec()); - EXPECT_EQ(tab3_new_url.spec(), tab3_url.spec()); -} - -// Drag Tab_2 out of the Tab strip. A new window should open with this tab. -TEST_F(TabDraggingTest, MAYBE_Tab2OutOfTabStrip) { - scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser.get()); - scoped_refptr<WindowProxy> window(browser->GetWindow()); - ASSERT_TRUE(window.get()); - - // Get initial tab count. - int initial_tab_count = 0; - ASSERT_TRUE(browser->GetTabCount(&initial_tab_count)); - ASSERT_TRUE(1 == initial_tab_count); - - // Get Tab_1 which comes with the browser window. - scoped_refptr<TabProxy> tab1(browser->GetTab(0)); - ASSERT_TRUE(tab1.get()); - GURL tab1_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url)); - - // Add Tab_2. - GURL tab2_url("about:version"); - ASSERT_TRUE(browser->AppendTab(tab2_url)); - scoped_refptr<TabProxy> tab2(browser->GetTab(1)); - ASSERT_TRUE(tab2.get()); - - // Add Tab_3. - GURL tab3_url("about:plugins"); - ASSERT_TRUE(browser->AppendTab(tab3_url)); - scoped_refptr<TabProxy> tab3(browser->GetTab(2)); - ASSERT_TRUE(tab3.get()); - - // Make sure 3 tabs are opened. - ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2)); - - // Make sure all the tab URL specs are different. - ASSERT_TRUE(tab1_url != tab2_url); - ASSERT_TRUE(tab1_url != tab3_url); - ASSERT_TRUE(tab2_url != tab3_url); - - // Get bounds for the tabs. - gfx::Rect bounds1; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false)); - EXPECT_LT(0, bounds1.x()); - EXPECT_LT(0, bounds1.width()); - EXPECT_LT(0, bounds1.height()); - - gfx::Rect bounds2; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false)); - EXPECT_LT(0, bounds2.width()); - EXPECT_LT(0, bounds2.height()); - EXPECT_LT(bounds1.x(), bounds2.x()); - EXPECT_EQ(bounds2.y(), bounds1.y()); - - gfx::Rect bounds3; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false)); - EXPECT_LT(0, bounds3.width()); - EXPECT_LT(0, bounds3.height()); - EXPECT_LT(bounds2.x(), bounds3.x()); - EXPECT_EQ(bounds3.y(), bounds2.y()); - - // Get url Bar bounds. - gfx::Rect urlbar_bounds; - ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds, - false)); - EXPECT_LT(0, urlbar_bounds.x()); - EXPECT_LT(0, urlbar_bounds.y()); - EXPECT_LT(0, urlbar_bounds.width()); - EXPECT_LT(0, urlbar_bounds.height()); - - /* - TEST: Move Tab_2 down, out of the tab strip. - This should result in the following: - 1- Tab_3 shift left in place of Tab_2 in Window 1 - 2- Tab_1 to remain in its place - 3- Tab_2 openes in a new window - - ____________ ____________ ____________ - / \ / \ / \ - | Tab_1 | Tab_2 | Tab_3 | - ---- ---- ---- ---- ---- ---- ---- ---- ---- - x - | - | (Drag this below, out of tab strip) - V - ____________ - / X \ - | Tab_2 | (New Window) - ---- ---- ---- ---- ---- ---- ---- - */ - - gfx::Point start(bounds2.x() + bounds2.width() / 2, - bounds2.y() + bounds2.height() / 2); - gfx::Point end(start.x(), - start.y() + 3 * urlbar_bounds.height()); - - // Simulate tab drag. - ASSERT_TRUE(browser->SimulateDrag(start, end, - views::Event::EF_LEFT_BUTTON_DOWN, - false)); - - // Now, first make sure that the old window has only two tabs remaining. - int new_tab_count = 0; - ASSERT_TRUE(browser->GetTabCount(&new_tab_count)); - ASSERT_EQ(2, new_tab_count); - - // Get the two tabs - they are called Tab_1 and Tab_2 in the old window. - tab1 = browser->GetTab(0); - ASSERT_TRUE(tab1.get()); - GURL tab1_new_url; - ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url)); - - tab2 = browser->GetTab(1); - ASSERT_TRUE(tab2.get()); - GURL tab2_new_url; - ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url)); - - // Now check for proper shifting of tabs; i.e., Tab_3 in window 1 should - // shift left to the position of Tab_2; Tab_1 should stay where it was. - EXPECT_EQ(tab1_new_url.spec(), tab1_url.spec()); - EXPECT_EQ(tab2_new_url.spec(), tab3_url.spec()); - - // Now check to make sure a new window has opened. - scoped_refptr<BrowserProxy> browser2(automation()->GetBrowserWindow(1)); - ASSERT_TRUE(browser2.get()); - scoped_refptr<WindowProxy> window2(browser2->GetWindow()); - ASSERT_TRUE(window2.get()); - - // Make sure that the new window has only one tab. - int tab_count_window_2 = 0; - ASSERT_TRUE(browser2->GetTabCount(&tab_count_window_2)); - ASSERT_EQ(1, tab_count_window_2); - - // Get Tab_1_2 which should be Tab_1 in Window 2. - scoped_refptr<TabProxy> tab1_2(browser2->GetTab(0)); - ASSERT_TRUE(tab1_2.get()); - GURL tab1_2_url; - ASSERT_TRUE(tab1_2->GetCurrentURL(&tab1_2_url)); - - // Tab_1_2 of Window 2 should essentially be Tab_2 of Window 1. - EXPECT_EQ(tab1_2_url.spec(), tab2_url.spec()); - EXPECT_NE(tab1_2_url.spec(), tab1_url.spec()); - EXPECT_NE(tab1_2_url.spec(), tab3_url.spec()); -} diff --git a/chrome/browser/views/tabs/tab_renderer_data.h b/chrome/browser/views/tabs/tab_renderer_data.h index 31e84ed..dca47c9 100644 --- a/chrome/browser/views/tabs/tab_renderer_data.h +++ b/chrome/browser/views/tabs/tab_renderer_data.h @@ -6,41 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_TAB_RENDERER_DATA_H_ #pragma once -#include "base/string16.h" -#include "third_party/skia/include/core/SkBitmap.h" - -// Wraps the state needed by the renderers. -struct TabRendererData { - // Different types of network activity for a tab. The NetworkState of a tab - // may be used to alter the UI (e.g. show different kinds of loading - // animations). - enum NetworkState { - NETWORK_STATE_NONE, // no network activity. - NETWORK_STATE_WAITING, // waiting for a connection. - NETWORK_STATE_LOADING, // connected, transferring data. - }; - - TabRendererData() - : network_state(NETWORK_STATE_NONE), - loading(false), - crashed(false), - off_the_record(false), - show_icon(true), - mini(false), - blocked(false), - app(false) { - } - - SkBitmap favicon; - NetworkState network_state; - string16 title; - bool loading; - bool crashed; - bool off_the_record; - bool show_icon; - bool mini; - bool blocked; - bool app; -}; +#include "chrome/browser/ui/views/tabs/tab_renderer_data.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_TAB_RENDERER_DATA_H_ + diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc deleted file mode 100644 index 9b25dfa..0000000 --- a/chrome/browser/views/tabs/tab_strip.cc +++ /dev/null @@ -1,982 +0,0 @@ -// 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/tabs/tab_strip.h" - -#include "app/animation_container.h" -#include "app/drag_drop_types.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/compiler_specific.h" -#include "base/stl_util-inl.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/defaults.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/tabs/tab.h" -#include "chrome/browser/views/tabs/tab_strip_controller.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas_skia.h" -#include "gfx/path.h" -#include "gfx/size.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/image_view.h" -#include "views/widget/default_theme_provider.h" -#include "views/window/non_client_view.h" -#include "views/window/window.h" - -#if defined(OS_WIN) -#include "app/win_util.h" -#include "views/widget/widget_win.h" -#elif defined(OS_LINUX) -#include "views/widget/widget_gtk.h" -#endif - -#undef min -#undef max - -#if defined(COMPILER_GCC) -// Squash false positive signed overflow warning in GenerateStartAndEndWidths -// when doing 'start_tab_count < end_tab_count'. -#pragma GCC diagnostic ignored "-Wstrict-overflow" -#endif - -using views::DropTargetEvent; - -static const int kNewTabButtonHOffset = -5; -static const int kNewTabButtonVOffset = 5; -static const int kSuspendAnimationsTimeMs = 200; -static const int kTabHOffset = -16; -static const int kTabStripAnimationVSlop = 40; - -// Size of the drop indicator. -static int drop_indicator_width; -static int drop_indicator_height; - -static inline int Round(double x) { - // Why oh why is this not in a standard header? - return static_cast<int>(floor(x + 0.5)); -} - -namespace { - -/////////////////////////////////////////////////////////////////////////////// -// NewTabButton -// -// A subclass of button that hit-tests to the shape of the new tab button. - -class NewTabButton : public views::ImageButton { - public: - explicit NewTabButton(views::ButtonListener* listener) - : views::ImageButton(listener) { - } - virtual ~NewTabButton() {} - - protected: - // Overridden from views::View: - virtual bool HasHitTestMask() const { - // When the button is sized to the top of the tab strip we want the user to - // be able to click on complete bounds, and so don't return a custom hit - // mask. - return !browser_defaults::kSizeTabButtonToTopOfTabStrip; - } - virtual void GetHitTestMask(gfx::Path* path) const { - DCHECK(path); - - SkScalar w = SkIntToScalar(width()); - - // These values are defined by the shape of the new tab bitmap. Should that - // bitmap ever change, these values will need to be updated. They're so - // custom it's not really worth defining constants for. - path->moveTo(0, 1); - path->lineTo(w - 7, 1); - path->lineTo(w - 4, 4); - path->lineTo(w, 16); - path->lineTo(w - 1, 17); - path->lineTo(7, 17); - path->lineTo(4, 13); - path->lineTo(0, 1); - path->close(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(NewTabButton); -}; - -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// TabStrip, public: - -// static -const int TabStrip::mini_to_non_mini_gap_ = 3; - -TabStrip::TabStrip(TabStripController* controller) - : BaseTabStrip(controller, BaseTabStrip::HORIZONTAL_TAB_STRIP), - current_unselected_width_(Tab::GetStandardSize().width()), - current_selected_width_(Tab::GetStandardSize().width()), - available_width_for_tabs_(-1), - in_tab_close_(false), - animation_container_(new AnimationContainer()) { - Init(); -} - -TabStrip::~TabStrip() { - // The animations may reference the tabs. Shut down the animation before we - // delete the tabs. - StopAnimating(false); - - DestroyDragController(); - - // Make sure we unhook ourselves as a message loop observer so that we don't - // crash in the case where the user closes the window after closing a tab - // but before moving the mouse. - RemoveMessageLoopObserver(); - - // The children (tabs) may callback to us from their destructor. Delete them - // so that if they call back we aren't in a weird state. - RemoveAllChildViews(true); -} - -void TabStrip::InitTabStripButtons() { - newtab_button_ = new NewTabButton(this); - if (browser_defaults::kSizeTabButtonToTopOfTabStrip) { - newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, - views::ImageButton::ALIGN_BOTTOM); - } - LoadNewTabButtonImage(); - newtab_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_NEWTAB)); - AddChildView(newtab_button_); -} - -gfx::Rect TabStrip::GetNewTabButtonBounds() { - return newtab_button_->bounds(); -} - -void TabStrip::MouseMovedOutOfView() { - ResizeLayoutTabs(); -} - -//////////////////////////////////////////////////////////////////////////////// -// TabStrip, BaseTabStrip implementation: - -int TabStrip::GetPreferredHeight() { - return GetPreferredSize().height(); -} - -void TabStrip::SetBackgroundOffset(const gfx::Point& offset) { - for (int i = 0; i < tab_count(); ++i) - GetTabAtTabDataIndex(i)->SetBackgroundOffset(offset); -} - -bool TabStrip::IsPositionInWindowCaption(const gfx::Point& point) { - views::View* v = GetViewForPoint(point); - - // If there is no control at this location, claim the hit was in the title - // bar to get a move action. - if (v == this) - return true; - - // Check to see if the point is within the non-button parts of the new tab - // button. The button has a non-rectangular shape, so if it's not in the - // visual portions of the button we treat it as a click to the caption. - gfx::Point point_in_newtab_coords(point); - View::ConvertPointToView(this, newtab_button_, &point_in_newtab_coords); - if (newtab_button_->bounds().Contains(point) && - !newtab_button_->HitTest(point_in_newtab_coords)) { - return true; - } - - // All other regions, including the new Tab button, should be considered part - // of the containing Window's client area so that regular events can be - // processed for them. - return false; -} - -void TabStrip::SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds) { -} - -TabStrip* TabStrip::AsTabStrip() { - return this; -} - -void TabStrip::PrepareForCloseAt(int model_index) { - if (!in_tab_close_ && IsAnimating()) { - // Cancel any current animations. We do this as remove uses the current - // ideal bounds and we need to know ideal bounds is in a good state. - StopAnimating(true); - } - - int model_count = GetModelCount(); - if (model_index + 1 != model_count && model_count > 1) { - // The user is about to close a tab other than the last tab. Set - // available_width_for_tabs_ so that if we do a layout we don't position a - // tab past the end of the second to last tab. We do this so that as the - // user closes tabs with the mouse a tab continues to fall under the mouse. - available_width_for_tabs_ = GetAvailableWidthForTabs( - GetTabAtModelIndex(model_count - 2)); - } - - in_tab_close_ = true; - AddMessageLoopObserver(); -} - -void TabStrip::RemoveTabAt(int model_index) { - if (in_tab_close_ && model_index != GetModelCount()) - StartMouseInitiatedRemoveTabAnimation(model_index); - else - StartRemoveTabAnimation(model_index); -} - -void TabStrip::SelectTabAt(int old_model_index, int new_model_index) { - // We have "tiny tabs" if the tabs are so tiny that the unselected ones are - // a different size to the selected ones. - bool tiny_tabs = current_unselected_width_ != current_selected_width_; - if (!IsAnimating() && (!in_tab_close_ || tiny_tabs)) { - DoLayout(); - } else { - SchedulePaint(); - } - - if (old_model_index >= 0) { - GetTabAtTabDataIndex(ModelIndexToTabIndex(old_model_index))-> - StopMiniTabTitleAnimation(); - } -} - -void TabStrip::TabTitleChangedNotLoading(int model_index) { - Tab* tab = GetTabAtModelIndex(model_index); - if (tab->data().mini && !tab->IsSelected()) - tab->StartMiniTabTitleAnimation(); -} - -void TabStrip::StartHighlight(int model_index) { - GetTabAtModelIndex(model_index)->StartPulse(); -} - -void TabStrip::StopAllHighlighting() { - for (int i = 0; i < tab_count(); ++i) - GetTabAtTabDataIndex(i)->StopPulse(); -} - -BaseTab* TabStrip::CreateTabForDragging() { - Tab* tab = new Tab(NULL); - // Make sure the dragged tab shares our theme provider. We need to explicitly - // do this as during dragging there isn't a theme provider. - tab->set_theme_provider(GetThemeProvider()); - return tab; -} - -/////////////////////////////////////////////////////////////////////////////// -// TabStrip, views::View overrides: - -void TabStrip::PaintChildren(gfx::Canvas* canvas) { - // Tabs are painted in reverse order, so they stack to the left. - Tab* selected_tab = NULL; - Tab* dragging_tab = NULL; - - for (int i = tab_count() - 1; i >= 0; --i) { - Tab* tab = GetTabAtTabDataIndex(i); - // We must ask the _Tab's_ model, not ourselves, because in some situations - // the model will be different to this object, e.g. when a Tab is being - // removed after its TabContents has been destroyed. - if (tab->dragging()) { - dragging_tab = tab; - } else if (!tab->IsSelected()) { - tab->ProcessPaint(canvas); - } else { - selected_tab = tab; - } - } - - if (GetWindow()->GetNonClientView()->UseNativeFrame()) { - // Make sure unselected tabs are somewhat transparent. - SkPaint paint; - paint.setColor(SkColorSetARGB(200, 255, 255, 255)); - paint.setXfermodeMode(SkXfermode::kDstIn_Mode); - paint.setStyle(SkPaint::kFill_Style); - canvas->DrawRectInt(0, 0, width(), - height() - 2, // Visible region that overlaps the toolbar. - paint); - } - - // Paint the selected tab last, so it overlaps all the others. - if (selected_tab) - selected_tab->ProcessPaint(canvas); - - // Paint the New Tab button. - newtab_button_->ProcessPaint(canvas); - - // And the dragged tab. - if (dragging_tab) - dragging_tab->ProcessPaint(canvas); -} - -// Overridden to support automation. See automation_proxy_uitest.cc. -views::View* TabStrip::GetViewByID(int view_id) const { - if (tab_count() > 0) { - if (view_id == VIEW_ID_TAB_LAST) { - return GetTabAtTabDataIndex(tab_count() - 1); - } else if ((view_id >= VIEW_ID_TAB_0) && (view_id < VIEW_ID_TAB_LAST)) { - int index = view_id - VIEW_ID_TAB_0; - if (index >= 0 && index < tab_count()) { - return GetTabAtTabDataIndex(index); - } else { - return NULL; - } - } - } - - return View::GetViewByID(view_id); -} - -gfx::Size TabStrip::GetPreferredSize() { - return gfx::Size(0, Tab::GetMinimumUnselectedSize().height()); -} - -void TabStrip::OnDragEntered(const DropTargetEvent& event) { - // Force animations to stop, otherwise it makes the index calculation tricky. - StopAnimating(true); - - UpdateDropIndex(event); -} - -int TabStrip::OnDragUpdated(const DropTargetEvent& event) { - UpdateDropIndex(event); - return GetDropEffect(event); -} - -void TabStrip::OnDragExited() { - SetDropIndex(-1, false); -} - -int TabStrip::OnPerformDrop(const DropTargetEvent& event) { - if (!drop_info_.get()) - return DragDropTypes::DRAG_NONE; - - const int drop_index = drop_info_->drop_index; - const bool drop_before = drop_info_->drop_before; - - // Hide the drop indicator. - SetDropIndex(-1, false); - - GURL url; - std::wstring title; - if (!event.GetData().GetURLAndTitle(&url, &title) || !url.is_valid()) - return DragDropTypes::DRAG_NONE; - - controller()->PerformDrop(drop_before, drop_index, url); - - return GetDropEffect(event); -} - -AccessibilityTypes::Role TabStrip::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PAGETABLIST; -} - -views::View* TabStrip::GetViewForPoint(const gfx::Point& point) { - // Return any view that isn't a Tab or this TabStrip immediately. We don't - // want to interfere. - views::View* v = View::GetViewForPoint(point); - if (v && v != this && v->GetClassName() != Tab::kViewClassName) - return v; - - // The display order doesn't necessarily match the child list order, so we - // walk the display list hit-testing Tabs. Since the selected tab always - // renders on top of adjacent tabs, it needs to be hit-tested before any - // left-adjacent Tab, so we look ahead for it as we walk. - for (int i = 0; i < tab_count(); ++i) { - Tab* next_tab = i < (tab_count() - 1) ? GetTabAtTabDataIndex(i + 1) : NULL; - if (next_tab && next_tab->IsSelected() && IsPointInTab(next_tab, point)) - return next_tab; - Tab* tab = GetTabAtTabDataIndex(i); - if (IsPointInTab(tab, point)) - return tab; - } - - // No need to do any floating view stuff, we don't use them in the TabStrip. - return this; -} - -void TabStrip::OnThemeChanged() { - LoadNewTabButtonImage(); -} - -BaseTab* TabStrip::CreateTab() { - Tab* tab = new Tab(this); - tab->set_animation_container(animation_container_.get()); - return tab; -} - -void TabStrip::StartInsertTabAnimation(int model_index, bool foreground) { - PrepareForAnimation(); - - // The TabStrip can now use its entire width to lay out Tabs. - in_tab_close_ = false; - available_width_for_tabs_ = -1; - - GenerateIdealBounds(); - - int tab_data_index = ModelIndexToTabIndex(model_index); - BaseTab* tab = base_tab_at_tab_index(tab_data_index); - if (model_index == 0) { - tab->SetBounds(0, ideal_bounds(tab_data_index).y(), 0, - ideal_bounds(tab_data_index).height()); - } else { - BaseTab* last_tab = base_tab_at_tab_index(tab_data_index - 1); - tab->SetBounds(last_tab->bounds().right() + kTabHOffset, - ideal_bounds(tab_data_index).y(), 0, - ideal_bounds(tab_data_index).height()); - } - - AnimateToIdealBounds(); -} - -void TabStrip::StartMoveTabAnimation() { - PrepareForAnimation(); - - GenerateIdealBounds(); - AnimateToIdealBounds(); -} - -void TabStrip::AnimateToIdealBounds() { - for (int i = 0; i < tab_count(); ++i) { - Tab* tab = GetTabAtTabDataIndex(i); - if (!tab->closing() && !tab->dragging()) - bounds_animator().AnimateViewTo(tab, ideal_bounds(i)); - } - - bounds_animator().AnimateViewTo(newtab_button_, newtab_button_bounds_); -} - -bool TabStrip::ShouldHighlightCloseButtonAfterRemove() { - return in_tab_close_; -} - -void TabStrip::DoLayout() { - BaseTabStrip::DoLayout(); - - newtab_button_->SetBounds(newtab_button_bounds_); -} - -void TabStrip::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - InitTabStripButtons(); -} - -/////////////////////////////////////////////////////////////////////////////// -// TabStrip, Tab::Delegate implementation: - -bool TabStrip::IsTabSelected(const BaseTab* btr) const { - const Tab* tab = static_cast<const Tab*>(btr); - return !tab->closing() && BaseTabStrip::IsTabSelected(btr); -} - -/////////////////////////////////////////////////////////////////////////////// -// TabStrip, views::BaseButton::ButtonListener implementation: - -void TabStrip::ButtonPressed(views::Button* sender, const views::Event& event) { - if (sender == newtab_button_) - controller()->CreateNewTab(); -} - -/////////////////////////////////////////////////////////////////////////////// -// TabStrip, private: - -void TabStrip::Init() { - SetID(VIEW_ID_TAB_STRIP); - newtab_button_bounds_.SetRect(0, 0, kNewTabButtonWidth, kNewTabButtonHeight); - if (browser_defaults::kSizeTabButtonToTopOfTabStrip) { - newtab_button_bounds_.set_height( - kNewTabButtonHeight + kNewTabButtonVOffset); - } - if (drop_indicator_width == 0) { - // Direction doesn't matter, both images are the same size. - SkBitmap* drop_image = GetDropArrowImage(true); - drop_indicator_width = drop_image->width(); - drop_indicator_height = drop_image->height(); - } -} - -void TabStrip::LoadNewTabButtonImage() { - ThemeProvider* tp = GetThemeProvider(); - - // If we don't have a theme provider yet, it means we do not have a - // root view, and are therefore in a test. - bool in_test = false; - if (tp == NULL) { - tp = new views::DefaultThemeProvider(); - in_test = true; - } - - SkBitmap* bitmap = tp->GetBitmapNamed(IDR_NEWTAB_BUTTON); - SkColor color = tp->GetColor(BrowserThemeProvider::COLOR_BUTTON_BACKGROUND); - SkBitmap* background = tp->GetBitmapNamed( - IDR_THEME_WINDOW_CONTROL_BACKGROUND); - - newtab_button_->SetImage(views::CustomButton::BS_NORMAL, bitmap); - newtab_button_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_NEWTAB_BUTTON_P)); - newtab_button_->SetImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_NEWTAB_BUTTON_H)); - newtab_button_->SetBackground(color, background, - tp->GetBitmapNamed(IDR_NEWTAB_BUTTON_MASK)); - if (in_test) - delete tp; -} - -Tab* TabStrip::GetTabAtTabDataIndex(int tab_data_index) const { - return static_cast<Tab*>(base_tab_at_tab_index(tab_data_index)); -} - -Tab* TabStrip::GetTabAtModelIndex(int model_index) const { - return GetTabAtTabDataIndex(ModelIndexToTabIndex(model_index)); -} - -void TabStrip::GetCurrentTabWidths(double* unselected_width, - double* selected_width) const { - *unselected_width = current_unselected_width_; - *selected_width = current_selected_width_; -} - -void TabStrip::GetDesiredTabWidths(int tab_count, - int mini_tab_count, - double* unselected_width, - double* selected_width) const { - DCHECK(tab_count >= 0 && mini_tab_count >= 0 && mini_tab_count <= tab_count); - const double min_unselected_width = Tab::GetMinimumUnselectedSize().width(); - const double min_selected_width = Tab::GetMinimumSelectedSize().width(); - - *unselected_width = min_unselected_width; - *selected_width = min_selected_width; - - if (tab_count == 0) { - // Return immediately to avoid divide-by-zero below. - return; - } - - // Determine how much space we can actually allocate to tabs. - int available_width; - if (available_width_for_tabs_ < 0) { - available_width = width(); - available_width -= (kNewTabButtonHOffset + newtab_button_bounds_.width()); - } else { - // Interesting corner case: if |available_width_for_tabs_| > the result - // of the calculation in the conditional arm above, the strip is in - // overflow. We can either use the specified width or the true available - // width here; the first preserves the consistent "leave the last tab under - // the user's mouse so they can close many tabs" behavior at the cost of - // prolonging the glitchy appearance of the overflow state, while the second - // gets us out of overflow as soon as possible but forces the user to move - // their mouse for a few tabs' worth of closing. We choose visual - // imperfection over behavioral imperfection and select the first option. - available_width = available_width_for_tabs_; - } - - if (mini_tab_count > 0) { - available_width -= mini_tab_count * (Tab::GetMiniWidth() + kTabHOffset); - tab_count -= mini_tab_count; - if (tab_count == 0) { - *selected_width = *unselected_width = Tab::GetStandardSize().width(); - return; - } - // Account for gap between the last mini-tab and first non-mini-tab. - available_width -= mini_to_non_mini_gap_; - } - - // Calculate the desired tab widths by dividing the available space into equal - // portions. Don't let tabs get larger than the "standard width" or smaller - // than the minimum width for each type, respectively. - const int total_offset = kTabHOffset * (tab_count - 1); - const double desired_tab_width = std::min((static_cast<double>( - available_width - total_offset) / static_cast<double>(tab_count)), - static_cast<double>(Tab::GetStandardSize().width())); - *unselected_width = std::max(desired_tab_width, min_unselected_width); - *selected_width = std::max(desired_tab_width, min_selected_width); - - // When there are multiple tabs, we'll have one selected and some unselected - // tabs. If the desired width was between the minimum sizes of these types, - // try to shrink the tabs with the smaller minimum. For example, if we have - // a strip of width 10 with 4 tabs, the desired width per tab will be 2.5. If - // selected tabs have a minimum width of 4 and unselected tabs have a minimum - // width of 1, the above code would set *unselected_width = 2.5, - // *selected_width = 4, which results in a total width of 11.5. Instead, we - // want to set *unselected_width = 2, *selected_width = 4, for a total width - // of 10. - if (tab_count > 1) { - if ((min_unselected_width < min_selected_width) && - (desired_tab_width < min_selected_width)) { - // Unselected width = (total width - selected width) / (num_tabs - 1) - *unselected_width = std::max(static_cast<double>( - available_width - total_offset - min_selected_width) / - static_cast<double>(tab_count - 1), min_unselected_width); - } else if ((min_unselected_width > min_selected_width) && - (desired_tab_width < min_unselected_width)) { - // Selected width = (total width - (unselected width * (num_tabs - 1))) - *selected_width = std::max(available_width - total_offset - - (min_unselected_width * (tab_count - 1)), min_selected_width); - } - } -} - -void TabStrip::ResizeLayoutTabs() { - // We've been called back after the TabStrip has been emptied out (probably - // just prior to the window being destroyed). We need to do nothing here or - // else GetTabAt below will crash. - if (tab_count() == 0) - return; - - // It is critically important that this is unhooked here, otherwise we will - // keep spying on messages forever. - RemoveMessageLoopObserver(); - - in_tab_close_ = false; - available_width_for_tabs_ = -1; - int mini_tab_count = GetMiniTabCount(); - if (mini_tab_count == tab_count()) { - // Only mini-tabs, we know the tab widths won't have changed (all - // mini-tabs have the same width), so there is nothing to do. - return; - } - Tab* first_tab = GetTabAtTabDataIndex(mini_tab_count); - double unselected, selected; - GetDesiredTabWidths(tab_count(), mini_tab_count, &unselected, &selected); - int w = Round(first_tab->IsSelected() ? selected : selected); - - // We only want to run the animation if we're not already at the desired - // size. - if (abs(first_tab->width() - w) > 1) - StartResizeLayoutAnimation(); -} - -void TabStrip::AddMessageLoopObserver() { - if (!mouse_watcher_.get()) { - mouse_watcher_.reset( - new views::MouseWatcher(this, this, - gfx::Insets(0, 0, kTabStripAnimationVSlop, 0))); - } - mouse_watcher_->Start(); -} - -void TabStrip::RemoveMessageLoopObserver() { - mouse_watcher_.reset(NULL); -} - -gfx::Rect TabStrip::GetDropBounds(int drop_index, - bool drop_before, - bool* is_beneath) { - DCHECK(drop_index != -1); - int center_x; - if (drop_index < tab_count()) { - Tab* tab = GetTabAtTabDataIndex(drop_index); - if (drop_before) - center_x = tab->x() - (kTabHOffset / 2); - else - center_x = tab->x() + (tab->width() / 2); - } else { - Tab* last_tab = GetTabAtTabDataIndex(drop_index - 1); - center_x = last_tab->x() + last_tab->width() + (kTabHOffset / 2); - } - - // Mirror the center point if necessary. - center_x = MirroredXCoordinateInsideView(center_x); - - // Determine the screen bounds. - gfx::Point drop_loc(center_x - drop_indicator_width / 2, - -drop_indicator_height); - ConvertPointToScreen(this, &drop_loc); - gfx::Rect drop_bounds(drop_loc.x(), drop_loc.y(), drop_indicator_width, - drop_indicator_height); - - // If the rect doesn't fit on the monitor, push the arrow to the bottom. -#if defined(OS_WIN) - gfx::Rect monitor_bounds = win_util::GetMonitorBoundsForRect(drop_bounds); - *is_beneath = (monitor_bounds.IsEmpty() || - !monitor_bounds.Contains(drop_bounds)); -#else - *is_beneath = false; - NOTIMPLEMENTED(); -#endif - if (*is_beneath) - drop_bounds.Offset(0, drop_bounds.height() + height()); - - return drop_bounds; -} - -void TabStrip::UpdateDropIndex(const DropTargetEvent& event) { - // If the UI layout is right-to-left, we need to mirror the mouse - // coordinates since we calculate the drop index based on the - // original (and therefore non-mirrored) positions of the tabs. - const int x = MirroredXCoordinateInsideView(event.x()); - // We don't allow replacing the urls of mini-tabs. - for (int i = GetMiniTabCount(); i < tab_count(); ++i) { - Tab* tab = GetTabAtTabDataIndex(i); - const int tab_max_x = tab->x() + tab->width(); - const int hot_width = tab->width() / 3; - if (x < tab_max_x) { - if (x < tab->x() + hot_width) - SetDropIndex(i, true); - else if (x >= tab_max_x - hot_width) - SetDropIndex(i + 1, true); - else - SetDropIndex(i, false); - return; - } - } - - // The drop isn't over a tab, add it to the end. - SetDropIndex(tab_count(), true); -} - -void TabStrip::SetDropIndex(int tab_data_index, bool drop_before) { - if (tab_data_index == -1) { - if (drop_info_.get()) - drop_info_.reset(NULL); - return; - } - - if (drop_info_.get() && drop_info_->drop_index == tab_data_index && - drop_info_->drop_before == drop_before) { - return; - } - - bool is_beneath; - gfx::Rect drop_bounds = GetDropBounds(tab_data_index, drop_before, - &is_beneath); - - if (!drop_info_.get()) { - drop_info_.reset(new DropInfo(tab_data_index, drop_before, !is_beneath)); - } else { - drop_info_->drop_index = tab_data_index; - drop_info_->drop_before = drop_before; - if (is_beneath == drop_info_->point_down) { - drop_info_->point_down = !is_beneath; - drop_info_->arrow_view->SetImage( - GetDropArrowImage(drop_info_->point_down)); - } - } - - // Reposition the window. Need to show it too as the window is initially - // hidden. - -#if defined(OS_WIN) - drop_info_->arrow_window->SetWindowPos( - HWND_TOPMOST, drop_bounds.x(), drop_bounds.y(), drop_bounds.width(), - drop_bounds.height(), SWP_NOACTIVATE | SWP_SHOWWINDOW); -#else - drop_info_->arrow_window->SetBounds(drop_bounds); - drop_info_->arrow_window->Show(); -#endif -} - -int TabStrip::GetDropEffect(const views::DropTargetEvent& event) { - const int source_ops = event.GetSourceOperations(); - if (source_ops & DragDropTypes::DRAG_COPY) - return DragDropTypes::DRAG_COPY; - if (source_ops & DragDropTypes::DRAG_LINK) - return DragDropTypes::DRAG_LINK; - return DragDropTypes::DRAG_MOVE; -} - -// static -SkBitmap* TabStrip::GetDropArrowImage(bool is_down) { - return ResourceBundle::GetSharedInstance().GetBitmapNamed( - is_down ? IDR_TAB_DROP_DOWN : IDR_TAB_DROP_UP); -} - -// TabStrip::DropInfo ---------------------------------------------------------- - -TabStrip::DropInfo::DropInfo(int drop_index, bool drop_before, bool point_down) - : drop_index(drop_index), - drop_before(drop_before), - point_down(point_down) { - arrow_view = new views::ImageView; - arrow_view->SetImage(GetDropArrowImage(point_down)); - -#if defined(OS_WIN) - arrow_window = new views::WidgetWin; - arrow_window->set_window_style(WS_POPUP); - arrow_window->set_window_ex_style(WS_EX_TOPMOST | WS_EX_NOACTIVATE | - WS_EX_LAYERED | WS_EX_TRANSPARENT); -#else - arrow_window = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); - arrow_window->MakeTransparent(); -#endif - arrow_window->Init( - NULL, - gfx::Rect(0, 0, drop_indicator_width, drop_indicator_height)); - arrow_window->SetContentsView(arrow_view); -} - -TabStrip::DropInfo::~DropInfo() { - // Close eventually deletes the window, which deletes arrow_view too. - arrow_window->Close(); -} - -/////////////////////////////////////////////////////////////////////////////// - -// Called from: -// - BasicLayout -// - Tab insertion/removal -// - Tab reorder -void TabStrip::GenerateIdealBounds() { - int non_closing_tab_count = 0; - int mini_tab_count = 0; - for (int i = 0; i < tab_count(); ++i) { - BaseTab* tab = base_tab_at_tab_index(i); - if (!tab->closing()) { - ++non_closing_tab_count; - if (tab->data().mini) - mini_tab_count++; - } - } - - double unselected, selected; - GetDesiredTabWidths(non_closing_tab_count, mini_tab_count, &unselected, - &selected); - - current_unselected_width_ = unselected; - current_selected_width_ = selected; - - // NOTE: This currently assumes a tab's height doesn't differ based on - // selected state or the number of tabs in the strip! - int tab_height = Tab::GetStandardSize().height(); - double tab_x = 0; - bool last_was_mini = false; - for (int i = 0; i < tab_count(); ++i) { - Tab* tab = GetTabAtTabDataIndex(i); - if (!tab->closing()) { - double tab_width = unselected; - if (tab->data().mini) { - tab_width = Tab::GetMiniWidth(); - } else { - if (last_was_mini) { - // Give a bigger gap between mini and non-mini tabs. - tab_x += mini_to_non_mini_gap_; - } - if (tab->IsSelected()) - tab_width = selected; - } - double end_of_tab = tab_x + tab_width; - int rounded_tab_x = Round(tab_x); - set_ideal_bounds(i, - gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, - tab_height)); - tab_x = end_of_tab + kTabHOffset; - last_was_mini = tab->data().mini; - } - } - - // Update bounds of new tab button. - int new_tab_x; - int new_tab_y = browser_defaults::kSizeTabButtonToTopOfTabStrip ? - 0 : kNewTabButtonVOffset; - if (abs(Round(unselected) - Tab::GetStandardSize().width()) > 1 && - !in_tab_close_) { - // We're shrinking tabs, so we need to anchor the New Tab button to the - // right edge of the TabStrip's bounds, rather than the right edge of the - // right-most Tab, otherwise it'll bounce when animating. - new_tab_x = width() - newtab_button_bounds_.width(); - } else { - new_tab_x = Round(tab_x - kTabHOffset) + kNewTabButtonHOffset; - } - newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y)); -} - -void TabStrip::StartResizeLayoutAnimation() { - PrepareForAnimation(); - GenerateIdealBounds(); - AnimateToIdealBounds(); -} - -void TabStrip::StartMiniTabAnimation() { - in_tab_close_ = false; - available_width_for_tabs_ = -1; - - PrepareForAnimation(); - - GenerateIdealBounds(); - AnimateToIdealBounds(); -} - -void TabStrip::StartMouseInitiatedRemoveTabAnimation(int model_index) { - // The user initiated the close. We want to persist the bounds of all the - // existing tabs, so we manually shift ideal_bounds then animate. - int tab_data_index = ModelIndexToTabIndex(model_index); - DCHECK(tab_data_index != tab_count()); - BaseTab* tab_closing = base_tab_at_tab_index(tab_data_index); - int delta = tab_closing->width() + kTabHOffset; - if (tab_closing->data().mini && model_index + 1 < GetModelCount() && - !GetBaseTabAtModelIndex(model_index + 1)->data().mini) { - delta += mini_to_non_mini_gap_; - } - - for (int i = tab_data_index + 1; i < tab_count(); ++i) { - BaseTab* tab = base_tab_at_tab_index(i); - if (!tab->closing()) { - gfx::Rect bounds = ideal_bounds(i); - bounds.set_x(bounds.x() - delta); - set_ideal_bounds(i, bounds); - } - } - - newtab_button_bounds_.set_x(newtab_button_bounds_.x() - delta); - - PrepareForAnimation(); - - // Mark the tab as closing. - tab_closing->set_closing(true); - - AnimateToIdealBounds(); - - gfx::Rect tab_bounds = tab_closing->bounds(); - if (type() == HORIZONTAL_TAB_STRIP) - tab_bounds.set_width(0); - else - tab_bounds.set_height(0); - bounds_animator().AnimateViewTo(tab_closing, tab_bounds); - - // Register delegate to do cleanup when done, BoundsAnimator takes - // ownership of RemoveTabDelegate. - bounds_animator().SetAnimationDelegate(tab_closing, - CreateRemoveTabDelegate(tab_closing), - true); -} - -void TabStrip::StopAnimating(bool layout) { - if (!IsAnimating()) - return; - - bounds_animator().Cancel(); - - DCHECK(!IsAnimating()); - - if (layout) - DoLayout(); -} - -int TabStrip::GetMiniTabCount() const { - int mini_count = 0; - for (int i = 0; i < tab_count(); ++i) { - if (base_tab_at_tab_index(i)->data().mini) - mini_count++; - else - return mini_count; - } - return mini_count; -} - -int TabStrip::GetAvailableWidthForTabs(Tab* last_tab) const { - return last_tab->x() + last_tab->width(); -} - -bool TabStrip::IsPointInTab(Tab* tab, - const gfx::Point& point_in_tabstrip_coords) { - gfx::Point point_in_tab_coords(point_in_tabstrip_coords); - View::ConvertPointToView(this, tab, &point_in_tab_coords); - return tab->HitTest(point_in_tab_coords); -} diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h index f7ec80fd..4c24f8c 100644 --- a/chrome/browser/views/tabs/tab_strip.h +++ b/chrome/browser/views/tabs/tab_strip.h @@ -6,282 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_ #pragma once -#include "app/animation_container.h" -#include "base/ref_counted.h" -#include "base/timer.h" -#include "chrome/browser/views/tabs/base_tab_strip.h" -#include "gfx/point.h" -#include "gfx/rect.h" -#include "views/controls/button/image_button.h" -#include "views/mouse_watcher.h" - -class Tab; - -namespace views { -class ImageView; -#if defined(OS_LINUX) -class WidgetGtk; -#elif defined(OS_WIN) -class WidgetWin; -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -// -// TabStrip -// -// A View that represents the TabStripModel. The TabStrip has the -// following responsibilities: -// - It implements the TabStripModelObserver interface, and acts as a -// container for Tabs, and is also responsible for creating them. -// - It takes part in Tab Drag & Drop with Tab, TabDragHelper and -// DraggedTab, focusing on tasks that require reshuffling other tabs -// in response to dragged tabs. -// -/////////////////////////////////////////////////////////////////////////////// -class TabStrip : public BaseTabStrip, - public views::ButtonListener, - public views::MouseWatcherListener { - public: - explicit TabStrip(TabStripController* controller); - virtual ~TabStrip(); - - // Creates the new tab button. - void InitTabStripButtons(); - - // Returns the bounds of the new tab button. - gfx::Rect GetNewTabButtonBounds(); - - // MouseWatcherListener overrides: - virtual void MouseMovedOutOfView(); - - // BaseTabStrip implementation: - virtual int GetPreferredHeight(); - virtual void SetBackgroundOffset(const gfx::Point& offset); - virtual bool IsPositionInWindowCaption(const gfx::Point& point); - virtual void SetDraggedTabBounds(int tab_index, - const gfx::Rect& tab_bounds); - virtual TabStrip* AsTabStrip(); - virtual void PrepareForCloseAt(int model_index); - virtual void RemoveTabAt(int model_index); - virtual void SelectTabAt(int old_model_index, int new_model_index); - virtual void TabTitleChangedNotLoading(int model_index); - virtual void StartHighlight(int model_index); - virtual void StopAllHighlighting(); - virtual BaseTab* CreateTabForDragging(); - - // views::View overrides: - virtual void PaintChildren(gfx::Canvas* canvas); - virtual views::View* GetViewByID(int id) const; - virtual gfx::Size GetPreferredSize(); - // NOTE: the drag and drop methods are invoked from FrameView. This is done to - // allow for a drop region that extends outside the bounds of the TabStrip. - virtual void OnDragEntered(const views::DropTargetEvent& event); - virtual int OnDragUpdated(const views::DropTargetEvent& event); - virtual void OnDragExited(); - virtual int OnPerformDrop(const views::DropTargetEvent& event); - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual views::View* GetViewForPoint(const gfx::Point& point); - virtual void OnThemeChanged(); - - protected: - // BaseTabStrip overrides: - virtual BaseTab* CreateTab(); - virtual void StartInsertTabAnimation(int model_index, bool foreground); - virtual void StartMoveTabAnimation(); - virtual void AnimateToIdealBounds(); - virtual bool ShouldHighlightCloseButtonAfterRemove(); - virtual void DoLayout(); - - // views::View implementation: - virtual void ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child); - - // TabController overrides. - virtual bool IsTabSelected(const BaseTab* btr) const; - - // views::ButtonListener implementation: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Horizontal gap between mini and non-mini-tabs. - static const int mini_to_non_mini_gap_; - - private: - friend class DraggedTabController; - - // Used during a drop session of a url. Tracks the position of the drop as - // well as a window used to highlight where the drop occurs. - struct DropInfo { - DropInfo(int index, bool drop_before, bool paint_down); - ~DropInfo(); - - // Index of the tab to drop on. If drop_before is true, the drop should - // occur between the tab at drop_index - 1 and drop_index. - // WARNING: if drop_before is true it is possible this will == tab_count, - // which indicates the drop should create a new tab at the end of the tabs. - int drop_index; - bool drop_before; - - // Direction the arrow should point in. If true, the arrow is displayed - // above the tab and points down. If false, the arrow is displayed beneath - // the tab and points up. - bool point_down; - - // Renders the drop indicator. - // TODO(beng): should be views::Widget. -#if defined(OS_WIN) - views::WidgetWin* arrow_window; -#else - views::WidgetGtk* arrow_window; -#endif - views::ImageView* arrow_view; - - private: - DISALLOW_COPY_AND_ASSIGN(DropInfo); - }; - - void Init(); - - // Set the images for the new tab button. - void LoadNewTabButtonImage(); - - // Retrieves the Tab at the specified index. Remember, the specified index - // is in terms of tab_data, *not* the model. - Tab* GetTabAtTabDataIndex(int tab_data_index) const; - - // Returns the tab at the specified index. If a remove animation is on going - // and the index is >= the index of the tab being removed, the index is - // incremented. While a remove operation is on going the indices of the model - // do not line up with the indices of the view. This method adjusts the index - // accordingly. - // - // Use this instead of GetTabAtTabDataIndex if the index comes from the model. - Tab* GetTabAtModelIndex(int model_index) const; - - // Returns the number of mini-tabs. - int GetMiniTabCount() const; - - // -- Tab Resize Layout ----------------------------------------------------- - - // Returns the exact (unrounded) current width of each tab. - void GetCurrentTabWidths(double* unselected_width, - double* selected_width) const; - - // Returns the exact (unrounded) desired width of each tab, based on the - // desired strip width and number of tabs. If - // |width_of_tabs_for_mouse_close_| is nonnegative we use that value in - // calculating the desired strip width; otherwise we use the current width. - // |mini_tab_count| gives the number of mini-tabs and |tab_count| the number - // of mini and non-mini-tabs. - void GetDesiredTabWidths(int tab_count, - int mini_tab_count, - double* unselected_width, - double* selected_width) const; - - // Perform an animated resize-relayout of the TabStrip immediately. - void ResizeLayoutTabs(); - - // Ensure that the message loop observer used for event spying is added and - // removed appropriately so we can tell when to resize layout the tab strip. - void AddMessageLoopObserver(); - void RemoveMessageLoopObserver(); - - // -- Link Drag & Drop ------------------------------------------------------ - - // Returns the bounds to render the drop at, in screen coordinates. Sets - // |is_beneath| to indicate whether the arrow is beneath the tab, or above - // it. - gfx::Rect GetDropBounds(int drop_index, bool drop_before, bool* is_beneath); - - // Updates the location of the drop based on the event. - void UpdateDropIndex(const views::DropTargetEvent& event); - - // Sets the location of the drop, repainting as necessary. - void SetDropIndex(int tab_data_index, bool drop_before); - - // Returns the drop effect for dropping a URL on the tab strip. This does - // not query the data in anyway, it only looks at the source operations. - int GetDropEffect(const views::DropTargetEvent& event); - - // Returns the image to use for indicating a drop on a tab. If is_down is - // true, this returns an arrow pointing down. - static SkBitmap* GetDropArrowImage(bool is_down); - - // -- Animations ------------------------------------------------------------ - - // Generates the ideal bounds of the TabStrip when all Tabs have finished - // animating to their desired position/bounds. This is used by the standard - // Layout method and other callers like the DraggedTabController that need - // stable representations of Tab positions. - void GenerateIdealBounds(); - - // Starts various types of TabStrip animations. - void StartResizeLayoutAnimation(); - void StartMoveTabAnimation(int from_model_index, - int to_model_index); - void StartMiniTabAnimation(); - void StartMouseInitiatedRemoveTabAnimation(int model_index); - - // Stops any ongoing animations. If |layout| is true and an animation is - // ongoing this does a layout. - virtual void StopAnimating(bool layout); - - // Calculates the available width for tabs, assuming a Tab is to be closed. - int GetAvailableWidthForTabs(Tab* last_tab) const; - - // Returns true if the specified point in TabStrip coords is within the - // hit-test region of the specified Tab. - bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords); - - // -- Member Variables ------------------------------------------------------ - - // The "New Tab" button. - views::ImageButton* newtab_button_; - - // Ideal bounds of the new tab button. - gfx::Rect newtab_button_bounds_; - - // The current widths of various types of tabs. We save these so that, as - // users close tabs while we're holding them at the same size, we can lay out - // tabs exactly and eliminate the "pixel jitter" we'd get from just leaving - // them all at their existing, rounded widths. - double current_unselected_width_; - double current_selected_width_; - - // If this value is nonnegative, it is used in GetDesiredTabWidths() to - // calculate how much space in the tab strip to use for tabs. Most of the - // time this will be -1, but while we're handling closing a tab via the mouse, - // we'll set this to the edge of the last tab before closing, so that if we - // are closing the last tab and need to resize immediately, we'll resize only - // back to this width, thus once again placing the last tab under the mouse - // cursor. - int available_width_for_tabs_; - - // True if PrepareForCloseAt has been invoked. When true remove animations - // preserve current tab bounds. - bool in_tab_close_; - - // The size of the new tab button must be hardcoded because we need to be - // able to lay it out before we are able to get its image from the - // ThemeProvider. It also makes sense to do this, because the size of the - // new tab button should not need to be calculated dynamically. - static const int kNewTabButtonWidth = 28; - static const int kNewTabButtonHeight = 18; - - // Valid for the lifetime of a drag over us. - scoped_ptr<DropInfo> drop_info_; - - // To ensure all tabs pulse at the same time they share the same animation - // container. This is that animation container. - scoped_refptr<AnimationContainer> animation_container_; - - // Used for stage 1 of new tab animation. - base::OneShotTimer<TabStrip> new_tab_timer_; - - scoped_ptr<views::MouseWatcher> mouse_watcher_; - - DISALLOW_COPY_AND_ASSIGN(TabStrip); -}; +#include "chrome/browser/ui/views/tabs/tab_strip.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_ + diff --git a/chrome/browser/views/tabs/tab_strip_controller.h b/chrome/browser/views/tabs/tab_strip_controller.h index bd52452..b0c7be9 100644 --- a/chrome/browser/views/tabs/tab_strip_controller.h +++ b/chrome/browser/views/tabs/tab_strip_controller.h @@ -6,68 +6,8 @@ #define CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_CONTROLLER_H_ #pragma once -class BaseTab; -class BaseTabStrip; -class GURL; - -namespace gfx { -class Point; -} - -// Model/Controller for the TabStrip. -// NOTE: All indices used by this class are in model coordinates. -class TabStripController { - public: - virtual ~TabStripController() {} - - // Returns the number of tabs in the model. - virtual int GetCount() const = 0; - - // Returns true if |index| is a valid model index. - virtual bool IsValidIndex(int index) const = 0; - - // Returns the selected index, in terms of the model. - virtual int GetSelectedIndex() const = 0; - - // Returns true if the selected index is selected. - virtual bool IsTabSelected(int index) const = 0; - - // Returns true if the selected index is pinned. - virtual bool IsTabPinned(int index) const = 0; - - // Returns true if the selected index is closeable. - virtual bool IsTabCloseable(int index) const = 0; - - // Returns true if the selected index is the new tab page. - virtual bool IsNewTabPage(int index) const = 0; - - // Select the tab at the specified index in the model. - virtual void SelectTab(int index) = 0; - - // Closes the tab at the specified index in the model. - virtual void CloseTab(int index) = 0; - - // Shows a context menu for the tab at the specified point in screen coords. - virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p) = 0; - - // Updates the loading animations of all the tabs. - virtual void UpdateLoadingAnimations() = 0; - - // Returns true if the associated TabStrip's delegate supports tab moving or - // detaching. Used by the Frame to determine if dragging on the Tab - // itself should move the window in cases where there's only one - // non drag-able Tab. - virtual int HasAvailableDragActions() const = 0; - - // Performans a drop at the specified location. - virtual void PerformDrop(bool drop_before, int index, const GURL& url) = 0; - - // Return true if this tab strip is compatible with the provided tab strip. - // Compatible tab strips can transfer tabs during drag and drop. - virtual bool IsCompatibleWith(BaseTabStrip* other) const = 0; - - // Creates the new tab. - virtual void CreateNewTab() = 0; -}; +#include "chrome/browser/ui/views/tabs/tab_strip_controller.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_CONTROLLER_H_ + diff --git a/chrome/browser/views/task_manager_view.cc b/chrome/browser/views/task_manager_view.cc deleted file mode 100644 index f8432d4..0000000 --- a/chrome/browser/views/task_manager_view.cc +++ /dev/null @@ -1,691 +0,0 @@ -// 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/task_manager/task_manager.h" - -#include "app/l10n_util.h" -#include "app/table_model_observer.h" -#include "base/command_line.h" -#include "base/metrics/stats_table.h" -#include "base/utf_string_conversions.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/memory_purger.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/views/browser_dialogs.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/accelerator.h" -#include "views/background.h" -#include "views/controls/button/native_button.h" -#include "views/controls/link.h" -#include "views/controls/menu/menu.h" -#include "views/controls/table/group_table_view.h" -#include "views/controls/table/table_view_observer.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -// The task manager window default size. -static const int kDefaultWidth = 460; -static const int kDefaultHeight = 270; - -namespace { - -//////////////////////////////////////////////////////////////////////////////// -// TaskManagerTableModel class -//////////////////////////////////////////////////////////////////////////////// - -class TaskManagerTableModel : public views::GroupTableModel, - public TaskManagerModelObserver { - public: - explicit TaskManagerTableModel(TaskManagerModel* model) - : model_(model), - observer_(NULL) { - model_->AddObserver(this); - } - - ~TaskManagerTableModel() { - model_->RemoveObserver(this); - } - - // GroupTableModel. - int RowCount(); - std::wstring GetText(int row, int column); - SkBitmap GetIcon(int row); - void GetGroupRangeForItem(int item, views::GroupRange* range); - void SetObserver(TableModelObserver* observer); - virtual int CompareValues(int row1, int row2, int column_id); - - // TaskManagerModelObserver. - virtual void OnModelChanged(); - virtual void OnItemsChanged(int start, int length); - virtual void OnItemsAdded(int start, int length); - virtual void OnItemsRemoved(int start, int length); - - private: - TaskManagerModel* model_; - TableModelObserver* observer_; -}; - -int TaskManagerTableModel::RowCount() { - return model_->ResourceCount(); -} - -std::wstring TaskManagerTableModel::GetText(int row, int col_id) { - switch (col_id) { - case IDS_TASK_MANAGER_PAGE_COLUMN: // Process - return UTF16ToWide(model_->GetResourceTitle(row)); - - case IDS_TASK_MANAGER_NET_COLUMN: // Net - return UTF16ToWide(model_->GetResourceNetworkUsage(row)); - - case IDS_TASK_MANAGER_CPU_COLUMN: // CPU - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceCPUUsage(row)); - - case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourcePrivateMemory(row)); - - case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceSharedMemory(row)); - - case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN: // Memory - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourcePhysicalMemory(row)); - - case IDS_TASK_MANAGER_PROCESS_ID_COLUMN: - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceProcessId(row)); - - case IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN: // Goats Teleported! - return UTF16ToWide(model_->GetResourceGoatsTeleported(row)); - - case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN: - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceWebCoreImageCacheSize(row)); - - case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN: - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceWebCoreScriptsCacheSize(row)); - - case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceWebCoreCSSCacheSize(row)); - - case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN: - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceSqliteMemoryUsed(row)); - - case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN: - if (!model_->IsResourceFirstInGroup(row)) - return std::wstring(); - return UTF16ToWide(model_->GetResourceV8MemoryAllocatedSize(row)); - - default: - NOTREACHED(); - return std::wstring(); - } -} - -SkBitmap TaskManagerTableModel::GetIcon(int row) { - return model_->GetResourceIcon(row); -} - -void TaskManagerTableModel::GetGroupRangeForItem(int item, - views::GroupRange* range) { - std::pair<int, int> range_pair = model_->GetGroupRangeForResource(item); - range->start = range_pair.first; - range->length = range_pair.second; -} - -void TaskManagerTableModel::SetObserver(TableModelObserver* observer) { - observer_ = observer; -} - -int TaskManagerTableModel::CompareValues(int row1, int row2, int column_id) { - return model_->CompareValues(row1, row2, column_id); -} - -void TaskManagerTableModel::OnModelChanged() { - if (observer_) - observer_->OnModelChanged(); -} - -void TaskManagerTableModel::OnItemsChanged(int start, int length) { - if (observer_) - observer_->OnItemsChanged(start, length); -} - -void TaskManagerTableModel::OnItemsAdded(int start, int length) { - if (observer_) - observer_->OnItemsAdded(start, length); -} - -void TaskManagerTableModel::OnItemsRemoved(int start, int length) { - if (observer_) - observer_->OnItemsRemoved(start, length); -} - -// The Task manager UI container. -class TaskManagerView : public views::View, - public views::ButtonListener, - public views::DialogDelegate, - public views::TableViewObserver, - public views::LinkController, - public views::ContextMenuController, - public views::Menu::Delegate { - public: - TaskManagerView(); - virtual ~TaskManagerView(); - - // Shows the Task manager window, or re-activates an existing one. - static void Show(); - - // views::View - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual void ViewHierarchyChanged(bool is_add, views::View* parent, - views::View* child); - - // ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::DialogDelegate - virtual bool CanResize() const; - virtual bool CanMaximize() const; - virtual bool ExecuteWindowsCommand(int command_id); - virtual std::wstring GetWindowTitle() const; - virtual std::wstring GetWindowName() const; - virtual int GetDialogButtons() const; - virtual void WindowClosing(); - virtual views::View* GetContentsView(); - - // views::TableViewObserver implementation. - virtual void OnSelectionChanged(); - virtual void OnDoubleClick(); - virtual void OnKeyDown(app::KeyboardCode keycode); - - // views::LinkController implementation. - virtual void LinkActivated(views::Link* source, int event_flags); - - // Called by the column picker to pick up any new stat counters that - // may have appeared since last time. - void UpdateStatsCounters(); - - // Menu::Delegate - virtual void ShowContextMenu(views::View* source, - const gfx::Point& p, - bool is_mouse_gesture); - virtual bool IsItemChecked(int id) const; - virtual void ExecuteCommand(int id); - - private: - // Creates the child controls. - void Init(); - - // Initializes the state of the always-on-top setting as the window is shown. - void InitAlwaysOnTopState(); - - // Activates the tab associated with the focused row. - void ActivateFocusedTab(); - - // Adds an always on top item to the window's system menu. - void AddAlwaysOnTopSystemMenuItem(); - - // Restores saved always on top state from a previous session. - bool GetSavedAlwaysOnTopState(bool* always_on_top) const; - - views::NativeButton* purge_memory_button_; - views::NativeButton* kill_button_; - views::Link* about_memory_link_; - views::GroupTableView* tab_table_; - - TaskManager* task_manager_; - - TaskManagerModel* model_; - - // all possible columns, not necessarily visible - std::vector<TableColumn> columns_; - - scoped_ptr<TaskManagerTableModel> table_model_; - - // True when the Task Manager window should be shown on top of other windows. - bool is_always_on_top_; - - // We need to own the text of the menu, the Windows API does not copy it. - std::wstring always_on_top_menu_text_; - - // An open Task manager window. There can only be one open at a time. This - // is reset to NULL when the window is closed. - static TaskManagerView* instance_; - - DISALLOW_COPY_AND_ASSIGN(TaskManagerView); -}; - -// static -TaskManagerView* TaskManagerView::instance_ = NULL; - - -TaskManagerView::TaskManagerView() - : purge_memory_button_(NULL), - task_manager_(TaskManager::GetInstance()), - model_(TaskManager::GetInstance()->model()), - is_always_on_top_(false) { - Init(); -} - -TaskManagerView::~TaskManagerView() { - // Delete child views now, while our table model still exists. - RemoveAllChildViews(true); -} - -void TaskManagerView::Init() { - table_model_.reset(new TaskManagerTableModel(model_)); - - columns_.push_back(TableColumn(IDS_TASK_MANAGER_PAGE_COLUMN, - TableColumn::LEFT, -1, 1)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_SHARED_MEM_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_CPU_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_NET_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_PROCESS_ID_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back(TableColumn(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - columns_.push_back( - TableColumn(IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN, - TableColumn::RIGHT, -1, 0)); - columns_.back().sortable = true; - - tab_table_ = new views::GroupTableView(table_model_.get(), columns_, - views::ICON_AND_TEXT, false, true, - true); - - // Hide some columns by default - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_PROCESS_ID_COLUMN, false); - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_SHARED_MEM_COLUMN, false); - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, false); - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN, - false); - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN, - false); - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN, - false); - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN, - false); - tab_table_->SetColumnVisibility( - IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN, false); - tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN, - false); - - UpdateStatsCounters(); - tab_table_->SetObserver(this); - tab_table_->SetContextMenuController(this); - SetContextMenuController(this); - // If we're running with --purge-memory-button, add a "Purge memory" button. - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kPurgeMemoryButton)) { - purge_memory_button_ = new views::NativeButton(this, - l10n_util::GetString(IDS_TASK_MANAGER_PURGE_MEMORY)); - } - kill_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_TASK_MANAGER_KILL)); - kill_button_->AddAccelerator(views::Accelerator(app::VKEY_E, - false, false, false)); - kill_button_->SetAccessibleKeyboardShortcut(L"E"); - about_memory_link_ = new views::Link( - l10n_util::GetString(IDS_TASK_MANAGER_ABOUT_MEMORY_LINK)); - about_memory_link_->SetController(this); - - // Makes sure our state is consistent. - OnSelectionChanged(); -} - -void TaskManagerView::UpdateStatsCounters() { - base::StatsTable* stats = base::StatsTable::current(); - if (stats != NULL) { - int max = stats->GetMaxCounters(); - // skip the first row (it's header data) - for (int i = 1; i < max; i++) { - const char* row = stats->GetRowName(i); - if (row != NULL && row[0] != '\0' && !tab_table_->HasColumn(i)) { - // TODO(erikkay): Use l10n to get display names for stats. Right - // now we're just displaying the internal counter name. Perhaps - // stat names not in the string table would be filtered out. - // TODO(erikkay): Width is hard-coded right now, so many column - // names are clipped. - TableColumn col(i, ASCIIToWide(row), TableColumn::RIGHT, 90, 0); - col.sortable = true; - columns_.push_back(col); - tab_table_->AddColumn(col); - } - } - } -} - -void TaskManagerView::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - // Since we want the Kill button and the Memory Details link to show up in - // the same visual row as the close button, which is provided by the - // framework, we must add the buttons to the non-client view, which is the - // parent of this view. Similarly, when we're removed from the view - // hierarchy, we must take care to clean up those items as well. - if (child == this) { - if (is_add) { - parent->AddChildView(about_memory_link_); - if (purge_memory_button_) - parent->AddChildView(purge_memory_button_); - parent->AddChildView(kill_button_); - AddChildView(tab_table_); - } else { - parent->RemoveChildView(kill_button_); - if (purge_memory_button_) - parent->RemoveChildView(purge_memory_button_); - parent->RemoveChildView(about_memory_link_); - } - } -} - -void TaskManagerView::Layout() { - // kPanelHorizMargin is too big. - const int kTableButtonSpacing = 12; - - gfx::Size size = kill_button_->GetPreferredSize(); - int prefered_width = size.width(); - int prefered_height = size.height(); - - tab_table_->SetBounds(x() + kPanelHorizMargin, - y() + kPanelVertMargin, - width() - 2 * kPanelHorizMargin, - height() - 2 * kPanelVertMargin - prefered_height); - - // y-coordinate of button top left. - gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false); - int y_buttons = parent_bounds.bottom() - prefered_height - kButtonVEdgeMargin; - - kill_button_->SetBounds(x() + width() - prefered_width - kPanelHorizMargin, - y_buttons, - prefered_width, - prefered_height); - - if (purge_memory_button_) { - size = purge_memory_button_->GetPreferredSize(); - purge_memory_button_->SetBounds( - kill_button_->x() - size.width() - kUnrelatedControlHorizontalSpacing, - y_buttons, size.width(), size.height()); - } - - size = about_memory_link_->GetPreferredSize(); - int link_prefered_width = size.width(); - int link_prefered_height = size.height(); - // center between the two buttons horizontally, and line up with - // bottom of buttons vertically. - int link_y_offset = std::max(0, prefered_height - link_prefered_height) / 2; - about_memory_link_->SetBounds( - x() + kPanelHorizMargin, - y_buttons + prefered_height - link_prefered_height - link_y_offset, - link_prefered_width, - link_prefered_height); -} - -gfx::Size TaskManagerView::GetPreferredSize() { - return gfx::Size(kDefaultWidth, kDefaultHeight); -} - -// static -void TaskManagerView::Show() { - if (instance_) { - // If there's a Task manager window open already, just activate it. - instance_->window()->Activate(); - } else { - instance_ = new TaskManagerView; - views::Window::CreateChromeWindow(NULL, gfx::Rect(), instance_); - instance_->InitAlwaysOnTopState(); - instance_->model_->StartUpdating(); - instance_->window()->Show(); - - // Set the initial focus to the list of tasks. - views::FocusManager* focus_manager = instance_->GetFocusManager(); - if (focus_manager) - focus_manager->SetFocusedView(instance_->tab_table_); - } -} - -// ButtonListener implementation. -void TaskManagerView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (purge_memory_button_ && (sender == purge_memory_button_)) { - MemoryPurger::PurgeAll(); - } else { - DCHECK_EQ(sender, kill_button_); - for (views::TableSelectionIterator iter = tab_table_->SelectionBegin(); - iter != tab_table_->SelectionEnd(); ++iter) - task_manager_->KillProcess(*iter); - } -} - -// DialogDelegate implementation. -bool TaskManagerView::CanResize() const { - return true; -} - -bool TaskManagerView::CanMaximize() const { - return true; -} - -bool TaskManagerView::ExecuteWindowsCommand(int command_id) { - if (command_id == IDC_ALWAYS_ON_TOP) { - is_always_on_top_ = !is_always_on_top_; - - // Change the menu check state. - HMENU system_menu = GetSystemMenu(GetWindow()->GetNativeWindow(), FALSE); - MENUITEMINFO menu_info; - memset(&menu_info, 0, sizeof(MENUITEMINFO)); - menu_info.cbSize = sizeof(MENUITEMINFO); - BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, - FALSE, &menu_info); - DCHECK(r); - menu_info.fMask = MIIM_STATE; - if (is_always_on_top_) - menu_info.fState = MFS_CHECKED; - r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); - - // Now change the actual window's behavior. - window()->SetIsAlwaysOnTop(is_always_on_top_); - - // Save the state. - if (g_browser_process->local_state()) { - DictionaryValue* window_preferences = - g_browser_process->local_state()->GetMutableDictionary( - WideToUTF8(GetWindowName()).c_str()); - window_preferences->SetBoolean("always_on_top", is_always_on_top_); - } - return true; - } - return false; -} - -std::wstring TaskManagerView::GetWindowTitle() const { - return l10n_util::GetString(IDS_TASK_MANAGER_TITLE); -} - -std::wstring TaskManagerView::GetWindowName() const { - return UTF8ToWide(prefs::kTaskManagerWindowPlacement); -} - -int TaskManagerView::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_NONE; -} - -void TaskManagerView::WindowClosing() { - // Now that the window is closed, we can allow a new one to be opened. - instance_ = NULL; - task_manager_->OnWindowClosed(); -} - -views::View* TaskManagerView::GetContentsView() { - return this; -} - -// views::TableViewObserver implementation. -void TaskManagerView::OnSelectionChanged() { - bool selection_contains_browser_process = false; - for (views::TableSelectionIterator iter = tab_table_->SelectionBegin(); - iter != tab_table_->SelectionEnd(); ++iter) { - if (task_manager_->IsBrowserProcess(*iter)) { - selection_contains_browser_process = true; - break; - } - } - kill_button_->SetEnabled(!selection_contains_browser_process && - tab_table_->SelectedRowCount() > 0); -} - -void TaskManagerView::OnDoubleClick() { - ActivateFocusedTab(); -} - -void TaskManagerView::OnKeyDown(app::KeyboardCode keycode) { - if (keycode == app::VKEY_RETURN) - ActivateFocusedTab(); -} - -// views::LinkController implementation -void TaskManagerView::LinkActivated(views::Link* source, int event_flags) { - DCHECK(source == about_memory_link_); - task_manager_->OpenAboutMemory(); -} - -void TaskManagerView::ShowContextMenu(views::View* source, - const gfx::Point& p, - bool is_mouse_gesture) { - UpdateStatsCounters(); - scoped_ptr<views::Menu> menu(views::Menu::Create( - this, views::Menu::TOPLEFT, source->GetWidget()->GetNativeView())); - for (std::vector<TableColumn>::iterator i = - columns_.begin(); i != columns_.end(); ++i) { - menu->AppendMenuItem(i->id, i->title, views::Menu::CHECKBOX); - } - menu->RunMenuAt(p.x(), p.y()); -} - -bool TaskManagerView::IsItemChecked(int id) const { - return tab_table_->IsColumnVisible(id); -} - -void TaskManagerView::ExecuteCommand(int id) { - tab_table_->SetColumnVisibility(id, !tab_table_->IsColumnVisible(id)); -} - -void TaskManagerView::InitAlwaysOnTopState() { - is_always_on_top_ = false; - if (GetSavedAlwaysOnTopState(&is_always_on_top_)) - window()->SetIsAlwaysOnTop(is_always_on_top_); - AddAlwaysOnTopSystemMenuItem(); -} - -void TaskManagerView::ActivateFocusedTab() { - int row_count = tab_table_->RowCount(); - for (int i = 0; i < row_count; ++i) { - if (tab_table_->ItemHasTheFocus(i)) { - task_manager_->ActivateProcess(i); - break; - } - } -} - -void TaskManagerView::AddAlwaysOnTopSystemMenuItem() { - // The Win32 API requires that we own the text. - always_on_top_menu_text_ = l10n_util::GetString(IDS_ALWAYS_ON_TOP); - - // Let's insert a menu to the window. - HMENU system_menu = ::GetSystemMenu(GetWindow()->GetNativeWindow(), FALSE); - int index = ::GetMenuItemCount(system_menu) - 1; - if (index < 0) { - // Paranoia check. - NOTREACHED(); - index = 0; - } - // First we add the separator. - MENUITEMINFO menu_info; - memset(&menu_info, 0, sizeof(MENUITEMINFO)); - menu_info.cbSize = sizeof(MENUITEMINFO); - menu_info.fMask = MIIM_FTYPE; - menu_info.fType = MFT_SEPARATOR; - ::InsertMenuItem(system_menu, index, TRUE, &menu_info); - - // Then the actual menu. - menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE; - menu_info.fType = MFT_STRING; - menu_info.fState = MFS_ENABLED; - if (is_always_on_top_) - menu_info.fState |= MFS_CHECKED; - menu_info.wID = IDC_ALWAYS_ON_TOP; - menu_info.dwTypeData = const_cast<wchar_t*>(always_on_top_menu_text_.c_str()); - ::InsertMenuItem(system_menu, index, TRUE, &menu_info); -} - -bool TaskManagerView::GetSavedAlwaysOnTopState(bool* always_on_top) const { - if (!g_browser_process->local_state()) - return false; - - const DictionaryValue* dictionary = - g_browser_process->local_state()->GetDictionary( - WideToUTF8(GetWindowName()).c_str()); - return dictionary && - dictionary->GetBoolean("always_on_top", always_on_top) && always_on_top; -} - -} // namespace - -namespace browser { - -// Declared in browser_dialogs.h so others don't need to depend on our header. -void ShowTaskManager() { - TaskManagerView::Show(); -} - -} // namespace browser diff --git a/chrome/browser/views/textfield_views.cc b/chrome/browser/views/textfield_views.cc deleted file mode 100644 index f15be68..0000000 --- a/chrome/browser/views/textfield_views.cc +++ /dev/null @@ -1,34 +0,0 @@ -// 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/textfield_views.h" - -#include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/dom_ui/textfields_ui.h" -#include "chrome/browser/tab_contents/tab_contents.h" - -TextfieldViews::TextfieldViews() : DOMView() {} - -std::wstring TextfieldViews::GetText() { - TextfieldsUI* textfields_ui = dom_ui(); - return (textfields_ui) ? textfields_ui->text() : std::wstring(); -} - -void TextfieldViews::SetText(const std::wstring& text) { - TextfieldsUI* textfields_ui = dom_ui(); - if (textfields_ui) { - StringValue text_value(WideToUTF16(text)); - textfields_ui->CallJavascriptFunction(L"setTextfieldValue", text_value); - } - SchedulePaint(); -} - -TextfieldsUI* TextfieldViews::dom_ui() { - TextfieldsUI* dom_ui = NULL; - if (tab_contents_.get() && tab_contents_->dom_ui()) { - dom_ui = static_cast<TextfieldsUI*>(tab_contents_->dom_ui()); - } - return dom_ui; -} diff --git a/chrome/browser/views/textfield_views.h b/chrome/browser/views/textfield_views.h index 506a2e6..3b699f0 100644 --- a/chrome/browser/views/textfield_views.h +++ b/chrome/browser/views/textfield_views.h @@ -6,22 +6,8 @@ #define CHROME_BROWSER_VIEWS_TEXTFIELD_VIEWS_H_ #pragma once -#include <string> - -#include "chrome/browser/views/dom_view.h" - -class TextfieldsUI; - -class TextfieldViews : public DOMView { - public: - TextfieldViews(); - std::wstring GetText(); - void SetText(const std::wstring& text); - - private: - TextfieldsUI* dom_ui(); - - DISALLOW_COPY_AND_ASSIGN(TextfieldViews); -}; +#include "chrome/browser/ui/views/textfield_views.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TEXTFIELD_VIEWS_H_ + diff --git a/chrome/browser/views/theme_background.cc b/chrome/browser/views/theme_background.cc deleted file mode 100644 index ad8d2ed..0000000 --- a/chrome/browser/views/theme_background.cc +++ /dev/null @@ -1,60 +0,0 @@ -// 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/theme_background.h" - -#include "app/resource_bundle.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "gfx/canvas.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/view.h" - -ThemeBackground::ThemeBackground(BrowserView* browser_view) - : browser_view_(browser_view) { -} - -void ThemeBackground::Paint(gfx::Canvas* canvas, views::View* view) const { - SkBitmap* background; - - // Never theme app and popup windows. - if (!browser_view_->IsBrowserTypeNormal()) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - if (browser_view_->IsActive()) - background = rb.GetBitmapNamed(IDR_FRAME); - else - background = rb.GetBitmapNamed(IDR_THEME_FRAME_INACTIVE); - } else { - Profile* profile = browser_view_->browser()->profile(); - ThemeProvider* theme = profile->GetThemeProvider(); - if (browser_view_->IsActive()) { - background = theme->GetBitmapNamed( - profile->IsOffTheRecord() ? - IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME); - } else { - background = theme->GetBitmapNamed( - profile->IsOffTheRecord() ? - IDR_THEME_FRAME_INCOGNITO_INACTIVE : IDR_THEME_FRAME_INACTIVE); - } - } - - gfx::Point origin(0, 0); - views::View::ConvertPointToView(view, - browser_view_->frame()->GetFrameView(), - &origin); -#if defined(OS_CHROMEOS) - const int kCustomFrameBackgroundVerticalOffset = 15; - // TODO(oshima): Remove this once we fully migrated to views. - // See http://crbug.com/28580. - if (browser_view_->IsMaximized()) { - origin.Offset(0, kCustomFrameBackgroundVerticalOffset + 1); - } -#endif - canvas->TileImageInt(*background, - origin.x(), origin.y(), 0, 0, - view->width(), view->height()); -} diff --git a/chrome/browser/views/theme_background.h b/chrome/browser/views/theme_background.h index b904a71..98ce8f6 100644 --- a/chrome/browser/views/theme_background.h +++ b/chrome/browser/views/theme_background.h @@ -6,36 +6,8 @@ #define CHROME_BROWSER_VIEWS_THEME_BACKGROUND_H_ #pragma once -#include "views/background.h" - -class BrowserView; - -namespace views { -class View; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// ThemeBackground class. -// -// A ThemeBackground is used to paint the background theme image in a -// view in such a way that it's consistent with the frame's theme -// image. It takes care of active/inactive state, incognito state and -// the offset from the frame view. -// -//////////////////////////////////////////////////////////////////////////////// -class ThemeBackground : public views::Background { - public: - explicit ThemeBackground(BrowserView* browser); - virtual ~ThemeBackground() {} - - // Overridden from views:;Background. - virtual void Paint(gfx::Canvas* canvas, views::View* view) const; - - private: - BrowserView* browser_view_; - - DISALLOW_COPY_AND_ASSIGN(ThemeBackground); -}; +#include "chrome/browser/ui/views/theme_background.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_THEME_BACKGROUND_H_ + diff --git a/chrome/browser/views/theme_helpers.cc b/chrome/browser/views/theme_helpers.cc deleted file mode 100644 index 41f6db5..0000000 --- a/chrome/browser/views/theme_helpers.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2006-2008 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/theme_helpers.h" - -#include <atlbase.h> -#include <atlapp.h> -#include <atltheme.h> - -#include "base/logging.h" -#include "gfx/canvas_skia.h" -#include "skia/ext/bitmap_platform_device_win.h" -#include "third_party/skia/include/effects/SkGradientShader.h" - -void GetRebarGradientColors(int width, int x1, int x2, - SkColor* c1, SkColor* c2) { - DCHECK(c1 && c2) << - "ThemeHelpers::GetRebarGradientColors - c1 or c2 is NULL!"; - - // To get the colors we need, we draw a horizontal gradient using - // DrawThemeBackground, then extract the pixel values from and return - // those so calling code can use them to create gradient brushes for use in - // rendering in other directions. - - gfx::CanvasSkia canvas(width, 1, true); - - // Render the Rebar gradient into the DIB - CTheme theme; - if (theme.IsThemingSupported()) - theme.OpenThemeData(NULL, L"REBAR"); - // On Windows XP+, if using a Theme, we can ask the theme to render the - // gradient for us. - if (!theme.IsThemeNull()) { - HDC dc = canvas.beginPlatformPaint(); - RECT rect = { 0, 0, width, 1 }; - theme.DrawThemeBackground(dc, 0, 0, &rect, NULL); - canvas.endPlatformPaint(); - } else { - // On Windows 2000 or Windows XP+ with the Classic theme selected, we need - // to build our own gradient using system colors. - SkColor grad_colors[2]; - COLORREF hl_ref = ::GetSysColor(COLOR_3DHILIGHT); - grad_colors[0] = SkColorSetRGB(GetRValue(hl_ref), GetGValue(hl_ref), - GetBValue(hl_ref)); - COLORREF face_ref = ::GetSysColor(COLOR_3DFACE); - grad_colors[1] = SkColorSetRGB(GetRValue(face_ref), GetGValue(face_ref), - GetBValue(face_ref)); - SkPoint grad_points[2]; - grad_points[0].set(SkIntToScalar(0), SkIntToScalar(0)); - grad_points[1].set(SkIntToScalar(width), SkIntToScalar(0)); - SkShader* gradient_shader = SkGradientShader::CreateLinear( - grad_points, grad_colors, NULL, 2, SkShader::kRepeat_TileMode); - SkPaint paint; - paint.setShader(gradient_shader); - // Shader created with a ref count of 1, release as the paint now owns - // the gradient. - gradient_shader->unref(); - paint.setStyle(SkPaint::kFill_Style); - canvas.drawRectCoords(SkIntToScalar(0), SkIntToScalar(0), - SkIntToScalar(width), SkIntToScalar(1), paint); - } - - // Extract the color values from the selected pixels - // The | in the following operations forces the alpha to 0xFF. This is - // needed as windows sets the alpha to 0 when it renders. - skia::BitmapPlatformDevice& device = - static_cast<skia::BitmapPlatformDevice&>( - canvas.getTopPlatformDevice()); - *c1 = 0xFF000000 | device.getColorAt(x1, 0); - *c2 = 0xFF000000 | device.getColorAt(x2, 0); -} - -void GetDarkLineColor(SkColor* dark_color) { - DCHECK(dark_color) << "ThemeHelpers::DarkColor - dark_color is NULL!"; - - CTheme theme; - if (theme.IsThemingSupported()) - theme.OpenThemeData(NULL, L"REBAR"); - - // Note: the alpha values were chosen scientifically according to what looked - // best to me at the time! --beng - if (!theme.IsThemeNull()) { - *dark_color = SkColorSetARGB(60, 0, 0, 0); - } else { - COLORREF shadow_ref = ::GetSysColor(COLOR_3DSHADOW); - *dark_color = SkColorSetARGB(175, - GetRValue(shadow_ref), - GetGValue(shadow_ref), - GetBValue(shadow_ref)); - } -} diff --git a/chrome/browser/views/theme_helpers.h b/chrome/browser/views/theme_helpers.h index 68ea077..b7bd4f2 100644 --- a/chrome/browser/views/theme_helpers.h +++ b/chrome/browser/views/theme_helpers.h @@ -1,30 +1,13 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. -#ifndef CHROME_BROWSER_VIEWS_THEME_HELPERS_H__ -#define CHROME_BROWSER_VIEWS_THEME_HELPERS_H__ +#ifndef CHROME_BROWSER_VIEWS_THEME_HELPERS_H_ +#define CHROME_BROWSER_VIEWS_THEME_HELPERS_H_ #pragma once -#include <windows.h> +#include "chrome/browser/ui/views/theme_helpers.h" +// TODO(beng): remove this file once all includes have been updated. -#include "third_party/skia/include/core/SkColor.h" +#endif // CHROME_BROWSER_VIEWS_THEME_HELPERS_H_ -// Get the colors at two points on a Rebar background gradient. This is for -// drawing Rebar like backgrounds in Views. The reason not to just use -// DrawThemeBackground is that it only draws horizontally, but by extracting -// the colors at two points on the X axis of a background drawn -// by DrawThemeBackground, we can construct a LinearGradientBrush and draw -// such a gradient in any direction. -// -// The width parameter is the width of horizontal gradient that will be -// created to calculate the two colors. x1 and x2 are the two pixel positions -// along the X axis. -void GetRebarGradientColors(int width, int x1, int x2, - SkColor* c1, SkColor* c2); - - -// Gets the color used to draw dark (inset beveled) lines. -void GetDarkLineColor(SkColor* dark_color); - -#endif // CHROME_BROWSER_VIEWS_THEME_HELPERS_H__ diff --git a/chrome/browser/views/theme_install_bubble_view.cc b/chrome/browser/views/theme_install_bubble_view.cc deleted file mode 100644 index 7593fc7..0000000 --- a/chrome/browser/views/theme_install_bubble_view.cc +++ /dev/null @@ -1,165 +0,0 @@ -// 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/theme_install_bubble_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "gfx/canvas_skia.h" -#include "grit/generated_resources.h" -#include "views/widget/widget.h" - -namespace { - -// The roundedness of the edges of our bubble. -static const int kBubbleCornerRadius = 4; - -// Padding around text in popup box. -static const int kTextHorizPadding = 90; -static const int kTextVertPadding = 45; - -// Multiple loads can be started at once. Only show one bubble, and keep -// track of number of loads happening. Close bubble when num_loads < 1. -static int num_loads_extant_ = 0; - -} - -ThemeInstallBubbleView::ThemeInstallBubbleView(TabContents* tab_contents) - : popup_(NULL) { - if (!tab_contents) - Close(); - - text_ = l10n_util::GetString(IDS_THEME_LOADING_TITLE); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - gfx::Font font(rb.GetFont(ResourceBundle::LargeFont)); - SetFont(font); - - // We can't check for the size of tab_contents before we've generated - // the string and the font that determine the size of the bubble. - tab_contents->GetContainerBounds(&tab_contents_bounds_); - if (tab_contents_bounds_.height() < GetPreferredSize().height()) - Close(); - - // Close when theme has been installed. - registrar_.Add( - this, - NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources()); - - // Close when we are installing an extension, not a theme. - registrar_.Add( - this, - NotificationType::NO_THEME_DETECTED, - NotificationService::AllSources()); - registrar_.Add( - this, - NotificationType::EXTENSION_INSTALLED, - NotificationService::AllSources()); - registrar_.Add( - this, - NotificationType::EXTENSION_INSTALL_ERROR, - NotificationService::AllSources()); - - // Don't let the bubble overlap the confirm dialog. - registrar_.Add( - this, - NotificationType::EXTENSION_WILL_SHOW_CONFIRM_DIALOG, - NotificationService::AllSources()); - - gfx::Rect rc(0, 0, 0, 0); - popup_ = views::Widget::CreatePopupWidget(views::Widget::Transparent, - views::Widget::NotAcceptEvents, - views::Widget::DeleteOnDestroy, - views::Widget::MirrorOriginInRTL); - popup_->SetOpacity(0xCC); - popup_->Init(tab_contents->GetNativeView(), rc); - popup_->SetContentsView(this); - Reposition(); - popup_->Show(); - - SchedulePaint(); -} - -ThemeInstallBubbleView::~ThemeInstallBubbleView() { - num_loads_extant_ = 0; -} - -gfx::Size ThemeInstallBubbleView::GetPreferredSize() { - return gfx::Size(views::Label::font().GetStringWidth(text_) + - kTextHorizPadding, - ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::LargeFont).GetHeight() + kTextVertPadding); -} - -void ThemeInstallBubbleView::Reposition() { - if (!popup_) - Close(); - - gfx::Size size = GetPreferredSize(); - int mid_x = tab_contents_bounds_.x() + - (tab_contents_bounds_.right() - tab_contents_bounds_.x()) / 2; - - int x = base::i18n::IsRTL() ? - mid_x + size.width() / 2 : mid_x - size.width() / 2; - int y = static_cast<int>(tab_contents_bounds_.y() + - (tab_contents_bounds_.bottom() - tab_contents_bounds_.y()) / 2 - - size.height() / 2); - - popup_->SetBounds(gfx::Rect(x, y, size.width(), size.height())); -} - -void ThemeInstallBubbleView::Paint(gfx::Canvas* canvas) { - SkScalar rad[8]; - for (int i = 0; i < 8; ++i) - rad[i] = SkIntToScalar(kBubbleCornerRadius); - - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setFlags(SkPaint::kAntiAlias_Flag); - paint.setColor(SK_ColorBLACK); - - SkRect rect; - rect.set(0, 0, - SkIntToScalar(width()), - SkIntToScalar(height())); - SkPath path; - path.addRoundRect(rect, rad, SkPath::kCW_Direction); - canvas->AsCanvasSkia()->drawPath(path, paint); - - int text_width = views::Label::font().GetStringWidth(text_); - gfx::Rect body_bounds(kTextHorizPadding / 2, 0, text_width, height()); - body_bounds.set_x(MirroredLeftPointForRect(body_bounds)); - - SkColor text_color = SK_ColorWHITE; - canvas->DrawStringInt(text_, views::Label::font(), text_color, - body_bounds.x(), body_bounds.y(), body_bounds.width(), - body_bounds.height()); -} - -void ThemeInstallBubbleView::Close() { - --num_loads_extant_; - if (!popup_) { - num_loads_extant_ = 0; - return; - } - if (num_loads_extant_ < 1) { - registrar_.RemoveAll(); - popup_->Close(); - } -} - -void ThemeInstallBubbleView::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - Close(); -} - -// static -void ThemeInstallBubbleView::Show(TabContents* tab_contents) { - ++num_loads_extant_; - if (num_loads_extant_ < 2) - new ThemeInstallBubbleView(tab_contents); -} - diff --git a/chrome/browser/views/theme_install_bubble_view.h b/chrome/browser/views/theme_install_bubble_view.h index dfe9dc4..b0eddec 100644 --- a/chrome/browser/views/theme_install_bubble_view.h +++ b/chrome/browser/views/theme_install_bubble_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -6,74 +6,8 @@ #define CHROME_BROWSER_VIEWS_THEME_INSTALL_BUBBLE_VIEW_H_ #pragma once -#include <string> - -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "gfx/canvas.h" -#include "views/controls/label.h" - -class TabContents; - -namespace views { -class Widget; -} - -// ThemeInstallBubbleView is a view that provides a "Loading..." bubble in the -// center of a browser window for use when an extension or theme is loaded. -// (The Browser class only calls it to install itself into the currently active -// browser window.) If an extension is being applied, the bubble goes away -// immediately. If a theme is being applied, it disappears when the theme has -// been loaded. The purpose of this bubble is to warn the user that the browser -// may be unresponsive while the theme is being installed. -// -// Edge case: note that if one installs a theme in one window and then switches -// rapidly to another window to install a theme there as well (in the short time -// between install begin and theme caching seizing the UI thread), the loading -// bubble will only appear over the first window, as there is only ever one -// instance of the bubble. -class ThemeInstallBubbleView : public NotificationObserver, - public views::Label { - public: - ~ThemeInstallBubbleView(); - - // NotificationObserver - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Show the loading bubble. - static void Show(TabContents* tab_contents); - - private: - explicit ThemeInstallBubbleView(TabContents* tab_contents); - - // Put the popup in the correct place on the tab. - void Reposition(); - - // Inherited from views. - gfx::Size GetPreferredSize(); - - // Shut down the popup and remove our notifications. - void Close(); - - virtual void Paint(gfx::Canvas* canvas); - - // The content area at the start of the animation. - gfx::Rect tab_contents_bounds_; - - // Widget containing us. - views::Widget* popup_; - - // Text to show warning that theme is being installed. - std::wstring text_; - - // A scoped container for notification registries. - NotificationRegistrar registrar_; - - DISALLOW_COPY_AND_ASSIGN(ThemeInstallBubbleView); -}; +#include "chrome/browser/ui/views/theme_install_bubble_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_THEME_INSTALL_BUBBLE_VIEW_H_ diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc deleted file mode 100644 index cc82cdcd..0000000 --- a/chrome/browser/views/toolbar_view.cc +++ /dev/null @@ -1,741 +0,0 @@ -// 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/toolbar_view.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/accessibility/browser_accessibility_state.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/upgrade_detector.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/browser_actions_container.h" -#include "chrome/browser/views/event_utils.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/wrench_menu_model.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/pref_names.h" -#include "gfx/canvas.h" -#include "gfx/canvas_skia.h" -#include "gfx/skbitmap_operations.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/button_dropdown.h" -#include "views/focus/view_storage.h" -#include "views/widget/tooltip_manager.h" -#include "views/window/non_client_view.h" -#include "views/window/window.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/cros/update_library.h" -#include "chrome/browser/chromeos/dom_ui/wrench_menu_ui.h" -#include "views/controls/menu/menu_2.h" -#endif -#include "chrome/browser/views/wrench_menu.h" - -#if defined(OS_WIN) -#include "chrome/browser/enumerate_modules_model_win.h" -#endif - -// The space between items is 4 px in general. -const int ToolbarView::kStandardSpacing = 4; -// The top of the toolbar has an edge we have to skip over in addition to the 4 -// px of spacing. -const int ToolbarView::kVertSpacing = kStandardSpacing + 1; -// The edge graphics have some built-in spacing/shadowing, so we have to adjust -// our spacing to make it still appear to be 4 px. -static const int kEdgeSpacing = ToolbarView::kStandardSpacing - 1; -// The buttons to the left of the omnibox are close together. -static const int kButtonSpacing = 1; - -static const int kStatusBubbleWidth = 480; - -// The length of time to run the upgrade notification animation (the time it -// takes one pulse to run its course and go back to its original brightness). -static const int kPulseDuration = 2000; - -// How long to wait between pulsating the upgrade notifier. -static const int kPulsateEveryMs = 8000; - -static const int kPopupTopSpacingNonGlass = 3; -static const int kPopupBottomSpacingNonGlass = 2; -static const int kPopupBottomSpacingGlass = 1; - -static SkBitmap* kPopupBackgroundEdge = NULL; - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, public: - -ToolbarView::ToolbarView(Browser* browser) - : model_(browser->toolbar_model()), - back_(NULL), - forward_(NULL), - reload_(NULL), - home_(NULL), - location_bar_(NULL), - browser_actions_(NULL), - app_menu_(NULL), - profile_(NULL), - browser_(browser), - profiles_menu_contents_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), - destroyed_flag_(NULL) { - SetID(VIEW_ID_TOOLBAR); - - browser_->command_updater()->AddCommandObserver(IDC_BACK, this); - browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this); - browser_->command_updater()->AddCommandObserver(IDC_HOME, this); - - display_mode_ = browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ? - DISPLAYMODE_NORMAL : DISPLAYMODE_LOCATION; - - if (!kPopupBackgroundEdge) { - kPopupBackgroundEdge = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_LOCATIONBG_POPUPMODE_EDGE); - } - - if (!IsUpgradeRecommended()) { - registrar_.Add(this, NotificationType::UPGRADE_RECOMMENDED, - NotificationService::AllSources()); - } - registrar_.Add(this, NotificationType::MODULE_INCOMPATIBILITY_DETECTED, - NotificationService::AllSources()); -} - -ToolbarView::~ToolbarView() { - if (destroyed_flag_) - *destroyed_flag_ = true; - - // NOTE: Don't remove the command observers here. This object gets destroyed - // after the Browser (which owns the CommandUpdater), so the CommandUpdater is - // already gone. -} - -void ToolbarView::Init(Profile* profile) { - back_menu_model_.reset(new BackForwardMenuModel( - browser_, BackForwardMenuModel::BACKWARD_MENU)); - forward_menu_model_.reset(new BackForwardMenuModel( - browser_, BackForwardMenuModel::FORWARD_MENU)); - wrench_menu_model_.reset(new WrenchMenuModel(this, browser_)); -#if defined(OS_CHROMEOS) - if (chromeos::MenuUI::IsEnabled()) { - wrench_menu_2_.reset( - chromeos::WrenchMenuUI::CreateMenu2(wrench_menu_model_.get())); - } -#endif - back_ = new views::ButtonDropDown(this, back_menu_model_.get()); - back_->set_triggerable_event_flags(views::Event::EF_LEFT_BUTTON_DOWN | - views::Event::EF_MIDDLE_BUTTON_DOWN); - back_->set_tag(IDC_BACK); - back_->SetImageAlignment(views::ImageButton::ALIGN_RIGHT, - views::ImageButton::ALIGN_TOP); - back_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_BACK)); - back_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_BACK)); - back_->SetID(VIEW_ID_BACK_BUTTON); - - forward_ = new views::ButtonDropDown(this, forward_menu_model_.get()); - forward_->set_triggerable_event_flags(views::Event::EF_LEFT_BUTTON_DOWN | - views::Event::EF_MIDDLE_BUTTON_DOWN); - forward_->set_tag(IDC_FORWARD); - forward_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_FORWARD)); - forward_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_FORWARD)); - forward_->SetID(VIEW_ID_FORWARD_BUTTON); - - // Have to create this before |reload_| as |reload_|'s constructor needs it. - location_bar_ = new LocationBarView(profile, browser_->command_updater(), - model_, this, (display_mode_ == DISPLAYMODE_LOCATION) ? - LocationBarView::POPUP : LocationBarView::NORMAL); - - reload_ = new ReloadButton(location_bar_, browser_); - reload_->set_triggerable_event_flags(views::Event::EF_LEFT_BUTTON_DOWN | - views::Event::EF_MIDDLE_BUTTON_DOWN); - reload_->set_tag(IDC_RELOAD); - reload_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_RELOAD)); - reload_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_RELOAD)); - reload_->SetID(VIEW_ID_RELOAD_BUTTON); - - home_ = new views::ImageButton(this); - home_->set_triggerable_event_flags(views::Event::EF_LEFT_BUTTON_DOWN | - views::Event::EF_MIDDLE_BUTTON_DOWN); - home_->set_tag(IDC_HOME); - home_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_HOME)); - home_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_HOME)); - home_->SetID(VIEW_ID_HOME_BUTTON); - - browser_actions_ = new BrowserActionsContainer(browser_, this); - - app_menu_ = new views::MenuButton(NULL, std::wstring(), this, false); - app_menu_->set_border(NULL); - app_menu_->EnableCanvasFlippingForRTLUI(true); - app_menu_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_APP)); - app_menu_->SetTooltipText(l10n_util::GetStringF(IDS_APPMENU_TOOLTIP, - l10n_util::GetString(IDS_PRODUCT_NAME))); - app_menu_->SetID(VIEW_ID_APP_MENU); - - // Catch the case where the window is created after we detect a new version. - if (IsUpgradeRecommended() || ShouldShowIncompatibilityWarning()) - ShowNotificationDot(); - - LoadImages(); - - // Always add children in order from left to right, for accessibility. - AddChildView(back_); - AddChildView(forward_); - AddChildView(reload_); - AddChildView(home_); - AddChildView(location_bar_); - AddChildView(browser_actions_); - AddChildView(app_menu_); - - location_bar_->Init(); - show_home_button_.Init(prefs::kShowHomeButton, profile->GetPrefs(), this); - browser_actions_->Init(); - - SetProfile(profile); - - // Accessibility specific tooltip text. - if (Singleton<BrowserAccessibilityState>()->IsAccessibleBrowser()) { - back_->SetTooltipText(l10n_util::GetString(IDS_ACCNAME_TOOLTIP_BACK)); - forward_->SetTooltipText(l10n_util::GetString(IDS_ACCNAME_TOOLTIP_FORWARD)); - } -} - -void ToolbarView::SetProfile(Profile* profile) { - if (profile != profile_) { - profile_ = profile; - location_bar_->SetProfile(profile); - } -} - -void ToolbarView::Update(TabContents* tab, bool should_restore_state) { - if (location_bar_) - location_bar_->Update(should_restore_state ? tab : NULL); - - if (browser_actions_) - browser_actions_->RefreshBrowserActionViews(); -} - -void ToolbarView::SetPaneFocusAndFocusLocationBar(int view_storage_id) { - SetPaneFocus(view_storage_id, location_bar_); -} - -void ToolbarView::SetPaneFocusAndFocusAppMenu(int view_storage_id) { - SetPaneFocus(view_storage_id, app_menu_); -} - -bool ToolbarView::IsAppMenuFocused() { - return app_menu_->HasFocus(); -} - -void ToolbarView::AddMenuListener(views::MenuListener* listener) { -#if defined(OS_CHROMEOS) - if (chromeos::MenuUI::IsEnabled()) { - DCHECK(wrench_menu_2_.get()); - wrench_menu_2_->AddMenuListener(listener); - return; - } -#endif - menu_listeners_.push_back(listener); -} - -void ToolbarView::RemoveMenuListener(views::MenuListener* listener) { -#if defined(OS_CHROMEOS) - if (chromeos::MenuUI::IsEnabled()) { - DCHECK(wrench_menu_2_.get()); - wrench_menu_2_->RemoveMenuListener(listener); - return; - } -#endif - for (std::vector<views::MenuListener*>::iterator i(menu_listeners_.begin()); - i != menu_listeners_.end(); ++i) { - if (*i == listener) { - menu_listeners_.erase(i); - return; - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, AccessiblePaneView overrides: - -bool ToolbarView::SetPaneFocus( - int view_storage_id, views::View* initial_focus) { - if (!AccessiblePaneView::SetPaneFocus(view_storage_id, initial_focus)) - return false; - - location_bar_->SetShowFocusRect(true); - return true; -} - -AccessibilityTypes::Role ToolbarView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_TOOLBAR; -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, Menu::BaseControllerDelegate overrides: - -bool ToolbarView::GetAcceleratorInfo(int id, menus::Accelerator* accel) { - return GetWidget()->GetAccelerator(id, accel); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, views::MenuDelegate implementation: - -void ToolbarView::RunMenu(views::View* source, const gfx::Point& /* pt */) { - DCHECK_EQ(VIEW_ID_APP_MENU, source->GetID()); - - bool destroyed_flag = false; - destroyed_flag_ = &destroyed_flag; -#if defined(OS_CHROMEOS) - if (chromeos::MenuUI::IsEnabled()) { - gfx::Point screen_loc; - views::View::ConvertPointToScreen(app_menu_, &screen_loc); - gfx::Rect bounds(screen_loc, app_menu_->size()); - if (base::i18n::IsRTL()) - bounds.set_x(bounds.x() - app_menu_->size().width()); - wrench_menu_2_->RunMenuAt(gfx::Point(bounds.right(), bounds.bottom()), - views::Menu2::ALIGN_TOPRIGHT); - // TODO(oshima): nuke this once we made decision about go or no go - // for domui menu. - goto cleanup; - } -#endif - wrench_menu_ = new WrenchMenu(browser_); - wrench_menu_->Init(wrench_menu_model_.get()); - - for (size_t i = 0; i < menu_listeners_.size(); ++i) - menu_listeners_[i]->OnMenuOpened(); - - wrench_menu_->RunMenu(app_menu_); - -#if defined(OS_CHROMEOS) -cleanup: -#endif - if (destroyed_flag) - return; - destroyed_flag_ = NULL; - - // Stop pulsating the notification dot on the app menu (if active). - notification_dot_pulse_timer_.Stop(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, LocationBarView::Delegate implementation: - -TabContents* ToolbarView::GetTabContents() { - return browser_->GetSelectedTabContents(); -} - -InstantController* ToolbarView::GetInstant() { - return browser_->instant(); -} - -void ToolbarView::OnInputInProgress(bool in_progress) { - // The edit should make sure we're only notified when something changes. - DCHECK(model_->input_in_progress() != in_progress); - - model_->set_input_in_progress(in_progress); - location_bar_->Update(NULL); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, AnimationDelegate implementation: - -void ToolbarView::AnimationProgressed(const Animation* animation) { - app_menu_->SetIcon(GetAppMenuIcon(views::CustomButton::BS_NORMAL)); - app_menu_->SetHoverIcon(GetAppMenuIcon(views::CustomButton::BS_HOT)); - app_menu_->SetPushedIcon(GetAppMenuIcon(views::CustomButton::BS_PUSHED)); - SchedulePaint(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, CommandUpdater::CommandObserver implementation: - -void ToolbarView::EnabledStateChangedForCommand(int id, bool enabled) { - views::Button* button = NULL; - switch (id) { - case IDC_BACK: - button = back_; - break; - case IDC_FORWARD: - button = forward_; - break; - case IDC_HOME: - button = home_; - break; - } - if (button) - button->SetEnabled(enabled); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, views::Button::ButtonListener implementation: - -void ToolbarView::ButtonPressed(views::Button* sender, - const views::Event& event) { - int command = sender->tag(); - WindowOpenDisposition disposition = - event_utils::DispositionFromEventFlags(sender->mouse_event_flags()); - if ((disposition == CURRENT_TAB) && - ((command == IDC_BACK) || (command == IDC_FORWARD))) { - // Forcibly reset the location bar, since otherwise it won't discard any - // ongoing user edits, since it doesn't realize this is a user-initiated - // action. - location_bar_->Revert(); - } - browser_->ExecuteCommandWithDisposition(command, disposition); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, NotificationObserver implementation: - -void ToolbarView::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::PREF_CHANGED) { - std::string* pref_name = Details<std::string>(details).ptr(); - if (*pref_name == prefs::kShowHomeButton) { - Layout(); - SchedulePaint(); - } - } else if (type == NotificationType::UPGRADE_RECOMMENDED) { - ShowNotificationDot(); - } else if (type == NotificationType::MODULE_INCOMPATIBILITY_DETECTED) { - bool confirmed_bad = *Details<bool>(details).ptr(); - if (confirmed_bad) - ShowNotificationDot(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, menus::AcceleratorProvider implementation: - -bool ToolbarView::GetAcceleratorForCommandId(int command_id, - menus::Accelerator* accelerator) { - // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators - // anywhere so we need to check for them explicitly here. - // TODO(cpu) Bug 1109102. Query WebKit land for the actual bindings. - switch (command_id) { - case IDC_CUT: - *accelerator = views::Accelerator(app::VKEY_X, false, true, false); - return true; - case IDC_COPY: - *accelerator = views::Accelerator(app::VKEY_C, false, true, false); - return true; - case IDC_PASTE: - *accelerator = views::Accelerator(app::VKEY_V, false, true, false); - return true; - } - // Else, we retrieve the accelerator information from the frame. - return GetWidget()->GetAccelerator(command_id, accelerator); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, views::View overrides: - -gfx::Size ToolbarView::GetPreferredSize() { - if (IsDisplayModeNormal()) { - int min_width = kEdgeSpacing + - back_->GetPreferredSize().width() + kButtonSpacing + - forward_->GetPreferredSize().width() + kButtonSpacing + - reload_->GetPreferredSize().width() + kStandardSpacing + - (show_home_button_.GetValue() ? - (home_->GetPreferredSize().width() + kButtonSpacing) : 0) + - browser_actions_->GetPreferredSize().width() + - app_menu_->GetPreferredSize().width() + kEdgeSpacing; - - static SkBitmap normal_background; - if (normal_background.isNull()) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - normal_background = *rb.GetBitmapNamed(IDR_CONTENT_TOP_CENTER); - } - - return gfx::Size(min_width, normal_background.height()); - } - - int vertical_spacing = PopupTopSpacing() + - (GetWindow()->GetNonClientView()->UseNativeFrame() ? - kPopupBottomSpacingGlass : kPopupBottomSpacingNonGlass); - return gfx::Size(0, location_bar_->GetPreferredSize().height() + - vertical_spacing); -} - -void ToolbarView::Layout() { - // If we have not been initialized yet just do nothing. - if (back_ == NULL) - return; - - if (!IsDisplayModeNormal()) { - int edge_width = (browser_->window() && browser_->window()->IsMaximized()) ? - 0 : kPopupBackgroundEdge->width(); // See Paint(). - location_bar_->SetBounds(edge_width, PopupTopSpacing(), - width() - (edge_width * 2), location_bar_->GetPreferredSize().height()); - return; - } - - int child_y = std::min(kVertSpacing, height()); - // We assume all child elements are the same height. - int child_height = - std::min(back_->GetPreferredSize().height(), height() - child_y); - - // If the window is maximized, we extend the back button to the left so that - // clicking on the left-most pixel will activate the back button. - // TODO(abarth): If the window becomes maximized but is not resized, - // then Layout() might not be called and the back button - // will be slightly the wrong size. We should force a - // Layout() in this case. - // http://crbug.com/5540 - int back_width = back_->GetPreferredSize().width(); - if (browser_->window() && browser_->window()->IsMaximized()) - back_->SetBounds(0, child_y, back_width + kEdgeSpacing, child_height); - else - back_->SetBounds(kEdgeSpacing, child_y, back_width, child_height); - - forward_->SetBounds(back_->x() + back_->width() + kButtonSpacing, - child_y, forward_->GetPreferredSize().width(), child_height); - - reload_->SetBounds(forward_->x() + forward_->width() + kButtonSpacing, - child_y, reload_->GetPreferredSize().width(), child_height); - - if (show_home_button_.GetValue()) { - home_->SetVisible(true); - home_->SetBounds(reload_->x() + reload_->width() + kButtonSpacing, child_y, - home_->GetPreferredSize().width(), child_height); - } else { - home_->SetVisible(false); - home_->SetBounds(reload_->x() + reload_->width(), child_y, 0, child_height); - } - - int browser_actions_width = browser_actions_->GetPreferredSize().width(); - int app_menu_width = app_menu_->GetPreferredSize().width(); - int location_x = home_->x() + home_->width() + kStandardSpacing; - int available_width = width() - kEdgeSpacing - app_menu_width - - browser_actions_width - location_x; - - location_bar_->SetBounds(location_x, child_y, std::max(available_width, 0), - child_height); - - browser_actions_->SetBounds(location_bar_->x() + location_bar_->width(), 0, - browser_actions_width, height()); - // The browser actions need to do a layout explicitly, because when an - // extension is loaded/unloaded/changed, BrowserActionContainer removes and - // re-adds everything, regardless of whether it has a page action. For a - // page action, browser action bounds do not change, as a result of which - // SetBounds does not do a layout at all. - // TODO(sidchat): Rework the above behavior so that explicit layout is not - // required. - browser_actions_->Layout(); - - app_menu_->SetBounds(browser_actions_->x() + browser_actions_width, child_y, - app_menu_width, child_height); -} - -void ToolbarView::Paint(gfx::Canvas* canvas) { - View::Paint(canvas); - - if (IsDisplayModeNormal()) - return; - - // In maximized mode, we don't draw the endcaps on the location bar, because - // when they're flush against the edge of the screen they just look glitchy. - if (!browser_->window() || !browser_->window()->IsMaximized()) { - int top_spacing = PopupTopSpacing(); - canvas->DrawBitmapInt(*kPopupBackgroundEdge, 0, top_spacing); - canvas->DrawBitmapInt(*kPopupBackgroundEdge, - width() - kPopupBackgroundEdge->width(), top_spacing); - } - - // For glass, we need to draw a black line below the location bar to separate - // it from the content area. For non-glass, the NonClientView draws the - // toolbar background below the location bar for us. - if (GetWindow()->GetNonClientView()->UseNativeFrame()) - canvas->FillRectInt(SK_ColorBLACK, 0, height() - 1, width(), 1); -} - -void ToolbarView::OnThemeChanged() { - LoadImages(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, protected: - -// Override this so that when the user presses F6 to rotate toolbar panes, -// the location bar gets focus, not the first control in the toolbar. -views::View* ToolbarView::GetDefaultFocusableChild() { - return location_bar_; -} - -void ToolbarView::RemovePaneFocus() { - AccessiblePaneView::RemovePaneFocus(); - location_bar_->SetShowFocusRect(false); -} - -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, private: - -bool ToolbarView::IsUpgradeRecommended() { -#if defined(OS_CHROMEOS) - return (chromeos::CrosLibrary::Get()->GetUpdateLibrary()->status().status == - chromeos::UPDATE_STATUS_UPDATED_NEED_REBOOT); -#else - return (Singleton<UpgradeDetector>::get()->notify_upgrade()); -#endif -} - -bool ToolbarView::ShouldShowIncompatibilityWarning() { -#if defined(OS_WIN) - EnumerateModulesModel* loaded_modules = EnumerateModulesModel::GetSingleton(); - return loaded_modules->confirmed_bad_modules_detected() > 0; -#else - return false; -#endif -} - -int ToolbarView::PopupTopSpacing() const { - return GetWindow()->GetNonClientView()->UseNativeFrame() ? - 0 : kPopupTopSpacingNonGlass; -} - -void ToolbarView::LoadImages() { - ThemeProvider* tp = GetThemeProvider(); - - back_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_BACK)); - back_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_BACK_H)); - back_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_BACK_P)); - back_->SetImage(views::CustomButton::BS_DISABLED, - tp->GetBitmapNamed(IDR_BACK_D)); - - forward_->SetImage(views::CustomButton::BS_NORMAL, - tp->GetBitmapNamed(IDR_FORWARD)); - forward_->SetImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_FORWARD_H)); - forward_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_FORWARD_P)); - forward_->SetImage(views::CustomButton::BS_DISABLED, - tp->GetBitmapNamed(IDR_FORWARD_D)); - - reload_->SetImage(views::CustomButton::BS_NORMAL, - tp->GetBitmapNamed(IDR_RELOAD)); - reload_->SetImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_RELOAD_H)); - reload_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_RELOAD_P)); - reload_->SetToggledImage(views::CustomButton::BS_NORMAL, - tp->GetBitmapNamed(IDR_STOP)); - reload_->SetToggledImage(views::CustomButton::BS_HOT, - tp->GetBitmapNamed(IDR_STOP_H)); - reload_->SetToggledImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_STOP_P)); - reload_->SetToggledImage(views::CustomButton::BS_DISABLED, - tp->GetBitmapNamed(IDR_STOP_D)); - - home_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_HOME)); - home_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_HOME_H)); - home_->SetImage(views::CustomButton::BS_PUSHED, - tp->GetBitmapNamed(IDR_HOME_P)); - - app_menu_->SetIcon(GetAppMenuIcon(views::CustomButton::BS_NORMAL)); - app_menu_->SetHoverIcon(GetAppMenuIcon(views::CustomButton::BS_HOT)); - app_menu_->SetPushedIcon(GetAppMenuIcon(views::CustomButton::BS_PUSHED)); -} - -void ToolbarView::ShowNotificationDot() { - notification_dot_animation_.reset(new SlideAnimation(this)); - notification_dot_animation_->SetSlideDuration(kPulseDuration); - - // Then start the recurring timer for pulsating it. - notification_dot_pulse_timer_.Stop(); - notification_dot_pulse_timer_.Start( - base::TimeDelta::FromMilliseconds(kPulsateEveryMs), - this, &ToolbarView::PulsateNotificationDot); -} - -void ToolbarView::PulsateNotificationDot() { - // Start the pulsating animation. - notification_dot_animation_->Reset(0.0); - notification_dot_animation_->Show(); -} - -SkBitmap ToolbarView::GetAppMenuIcon(views::CustomButton::ButtonState state) { - ThemeProvider* tp = GetThemeProvider(); - - int id = 0; - switch (state) { - case views::CustomButton::BS_NORMAL: id = IDR_TOOLS; break; - case views::CustomButton::BS_HOT: id = IDR_TOOLS_H; break; - case views::CustomButton::BS_PUSHED: id = IDR_TOOLS_P; break; - default: NOTREACHED(); break; - } - SkBitmap icon = *tp->GetBitmapNamed(id); - - bool add_badge = IsUpgradeRecommended() || ShouldShowIncompatibilityWarning(); - if (!add_badge) - return icon; - - // Draw the chrome app menu icon onto the canvas. - scoped_ptr<gfx::CanvasSkia> canvas( - new gfx::CanvasSkia(icon.width(), icon.height(), false)); - canvas->DrawBitmapInt(icon, 0, 0); - - SkBitmap badge; - static bool has_faded_in = false; - if (!has_faded_in) { - SkBitmap* dot = NULL; - if (ShouldShowIncompatibilityWarning()) { -#if defined(OS_WIN) - dot = tp->GetBitmapNamed(IDR_INCOMPATIBILITY_DOT_INACTIVE); -#else - NOTREACHED(); -#endif - } else { - dot = tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE); - } - SkBitmap transparent; - transparent.setConfig(dot->getConfig(), dot->width(), dot->height()); - transparent.allocPixels(); - transparent.eraseARGB(0, 0, 0, 0); - badge = SkBitmapOperations::CreateBlendedBitmap( - *dot, transparent, - 1.0 - notification_dot_animation_->GetCurrentValue()); - if (notification_dot_animation_->GetCurrentValue() == 1.0) - has_faded_in = true; - } else { - // Convert animation values that start from 0.0 and incrementally go - // up to 1.0 into values that start in 0.0, go to 1.0 and then back - // to 0.0 (to create a pulsing effect). - double value = - 1.0 - abs(2.0 * notification_dot_animation_->GetCurrentValue() - 1.0); - - // Add the badge to it. - if (ShouldShowIncompatibilityWarning()) { -#if defined(OS_WIN) - badge = SkBitmapOperations::CreateBlendedBitmap( - *tp->GetBitmapNamed(IDR_INCOMPATIBILITY_DOT_INACTIVE), - *tp->GetBitmapNamed(IDR_INCOMPATIBILITY_DOT_ACTIVE), - value); -#else - NOTREACHED(); -#endif - } else { - badge = SkBitmapOperations::CreateBlendedBitmap( - *tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE), - *tp->GetBitmapNamed(IDR_UPGRADE_DOT_ACTIVE), - value); - } - } - - static const int kBadgeLeftSpacing = 8; - static const int kBadgeTopSpacing = 18; - canvas->DrawBitmapInt(badge, kBadgeLeftSpacing, kBadgeTopSpacing); - - return canvas->ExtractBitmap(); -} diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h index c9b92bd..da47f0f 100644 --- a/chrome/browser/views/toolbar_view.h +++ b/chrome/browser/views/toolbar_view.h @@ -6,231 +6,8 @@ #define CHROME_BROWSER_VIEWS_TOOLBAR_VIEW_H_ #pragma once -#include <vector> - -#include "app/menus/accelerator.h" -#include "app/slide_animation.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/back_forward_menu_model.h" -#include "chrome/browser/command_updater.h" -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/views/accessible_pane_view.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" -#include "chrome/browser/views/reload_button.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/menu/menu.h" -#include "views/controls/menu/menu_wrapper.h" -#include "views/controls/menu/view_menu_delegate.h" -#include "views/view.h" - -class BrowserActionsContainer; -class Browser; -class Profile; -#if defined(OS_CHROMEOS) -namespace views { -class Menu2; -} // namespace views -#endif -class WrenchMenu; - -// The Browser Window's toolbar. -class ToolbarView : public AccessiblePaneView, - public views::ViewMenuDelegate, - public menus::AcceleratorProvider, - public LocationBarView::Delegate, - public AnimationDelegate, - public NotificationObserver, - public CommandUpdater::CommandObserver, - public views::ButtonListener { - public: - explicit ToolbarView(Browser* browser); - virtual ~ToolbarView(); - - // Create the contents of the Browser Toolbar - void Init(Profile* profile); - - // Sets the profile which is active on the currently-active tab. - void SetProfile(Profile* profile); - Profile* profile() { return profile_; } - - // Updates the toolbar (and transitively the location bar) with the states of - // the specified |tab|. If |should_restore_state| is true, we're switching - // (back?) to this tab and should restore any previous location bar state - // (such as user editing) as well. - void Update(TabContents* tab, bool should_restore_state); - - // Set focus to the toolbar with complete keyboard access, with the - // focus initially set to the location bar. Focus will be restored - // to the ViewStorage with id |view_storage_id| if the user escapes. - void SetPaneFocusAndFocusLocationBar(int view_storage_id); - - // Set focus to the toolbar with complete keyboard access, with the - // focus initially set to the app menu. Focus will be restored - // to the ViewStorage with id |view_storage_id| if the user escapes. - void SetPaneFocusAndFocusAppMenu(int view_storage_id); - - // Returns true if the app menu is focused. - bool IsAppMenuFocused(); - - // Add a listener to receive a callback when the menu opens. - void AddMenuListener(views::MenuListener* listener); - - // Remove a menu listener. - void RemoveMenuListener(views::MenuListener* listener); - - // Accessors... - Browser* browser() const { return browser_; } - BrowserActionsContainer* browser_actions() const { return browser_actions_; } - ReloadButton* reload_button() const { return reload_; } - LocationBarView* location_bar() const { return location_bar_; } - views::MenuButton* app_menu() const { return app_menu_; } - - // Overridden from AccessiblePaneView - virtual bool SetPaneFocus(int view_storage_id, View* initial_focus); - virtual AccessibilityTypes::Role GetAccessibleRole(); - - // Overridden from Menu::BaseControllerDelegate: - virtual bool GetAcceleratorInfo(int id, menus::Accelerator* accel); - - // Overridden from views::MenuDelegate: - virtual void RunMenu(views::View* source, const gfx::Point& pt); - - // Overridden from LocationBarView::Delegate: - virtual TabContents* GetTabContents(); - virtual InstantController* GetInstant(); - virtual void OnInputInProgress(bool in_progress); - - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation); - - // Overridden from CommandUpdater::CommandObserver: - virtual void EnabledStateChangedForCommand(int id, bool enabled); - - // Overridden from views::BaseButton::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Overridden from menus::AcceleratorProvider: - virtual bool GetAcceleratorForCommandId(int command_id, - menus::Accelerator* accelerator); - - // Overridden from views::View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual void Paint(gfx::Canvas* canvas); - virtual void OnThemeChanged(); - - // The apparent horizontal space between most items, and the vertical padding - // above and below them. - static const int kStandardSpacing; - // The top of the toolbar has an edge we have to skip over in addition to the - // standard spacing. - static const int kVertSpacing; - - protected: - - // Overridden from AccessiblePaneView - virtual views::View* GetDefaultFocusableChild(); - virtual void RemovePaneFocus(); - - private: - // Returns true if we should show the upgrade recommended dot. - bool IsUpgradeRecommended(); - - // Returns true if we should show the warning for incompatible software. - bool ShouldShowIncompatibilityWarning(); - - // Returns the number of pixels above the location bar in non-normal display. - int PopupTopSpacing() const; - - // Loads the images for all the child views. - void LoadImages(); - - // Types of display mode this toolbar can have. - enum DisplayMode { - DISPLAYMODE_NORMAL, // Normal toolbar with buttons, etc. - DISPLAYMODE_LOCATION // Slimline toolbar showing only compact location - // bar, used for popups. - }; - bool IsDisplayModeNormal() const { - return display_mode_ == DISPLAYMODE_NORMAL; - } - - // Starts the recurring timer that periodically asks the notification dot - // to pulsate. - void ShowNotificationDot(); - - // Show the reminder, tempting the user to take a look. - void PulsateNotificationDot(); - - // Gets a canvas with the icon for the app menu. It will possibly contain - // an overlaid badge if an update is recommended. - SkBitmap GetAppMenuIcon(views::CustomButton::ButtonState state); - - scoped_ptr<BackForwardMenuModel> back_menu_model_; - scoped_ptr<BackForwardMenuModel> forward_menu_model_; - - // The model that contains the security level, text, icon to display... - ToolbarModel* model_; - - // Controls - views::ImageButton* back_; - views::ImageButton* forward_; - ReloadButton* reload_; - views::ImageButton* home_; - LocationBarView* location_bar_; - BrowserActionsContainer* browser_actions_; - views::MenuButton* app_menu_; - Profile* profile_; - Browser* browser_; - - // Contents of the profiles menu to populate with profile names. - scoped_ptr<menus::SimpleMenuModel> profiles_menu_contents_; - - // Controls whether or not a home button should be shown on the toolbar. - BooleanPrefMember show_home_button_; - - // The display mode used when laying out the toolbar. - DisplayMode display_mode_; - - // The contents of the wrench menu. - scoped_ptr<menus::SimpleMenuModel> wrench_menu_model_; - -#if defined(OS_CHROMEOS) - // Wrench menu using domui menu. - // MenuLister is managed by Menu2. - scoped_ptr<views::Menu2> wrench_menu_2_; -#endif - - // Wrench menu. - scoped_refptr<WrenchMenu> wrench_menu_; - - // Vector of listeners to receive callbacks when the menu opens. - std::vector<views::MenuListener*> menu_listeners_; - - // The animation that makes the notification dot pulse. - scoped_ptr<SlideAnimation> notification_dot_animation_; - - // We periodically restart the animation after it has been showed - // once, to create a pulsating effect. - base::RepeatingTimer<ToolbarView> notification_dot_pulse_timer_; - - // Used to post tasks to switch to the next/previous menu. - ScopedRunnableMethodFactory<ToolbarView> method_factory_; - - NotificationRegistrar registrar_; - - // If non-null the destructor sets this to true. This is set to a non-null - // while the menu is showing and used to detect if the menu was deleted while - // running. - bool* destroyed_flag_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ToolbarView); -}; +#include "chrome/browser/ui/views/toolbar_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_TOOLBAR_VIEW_H_ + diff --git a/chrome/browser/views/unhandled_keyboard_event_handler.cc b/chrome/browser/views/unhandled_keyboard_event_handler.cc deleted file mode 100644 index 9da60ee2..0000000 --- a/chrome/browser/views/unhandled_keyboard_event_handler.cc +++ /dev/null @@ -1,75 +0,0 @@ -// 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/unhandled_keyboard_event_handler.h" - -#include "base/logging.h" -#include "views/focus/focus_manager.h" - -UnhandledKeyboardEventHandler::UnhandledKeyboardEventHandler() { -#if defined(OS_WIN) - ignore_next_char_event_ = false; -#endif -} - -UnhandledKeyboardEventHandler::~UnhandledKeyboardEventHandler() { -} - -void UnhandledKeyboardEventHandler::HandleKeyboardEvent( - const NativeWebKeyboardEvent& event, - views::FocusManager* focus_manager) { - if (!focus_manager) { - NOTREACHED(); - return; - } -#if defined(OS_WIN) - // Previous calls to TranslateMessage can generate Char events as well as - // RawKeyDown events, even if the latter triggered an accelerator. In these - // cases, we discard the Char events. - if (event.type == WebKit::WebInputEvent::Char && ignore_next_char_event_) { - ignore_next_char_event_ = false; - return; - } - // It's necessary to reset this flag, because a RawKeyDown event may not - // always generate a Char event. - ignore_next_char_event_ = false; -#endif - - if (event.type == WebKit::WebInputEvent::RawKeyDown) { - views::Accelerator accelerator( - static_cast<app::KeyboardCode>(event.windowsKeyCode), - (event.modifiers & NativeWebKeyboardEvent::ShiftKey) == - NativeWebKeyboardEvent::ShiftKey, - (event.modifiers & NativeWebKeyboardEvent::ControlKey) == - NativeWebKeyboardEvent::ControlKey, - (event.modifiers & NativeWebKeyboardEvent::AltKey) == - NativeWebKeyboardEvent::AltKey); - -#if defined(OS_WIN) - // This is tricky: we want to set ignore_next_char_event_ if - // ProcessAccelerator returns true. But ProcessAccelerator might delete - // |this| if the accelerator is a "close tab" one. So we speculatively - // set the flag and fix it if no event was handled. - ignore_next_char_event_ = true; -#endif - - if (focus_manager->ProcessAccelerator(accelerator)) { - return; - } - -#if defined(OS_WIN) - // ProcessAccelerator didn't handle the accelerator, so we know both - // that |this| is still valid, and that we didn't want to set the flag. - ignore_next_char_event_ = false; -#endif - } - -#if defined(OS_WIN) - // Any unhandled keyboard/character messages should be defproced. - // This allows stuff like F10, etc to work correctly. - DefWindowProc(event.os_event.hwnd, event.os_event.message, - event.os_event.wParam, event.os_event.lParam); -#endif -} - diff --git a/chrome/browser/views/unhandled_keyboard_event_handler.h b/chrome/browser/views/unhandled_keyboard_event_handler.h index 13ac26d..a007663 100644 --- a/chrome/browser/views/unhandled_keyboard_event_handler.h +++ b/chrome/browser/views/unhandled_keyboard_event_handler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// 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. @@ -6,35 +6,8 @@ #define CHROME_BROWSER_VIEWS_UNHANDLED_KEYBOARD_EVENT_HANDLER_H_ #pragma once -#include "views/view.h" -#include "chrome/common/native_web_keyboard_event.h" - -namespace views { -class FocusManager; -} // namespace views - -// This class handles unhandled keyboard messages coming back from the renderer -// process. -class UnhandledKeyboardEventHandler { - public: - UnhandledKeyboardEventHandler(); - ~UnhandledKeyboardEventHandler(); - - void HandleKeyboardEvent(const NativeWebKeyboardEvent& event, - views::FocusManager* focus_manager); - - private: -#if defined(OS_WIN) - // Whether to ignore the next Char keyboard event. - // If a RawKeyDown event was handled as a shortcut key, then we're done - // handling it and should eat any Char event that the translate phase may - // have produced from it. (Handling this event may cause undesirable effects, - // such as a beep if DefWindowProc() has no default handling for the given - // Char.) - bool ignore_next_char_event_; -#endif - - DISALLOW_COPY_AND_ASSIGN(UnhandledKeyboardEventHandler); -}; +#include "chrome/browser/ui/views/unhandled_keyboard_event_handler.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_UNHANDLED_KEYBOARD_EVENT_HANDLER_H_ + diff --git a/chrome/browser/views/uninstall_view.cc b/chrome/browser/views/uninstall_view.cc deleted file mode 100644 index a7535b0..0000000 --- a/chrome/browser/views/uninstall_view.cc +++ /dev/null @@ -1,152 +0,0 @@ -// 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/uninstall_view.h" - -#include "app/l10n_util.h" -#include "base/message_loop.h" -#include "base/process_util.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/shell_integration.h" -#include "chrome/common/result_codes.h" -#include "chrome/installer/util/browser_distribution.h" -#include "chrome/installer/util/shell_util.h" -#include "views/controls/button/checkbox.h" -#include "views/controls/label.h" -#include "views/standard_layout.h" - -#include "grit/chromium_strings.h" - -UninstallView::UninstallView(int& user_selection) - : confirm_label_(NULL), - delete_profile_(NULL), - change_default_browser_(NULL), - browsers_combo_(NULL), - browsers_(NULL), - user_selection_(user_selection) { - SetupControls(); -} - -UninstallView::~UninstallView() { - // Exit the message loop we were started with so that uninstall can continue. - MessageLoop::current()->Quit(); -} - -void UninstallView::SetupControls() { - using views::ColumnSet; - using views::GridLayout; - - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - // Message to confirm uninstallation. - int column_set_id = 0; - ColumnSet* column_set = layout->AddColumnSet(column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, column_set_id); - confirm_label_ = new views::Label(l10n_util::GetString(IDS_UNINSTALL_VERIFY)); - confirm_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->AddView(confirm_label_); - - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - // The "delete profile" check box. - ++column_set_id; - column_set = layout->AddColumnSet(column_set_id); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, column_set_id); - delete_profile_ = new views::Checkbox( - l10n_util::GetString(IDS_UNINSTALL_DELETE_PROFILE)); - layout->AddView(delete_profile_); - - // Set default browser combo box - if (BrowserDistribution::GetDistribution()->CanSetAsDefault() && - ShellIntegration::IsDefaultBrowser()) { - browsers_.reset(new BrowsersMap()); - ShellUtil::GetRegisteredBrowsers(browsers_.get()); - if (!browsers_->empty()) { - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - ++column_set_id; - column_set = layout->AddColumnSet(column_set_id); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, column_set_id); - change_default_browser_ = new views::Checkbox( - l10n_util::GetString(IDS_UNINSTALL_SET_DEFAULT_BROWSER)); - change_default_browser_->set_listener(this); - layout->AddView(change_default_browser_); - browsers_combo_ = new views::Combobox(this); - layout->AddView(browsers_combo_); - browsers_combo_->SetEnabled(false); - } - } - - layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); -} - -bool UninstallView::Accept() { - user_selection_ = ResultCodes::NORMAL_EXIT; - if (delete_profile_->checked()) - user_selection_ = ResultCodes::UNINSTALL_DELETE_PROFILE; - if (change_default_browser_ && change_default_browser_->checked()) { - int index = browsers_combo_->selected_item(); - BrowsersMap::const_iterator it = browsers_->begin(); - std::advance(it, index); - base::LaunchApp((*it).second, false, true, NULL); - } - return true; -} - -bool UninstallView::Cancel() { - user_selection_ = ResultCodes::UNINSTALL_USER_CANCEL; - return true; -} - -std::wstring UninstallView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - // We only want to give custom name to OK button - 'Uninstall'. Cancel - // button remains same. - std::wstring label = L""; - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - label = l10n_util::GetString(IDS_UNINSTALL_BUTTON_TEXT); - return label; -} - -void UninstallView::ButtonPressed( - views::Button* sender, const views::Event& event) { - if (change_default_browser_ == sender) { - // Disable the browsers combobox if the user unchecks the checkbox. - DCHECK(browsers_combo_); - browsers_combo_->SetEnabled(change_default_browser_->checked()); - } -} - -std::wstring UninstallView::GetWindowTitle() const { - return l10n_util::GetString(IDS_UNINSTALL_CHROME); -} - -views::View* UninstallView::GetContentsView() { - return this; -} - -int UninstallView::GetItemCount() { - DCHECK(!browsers_->empty()); - return browsers_->size(); -} - -string16 UninstallView::GetItemAt(int index) { - DCHECK(index < (int) browsers_->size()); - BrowsersMap::const_iterator it = browsers_->begin(); - std::advance(it, index); - return WideToUTF16Hack((*it).first); -} diff --git a/chrome/browser/views/uninstall_view.h b/chrome/browser/views/uninstall_view.h index 30a6268..e366791 100644 --- a/chrome/browser/views/uninstall_view.h +++ b/chrome/browser/views/uninstall_view.h @@ -6,57 +6,8 @@ #define CHROME_BROWSER_VIEWS_UNINSTALL_VIEW_H_ #pragma once -#include "app/combobox_model.h" -#include "base/string16.h" -#include "views/controls/combobox/combobox.h" -#include "views/window/dialog_delegate.h" - -namespace views { -class Checkbox; -class Label; -} - -// UninstallView implements the dialog that confirms Chrome uninstallation -// and asks whether to delete Chrome profile. Also if currently Chrome is set -// as default browser, it asks users whether to set another browser as default. -class UninstallView : public views::View, - public views::ButtonListener, - public views::DialogDelegate, - public ComboboxModel { - public: - explicit UninstallView(int& user_selection); - virtual ~UninstallView(); - - // Overridden from views::DialogDelegate: - virtual bool Accept(); - virtual bool Cancel(); - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - - // Overridden form views::ButtonListener. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // Overridden from views::WindowDelegate: - virtual std::wstring GetWindowTitle() const; - virtual views::View* GetContentsView(); - - // Overridden from views::Combobox::Model. - virtual int GetItemCount(); - virtual string16 GetItemAt(int index); - - private: - // Initializes the controls on the dialog. - void SetupControls(); - - views::Label* confirm_label_; - views::Checkbox* delete_profile_; - views::Checkbox* change_default_browser_; - views::Combobox* browsers_combo_; - typedef std::map<std::wstring, std::wstring> BrowsersMap; - scoped_ptr<BrowsersMap> browsers_; - int& user_selection_; - - DISALLOW_COPY_AND_ASSIGN(UninstallView); -}; +#include "chrome/browser/ui/views/uninstall_view.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_UNINSTALL_VIEW_H_ + diff --git a/chrome/browser/views/update_recommended_message_box.cc b/chrome/browser/views/update_recommended_message_box.cc deleted file mode 100644 index baf69ab..0000000 --- a/chrome/browser/views/update_recommended_message_box.cc +++ /dev/null @@ -1,99 +0,0 @@ -// 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/update_recommended_message_box.h" - -#include "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/views/window.h" -#include "chrome/common/pref_names.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" -#include "views/window/window.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/cros/power_library.h" -#endif - -//////////////////////////////////////////////////////////////////////////////// -// UpdateRecommendedMessageBox, public: - -// static -void UpdateRecommendedMessageBox::ShowMessageBox( - gfx::NativeWindow parent_window) { - // When the window closes, it will delete itself. - new UpdateRecommendedMessageBox(parent_window); -} - -bool UpdateRecommendedMessageBox::Accept() { - // Set the flag to restore the last session on shutdown. - PrefService* pref_service = g_browser_process->local_state(); - pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true); - -#if defined(OS_CHROMEOS) - chromeos::CrosLibrary::Get()->GetPowerLibrary()->RequestRestart(); - // If running the Chrome OS build, but we're not on the device, fall through -#endif - BrowserList::CloseAllBrowsersAndExit(); - - return true; -} - -int UpdateRecommendedMessageBox::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_OK | - MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring UpdateRecommendedMessageBox::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - DCHECK(button == MessageBoxFlags::DIALOGBUTTON_OK || - button == MessageBoxFlags::DIALOGBUTTON_CANCEL); - return button == MessageBoxFlags::DIALOGBUTTON_OK ? - l10n_util::GetString(IDS_RESTART_AND_UPDATE) : - l10n_util::GetString(IDS_NOT_NOW); -} - -std::wstring UpdateRecommendedMessageBox::GetWindowTitle() const { - return l10n_util::GetString(IDS_PRODUCT_NAME); -} - -void UpdateRecommendedMessageBox::DeleteDelegate() { - delete this; -} - -bool UpdateRecommendedMessageBox::IsModal() const { - return true; -} - -views::View* UpdateRecommendedMessageBox::GetContentsView() { - return message_box_view_; -} - -//////////////////////////////////////////////////////////////////////////////// -// UpdateRecommendedMessageBox, private: - -UpdateRecommendedMessageBox::UpdateRecommendedMessageBox( - gfx::NativeWindow parent_window) { - const int kDialogWidth = 400; -#if defined(OS_CHROMEOS) - const std::wstring product_name = l10n_util::GetString(IDS_PRODUCT_OS_NAME); -#else - const std::wstring product_name = l10n_util::GetString(IDS_PRODUCT_NAME); -#endif - // Also deleted when the window closes. - message_box_view_ = new MessageBoxView( - MessageBoxFlags::kFlagHasMessage | MessageBoxFlags::kFlagHasOKButton, - l10n_util::GetStringF(IDS_UPDATE_RECOMMENDED, product_name), - std::wstring(), - kDialogWidth); - browser::CreateViewsWindow(parent_window, gfx::Rect(), this)->Show(); -} - -UpdateRecommendedMessageBox::~UpdateRecommendedMessageBox() { -} diff --git a/chrome/browser/views/update_recommended_message_box.h b/chrome/browser/views/update_recommended_message_box.h index 033dc01..a5f589e 100644 --- a/chrome/browser/views/update_recommended_message_box.h +++ b/chrome/browser/views/update_recommended_message_box.h @@ -2,45 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VIEWS_UPDATE_RECOMMENDED_MESSAGE_BOX_H_ -#define CHROME_BROWSER_VIEWS_UPDATE_RECOMMENDED_MESSAGE_BOX_H_ +#ifndef CHROME_BROWSER_UPDATE_RECOMMENDED_MESSAGE_BOX_H_ +#define CHROME_BROWSER_UPDATE_RECOMMENDED_MESSAGE_BOX_H_ #pragma once -#include "base/basictypes.h" -#include "gfx/native_widget_types.h" -#include "views/window/dialog_delegate.h" +#include "chrome/browser/ui/views/update_recommended_message_box.h" +// TODO(beng): remove this file once all includes have been updated. -class MessageBoxView; +#endif // CHROME_BROWSER_UPDATE_RECOMMENDED_MESSAGE_BOX_H_ -// A dialog box that tells the user that an update is recommended in order for -// the latest version to be put to use. -class UpdateRecommendedMessageBox : public views::DialogDelegate { - public: - // This box is modal to |parent_window|. - static void ShowMessageBox(gfx::NativeWindow parent_window); - - // Overridden from views::DialogDelegate: - virtual bool Accept(); - - protected: - // Overridden from views::DialogDelegate: - virtual int GetDialogButtons() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual std::wstring GetWindowTitle() const; - - // Overridden from views::WindowDelegate: - virtual void DeleteDelegate(); - virtual bool IsModal() const; - virtual views::View* GetContentsView(); - - private: - explicit UpdateRecommendedMessageBox(gfx::NativeWindow parent_window); - virtual ~UpdateRecommendedMessageBox(); - - MessageBoxView* message_box_view_; - - DISALLOW_COPY_AND_ASSIGN(UpdateRecommendedMessageBox); -}; - -#endif // CHROME_BROWSER_VIEWS_UPDATE_RECOMMENDED_MESSAGE_BOX_H_ diff --git a/chrome/browser/views/url_picker.cc b/chrome/browser/views/url_picker.cc deleted file mode 100644 index 4051e63..0000000 --- a/chrome/browser/views/url_picker.cc +++ /dev/null @@ -1,249 +0,0 @@ -// 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/url_picker.h" - -#include "app/keyboard_codes.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "app/table_model.h" -#include "base/stl_util-inl.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/browser/possible_url_model.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/pref_names.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/base/net_util.h" -#include "views/background.h" -#include "views/controls/label.h" -#include "views/controls/table/table_view.h" -#include "views/controls/textfield/textfield.h" -#include "views/focus/focus_manager.h" -#include "views/grid_layout.h" -#include "views/standard_layout.h" -#include "views/widget/widget.h" - -using views::ColumnSet; -using views::GridLayout; - -// Preferred width of the table. -static const int kTableWidth = 300; - -UrlPickerDelegate::~UrlPickerDelegate() {} - -//////////////////////////////////////////////////////////////////////////////// -// -// UrlPicker implementation -// -//////////////////////////////////////////////////////////////////////////////// -UrlPicker::UrlPicker(UrlPickerDelegate* delegate, - Profile* profile) - : profile_(profile), - delegate_(delegate) { - DCHECK(profile_); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - url_table_model_.reset(new PossibleURLModel()); - - TableColumn col1(IDS_ASI_PAGE_COLUMN, TableColumn::LEFT, -1, - 50); - col1.sortable = true; - TableColumn col2(IDS_ASI_URL_COLUMN, TableColumn::LEFT, -1, - 50); - col2.sortable = true; - std::vector<TableColumn> cols; - cols.push_back(col1); - cols.push_back(col2); - - url_table_ = new views::TableView(url_table_model_.get(), cols, - views::ICON_AND_TEXT, true, true, - true); - url_table_->SetObserver(this); - - // Yummy layout code. - GridLayout* layout = CreatePanelGridLayout(this); - SetLayoutManager(layout); - - const int labels_column_set_id = 0; - const int single_column_view_set_id = 1; - - ColumnSet* column_set = layout->AddColumnSet(labels_column_set_id); - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, - GridLayout::USE_PREF, 0, 0); - - column_set = layout->AddColumnSet(single_column_view_set_id); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::FIXED, kTableWidth, 0); - - layout->StartRow(0, labels_column_set_id); - views::Label* url_label = new views::Label(); - url_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - url_label->SetText(l10n_util::GetString(IDS_ASI_URL)); - layout->AddView(url_label); - - url_field_ = new views::Textfield(); - url_field_->SetController(this); - layout->AddView(url_field_); - - layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); - - layout->StartRow(0, single_column_view_set_id); - views::Label* description_label = new views::Label(); - description_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - description_label->SetText(l10n_util::GetString(IDS_ASI_DESCRIPTION)); - description_label->SetFont( - description_label->font().DeriveFont(0, gfx::Font::BOLD)); - layout->AddView(description_label); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - layout->StartRow(1, single_column_view_set_id); - layout->AddView(url_table_); - - layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - - AddAccelerator(views::Accelerator(app::VKEY_RETURN, false, false, false)); -} - -UrlPicker::~UrlPicker() { - url_table_->SetModel(NULL); -} - -void UrlPicker::Show(HWND parent) { - DCHECK(!window()); - views::Window::CreateChromeWindow(parent, gfx::Rect(), this)->Show(); - url_field_->SelectAll(); - url_field_->RequestFocus(); - url_table_model_->Reload(profile_); -} - -void UrlPicker::Close() { - DCHECK(window()); - window()->Close(); -} - -std::wstring UrlPicker::GetWindowTitle() const { - return l10n_util::GetString(IDS_ASI_ADD_TITLE); -} - -bool UrlPicker::IsModal() const { - return true; -} - -std::wstring UrlPicker::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - return l10n_util::GetString(IDS_ASI_ADD); - return std::wstring(); -} - -void UrlPicker::ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents) { - GetDialogClientView()->UpdateDialogButtons(); -} - -bool UrlPicker::Accept() { - if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) { - if (!GetInputURL().is_valid()) - url_field_->RequestFocus(); - return false; - } - PerformModelChange(); - return true; -} - -int UrlPicker::GetDefaultDialogButton() const { - // Don't set a default button, this view already has an accelerator for the - // enter key. - return MessageBoxFlags::DIALOGBUTTON_NONE; -} - -bool UrlPicker::IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const { - if (button == MessageBoxFlags::DIALOGBUTTON_OK) - return GetInputURL().is_valid(); - return true; -} - -views::View* UrlPicker::GetContentsView() { - return this; -} - -void UrlPicker::PerformModelChange() { - DCHECK(delegate_); - GURL url(GetInputURL()); - delegate_->AddBookmark(this, std::wstring(), url); -} - -gfx::Size UrlPicker::GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_URLPICKER_DIALOG_WIDTH_CHARS, - IDS_URLPICKER_DIALOG_HEIGHT_LINES)); -} - -bool UrlPicker::AcceleratorPressed( - const views::Accelerator& accelerator) { - if (accelerator.GetKeyCode() == VK_ESCAPE) { - window()->Close(); - } else if (accelerator.GetKeyCode() == VK_RETURN) { - views::FocusManager* fm = GetFocusManager(); - if (fm->GetFocusedView() == url_table_) { - // Return on table behaves like a double click. - OnDoubleClick(); - } else if (fm->GetFocusedView()== url_field_) { - // Return on the url field accepts the input if url is valid. If the URL - // is invalid, focus is left on the url field. - if (GetInputURL().is_valid()) { - PerformModelChange(); - if (window()) - window()->Close(); - } else { - url_field_->SelectAll(); - } - } - } - return true; -} - -void UrlPicker::OnSelectionChanged() { - int selection = url_table_->FirstSelectedRow(); - if (selection >= 0 && selection < url_table_model_->RowCount()) { - std::string languages = - profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); - // Because this gets parsed by FixupURL(), it's safe to omit the scheme or - // trailing slash, and unescape most characters, but we need to not drop any - // username/password, or unescape anything that changes the meaning. - string16 formatted = net::FormatUrl(url_table_model_->GetURL(selection), - languages, - net::kFormatUrlOmitAll & ~net::kFormatUrlOmitUsernamePassword, - UnescapeRule::SPACES, NULL, NULL, NULL); - url_field_->SetText(UTF16ToWide(formatted)); - GetDialogClientView()->UpdateDialogButtons(); - } -} - -void UrlPicker::OnDoubleClick() { - int selection = url_table_->FirstSelectedRow(); - if (selection >= 0 && selection < url_table_model_->RowCount()) { - OnSelectionChanged(); - PerformModelChange(); - if (window()) - window()->Close(); - } -} - -GURL UrlPicker::GetInputURL() const { - return URLFixerUpper::FixupURL(UTF16ToUTF8(url_field_->text()), - std::string()); -} diff --git a/chrome/browser/views/url_picker.h b/chrome/browser/views/url_picker.h index e08892e..c716ec5 100644 --- a/chrome/browser/views/url_picker.h +++ b/chrome/browser/views/url_picker.h @@ -6,105 +6,8 @@ #define CHROME_BROWSER_VIEWS_URL_PICKER_H_ #pragma once -#include "views/controls/button/native_button.h" -#include "views/controls/table/table_view_observer.h" -#include "views/controls/textfield/textfield.h" -#include "views/view.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -namespace views { -class Button; -class Label; -class TableView; -} - -class PossibleURLModel; -class Profile; -class UrlPicker; - -// UrlPicker delegate. Notified when the user accepts the entry. -class UrlPickerDelegate { - public: - virtual ~UrlPickerDelegate(); - - virtual void AddBookmark(UrlPicker* dialog, - const std::wstring& title, - const GURL& url) = 0; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// This class implements the dialog that let the user add a bookmark or page -// to the list of urls to open on startup. -// UrlPicker deletes itself when the dialog is closed. -// -//////////////////////////////////////////////////////////////////////////////// -class UrlPicker : public views::View, - public views::DialogDelegate, - public views::Textfield::Controller, - public views::TableViewObserver { - public: - UrlPicker(UrlPickerDelegate* delegate, - Profile* profile); - virtual ~UrlPicker(); - - // Show the dialog on the provided contents. - virtual void Show(HWND parent); - - // Closes the dialog. - void Close(); - - // DialogDelegate. - virtual std::wstring GetWindowTitle() const; - virtual bool IsModal() const; - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual bool Accept(); - virtual int GetDefaultDialogButton() const; - virtual bool IsDialogButtonEnabled( - MessageBoxFlags::DialogButton button) const; - virtual views::View* GetContentsView(); - - // TextField::Controller. - virtual void ContentsChanged(views::Textfield* sender, - const std::wstring& new_contents); - virtual bool HandleKeystroke(views::Textfield* sender, - const views::Textfield::Keystroke& key) { - return false; - } - - // Overridden from View. - virtual gfx::Size GetPreferredSize(); - virtual bool AcceleratorPressed(const views::Accelerator& accelerator); - - // TableViewObserver. - virtual void OnSelectionChanged(); - virtual void OnDoubleClick(); - - private: - // Modify the model from the user interface. - void PerformModelChange(); - - // Returns the URL the user has typed. - GURL GetInputURL() const; - - // Profile. - Profile* profile_; - - // URL Field. - views::Textfield* url_field_; - - // The table model. - scoped_ptr<PossibleURLModel> url_table_model_; - - // The table of visited urls. - views::TableView* url_table_; - - // The delegate. - UrlPickerDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(UrlPicker); -}; +#include "chrome/browser/ui/views/url_picker.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_URL_PICKER_H_ + diff --git a/chrome/browser/views/user_data_dir_dialog.cc b/chrome/browser/views/user_data_dir_dialog.cc deleted file mode 100644 index 59a8a8a..0000000 --- a/chrome/browser/views/user_data_dir_dialog.cc +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2006-2008 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 "app/l10n_util.h" -#include "app/message_box_flags.h" -#include "base/logging.h" -#include "chrome/browser/views/user_data_dir_dialog.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" -#include "views/widget/widget.h" -#include "views/window/window.h" - -// static -FilePath UserDataDirDialog::RunUserDataDirDialog( - const FilePath& user_data_dir) { - // When the window closes, it will delete itself. - UserDataDirDialog* dlg = new UserDataDirDialog(user_data_dir); - MessageLoopForUI::current()->Run(dlg); - return dlg->user_data_dir(); -} - -UserDataDirDialog::UserDataDirDialog(const FilePath& user_data_dir) - : ALLOW_THIS_IN_INITIALIZER_LIST( - select_file_dialog_(SelectFileDialog::Create(this))), - is_blocking_(true) { - std::wstring message_text = l10n_util::GetStringF( - IDS_CANT_WRITE_USER_DIRECTORY_SUMMARY, user_data_dir.ToWStringHack()); - const int kDialogWidth = 400; - message_box_view_ = new MessageBoxView(MessageBoxFlags::kIsConfirmMessageBox, - message_text.c_str(), std::wstring(), kDialogWidth); - - views::Window::CreateChromeWindow(NULL, gfx::Rect(), this)->Show(); -} - -UserDataDirDialog::~UserDataDirDialog() { - select_file_dialog_->ListenerDestroyed(); -} - -std::wstring UserDataDirDialog::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString( - IDS_CANT_WRITE_USER_DIRECTORY_CHOOSE_DIRECTORY_BUTTON); - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return l10n_util::GetString(IDS_CANT_WRITE_USER_DIRECTORY_EXIT_BUTTON); - default: - NOTREACHED(); - } - - return std::wstring(); -} - -std::wstring UserDataDirDialog::GetWindowTitle() const { - return l10n_util::GetString(IDS_CANT_WRITE_USER_DIRECTORY_TITLE); -} - -void UserDataDirDialog::DeleteDelegate() { - delete this; -} - -bool UserDataDirDialog::Accept() { - // Directory picker - std::wstring dialog_title = l10n_util::GetString( - IDS_CANT_WRITE_USER_DIRECTORY_CHOOSE_DIRECTORY_BUTTON); - HWND owning_hwnd = - GetAncestor(message_box_view_->GetWidget()->GetNativeView(), GA_ROOT); - select_file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER, - dialog_title, FilePath(), NULL, - 0, std::wstring(), owning_hwnd, NULL); - return false; -} - -bool UserDataDirDialog::Cancel() { - is_blocking_ = false; - return true; -} - -views::View* UserDataDirDialog::GetContentsView() { - return message_box_view_; -} - -bool UserDataDirDialog::Dispatch(const MSG& msg) { - TranslateMessage(&msg); - DispatchMessage(&msg); - return is_blocking_; -} - -void UserDataDirDialog::FileSelected(const FilePath& path, - int index, void* params) { - user_data_dir_ = path; - is_blocking_ = false; -} - -void UserDataDirDialog::FileSelectionCanceled(void* params) { -} diff --git a/chrome/browser/views/user_data_dir_dialog.h b/chrome/browser/views/user_data_dir_dialog.h index 2ada803..3ca925d 100644 --- a/chrome/browser/views/user_data_dir_dialog.h +++ b/chrome/browser/views/user_data_dir_dialog.h @@ -1,72 +1,13 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. -// -// A dialog box that tells the user that we can't write to the specified user -// data directory. Provides the user a chance to pick a different directory. #ifndef CHROME_BROWSER_VIEWS_USER_DATA_DIR_DIALOG_H_ #define CHROME_BROWSER_VIEWS_USER_DATA_DIR_DIALOG_H_ #pragma once -#include "base/basictypes.h" -#include "base/message_loop.h" -#include "chrome/browser/shell_dialogs.h" -#include "views/window/dialog_delegate.h" - -class FilePath; -class MessageBoxView; -namespace views { -class Window; -} - -class UserDataDirDialog : public views::DialogDelegate, - public MessageLoopForUI::Dispatcher, - public SelectFileDialog::Listener { - public: - // Creates and runs a user data directory picker dialog. The method blocks - // while the dialog is showing. If the user picks a directory, this method - // returns the chosen directory. |user_data_dir| is the value of the - // directory we were not able to use. - static FilePath RunUserDataDirDialog(const FilePath& user_data_dir); - virtual ~UserDataDirDialog(); - - FilePath user_data_dir() const { return user_data_dir_; } - - // views::DialogDelegate Methods: - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; - virtual std::wstring GetWindowTitle() const; - virtual void DeleteDelegate(); - virtual bool Accept(); - virtual bool Cancel(); - - // views::WindowDelegate Methods: - virtual bool IsAlwaysOnTop() const { return false; } - virtual bool IsModal() const { return false; } - virtual views::View* GetContentsView(); - - // MessageLoop::Dispatcher Method: - virtual bool Dispatch(const MSG& msg); - - // SelectFileDialog::Listener Methods: - virtual void FileSelected(const FilePath& path, int index, void* params); - virtual void FileSelectionCanceled(void* params); - - private: - explicit UserDataDirDialog(const FilePath& user_data_dir); - - // Empty until the user picks a directory. - FilePath user_data_dir_; - - MessageBoxView* message_box_view_; - scoped_refptr<SelectFileDialog> select_file_dialog_; - - // Used to keep track of whether or not to block the message loop (still - // waiting for the user to dismiss the dialog). - bool is_blocking_; - - DISALLOW_COPY_AND_ASSIGN(UserDataDirDialog); -}; +#include "chrome/browser/ui/views/user_data_dir_dialog.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_USER_DATA_DIR_DIALOG_H_ + diff --git a/chrome/browser/views/window.cc b/chrome/browser/views/window.cc deleted file mode 100644 index ae28ce4..0000000 --- a/chrome/browser/views/window.cc +++ /dev/null @@ -1,29 +0,0 @@ -// 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/window.h" - -#include "gfx/rect.h" -#include "views/window/window.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/frame/bubble_window.h" -#endif // defined(OS_CHROMEOS) - -namespace browser { - -views::Window* CreateViewsWindow(gfx::NativeWindow parent, - const gfx::Rect& bounds, - views::WindowDelegate* delegate) { -#if defined(OS_CHROMEOS) - return chromeos::BubbleWindow::Create(parent, - gfx::Rect(), - chromeos::BubbleWindow::STYLE_GENERIC, - delegate); -#else - return views::Window::CreateChromeWindow(parent, gfx::Rect(), delegate); -#endif -} - -} // namespace browser diff --git a/chrome/browser/views/window.h b/chrome/browser/views/window.h index c2f2bb4..9733676 100644 --- a/chrome/browser/views/window.h +++ b/chrome/browser/views/window.h @@ -6,24 +6,8 @@ #define CHROME_BROWSER_VIEWS_WINDOW_H_ #pragma once -#include "gfx/native_widget_types.h" - -namespace gfx { -class Rect; -} - -namespace views { -class Window; -class WindowDelegate; -} - -namespace browser { - -// Create a window for given |delegate| using default frame view. -views::Window* CreateViewsWindow(gfx::NativeWindow parent, - const gfx::Rect& bounds, - views::WindowDelegate* delegate); - -} // namespace browser +#include "chrome/browser/ui/views/window.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_WINDOW_H_ + diff --git a/chrome/browser/views/wrench_menu.cc b/chrome/browser/views/wrench_menu.cc deleted file mode 100644 index 4ad20f0..0000000 --- a/chrome/browser/views/wrench_menu.cc +++ /dev/null @@ -1,737 +0,0 @@ -// 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/wrench_menu.h" - -#include <cmath> - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" -#include "gfx/canvas.h" -#include "gfx/canvas_skia.h" -#include "gfx/skia_util.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "views/background.h" -#include "views/controls/button/image_button.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/button/text_button.h" -#include "views/controls/label.h" -#include "views/controls/menu/menu_config.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/controls/menu/menu_scroll_view_container.h" -#include "views/controls/menu/submenu_view.h" -#include "views/window/window.h" - -using menus::MenuModel; -using views::CustomButton; -using views::ImageButton; -using views::Label; -using views::MenuConfig; -using views::MenuItemView; -using views::TextButton; -using views::View; - -namespace { - -// Colors used for buttons. -const SkColor kHotBorderColor = SkColorSetARGB(72, 0, 0, 0); -const SkColor kBorderColor = SkColorSetARGB(36, 0, 0, 0); -const SkColor kPushedBorderColor = SkColorSetARGB(72, 0, 0, 0); -const SkColor kHotBackgroundColor = SkColorSetARGB(204, 255, 255, 255); -const SkColor kBackgroundColor = SkColorSetARGB(102, 255, 255, 255); -const SkColor kPushedBackgroundColor = SkColorSetARGB(13, 0, 0, 0); - -// Horizontal padding on the edges of the buttons. -const int kHorizontalPadding = 6; - -// Subclass of ImageButton whose preferred size includes the size of the border. -class FullscreenButton : public ImageButton { - public: - explicit FullscreenButton(views::ButtonListener* listener) - : ImageButton(listener) { } - - virtual gfx::Size GetPreferredSize() { - gfx::Size pref = ImageButton::GetPreferredSize(); - gfx::Insets insets; - if (border()) - border()->GetInsets(&insets); - pref.Enlarge(insets.width(), insets.height()); - return pref; - } - - private: - DISALLOW_COPY_AND_ASSIGN(FullscreenButton); -}; - -// Border for buttons contained in the menu. This is only used for getting the -// insets, the actual painting is done in MenuButtonBackground. -class MenuButtonBorder : public views::Border { - public: - MenuButtonBorder() {} - - virtual void Paint(const View& view, gfx::Canvas* canvas) const { - // Painting of border is done in MenuButtonBackground. - } - - virtual void GetInsets(gfx::Insets* insets) const { - insets->Set(MenuConfig::instance().item_top_margin, - kHorizontalPadding, - MenuConfig::instance().item_bottom_margin, - kHorizontalPadding); - } - - private: - DISALLOW_COPY_AND_ASSIGN(MenuButtonBorder); -}; - -// Combination border/background for the buttons contained in the menu. The -// painting of the border/background is done here as TextButton does not always -// paint the border. -class MenuButtonBackground : public views::Background { - public: - enum ButtonType { - LEFT_BUTTON, - CENTER_BUTTON, - RIGHT_BUTTON, - SINGLE_BUTTON, - }; - - explicit MenuButtonBackground(ButtonType type) - : type_(type), - left_button_(NULL), - right_button_(NULL) {} - - // Used when the type is CENTER_BUTTON to determine if the left/right edge - // needs to be rendered selected. - void SetOtherButtons(CustomButton* left_button, CustomButton* right_button) { - if (base::i18n::IsRTL()) { - left_button_ = right_button; - right_button_ = left_button; - } else { - left_button_ = left_button; - right_button_ = right_button; - } - } - - virtual void Paint(gfx::Canvas* canvas, View* view) const { - CustomButton::ButtonState state = - (view->GetClassName() == views::Label::kViewClassName) ? - CustomButton::BS_NORMAL : static_cast<CustomButton*>(view)->state(); - int w = view->width(); - int h = view->height(); - switch (TypeAdjustedForRTL()) { - case LEFT_BUTTON: - canvas->FillRectInt(background_color(state), 1, 1, w, h - 2); - canvas->FillRectInt(border_color(state), 2, 0, w, 1); - canvas->FillRectInt(border_color(state), 1, 1, 1, 1); - canvas->FillRectInt(border_color(state), 0, 2, 1, h - 4); - canvas->FillRectInt(border_color(state), 1, h - 2, 1, 1); - canvas->FillRectInt(border_color(state), 2, h - 1, w, 1); - break; - - case CENTER_BUTTON: { - canvas->FillRectInt(background_color(state), 1, 1, w - 2, h - 2); - SkColor left_color = state != CustomButton::BS_NORMAL ? - border_color(state) : border_color(left_button_->state()); - canvas->FillRectInt(left_color, 0, 0, 1, h); - canvas->FillRectInt(border_color(state), 1, 0, w - 2, 1); - canvas->FillRectInt(border_color(state), 1, h - 1, w - 2, 1); - SkColor right_color = state != CustomButton::BS_NORMAL ? - border_color(state) : border_color(right_button_->state()); - canvas->FillRectInt(right_color, w - 1, 0, 1, h); - break; - } - - case RIGHT_BUTTON: - canvas->FillRectInt(background_color(state), 0, 1, w - 1, h - 2); - canvas->FillRectInt(border_color(state), 0, 0, w - 2, 1); - canvas->FillRectInt(border_color(state), w - 2, 1, 1, 1); - canvas->FillRectInt(border_color(state), w - 1, 2, 1, h - 4); - canvas->FillRectInt(border_color(state), w - 2, h - 2, 1, 1); - canvas->FillRectInt(border_color(state), 0, h - 1, w - 2, 1); - break; - - case SINGLE_BUTTON: - canvas->FillRectInt(background_color(state), 1, 1, w - 2, h - 2); - canvas->FillRectInt(border_color(state), 2, 0, w - 4, 1); - canvas->FillRectInt(border_color(state), 1, 1, 1, 1); - canvas->FillRectInt(border_color(state), 0, 2, 1, h - 4); - canvas->FillRectInt(border_color(state), 1, h - 2, 1, 1); - canvas->FillRectInt(border_color(state), 2, h - 1, w - 4, 1); - canvas->FillRectInt(border_color(state), w - 2, 1, 1, 1); - canvas->FillRectInt(border_color(state), w - 1, 2, 1, h - 4); - canvas->FillRectInt(border_color(state), w - 2, h - 2, 1, 1); - break; - - default: - NOTREACHED(); - break; - } - } - - private: - static SkColor border_color(CustomButton::ButtonState state) { - switch (state) { - case CustomButton::BS_HOT: return kHotBorderColor; - case CustomButton::BS_PUSHED: return kPushedBorderColor; - default: return kBorderColor; - } - } - - static SkColor background_color(CustomButton::ButtonState state) { - switch (state) { - case CustomButton::BS_HOT: return kHotBackgroundColor; - case CustomButton::BS_PUSHED: return kPushedBackgroundColor; - default: return kBackgroundColor; - } - } - - ButtonType TypeAdjustedForRTL() const { - if (!base::i18n::IsRTL()) - return type_; - - switch (type_) { - case LEFT_BUTTON: return RIGHT_BUTTON; - case RIGHT_BUTTON: return LEFT_BUTTON; - default: break; - } - return type_; - } - - const ButtonType type_; - - // See description above setter for details. - CustomButton* left_button_; - CustomButton* right_button_; - - DISALLOW_COPY_AND_ASSIGN(MenuButtonBackground); -}; - -// A View subclass that forces SchedulePaint to paint all. Normally when the -// mouse enters/exits a button the buttons invokes SchedulePaint. As part of the -// button border (MenuButtonBackground) is rendered by the button to the -// left/right of it SchedulePaint on the the button may not be enough, so this -// forces a paint all. -class ScheduleAllView : public views::View { - public: - ScheduleAllView() {} - - virtual void SchedulePaint(const gfx::Rect& r, bool urgent) { - if (!IsVisible()) - return; - - if (GetParent()) { - GetParent()->SchedulePaint(GetBounds(APPLY_MIRRORING_TRANSFORMATION), - urgent); - } - } - - private: - DISALLOW_COPY_AND_ASSIGN(ScheduleAllView); -}; - -std::wstring GetAccessibleNameForWrenchMenuItem( - MenuModel* model, int item_index, int accessible_string_id) { - std::wstring accessible_name = l10n_util::GetString(accessible_string_id); - std::wstring accelerator_text; - - menus::Accelerator menu_accelerator; - if (model->GetAcceleratorAt(item_index, &menu_accelerator)) { - accelerator_text = - views::Accelerator(menu_accelerator.GetKeyCode(), - menu_accelerator.modifiers()).GetShortcutText(); - } - - return MenuItemView::GetAccessibleNameForMenuItem( - accessible_name, accelerator_text); -} - -// WrenchMenuView is a view that can contain text buttons. -class WrenchMenuView : public ScheduleAllView, public views::ButtonListener { - public: - WrenchMenuView(WrenchMenu* menu, MenuModel* menu_model) - : menu_(menu), menu_model_(menu_model) { } - - TextButton* CreateAndConfigureButton(int string_id, - MenuButtonBackground::ButtonType type, - int index, - MenuButtonBackground** background) { - return CreateButtonWithAccName( - string_id, type, index, background, string_id); - } - - TextButton* CreateButtonWithAccName(int string_id, - MenuButtonBackground::ButtonType type, - int index, - MenuButtonBackground** background, - int acc_string_id) { - TextButton* button = - new TextButton(this, l10n_util::GetString(string_id)); - button->SetAccessibleName( - GetAccessibleNameForWrenchMenuItem(menu_model_, index, acc_string_id)); - button->SetFocusable(true); - button->set_request_focus_on_press(false); - button->set_tag(index); - button->SetEnabled(menu_model_->IsEnabledAt(index)); - button->set_prefix_type(TextButton::PREFIX_HIDE); - MenuButtonBackground* bg = new MenuButtonBackground(type); - button->set_background(bg); - button->SetEnabledColor(MenuConfig::instance().text_color); - if (background) - *background = bg; - button->set_border(new MenuButtonBorder()); - button->set_alignment(TextButton::ALIGN_CENTER); - button->SetNormalHasBorder(true); - button->SetFont(views::MenuConfig::instance().font); - button->ClearMaxTextSize(); - AddChildView(button); - return button; - } - - protected: - // Hosting WrenchMenu. - WrenchMenu* menu_; - - // The menu model containing the increment/decrement/reset items. - MenuModel* menu_model_; - - private: - DISALLOW_COPY_AND_ASSIGN(WrenchMenuView); -}; - -} // namespace - -// CutCopyPasteView ------------------------------------------------------------ - -// CutCopyPasteView is the view containing the cut/copy/paste buttons. -class WrenchMenu::CutCopyPasteView : public WrenchMenuView { - public: - CutCopyPasteView(WrenchMenu* menu, - MenuModel* menu_model, - int cut_index, - int copy_index, - int paste_index) - : WrenchMenuView(menu, menu_model) { - TextButton* cut = CreateAndConfigureButton( - IDS_CUT, MenuButtonBackground::LEFT_BUTTON, cut_index, NULL); - - MenuButtonBackground* copy_background = NULL; - CreateAndConfigureButton( - IDS_COPY, MenuButtonBackground::CENTER_BUTTON, copy_index, - ©_background); - - TextButton* paste = CreateAndConfigureButton( - IDS_PASTE, MenuButtonBackground::RIGHT_BUTTON, paste_index, NULL); - - copy_background->SetOtherButtons(cut, paste); - } - - gfx::Size GetPreferredSize() { - // Returned height doesn't matter as MenuItemView forces everything to the - // height of the menuitemview. - return gfx::Size(GetMaxChildViewPreferredWidth() * GetChildViewCount(), 0); - } - - void Layout() { - // All buttons are given the same width. - int width = GetMaxChildViewPreferredWidth(); - for (int i = 0; i < GetChildViewCount(); ++i) - GetChildViewAt(i)->SetBounds(i * width, 0, width, height()); - } - - // ButtonListener - virtual void ButtonPressed(views::Button* sender, const views::Event& event) { - menu_->CancelAndEvaluate(menu_model_, sender->tag()); - } - - private: - // Returns the max preferred width of all the children. - int GetMaxChildViewPreferredWidth() { - int width = 0; - for (int i = 0; i < GetChildViewCount(); ++i) - width = std::max(width, GetChildViewAt(i)->GetPreferredSize().width()); - return width; - } - - DISALLOW_COPY_AND_ASSIGN(CutCopyPasteView); -}; - -// ZoomView -------------------------------------------------------------------- - -// Padding between the increment buttons and the reset button. -static const int kZoomPadding = 6; - -// ZoomView contains the various zoom controls: two buttons to increase/decrease -// the zoom, a label showing the current zoom percent, and a button to go -// full-screen. -class WrenchMenu::ZoomView : public WrenchMenuView, - public NotificationObserver { - public: - ZoomView(WrenchMenu* menu, - MenuModel* menu_model, - int decrement_index, - int increment_index, - int fullscreen_index) - : WrenchMenuView(menu, menu_model), - fullscreen_index_(fullscreen_index), - increment_button_(NULL), - zoom_label_(NULL), - decrement_button_(NULL), - fullscreen_button_(NULL), - zoom_label_width_(0) { - decrement_button_ = CreateButtonWithAccName( - IDS_ZOOM_MINUS2, MenuButtonBackground::LEFT_BUTTON, decrement_index, - NULL, IDS_ACCNAME_ZOOM_MINUS2); - - zoom_label_ = new Label(l10n_util::GetStringF(IDS_ZOOM_PERCENT, L"100")); - zoom_label_->SetColor(MenuConfig::instance().text_color); - zoom_label_->SetHorizontalAlignment(Label::ALIGN_RIGHT); - MenuButtonBackground* center_bg = - new MenuButtonBackground(MenuButtonBackground::CENTER_BUTTON); - zoom_label_->set_background(center_bg); - zoom_label_->set_border(new MenuButtonBorder()); - zoom_label_->SetFont(MenuConfig::instance().font); - AddChildView(zoom_label_); - zoom_label_width_ = MaxWidthForZoomLabel(); - - increment_button_ = CreateButtonWithAccName( - IDS_ZOOM_PLUS2, MenuButtonBackground::RIGHT_BUTTON, increment_index, - NULL, IDS_ACCNAME_ZOOM_PLUS2); - - center_bg->SetOtherButtons(decrement_button_, increment_button_); - - fullscreen_button_ = new FullscreenButton(this); - fullscreen_button_->SetImage( - ImageButton::BS_NORMAL, - ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_FULLSCREEN_MENU_BUTTON)); - fullscreen_button_->SetFocusable(true); - fullscreen_button_->set_request_focus_on_press(false); - fullscreen_button_->set_tag(fullscreen_index); - fullscreen_button_->SetImageAlignment( - ImageButton::ALIGN_CENTER, ImageButton::ALIGN_MIDDLE); - fullscreen_button_->set_border(views::Border::CreateEmptyBorder( - 0, kHorizontalPadding, 0, kHorizontalPadding)); - fullscreen_button_->set_background( - new MenuButtonBackground(MenuButtonBackground::SINGLE_BUTTON)); - fullscreen_button_->SetAccessibleName( - GetAccessibleNameForWrenchMenuItem( - menu_model, fullscreen_index, IDS_ACCNAME_FULLSCREEN)); - AddChildView(fullscreen_button_); - - UpdateZoomControls(); - - registrar_.Add(this, NotificationType::ZOOM_LEVEL_CHANGED, - Source<Profile>(menu->browser_->profile())); - } - - gfx::Size GetPreferredSize() { - // The increment/decrement button are forced to the same width. - int button_width = std::max(increment_button_->GetPreferredSize().width(), - decrement_button_->GetPreferredSize().width()); - int fullscreen_width = fullscreen_button_->GetPreferredSize().width(); - // Returned height doesn't matter as MenuItemView forces everything to the - // height of the menuitemview. - return gfx::Size(button_width + zoom_label_width_ + button_width + - kZoomPadding + fullscreen_width, 0); - } - - void Layout() { - int x = 0; - int button_width = std::max(increment_button_->GetPreferredSize().width(), - decrement_button_->GetPreferredSize().width()); - gfx::Rect bounds(0, 0, button_width, height()); - - decrement_button_->SetBounds(bounds); - - x += bounds.width(); - bounds.set_x(x); - bounds.set_width(zoom_label_width_); - zoom_label_->SetBounds(bounds); - - x += bounds.width(); - bounds.set_x(x); - bounds.set_width(button_width); - increment_button_->SetBounds(bounds); - - x += bounds.width() + kZoomPadding; - bounds.set_x(x); - bounds.set_width(fullscreen_button_->GetPreferredSize().width()); - fullscreen_button_->SetBounds(bounds); - } - - // ButtonListener: - virtual void ButtonPressed(views::Button* sender, const views::Event& event) { - if (sender->tag() == fullscreen_index_) { - menu_->CancelAndEvaluate(menu_model_, sender->tag()); - } else { - // Zoom buttons don't close the menu. - menu_model_->ActivatedAt(sender->tag()); - } - } - - // NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK_EQ(NotificationType::ZOOM_LEVEL_CHANGED, type.value); - UpdateZoomControls(); - } - - private: - void UpdateZoomControls() { - bool enable_increment = false; - bool enable_decrement = false; - TabContents* selected_tab = menu_->browser_->GetSelectedTabContents(); - int zoom = 100; - if (selected_tab) - zoom = selected_tab->GetZoomPercent(&enable_increment, &enable_decrement); - increment_button_->SetEnabled(enable_increment); - decrement_button_->SetEnabled(enable_decrement); - zoom_label_->SetText(l10n_util::GetStringF( - IDS_ZOOM_PERCENT, - UTF8ToWide(base::IntToString(zoom)))); - - zoom_label_width_ = MaxWidthForZoomLabel(); - } - - // Calculates the max width the zoom string can be. - int MaxWidthForZoomLabel() { - gfx::Font font = zoom_label_->font(); - gfx::Insets insets; - if (zoom_label_->border()) - zoom_label_->border()->GetInsets(&insets); - - int max_w = 0; - - TabContents* selected_tab = menu_->browser_->GetSelectedTabContents(); - if (selected_tab) { - int min_percent = selected_tab->minimum_zoom_percent(); - int max_percent = selected_tab->maximum_zoom_percent(); - - int step = (max_percent - min_percent) / 10; - for (int i = min_percent; i <= max_percent; i += step) { - int w = font.GetStringWidth(l10n_util::GetStringF(IDS_ZOOM_PERCENT, i)); - max_w = std::max(w, max_w); - } - } else { - max_w = font.GetStringWidth(l10n_util::GetStringF(IDS_ZOOM_PERCENT, 100)); - } - - return max_w + insets.width(); - } - - // Index of the fullscreen menu item in the model. - const int fullscreen_index_; - - NotificationRegistrar registrar_; - - // Button for incrementing the zoom. - TextButton* increment_button_; - - // Label showing zoom as a percent. - Label* zoom_label_; - - // Button for decrementing the zoom. - TextButton* decrement_button_; - - ImageButton* fullscreen_button_; - - // Width given to |zoom_label_|. This is the width at 100%. - int zoom_label_width_; - - DISALLOW_COPY_AND_ASSIGN(ZoomView); -}; - -// WrenchMenu ------------------------------------------------------------------ - -WrenchMenu::WrenchMenu(Browser* browser) - : browser_(browser), - selected_menu_model_(NULL), - selected_index_(0) { -} - -void WrenchMenu::Init(menus::MenuModel* model) { - DCHECK(!root_.get()); - root_.reset(new MenuItemView(this)); - root_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_APP)); - root_->set_has_icons(true); // We have checks, radios and icons, set this - // so we get the taller menu style. - int next_id = 1; - PopulateMenu(root_.get(), model, &next_id); -} - -void WrenchMenu::RunMenu(views::MenuButton* host) { - // Up the ref count while the menu is displaying. This way if the window is - // deleted while we're running we won't prematurely delete the menu. - // TODO(sky): fix this, the menu should really take ownership of the menu - // (57890). - scoped_refptr<WrenchMenu> dont_delete_while_running(this); - gfx::Point screen_loc; - views::View::ConvertPointToScreen(host, &screen_loc); - gfx::Rect bounds(screen_loc, host->size()); - root_->RunMenuAt(host->GetWindow()->GetNativeWindow(), host, bounds, - base::i18n::IsRTL() ? MenuItemView::TOPLEFT : MenuItemView::TOPRIGHT, - true); - if (selected_menu_model_) - selected_menu_model_->ActivatedAt(selected_index_); -} - -bool WrenchMenu::IsItemChecked(int id) const { - const Entry& entry = id_to_entry_.find(id)->second; - return entry.first->IsItemCheckedAt(entry.second); -} - -bool WrenchMenu::IsCommandEnabled(int id) const { - if (id == 0) - return false; // The root item. - - const Entry& entry = id_to_entry_.find(id)->second; - int command_id = entry.first->GetCommandIdAt(entry.second); - // The items representing the cut (cut/copy/paste) and zoom menu - // (increment/decrement/reset) are always enabled. The child views of these - // items enabled state updates appropriately. - return command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS || - entry.first->IsEnabledAt(entry.second); -} - -void WrenchMenu::ExecuteCommand(int id) { - const Entry& entry = id_to_entry_.find(id)->second; - int command_id = entry.first->GetCommandIdAt(entry.second); - - if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { - // These items are represented by child views. If ExecuteCommand is invoked - // it means the user clicked on the area around the buttons and we should - // not do anyting. - return; - } - - return entry.first->ActivatedAt(entry.second); -} - -bool WrenchMenu::GetAccelerator(int id, views::Accelerator* accelerator) { - const Entry& entry = id_to_entry_.find(id)->second; - int command_id = entry.first->GetCommandIdAt(entry.second); - if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { - // These have special child views; don't show the accelerator for them. - return false; - } - - menus::Accelerator menu_accelerator; - if (!entry.first->GetAcceleratorAt(entry.second, &menu_accelerator)) - return false; - - *accelerator = views::Accelerator(menu_accelerator.GetKeyCode(), - menu_accelerator.modifiers()); - return true; -} - -WrenchMenu::~WrenchMenu() { -} - -void WrenchMenu::PopulateMenu(MenuItemView* parent, - MenuModel* model, - int* next_id) { - int index_offset = model->GetFirstItemIndex(NULL); - for (int i = 0, max = model->GetItemCount(); i < max; ++i) { - int index = i + index_offset; - - MenuItemView* item = - AppendMenuItem(parent, model, index, model->GetTypeAt(index), next_id); - - if (model->GetTypeAt(index) == MenuModel::TYPE_SUBMENU) - PopulateMenu(item, model->GetSubmenuModelAt(index), next_id); - - if (model->GetCommandIdAt(index) == IDC_CUT) { - DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index)); - DCHECK_LT(i + 2, max); - DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(index + 1)); - DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(index + 2)); - item->SetTitle(l10n_util::GetString(IDS_EDIT2)); - item->AddChildView( - new CutCopyPasteView(this, model, index, index + 1, index + 2)); - i += 2; - } else if (model->GetCommandIdAt(index) == IDC_ZOOM_MINUS) { - DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index)); - DCHECK_EQ(IDC_ZOOM_PLUS, model->GetCommandIdAt(index + 1)); - DCHECK_EQ(IDC_FULLSCREEN, model->GetCommandIdAt(index + 2)); - item->SetTitle(l10n_util::GetString(IDS_ZOOM_MENU2)); - item->AddChildView( - new ZoomView(this, model, index, index + 1, index + 2)); - i += 2; - } - } -} - -MenuItemView* WrenchMenu::AppendMenuItem(MenuItemView* parent, - MenuModel* model, - int index, - MenuModel::ItemType menu_type, - int* next_id) { - int id = (*next_id)++; - SkBitmap icon; - std::wstring label; - MenuItemView::Type type; - switch (menu_type) { - case MenuModel::TYPE_COMMAND: - model->GetIconAt(index, &icon); - type = MenuItemView::NORMAL; - label = UTF16ToWide(model->GetLabelAt(index)); - break; - case MenuModel::TYPE_CHECK: - type = MenuItemView::CHECKBOX; - label = UTF16ToWide(model->GetLabelAt(index)); - break; - case MenuModel::TYPE_RADIO: - type = MenuItemView::RADIO; - label = UTF16ToWide(model->GetLabelAt(index)); - break; - case MenuModel::TYPE_SEPARATOR: - type = MenuItemView::SEPARATOR; - break; - case MenuModel::TYPE_SUBMENU: - type = MenuItemView::SUBMENU; - label = UTF16ToWide(model->GetLabelAt(index)); - break; - default: - NOTREACHED(); - type = MenuItemView::NORMAL; - break; - } - - id_to_entry_[id].first = model; - id_to_entry_[id].second = index; - - MenuItemView* menu_item = parent->AppendMenuItemImpl(id, label, icon, type); - - if (menu_item) - menu_item->SetVisible(model->IsVisibleAt(index)); - - if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) { - SkBitmap icon; - if (model->GetIconAt(index, &icon)) - menu_item->SetIcon(icon); - } - - return menu_item; -} - -void WrenchMenu::CancelAndEvaluate(MenuModel* model, int index) { - selected_menu_model_ = model; - selected_index_ = index; - root_->Cancel(); -} diff --git a/chrome/browser/views/wrench_menu.h b/chrome/browser/views/wrench_menu.h index e9aa2fb..1a2c52b 100644 --- a/chrome/browser/views/wrench_menu.h +++ b/chrome/browser/views/wrench_menu.h @@ -6,87 +6,8 @@ #define CHROME_BROWSER_VIEWS_WRENCH_MENU_H_ #pragma once -#include <map> -#include <utility> - -#include "app/menus/menu_model.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "views/controls/menu/menu_delegate.h" - -class Browser; - -namespace views { -class MenuButton; -class MenuItemView; -class View; -} // namespace views - -// WrenchMenu adapts the WrenchMenuModel to view's menu related classes. -class WrenchMenu : public base::RefCounted<WrenchMenu>, - public views::MenuDelegate { - public: - explicit WrenchMenu(Browser* browser); - - void Init(menus::MenuModel* model); - - // Shows the menu relative to the specified view. - void RunMenu(views::MenuButton* host); - - // MenuDelegate overrides: - virtual bool IsItemChecked(int id) const; - virtual bool IsCommandEnabled(int id) const; - virtual void ExecuteCommand(int id); - virtual bool GetAccelerator(int id, views::Accelerator* accelerator); - - private: - friend class base::RefCounted<WrenchMenu>; - - class CutCopyPasteView; - class ZoomView; - - typedef std::pair<menus::MenuModel*,int> Entry; - typedef std::map<int,Entry> IDToEntry; - - ~WrenchMenu(); - - // Populates |parent| with all the child menus in |model|. Recursively invokes - // |PopulateMenu| for any submenu. |next_id| is incremented for every menu - // that is created. - void PopulateMenu(views::MenuItemView* parent, - menus::MenuModel* model, - int* next_id); - - // Adds a new menu to |parent| to represent the MenuModel/index pair passed - // in. - views::MenuItemView* AppendMenuItem(views::MenuItemView* parent, - menus::MenuModel* model, - int index, - menus::MenuModel::ItemType menu_type, - int* next_id); - - // Invoked from the cut/copy/paste menus. Cancels the current active menu and - // activates the menu item in |model| at |index|. - void CancelAndEvaluate(menus::MenuModel* model, int index); - - // The views menu. - scoped_ptr<views::MenuItemView> root_; - - // Maps from the ID as understood by MenuItemView to the model/index pair the - // item came from. - IDToEntry id_to_entry_; - - // Browser the menu is being shown for. - Browser* browser_; - - // |CancelAndEvaluate| sets |selected_menu_model_| and |selected_index_|. - // If |selected_menu_model_| is non-null after the menu completes - // ActivatedAt is invoked. This is done so that ActivatedAt isn't invoked - // while the message loop is nested. - menus::MenuModel* selected_menu_model_; - int selected_index_; - - DISALLOW_COPY_AND_ASSIGN(WrenchMenu); -}; +#include "chrome/browser/ui/views/wrench_menu.h" +// TODO(beng): remove this file once all includes have been updated. #endif // CHROME_BROWSER_VIEWS_WRENCH_MENU_H_ + |