| Index: chrome/browser/ui/views/content_setting_bubble_contents.cc
|
| diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc
|
| index 7a01e388149a61df764e1164a9ddb37189604b31..f411559e09f68eb1c12804e55ff8a54e888ada2a 100644
|
| --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc
|
| +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
|
| @@ -1,330 +1,489 @@
|
| -// Copyright (c) 2012 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/ui/views/content_setting_bubble_contents.h"
|
| -
|
| -#include <algorithm>
|
| -#include <set>
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/utf_string_conversions.h"
|
| -#include "chrome/browser/content_settings/host_content_settings_map.h"
|
| -#include "chrome/browser/plugins/plugin_finder.h"
|
| -#include "chrome/browser/plugins/plugin_metadata.h"
|
| -#include "chrome/browser/ui/chrome_style.h"
|
| -#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
|
| -#include "chrome/browser/ui/views/browser_dialogs.h"
|
| -#include "content/public/browser/notification_source.h"
|
| -#include "content/public/browser/notification_types.h"
|
| -#include "content/public/browser/plugin_service.h"
|
| -#include "grit/generated_resources.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/views/controls/button/radio_button.h"
|
| -#include "ui/views/controls/button/text_button.h"
|
| -#include "ui/views/controls/image_view.h"
|
| -#include "ui/views/controls/label.h"
|
| -#include "ui/views/controls/link.h"
|
| -#include "ui/views/controls/separator.h"
|
| -#include "ui/views/layout/grid_layout.h"
|
| -#include "ui/views/layout/layout_constants.h"
|
| -
|
| -#if defined(USE_AURA)
|
| -#include "ui/base/cursor/cursor.h"
|
| -#endif
|
| -
|
| -// 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;
|
| -
|
| -using content::PluginService;
|
| -using content::WebContents;
|
| -
|
| -class ContentSettingBubbleContents::Favicon : public views::ImageView {
|
| - public:
|
| - Favicon(const gfx::Image& image,
|
| - ContentSettingBubbleContents* parent,
|
| - views::Link* link);
|
| - virtual ~Favicon();
|
| -
|
| - private:
|
| - // views::View overrides:
|
| - virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
|
| - virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
|
| - virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
|
| -
|
| - ContentSettingBubbleContents* parent_;
|
| - views::Link* link_;
|
| -};
|
| -
|
| -ContentSettingBubbleContents::Favicon::Favicon(
|
| - const gfx::Image& image,
|
| - ContentSettingBubbleContents* parent,
|
| - views::Link* link)
|
| - : parent_(parent),
|
| - link_(link) {
|
| - SetImage(image.AsImageSkia());
|
| -}
|
| -
|
| -ContentSettingBubbleContents::Favicon::~Favicon() {
|
| -}
|
| -
|
| -bool ContentSettingBubbleContents::Favicon::OnMousePressed(
|
| - const ui::MouseEvent& event) {
|
| - return event.IsLeftMouseButton() || event.IsMiddleMouseButton();
|
| -}
|
| -
|
| -void ContentSettingBubbleContents::Favicon::OnMouseReleased(
|
| - const ui::MouseEvent& event) {
|
| - if ((event.IsLeftMouseButton() || event.IsMiddleMouseButton()) &&
|
| - HitTestPoint(event.location())) {
|
| - parent_->LinkClicked(link_, event.flags());
|
| - }
|
| -}
|
| -
|
| -gfx::NativeCursor ContentSettingBubbleContents::Favicon::GetCursor(
|
| - const ui::MouseEvent& event) {
|
| -#if defined(USE_AURA)
|
| - return ui::kCursorHand;
|
| -#elif defined(OS_WIN)
|
| - static HCURSOR g_hand_cursor = LoadCursor(NULL, IDC_HAND);
|
| - return g_hand_cursor;
|
| -#endif
|
| -}
|
| -
|
| -ContentSettingBubbleContents::ContentSettingBubbleContents(
|
| - ContentSettingBubbleModel* content_setting_bubble_model,
|
| - WebContents* web_contents,
|
| - views::View* anchor_view,
|
| - views::BubbleBorder::ArrowLocation arrow_location)
|
| - : BubbleDelegateView(anchor_view, arrow_location),
|
| - content_setting_bubble_model_(content_setting_bubble_model),
|
| - web_contents_(web_contents),
|
| - custom_link_(NULL),
|
| - manage_link_(NULL),
|
| - close_button_(NULL) {
|
| - // Compensate for built-in vertical padding in the anchor view's image.
|
| - set_anchor_insets(gfx::Insets(5, 0, 5, 0));
|
| -
|
| - registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
|
| - content::Source<WebContents>(web_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::Init() {
|
| - using views::GridLayout;
|
| -
|
| - GridLayout* layout = new views::GridLayout(this);
|
| - SetLayoutManager(layout);
|
| -
|
| - const int kSingleColumnSetId = 0;
|
| - views::ColumnSet* column_set = layout->AddColumnSet(kSingleColumnSetId);
|
| - column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
|
| - GridLayout::USE_PREF, 0, 0);
|
| -
|
| - const ContentSettingBubbleModel::BubbleContent& bubble_content =
|
| - content_setting_bubble_model_->bubble_content();
|
| - bool bubble_content_empty = true;
|
| -
|
| - if (!bubble_content.title.empty()) {
|
| - views::Label* title_label = new views::Label(UTF8ToUTF16(
|
| - bubble_content.title));
|
| - layout->StartRow(0, kSingleColumnSetId);
|
| - layout->AddView(title_label);
|
| - bubble_content_empty = false;
|
| - }
|
| -
|
| - const std::set<std::string>& plugins = bubble_content.resource_identifiers;
|
| - if (!plugins.empty()) {
|
| - if (!bubble_content_empty)
|
| - layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| - PluginFinder* finder = PluginFinder::GetInstance();
|
| - for (std::set<std::string>::const_iterator i(plugins.begin());
|
| - i != plugins.end(); ++i) {
|
| - string16 name = finder->FindPluginNameWithIdentifier(*i);
|
| - layout->StartRow(0, kSingleColumnSetId);
|
| - layout->AddView(new views::Label(name));
|
| - bubble_content_empty = false;
|
| - }
|
| - }
|
| -
|
| - if (content_setting_bubble_model_->content_type() ==
|
| - CONTENT_SETTINGS_TYPE_POPUPS) {
|
| - const int kPopupColumnSetId = 2;
|
| - views::ColumnSet* popup_column_set =
|
| - layout->AddColumnSet(kPopupColumnSetId);
|
| - popup_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 0,
|
| - GridLayout::USE_PREF, 0, 0);
|
| - popup_column_set->AddPaddingColumn(
|
| - 0, views::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 (!bubble_content_empty)
|
| - layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| - layout->StartRow(0, kPopupColumnSetId);
|
| -
|
| - views::Link* link = new views::Link(UTF8ToUTF16(i->title));
|
| - link->set_listener(this);
|
| - link->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE);
|
| - popup_links_[link] = i - bubble_content.popup_items.begin();
|
| - layout->AddView(new Favicon(i->image, this, link));
|
| - layout->AddView(link);
|
| - bubble_content_empty = false;
|
| - }
|
| - }
|
| -
|
| - const int indented_kSingleColumnSetId = 3;
|
| - // Insert a column set with greater indent.
|
| - views::ColumnSet* indented_single_column_set =
|
| - layout->AddColumnSet(indented_kSingleColumnSetId);
|
| - indented_single_column_set->AddPaddingColumn(
|
| - 0, chrome_style::kCheckboxIndent);
|
| - indented_single_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL,
|
| - 1, GridLayout::USE_PREF, 0, 0);
|
| -
|
| - const ContentSettingBubbleModel::RadioGroup& radio_group =
|
| - bubble_content.radio_group;
|
| - if (!radio_group.radio_items.empty()) {
|
| - if (!bubble_content_empty)
|
| - layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| - for (ContentSettingBubbleModel::RadioItems::const_iterator i(
|
| - radio_group.radio_items.begin());
|
| - i != radio_group.radio_items.end(); ++i) {
|
| - views::RadioButton* radio = new views::RadioButton(UTF8ToUTF16(*i), 0);
|
| - radio->SetEnabled(bubble_content.radio_group_enabled);
|
| - radio->set_listener(this);
|
| - radio_group_.push_back(radio);
|
| - layout->StartRow(0, indented_kSingleColumnSetId);
|
| - layout->AddView(radio);
|
| - bubble_content_empty = false;
|
| - }
|
| - DCHECK(!radio_group_.empty());
|
| - // 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);
|
| - for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i(
|
| - bubble_content.domain_lists.begin());
|
| - i != bubble_content.domain_lists.end(); ++i) {
|
| - layout->StartRow(0, kSingleColumnSetId);
|
| - views::Label* section_title = new views::Label(UTF8ToUTF16(i->title));
|
| - section_title->SetMultiLine(true);
|
| - section_title->SetHorizontalAlignment(gfx::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_kSingleColumnSetId);
|
| - layout->AddView(new views::Label(UTF8ToUTF16(*j), domain_font));
|
| - }
|
| - bubble_content_empty = false;
|
| - }
|
| -
|
| - if (!bubble_content.custom_link.empty()) {
|
| - custom_link_ = new views::Link(UTF8ToUTF16(bubble_content.custom_link));
|
| - custom_link_->SetEnabled(bubble_content.custom_link_enabled);
|
| - custom_link_->set_listener(this);
|
| - if (!bubble_content_empty)
|
| - layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| - layout->StartRow(0, kSingleColumnSetId);
|
| - layout->AddView(custom_link_);
|
| - bubble_content_empty = false;
|
| - }
|
| -
|
| - if (!bubble_content_empty) {
|
| - layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| - layout->StartRow(0, kSingleColumnSetId);
|
| - layout->AddView(new views::Separator, 1, 1,
|
| - GridLayout::FILL, GridLayout::FILL);
|
| - layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| - }
|
| -
|
| - const int kDoubleColumnSetId = 1;
|
| - views::ColumnSet* double_column_set =
|
| - layout->AddColumnSet(kDoubleColumnSetId);
|
| - double_column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
|
| - GridLayout::USE_PREF, 0, 0);
|
| - double_column_set->AddPaddingColumn(
|
| - 0, views::kUnrelatedControlHorizontalSpacing);
|
| - double_column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
|
| - GridLayout::USE_PREF, 0, 0);
|
| -
|
| - layout->StartRow(0, kDoubleColumnSetId);
|
| - manage_link_ = new views::Link(UTF8ToUTF16(bubble_content.manage_link));
|
| - manage_link_->set_listener(this);
|
| - layout->AddView(manage_link_);
|
| -
|
| - close_button_ = new views::NativeTextButton(
|
| - this, l10n_util::GetStringUTF16(IDS_DONE));
|
| - layout->AddView(close_button_);
|
| -}
|
| -
|
| -void ContentSettingBubbleContents::ButtonPressed(views::Button* sender,
|
| - const ui::Event& event) {
|
| - if (sender == close_button_) {
|
| - content_setting_bubble_model_->OnDoneClicked();
|
| - StartFade(false);
|
| - 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::LinkClicked(views::Link* source,
|
| - int event_flags) {
|
| - if (source == custom_link_) {
|
| - content_setting_bubble_model_->OnCustomLinkClicked();
|
| - StartFade(false);
|
| - return;
|
| - }
|
| - if (source == manage_link_) {
|
| - StartFade(false);
|
| - 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;
|
| - }
|
| -
|
| - PopupLinks::const_iterator i(popup_links_.find(source));
|
| - DCHECK(i != popup_links_.end());
|
| - content_setting_bubble_model_->OnPopupClicked(i->second);
|
| -}
|
| -
|
| -void ContentSettingBubbleContents::Observe(
|
| - int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) {
|
| - DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type);
|
| - DCHECK(source == content::Source<WebContents>(web_contents_));
|
| - web_contents_ = NULL;
|
| -}
|
| +// Copyright (c) 2012 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/ui/views/content_setting_bubble_contents.h"
|
| +
|
| +#include <algorithm>
|
| +#include <set>
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/stl_util.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "chrome/browser/content_settings/host_content_settings_map.h"
|
| +#include "chrome/browser/plugins/plugin_finder.h"
|
| +#include "chrome/browser/plugins/plugin_metadata.h"
|
| +#include "chrome/browser/ui/chrome_style.h"
|
| +#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
|
| +#include "chrome/browser/ui/content_settings/content_setting_media_menu_model.h"
|
| +#include "chrome/browser/ui/views/browser_dialogs.h"
|
| +#include "content/public/browser/notification_source.h"
|
| +#include "content/public/browser/notification_types.h"
|
| +#include "content/public/browser/plugin_service.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "grit/generated_resources.h"
|
| +#include "grit/theme_resources.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/models/simple_menu_model.h"
|
| +#include "ui/views/controls/button/menu_button.h"
|
| +#include "ui/views/controls/button/radio_button.h"
|
| +#include "ui/views/controls/button/text_button.h"
|
| +#include "ui/views/controls/image_view.h"
|
| +#include "ui/views/controls/label.h"
|
| +#include "ui/views/controls/link.h"
|
| +#include "ui/views/controls/menu/menu.h"
|
| +#include "ui/views/controls/menu/menu_model_adapter.h"
|
| +#include "ui/views/controls/menu/menu_runner.h"
|
| +#include "ui/views/controls/separator.h"
|
| +#include "ui/views/layout/grid_layout.h"
|
| +#include "ui/views/layout/layout_constants.h"
|
| +
|
| +#if defined(USE_AURA)
|
| +#include "ui/base/cursor/cursor.h"
|
| +#endif
|
| +
|
| +namespace {
|
| +
|
| +// 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;
|
| +
|
| +// The minimum and maximum width of the media menu buttons.
|
| +const int kMinMediaMenuButtonWidth = 100;
|
| +const int kMaxMediaMenuButtonWidth = 600;
|
| +
|
| +}
|
| +
|
| +using content::PluginService;
|
| +using content::WebContents;
|
| +
|
| +
|
| +// ContentSettingBubbleContents::Favicon --------------------------------------
|
| +
|
| +class ContentSettingBubbleContents::Favicon : public views::ImageView {
|
| + public:
|
| + Favicon(const gfx::Image& image,
|
| + ContentSettingBubbleContents* parent,
|
| + views::Link* link);
|
| + virtual ~Favicon();
|
| +
|
| + private:
|
| + // views::View overrides:
|
| + virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
|
| + virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
|
| + virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
|
| +
|
| + ContentSettingBubbleContents* parent_;
|
| + views::Link* link_;
|
| +};
|
| +
|
| +ContentSettingBubbleContents::Favicon::Favicon(
|
| + const gfx::Image& image,
|
| + ContentSettingBubbleContents* parent,
|
| + views::Link* link)
|
| + : parent_(parent),
|
| + link_(link) {
|
| + SetImage(image.AsImageSkia());
|
| +}
|
| +
|
| +ContentSettingBubbleContents::Favicon::~Favicon() {
|
| +}
|
| +
|
| +bool ContentSettingBubbleContents::Favicon::OnMousePressed(
|
| + const ui::MouseEvent& event) {
|
| + return event.IsLeftMouseButton() || event.IsMiddleMouseButton();
|
| +}
|
| +
|
| +void ContentSettingBubbleContents::Favicon::OnMouseReleased(
|
| + const ui::MouseEvent& event) {
|
| + if ((event.IsLeftMouseButton() || event.IsMiddleMouseButton()) &&
|
| + HitTestPoint(event.location())) {
|
| + parent_->LinkClicked(link_, event.flags());
|
| + }
|
| +}
|
| +
|
| +gfx::NativeCursor ContentSettingBubbleContents::Favicon::GetCursor(
|
| + const ui::MouseEvent& event) {
|
| +#if defined(USE_AURA)
|
| + return ui::kCursorHand;
|
| +#elif defined(OS_WIN)
|
| + static HCURSOR g_hand_cursor = LoadCursor(NULL, IDC_HAND);
|
| + return g_hand_cursor;
|
| +#endif
|
| +}
|
| +
|
| +
|
| +// ContentSettingBubbleContents::MediaMenuParts -------------------------------
|
| +
|
| +struct ContentSettingBubbleContents::MediaMenuParts {
|
| + explicit MediaMenuParts(content::MediaStreamType type);
|
| + ~MediaMenuParts();
|
| +
|
| + content::MediaStreamType type;
|
| + scoped_ptr<ui::SimpleMenuModel> menu_model;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(MediaMenuParts);
|
| +};
|
| +
|
| +ContentSettingBubbleContents::MediaMenuParts::MediaMenuParts(
|
| + content::MediaStreamType type)
|
| + : type(type) {}
|
| +
|
| +ContentSettingBubbleContents::MediaMenuParts::~MediaMenuParts() {}
|
| +
|
| +
|
| +// ContentSettingBubbleContents -----------------------------------------------
|
| +
|
| +ContentSettingBubbleContents::ContentSettingBubbleContents(
|
| + ContentSettingBubbleModel* content_setting_bubble_model,
|
| + WebContents* web_contents,
|
| + views::View* anchor_view,
|
| + views::BubbleBorder::ArrowLocation arrow_location)
|
| + : BubbleDelegateView(anchor_view, arrow_location),
|
| + content_setting_bubble_model_(content_setting_bubble_model),
|
| + web_contents_(web_contents),
|
| + custom_link_(NULL),
|
| + manage_link_(NULL),
|
| + close_button_(NULL) {
|
| + // Compensate for built-in vertical padding in the anchor view's image.
|
| + set_anchor_insets(gfx::Insets(5, 0, 5, 0));
|
| +
|
| + registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
|
| + content::Source<WebContents>(web_contents));
|
| +}
|
| +
|
| +ContentSettingBubbleContents::~ContentSettingBubbleContents() {
|
| + STLDeleteValues(&media_menus_);
|
| +}
|
| +
|
| +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::UpdateMenuLabel(
|
| + content::MediaStreamType type,
|
| + const std::string& label) {
|
| + for (MediaMenuPartsMap::const_iterator it = media_menus_.begin();
|
| + it != media_menus_.end(); ++it) {
|
| + if (it->second->type == type) {
|
| + it->first->SetText(UTF8ToUTF16(label));
|
| + return;
|
| + }
|
| + }
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ContentSettingBubbleContents::Init() {
|
| + using views::GridLayout;
|
| +
|
| + GridLayout* layout = new views::GridLayout(this);
|
| + SetLayoutManager(layout);
|
| +
|
| + const int kSingleColumnSetId = 0;
|
| + views::ColumnSet* column_set = layout->AddColumnSet(kSingleColumnSetId);
|
| + column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
|
| + GridLayout::USE_PREF, 0, 0);
|
| +
|
| + const ContentSettingBubbleModel::BubbleContent& bubble_content =
|
| + content_setting_bubble_model_->bubble_content();
|
| + bool bubble_content_empty = true;
|
| +
|
| + if (!bubble_content.title.empty()) {
|
| + views::Label* title_label = new views::Label(UTF8ToUTF16(
|
| + bubble_content.title));
|
| + layout->StartRow(0, kSingleColumnSetId);
|
| + layout->AddView(title_label);
|
| + bubble_content_empty = false;
|
| + }
|
| +
|
| + const std::set<std::string>& plugins = bubble_content.resource_identifiers;
|
| + if (!plugins.empty()) {
|
| + if (!bubble_content_empty)
|
| + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| + PluginFinder* finder = PluginFinder::GetInstance();
|
| + for (std::set<std::string>::const_iterator i(plugins.begin());
|
| + i != plugins.end(); ++i) {
|
| + string16 name = finder->FindPluginNameWithIdentifier(*i);
|
| + layout->StartRow(0, kSingleColumnSetId);
|
| + layout->AddView(new views::Label(name));
|
| + bubble_content_empty = false;
|
| + }
|
| + }
|
| +
|
| + if (content_setting_bubble_model_->content_type() ==
|
| + CONTENT_SETTINGS_TYPE_POPUPS) {
|
| + const int kPopupColumnSetId = 2;
|
| + views::ColumnSet* popup_column_set =
|
| + layout->AddColumnSet(kPopupColumnSetId);
|
| + popup_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 0,
|
| + GridLayout::USE_PREF, 0, 0);
|
| + popup_column_set->AddPaddingColumn(
|
| + 0, views::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 (!bubble_content_empty)
|
| + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| + layout->StartRow(0, kPopupColumnSetId);
|
| +
|
| + views::Link* link = new views::Link(UTF8ToUTF16(i->title));
|
| + link->set_listener(this);
|
| + link->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE);
|
| + popup_links_[link] = i - bubble_content.popup_items.begin();
|
| + layout->AddView(new Favicon(i->image, this, link));
|
| + layout->AddView(link);
|
| + bubble_content_empty = false;
|
| + }
|
| + }
|
| +
|
| + const int indented_kSingleColumnSetId = 3;
|
| + // Insert a column set with greater indent.
|
| + views::ColumnSet* indented_single_column_set =
|
| + layout->AddColumnSet(indented_kSingleColumnSetId);
|
| + indented_single_column_set->AddPaddingColumn(
|
| + 0, chrome_style::kCheckboxIndent);
|
| + indented_single_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL,
|
| + 1, GridLayout::USE_PREF, 0, 0);
|
| +
|
| + const ContentSettingBubbleModel::RadioGroup& radio_group =
|
| + bubble_content.radio_group;
|
| + if (!radio_group.radio_items.empty()) {
|
| + if (!bubble_content_empty)
|
| + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| + for (ContentSettingBubbleModel::RadioItems::const_iterator i(
|
| + radio_group.radio_items.begin());
|
| + i != radio_group.radio_items.end(); ++i) {
|
| + views::RadioButton* radio = new views::RadioButton(UTF8ToUTF16(*i), 0);
|
| + radio->SetEnabled(bubble_content.radio_group_enabled);
|
| + radio->set_listener(this);
|
| + radio_group_.push_back(radio);
|
| + layout->StartRow(0, indented_kSingleColumnSetId);
|
| + layout->AddView(radio);
|
| + bubble_content_empty = false;
|
| + }
|
| + DCHECK(!radio_group_.empty());
|
| + // 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);
|
| + }
|
| +
|
| + // Layout code for the media device menus.
|
| + if (content_setting_bubble_model_->content_type() ==
|
| + CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
|
| + const int kMediaMenuColumnSetId = 2;
|
| + views::ColumnSet* menu_column_set =
|
| + layout->AddColumnSet(kMediaMenuColumnSetId);
|
| + menu_column_set->AddPaddingColumn(
|
| + 0, chrome_style::kCheckboxIndent);
|
| + menu_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 0,
|
| + GridLayout::USE_PREF, 0, 0);
|
| + menu_column_set->AddPaddingColumn(
|
| + 0, views::kRelatedControlHorizontalSpacing);
|
| + menu_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
|
| + GridLayout::USE_PREF, 0, 0);
|
| +
|
| + int menu_width = 0;
|
| + for (ContentSettingBubbleModel::MediaMenuMap::const_iterator i(
|
| + bubble_content.media_menus.begin());
|
| + i != bubble_content.media_menus.end(); ++i) {
|
| + if (!bubble_content_empty)
|
| + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| + layout->StartRow(0, kMediaMenuColumnSetId);
|
| +
|
| + views::Label* label = new views::Label(UTF8ToUTF16(i->second.label));
|
| + label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| +
|
| + views::MenuButton* menu_button = new views::MenuButton(
|
| + NULL, UTF8ToUTF16((i->second.selected_device.name)), this, false);
|
| + menu_button->set_alignment(views::TextButton::ALIGN_LEFT);
|
| + menu_button->set_border(
|
| + new views::TextButtonNativeThemeBorder(menu_button));
|
| + menu_button->set_animate_on_state_change(false);
|
| +
|
| + MediaMenuParts* menu_view = new MediaMenuParts(i->first);
|
| + menu_view->menu_model.reset(new ContentSettingMediaMenuModel(
|
| + i->first,
|
| + content_setting_bubble_model_.get(),
|
| + base::Bind(&ContentSettingBubbleContents::UpdateMenuLabel,
|
| + base::Unretained(this))));
|
| + media_menus_[menu_button] = menu_view;
|
| +
|
| + // Use the longest width of the menus as the width of the menu buttons.
|
| + menu_width = std::max(menu_width,
|
| + GetPreferredMediaMenuWidth(
|
| + menu_button, menu_view->menu_model.get()));
|
| +
|
| + layout->AddView(label);
|
| + layout->AddView(menu_button);
|
| +
|
| + bubble_content_empty = false;
|
| + }
|
| +
|
| + // Make sure the width is within [kMinMediaMenuButtonWidth,
|
| + // kMaxMediaMenuButtonWidth].
|
| + menu_width = std::max(kMinMediaMenuButtonWidth, menu_width);
|
| + menu_width = std::min(kMaxMediaMenuButtonWidth, menu_width);
|
| +
|
| + // Set all the menu buttons to the width we calculated above.
|
| + for (MediaMenuPartsMap::const_iterator i = media_menus_.begin();
|
| + i != media_menus_.end(); ++i) {
|
| + i->first->set_min_width(menu_width);
|
| + i->first->set_max_width(menu_width);
|
| + }
|
| + }
|
| +
|
| + gfx::Font domain_font =
|
| + views::Label().font().DeriveFont(0, gfx::Font::BOLD);
|
| + for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i(
|
| + bubble_content.domain_lists.begin());
|
| + i != bubble_content.domain_lists.end(); ++i) {
|
| + layout->StartRow(0, kSingleColumnSetId);
|
| + views::Label* section_title = new views::Label(UTF8ToUTF16(i->title));
|
| + section_title->SetMultiLine(true);
|
| + section_title->SetHorizontalAlignment(gfx::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_kSingleColumnSetId);
|
| + layout->AddView(new views::Label(UTF8ToUTF16(*j), domain_font));
|
| + }
|
| + bubble_content_empty = false;
|
| + }
|
| +
|
| + if (!bubble_content.custom_link.empty()) {
|
| + custom_link_ = new views::Link(UTF8ToUTF16(bubble_content.custom_link));
|
| + custom_link_->SetEnabled(bubble_content.custom_link_enabled);
|
| + custom_link_->set_listener(this);
|
| + if (!bubble_content_empty)
|
| + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| + layout->StartRow(0, kSingleColumnSetId);
|
| + layout->AddView(custom_link_);
|
| + bubble_content_empty = false;
|
| + }
|
| +
|
| + if (!bubble_content_empty) {
|
| + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| + layout->StartRow(0, kSingleColumnSetId);
|
| + layout->AddView(new views::Separator, 1, 1,
|
| + GridLayout::FILL, GridLayout::FILL);
|
| + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| + }
|
| +
|
| + const int kDoubleColumnSetId = 1;
|
| + views::ColumnSet* double_column_set =
|
| + layout->AddColumnSet(kDoubleColumnSetId);
|
| + double_column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
|
| + GridLayout::USE_PREF, 0, 0);
|
| + double_column_set->AddPaddingColumn(
|
| + 0, views::kUnrelatedControlHorizontalSpacing);
|
| + double_column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
|
| + GridLayout::USE_PREF, 0, 0);
|
| +
|
| + layout->StartRow(0, kDoubleColumnSetId);
|
| + manage_link_ = new views::Link(UTF8ToUTF16(bubble_content.manage_link));
|
| + manage_link_->set_listener(this);
|
| + layout->AddView(manage_link_);
|
| +
|
| + close_button_ = new views::NativeTextButton(
|
| + this, l10n_util::GetStringUTF16(IDS_DONE));
|
| + layout->AddView(close_button_);
|
| +}
|
| +
|
| +void ContentSettingBubbleContents::ButtonPressed(views::Button* sender,
|
| + const ui::Event& event) {
|
| + if (sender == close_button_) {
|
| + content_setting_bubble_model_->OnDoneClicked();
|
| + StartFade(false);
|
| + 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::LinkClicked(views::Link* source,
|
| + int event_flags) {
|
| + if (source == custom_link_) {
|
| + content_setting_bubble_model_->OnCustomLinkClicked();
|
| + StartFade(false);
|
| + return;
|
| + }
|
| + if (source == manage_link_) {
|
| + StartFade(false);
|
| + 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;
|
| + }
|
| +
|
| + PopupLinks::const_iterator i(popup_links_.find(source));
|
| + DCHECK(i != popup_links_.end());
|
| + content_setting_bubble_model_->OnPopupClicked(i->second);
|
| +}
|
| +
|
| +void ContentSettingBubbleContents::OnMenuButtonClicked(
|
| + views::View* source,
|
| + const gfx::Point& point) {
|
| + MediaMenuPartsMap::iterator i(media_menus_.find(
|
| + static_cast<views::MenuButton*>(source)));
|
| + DCHECK(i != media_menus_.end());
|
| +
|
| + views::MenuModelAdapter menu_model_adapter(i->second->menu_model.get());
|
| + menu_runner_.reset(new views::MenuRunner(menu_model_adapter.CreateMenu()));
|
| +
|
| + gfx::Point screen_location;
|
| + views::View::ConvertPointToScreen(i->first, &screen_location);
|
| + ignore_result(menu_runner_->RunMenuAt(
|
| + source->GetWidget(),
|
| + i->first,
|
| + gfx::Rect(screen_location, i->first->size()),
|
| + views::MenuItemView::TOPLEFT,
|
| + views::MenuRunner::HAS_MNEMONICS));
|
| +}
|
| +
|
| +void ContentSettingBubbleContents::Observe(
|
| + int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type);
|
| + DCHECK(source == content::Source<WebContents>(web_contents_));
|
| + web_contents_ = NULL;
|
| +}
|
| +
|
| +int ContentSettingBubbleContents::GetPreferredMediaMenuWidth(
|
| + views::MenuButton* button,
|
| + ui::SimpleMenuModel* menu_model) {
|
| + string16 title = button->text();
|
| +
|
| + int width = button->GetPreferredSize().width();
|
| + for (int i = 0; i < menu_model->GetItemCount(); ++i) {
|
| + button->SetText(menu_model->GetLabelAt(i));
|
| + width = std::max(width, button->GetPreferredSize().width());
|
| + }
|
| +
|
| + // Recover the title for the menu button.
|
| + button->SetText(title);
|
| + return width;
|
| +}
|
|
|