Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / content_setting_bubble_contents.cc
index d82392d..4bee4e0 100644 (file)
 #include "base/bind.h"
 #include "base/stl_util.h"
 #include "base/strings/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/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 "chrome/grit/generated_resources.h"
+#include "components/content_settings/core/browser/host_content_settings_map.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/base/resource/resource_bundle.h"
 #include "ui/gfx/font_list.h"
+#include "ui/gfx/text_utils.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/button/menu_button.h"
 #include "ui/views/controls/button/radio_button.h"
@@ -33,6 +33,7 @@
 #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_config.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/controls/separator.h"
 #include "ui/views/layout/grid_layout.h"
@@ -53,7 +54,7 @@ const int kMaxContentsWidth = 500;
 const int kMinMultiLineContentsWidth = 250;
 
 // The minimum width of the media menu buttons.
-const int kMinMediaMenuButtonWidth = 100;
+const int kMinMediaMenuButtonWidth = 150;
 
 }  // namespace
 
@@ -68,13 +69,13 @@ class ContentSettingBubbleContents::Favicon : public views::ImageView {
   Favicon(const gfx::Image& image,
           ContentSettingBubbleContents* parent,
           views::Link* link);
-  virtual ~Favicon();
+  ~Favicon() override;
 
  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;
+  bool OnMousePressed(const ui::MouseEvent& event) override;
+  void OnMouseReleased(const ui::MouseEvent& event) override;
+  gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override;
 
   ContentSettingBubbleContents* parent_;
   views::Link* link_;
@@ -139,12 +140,15 @@ ContentSettingBubbleContents::MediaMenuParts::~MediaMenuParts() {}
 
 ContentSettingBubbleContents::ContentSettingBubbleContents(
     ContentSettingBubbleModel* content_setting_bubble_model,
+    content::WebContents* web_contents,
     views::View* anchor_view,
     views::BubbleBorder::Arrow arrow)
-    : BubbleDelegateView(anchor_view, arrow),
+    : content::WebContentsObserver(web_contents),
+      BubbleDelegateView(anchor_view, arrow),
       content_setting_bubble_model_(content_setting_bubble_model),
       custom_link_(NULL),
       manage_link_(NULL),
+      learn_more_link_(NULL),
       close_button_(NULL) {
   // Compensate for built-in vertical padding in the anchor view's image.
   set_anchor_view_insets(gfx::Insets(5, 0, 5, 0));
@@ -154,7 +158,7 @@ ContentSettingBubbleContents::~ContentSettingBubbleContents() {
   STLDeleteValues(&media_menus_);
 }
 
-gfx::Size ContentSettingBubbleContents::GetPreferredSize() {
+gfx::Size ContentSettingBubbleContents::GetPreferredSize() const {
   gfx::Size preferred_size(views::View::GetPreferredSize());
   int preferred_width =
       (!content_setting_bubble_model_->bubble_content().domain_lists.empty() &&
@@ -187,6 +191,9 @@ void ContentSettingBubbleContents::Init() {
   views::ColumnSet* column_set = layout->AddColumnSet(kSingleColumnSetId);
   column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
                         GridLayout::USE_PREF, 0, 0);
+  column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
+  column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
+                        GridLayout::USE_PREF, 0, 0);
 
   const ContentSettingBubbleModel::BubbleContent& bubble_content =
       content_setting_bubble_model_->bubble_content();
@@ -202,6 +209,15 @@ void ContentSettingBubbleContents::Init() {
     bubble_content_empty = false;
   }
 
+  if (!bubble_content.learn_more_link.empty()) {
+    learn_more_link_ =
+        new views::Link(base::UTF8ToUTF16(bubble_content.learn_more_link));
+    learn_more_link_->set_listener(this);
+    learn_more_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    layout->AddView(learn_more_link_);
+    bubble_content_empty = false;
+  }
+
   if (content_setting_bubble_model_->content_type() ==
       CONTENT_SETTINGS_TYPE_POPUPS) {
     const int kPopupColumnSetId = 2;
@@ -223,7 +239,7 @@ void ContentSettingBubbleContents::Init() {
 
       views::Link* link = new views::Link(base::UTF8ToUTF16(i->title));
       link->set_listener(this);
-      link->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE);
+      link->SetElideBehavior(gfx::ELIDE_MIDDLE);
       popup_links_[link] = i - bubble_content.popup_items.begin();
       layout->AddView(new Favicon(i->image, this, link));
       layout->AddView(link);
@@ -276,7 +292,6 @@ void ContentSettingBubbleContents::Init() {
     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) {
@@ -291,9 +306,8 @@ void ContentSettingBubbleContents::Init() {
       views::MenuButton* menu_button = new views::MenuButton(
           NULL, base::UTF8ToUTF16((i->second.selected_device.name)),
           this, true);
-      menu_button->set_alignment(views::TextButton::ALIGN_LEFT);
-      menu_button->SetBorder(scoped_ptr<views::Border>(
-          new views::TextButtonNativeThemeBorder(menu_button)));
+      menu_button->SetStyle(views::Button::STYLE_BUTTON);
+      menu_button->SetHorizontalAlignment(gfx::ALIGN_LEFT);
       menu_button->set_animate_on_state_change(false);
 
       MediaMenuParts* menu_view = new MediaMenuParts(i->first);
@@ -317,29 +331,15 @@ void ContentSettingBubbleContents::Init() {
       if (i->second.disabled)
         menu_button->SetEnabled(false);
 
-      // 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 at least kMinMediaMenuButtonWidth. The
-    // maximum width will be clamped by kMaxContentsWidth of the view.
-    menu_width = std::max(kMinMediaMenuButtonWidth, 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);
-    }
   }
 
+  UpdateMenuButtonSizes(GetNativeTheme());
+
   const gfx::FontList& domain_font =
       ui::ResourceBundle::GetSharedInstance().GetFontList(
           ui::ResourceBundle::BoldFont);
@@ -401,6 +401,21 @@ void ContentSettingBubbleContents::Init() {
     layout->AddView(close_button_);
 }
 
+void ContentSettingBubbleContents::DidNavigateMainFrame(
+    const content::LoadCommittedDetails& details,
+    const content::FrameNavigateParams& params) {
+  // Content settings are based on the main frame, so if it switches then
+  // close up shop.
+  content_setting_bubble_model_->OnDoneClicked();
+  GetWidget()->Close();
+}
+
+void ContentSettingBubbleContents::OnNativeThemeChanged(
+    const ui::NativeTheme* theme) {
+  views::BubbleDelegateView::OnNativeThemeChanged(theme);
+  UpdateMenuButtonSizes(theme);
+}
+
 void ContentSettingBubbleContents::ButtonPressed(views::Button* sender,
                                                  const ui::Event& event) {
   RadioGroup::const_iterator i(
@@ -416,6 +431,11 @@ void ContentSettingBubbleContents::ButtonPressed(views::Button* sender,
 
 void ContentSettingBubbleContents::LinkClicked(views::Link* source,
                                                int event_flags) {
+  if (source == learn_more_link_) {
+    content_setting_bubble_model_->OnLearnMoreLinkClicked();
+    GetWidget()->Close();
+    return;
+  }
   if (source == custom_link_) {
     content_setting_bubble_model_->OnCustomLinkClicked();
     GetWidget()->Close();
@@ -440,31 +460,49 @@ void ContentSettingBubbleContents::OnMenuButtonClicked(
     MediaMenuPartsMap::iterator j(media_menus_.find(
         static_cast<views::MenuButton*>(source)));
     DCHECK(j != media_menus_.end());
-    menu_runner_.reset(new views::MenuRunner(j->second->menu_model.get()));
+    menu_runner_.reset(new views::MenuRunner(j->second->menu_model.get(),
+                                             views::MenuRunner::HAS_MNEMONICS));
 
     gfx::Point screen_location;
     views::View::ConvertPointToScreen(j->first, &screen_location);
-    ignore_result(menu_runner_->RunMenuAt(
-        source->GetWidget(),
-        j->first,
-        gfx::Rect(screen_location, j->first->size()),
-        views::MenuItemView::TOPLEFT,
-        ui::MENU_SOURCE_NONE,
-        views::MenuRunner::HAS_MNEMONICS));
+    ignore_result(
+        menu_runner_->RunMenuAt(source->GetWidget(),
+                                j->first,
+                                gfx::Rect(screen_location, j->first->size()),
+                                views::MENU_ANCHOR_TOPLEFT,
+                                ui::MENU_SOURCE_NONE));
 }
 
-int ContentSettingBubbleContents::GetPreferredMediaMenuWidth(
-    views::MenuButton* button,
-    ui::SimpleMenuModel* menu_model) {
-  base::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());
+void ContentSettingBubbleContents::UpdateMenuButtonSizes(
+    const ui::NativeTheme* theme) {
+  const views::MenuConfig config = views::MenuConfig(theme);
+  const int margins = config.item_left_margin + config.check_width +
+                      config.label_to_arrow_padding + config.arrow_width +
+                      config.arrow_to_edge_padding;
+
+  // The preferred media menu size sort of copies the logic in
+  // MenuItemView::CalculateDimensions(). When this was using TextButton, it
+  // completely coincidentally matched the logic in MenuItemView. We now need
+  // to redo this manually.
+  int menu_width = 0;
+  for (MediaMenuPartsMap::const_iterator i = media_menus_.begin();
+       i != media_menus_.end(); ++i) {
+    for (int j = 0; j < i->second->menu_model->GetItemCount(); ++j) {
+      int string_width = gfx::GetStringWidth(
+          i->second->menu_model->GetLabelAt(j),
+          config.font_list);
+
+      menu_width = std::max(menu_width, string_width);
+    }
   }
 
-  // Recover the title for the menu button.
-  button->SetText(title);
-  return width;
+  // Make sure the width is at least kMinMediaMenuButtonWidth. The
+  // maximum width will be clamped by kMaxContentsWidth of the view.
+  menu_width = std::max(kMinMediaMenuButtonWidth, menu_width + margins);
+
+  for (MediaMenuPartsMap::const_iterator i = media_menus_.begin();
+       i != media_menus_.end(); ++i) {
+    i->first->SetMinSize(gfx::Size(menu_width, 0));
+    i->first->SetMaxSize(gfx::Size(menu_width, 0));
+  }
 }