1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/certificate_viewer.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/views/collected_cookies_views.h"
14 #include "chrome/browser/ui/views/website_settings/permission_selector_view.h"
15 #include "chrome/browser/ui/website_settings/website_settings.h"
16 #include "chrome/browser/ui/website_settings/website_settings_utils.h"
17 #include "chrome/common/content_settings_types.h"
18 #include "chrome/common/url_constants.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/cert_store.h"
21 #include "content/public/browser/user_metrics.h"
22 #include "grit/chromium_strings.h"
23 #include "grit/generated_resources.h"
24 #include "grit/theme_resources.h"
25 #include "grit/ui_resources.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/models/simple_menu_model.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/font.h"
31 #include "ui/gfx/image/image.h"
32 #include "ui/gfx/insets.h"
33 #include "ui/views/controls/button/image_button.h"
34 #include "ui/views/controls/button/menu_button.h"
35 #include "ui/views/controls/button/menu_button_listener.h"
36 #include "ui/views/controls/image_view.h"
37 #include "ui/views/controls/label.h"
38 #include "ui/views/controls/link.h"
39 #include "ui/views/controls/menu/menu_model_adapter.h"
40 #include "ui/views/controls/menu/menu_runner.h"
41 #include "ui/views/controls/separator.h"
42 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
43 #include "ui/views/layout/box_layout.h"
44 #include "ui/views/layout/grid_layout.h"
45 #include "ui/views/layout/layout_manager.h"
46 #include "ui/views/view.h"
47 #include "ui/views/widget/widget.h"
52 // Padding values for sections on the connection tab.
53 const int kConnectionSectionPaddingBottom = 16;
54 const int kConnectionSectionPaddingLeft = 18;
55 const int kConnectionSectionPaddingTop = 16;
56 const int kConnectionSectionPaddingRight = 18;
58 // Font size of the label for the site identity.
59 const int kIdentityNameFontSize = 14;
60 // The text color that is used for the site identity status text, if the site's
61 // identity was sucessfully verified.
62 const int kIdentityVerifiedTextColor = 0xFF298a27;
65 const int kIconMarginLeft = 6;
67 // Margin and padding values for the |PopupHeaderView|.
68 const int kHeaderMarginBottom = 10;
69 const int kHeaderPaddingBottom = 12;
70 const int kHeaderPaddingLeft = 18;
71 const int kHeaderPaddingRight = 8;
72 const int kHeaderPaddingTop = 12;
74 // Spacing between the site identity label and the site identity status text in
76 const int kHeaderRowSpacing = 4;
78 // To make the bubble's arrow point directly at the location icon rather than at
79 // the Omnibox's edge, inset the bubble's anchor rect by this amount of pixels.
80 const int kLocationIconVerticalMargin = 5;
82 // The max possible width of the popup.
83 const int kMaxPopupWidth = 500;
85 // The margins between the popup border and the popup content.
86 const int kPopupMarginTop = 4;
87 const int kPopupMarginLeft = 0;
88 const int kPopupMarginBottom = 10;
89 const int kPopupMarginRight = 0;
91 // Padding values for sections on the permissions tab.
92 const int kPermissionsSectionContentMinWidth = 300;
93 const int kPermissionsSectionPaddingBottom = 6;
94 const int kPermissionsSectionPaddingLeft = 18;
95 const int kPermissionsSectionPaddingTop = 16;
97 // Space between the headline and the content of a section on the permissions
99 const int kPermissionsSectionHeadlineMarginBottom = 10;
100 // The content of the "Permissions" section and the "Cookies and Site Data"
101 // section is structured in individual rows. |kPermissionsSectionRowSpacing|
102 // is the space between these rows.
103 const int kPermissionsSectionRowSpacing = 2;
105 const int kSiteDataIconColumnWidth = 20;
106 const int kSiteDataSectionRowSpacing = 11;
110 // |PopupHeaderView| is the UI element (view) that represents the header of the
111 // |WebsiteSettingsPopupView|. The header shows the status of the site's
112 // identity check and the name of the site's identity.
113 class PopupHeaderView : public views::View {
115 explicit PopupHeaderView(views::ButtonListener* close_button_listener);
116 virtual ~PopupHeaderView();
118 // Sets the name of the site's identity.
119 void SetIdentityName(const string16& name);
121 // Sets the |status_text| for the identity check of this site and the
123 void SetIdentityStatus(const string16& status_text, SkColor text_color);
126 // The label that displays the name of the site's identity.
128 // The label that displays the status of the identity check for this site.
129 views::Label* status_;
131 DISALLOW_COPY_AND_ASSIGN(PopupHeaderView);
134 // Website Settings are not supported for internal Chrome pages. Instead of the
135 // |WebsiteSettingsPopupView|, the |InternalPageInfoPopupView| is
137 class InternalPageInfoPopupView : public views::BubbleDelegateView {
139 explicit InternalPageInfoPopupView(views::View* anchor_view);
140 virtual ~InternalPageInfoPopupView();
143 DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupView);
146 ////////////////////////////////////////////////////////////////////////////////
148 ////////////////////////////////////////////////////////////////////////////////
150 PopupHeaderView::PopupHeaderView(views::ButtonListener* close_button_listener)
151 : name_(NULL), status_(NULL) {
152 views::GridLayout* layout = new views::GridLayout(this);
153 SetLayoutManager(layout);
155 const int label_column = 0;
156 views::ColumnSet* column_set = layout->AddColumnSet(label_column);
157 column_set->AddPaddingColumn(0, kHeaderPaddingLeft);
158 column_set->AddColumn(views::GridLayout::FILL,
159 views::GridLayout::FILL,
161 views::GridLayout::USE_PREF,
164 column_set->AddPaddingColumn(1,0);
165 column_set->AddColumn(views::GridLayout::FILL,
166 views::GridLayout::FILL,
168 views::GridLayout::USE_PREF,
171 column_set->AddPaddingColumn(0, kHeaderPaddingRight);
173 layout->AddPaddingRow(0, kHeaderPaddingTop);
175 layout->StartRow(0, label_column);
176 name_ = new views::Label(string16());
177 gfx::Font headline_font(name_->font().GetFontName(), kIdentityNameFontSize);
178 name_->SetFont(headline_font.DeriveFont(0, gfx::Font::BOLD));
179 layout->AddView(name_, 1, 1, views::GridLayout::LEADING,
180 views::GridLayout::TRAILING);
181 views::ImageButton* close_button =
182 new views::ImageButton(close_button_listener);
183 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
184 close_button->SetImage(views::CustomButton::STATE_NORMAL,
185 rb.GetImageNamed(IDR_CLOSE_2).ToImageSkia());
186 close_button->SetImage(views::CustomButton::STATE_HOVERED,
187 rb.GetImageNamed(IDR_CLOSE_2_H).ToImageSkia());
188 close_button->SetImage(views::CustomButton::STATE_PRESSED,
189 rb.GetImageNamed(IDR_CLOSE_2_P).ToImageSkia());
190 layout->AddView(close_button, 1, 1, views::GridLayout::TRAILING,
191 views::GridLayout::LEADING);
193 layout->AddPaddingRow(0, kHeaderRowSpacing);
195 layout->StartRow(0, label_column);
196 status_ = new views::Label(string16());
197 layout->AddView(status_,
200 views::GridLayout::LEADING,
201 views::GridLayout::CENTER);
203 layout->AddPaddingRow(0, kHeaderPaddingBottom);
206 PopupHeaderView::~PopupHeaderView() {
209 void PopupHeaderView::SetIdentityName(const string16& name) {
210 name_->SetText(name);
213 void PopupHeaderView::SetIdentityStatus(const string16& status,
214 SkColor text_color) {
215 status_->SetText(status);
216 status_->SetEnabledColor(text_color);
219 ////////////////////////////////////////////////////////////////////////////////
220 // InternalPageInfoPopupView
221 ////////////////////////////////////////////////////////////////////////////////
223 InternalPageInfoPopupView::InternalPageInfoPopupView(views::View* anchor_view)
224 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT) {
225 // Compensate for built-in vertical padding in the anchor view's image.
226 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin, 0,
227 kLocationIconVerticalMargin, 0));
229 const int kSpacing = 4;
230 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, kSpacing,
231 kSpacing, kSpacing));
232 views::ImageView* icon_view = new views::ImageView();
233 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
234 icon_view->SetImage(rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_26));
235 AddChildView(icon_view);
237 views::Label* label =
238 new views::Label(l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE));
239 label->SetMultiLine(true);
240 label->SetAllowCharacterBreak(true);
241 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
244 views::BubbleDelegateView::CreateBubble(this)->Show();
248 InternalPageInfoPopupView::~InternalPageInfoPopupView() {
251 ////////////////////////////////////////////////////////////////////////////////
252 // WebsiteSettingsPopupView
253 ////////////////////////////////////////////////////////////////////////////////
255 WebsiteSettingsPopupView::~WebsiteSettingsPopupView() {
259 void WebsiteSettingsPopupView::ShowPopup(views::View* anchor_view,
261 content::WebContents* web_contents,
263 const content::SSLStatus& ssl,
265 if (InternalChromePage(url)) {
266 new InternalPageInfoPopupView(anchor_view);
268 new WebsiteSettingsPopupView(anchor_view, profile, web_contents, url, ssl,
273 WebsiteSettingsPopupView::WebsiteSettingsPopupView(
274 views::View* anchor_view,
276 content::WebContents* web_contents,
278 const content::SSLStatus& ssl,
280 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
281 web_contents_(web_contents),
285 site_data_content_(NULL),
286 cookie_dialog_link_(NULL),
287 permissions_content_(NULL),
288 connection_tab_(NULL),
289 identity_info_content_(NULL),
290 certificate_dialog_link_(NULL),
292 help_center_link_(NULL),
293 connection_info_content_(NULL),
294 page_info_content_(NULL),
295 weak_factory_(this) {
296 // Compensate for built-in vertical padding in the anchor view's image.
297 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin, 0,
298 kLocationIconVerticalMargin, 0));
300 views::GridLayout* layout = new views::GridLayout(this);
301 SetLayoutManager(layout);
302 const int content_column = 0;
303 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
304 column_set->AddColumn(views::GridLayout::FILL,
305 views::GridLayout::FILL,
307 views::GridLayout::USE_PREF,
311 header_ = new PopupHeaderView(this);
312 layout->StartRow(1, content_column);
313 layout->AddView(header_);
315 layout->AddPaddingRow(1, kHeaderMarginBottom);
316 tabbed_pane_ = new views::TabbedPane(false);
317 layout->StartRow(1, content_column);
318 layout->AddView(tabbed_pane_);
319 // Tabs must be added after the tabbed_pane_ was added to the views
320 // hierachy. Adding the |tabbed_pane_| to the views hierachy triggers the
321 // initialization of the native tab UI element. If the native tab UI
322 // element is not initalized adding a tab will result in a NULL pointer
324 tabbed_pane_->AddTabAtIndex(
326 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS),
327 CreatePermissionsTab());
328 connection_tab_ = CreateConnectionTab();
329 tabbed_pane_->AddTabAtIndex(
331 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION),
333 DCHECK_EQ(tabbed_pane_->GetTabCount(), NUM_TAB_IDS);
334 tabbed_pane_->set_listener(this);
336 set_margins(gfx::Insets(kPopupMarginTop, kPopupMarginLeft,
337 kPopupMarginBottom, kPopupMarginRight));
339 views::BubbleDelegateView::CreateBubble(this)->Show();
342 presenter_.reset(new WebsiteSettings(
344 TabSpecificContentSettings::FromWebContents(web_contents),
345 InfoBarService::FromWebContents(web_contents), url, ssl,
346 content::CertStore::GetInstance()));
349 void WebsiteSettingsPopupView::OnPermissionChanged(
350 PermissionSelectorView* permission_selector) {
351 DCHECK(permission_selector);
352 presenter_->OnSitePermissionChanged(permission_selector->type(),
353 permission_selector->current_setting());
356 void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget* widget) {
357 presenter_->OnUIClosing();
360 void WebsiteSettingsPopupView::ButtonPressed(
361 views::Button* button,
362 const ui::Event& event) {
363 GetWidget()->Close();
366 void WebsiteSettingsPopupView::LinkClicked(views::Link* source,
368 // The popup closes automatically when the collected cookies dialog or the
369 // certificate viewer opens. So delay handling of the link clicked to avoid
370 // a crash in the base class which needs to complete the mouse event handling.
371 content::BrowserThread::PostTask(
372 content::BrowserThread::UI, FROM_HERE,
373 base::Bind(&WebsiteSettingsPopupView::HandleLinkClickedAsync,
374 weak_factory_.GetWeakPtr(), source));
377 void WebsiteSettingsPopupView::TabSelectedAt(int index) {
378 tabbed_pane_->GetSelectedTab()->Layout();
382 gfx::Size WebsiteSettingsPopupView::GetPreferredSize() {
383 if (header_ == NULL && tabbed_pane_ == NULL)
384 return views::View::GetPreferredSize();
388 height += header_->GetPreferredSize().height();
390 height += tabbed_pane_->GetPreferredSize().height();
392 int width = kPermissionsSectionContentMinWidth;
393 if (site_data_content_)
394 width = std::max(width, site_data_content_->GetPreferredSize().width());
395 if (permissions_content_)
396 width = std::max(width, permissions_content_->GetPreferredSize().width());
397 width += kPermissionsSectionPaddingLeft;
398 width = std::min(width, kMaxPopupWidth);
400 return gfx::Size(width, height);
403 void WebsiteSettingsPopupView::SetCookieInfo(
404 const CookieInfoList& cookie_info_list) {
405 site_data_content_->RemoveAllChildViews(true);
407 views::GridLayout* layout = new views::GridLayout(site_data_content_);
408 site_data_content_->SetLayoutManager(layout);
410 const int site_data_content_column = 0;
411 views::ColumnSet* column_set =
412 layout->AddColumnSet(site_data_content_column);
413 column_set->AddColumn(views::GridLayout::FILL,
414 views::GridLayout::FILL,
416 views::GridLayout::FIXED,
417 kSiteDataIconColumnWidth,
419 column_set->AddPaddingColumn(0, kIconMarginLeft);
420 column_set->AddColumn(views::GridLayout::FILL,
421 views::GridLayout::FILL,
423 views::GridLayout::USE_PREF,
427 layout->AddPaddingRow(1, 5);
428 for (CookieInfoList::const_iterator i(cookie_info_list.begin());
429 i != cookie_info_list.end();
431 string16 label_text = l10n_util::GetStringFUTF16(
432 IDS_WEBSITE_SETTINGS_SITE_DATA_STATS_LINE,
433 UTF8ToUTF16(i->cookie_source),
434 base::IntToString16(i->allowed),
435 base::IntToString16(i->blocked));
436 if (i != cookie_info_list.begin())
437 layout->AddPaddingRow(1, kSiteDataSectionRowSpacing);
438 layout->StartRow(1, site_data_content_column);
439 views::ImageView* icon = new views::ImageView();
440 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(
441 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_ALLOW);
442 icon->SetImage(image.ToImageSkia());
443 layout->AddView(icon, 1, 1, views::GridLayout::CENTER,
444 views::GridLayout::CENTER);
445 layout->AddView(new views::Label(label_text), 1, 1,
446 views::GridLayout::LEADING, views::GridLayout::CENTER);
448 layout->AddPaddingRow(1, 6);
450 layout->Layout(site_data_content_);
454 void WebsiteSettingsPopupView::SetPermissionInfo(
455 const PermissionInfoList& permission_info_list) {
456 permissions_content_->RemoveAllChildViews(true);
458 views::GridLayout* layout =
459 new views::GridLayout(permissions_content_);
460 permissions_content_->SetLayoutManager(layout);
461 const int content_column = 0;
462 views::ColumnSet* column_set =
463 layout->AddColumnSet(content_column);
464 column_set->AddColumn(views::GridLayout::FILL,
465 views::GridLayout::FILL,
467 views::GridLayout::USE_PREF,
470 for (PermissionInfoList::const_iterator permission =
471 permission_info_list.begin();
472 permission != permission_info_list.end();
474 layout->StartRow(1, content_column);
475 PermissionSelectorView* selector = new PermissionSelectorView(
476 web_contents_ ? web_contents_->GetURL() : GURL::EmptyGURL(),
478 permission->default_setting,
481 selector->AddObserver(this);
482 layout->AddView(selector,
485 views::GridLayout::LEADING,
486 views::GridLayout::CENTER);
487 layout->AddPaddingRow(1, kPermissionsSectionRowSpacing);
493 void WebsiteSettingsPopupView::SetIdentityInfo(
494 const IdentityInfo& identity_info) {
495 string16 identity_status_text;
496 SkColor text_color = SK_ColorBLACK;
497 switch (identity_info.identity_status) {
498 case WebsiteSettings::SITE_IDENTITY_STATUS_CERT:
499 case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT:
500 identity_status_text =
501 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_VERIFIED);
502 text_color = kIdentityVerifiedTextColor;
504 case WebsiteSettings::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT:
505 identity_status_text =
506 l10n_util::GetStringUTF16(IDS_CERT_POLICY_PROVIDED_CERT_HEADER);
509 identity_status_text =
510 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_NOT_VERIFIED);
513 header_->SetIdentityName(UTF8ToUTF16(identity_info.site_identity));
514 header_->SetIdentityStatus(identity_status_text, text_color);
516 // The headline and the certificate dialog link of the site's identity
517 // section is only displayed if the site's identity was verified. If the
518 // site's identity was verified, then the headline contains the organization
519 // name from the provided certificate. If the organization name is not
520 // available than the hostname of the site is used instead.
522 if (identity_info.cert_id) {
523 cert_id_ = identity_info.cert_id;
524 certificate_dialog_link_ = new views::Link(
525 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON));
526 certificate_dialog_link_->set_listener(this);
527 headline = UTF8ToUTF16(identity_info.site_identity);
529 ResetConnectionSection(
530 identity_info_content_,
531 WebsiteSettingsUI::GetIdentityIcon(identity_info.identity_status),
532 string16(), // The identity section has no headline.
533 UTF8ToUTF16(identity_info.identity_status_description),
534 certificate_dialog_link_);
536 ResetConnectionSection(
537 connection_info_content_,
538 WebsiteSettingsUI::GetConnectionIcon(identity_info.connection_status),
539 string16(), // The connection section has no headline.
540 UTF8ToUTF16(identity_info.connection_status_description),
543 connection_tab_->InvalidateLayout();
548 void WebsiteSettingsPopupView::SetFirstVisit(const string16& first_visit) {
549 ResetConnectionSection(
551 WebsiteSettingsUI::GetFirstVisitIcon(first_visit),
552 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE),
555 connection_tab_->InvalidateLayout();
560 void WebsiteSettingsPopupView::SetSelectedTab(TabId tab_id) {
561 tabbed_pane_->SelectTabAt(tab_id);
564 views::View* WebsiteSettingsPopupView::CreatePermissionsTab() {
565 views::View* pane = new views::View();
566 pane->SetLayoutManager(
567 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
568 // Add cookies and site data section.
569 cookie_dialog_link_ = new views::Link(
570 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_SHOW_SITE_DATA));
571 cookie_dialog_link_->set_listener(this);
572 site_data_content_ = new views::View();
573 views::View* site_data_section =
574 CreateSection(l10n_util::GetStringUTF16(
575 IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA),
577 cookie_dialog_link_);
578 pane->AddChildView(site_data_section);
579 // Add permissions section.
580 permissions_content_ = new views::View();
581 views::View* permissions_section =
582 CreateSection(l10n_util::GetStringUTF16(
583 IDS_WEBSITE_SETTINGS_TITLE_SITE_PERMISSIONS),
584 permissions_content_,
586 pane->AddChildView(permissions_section);
590 views::View* WebsiteSettingsPopupView::CreateConnectionTab() {
591 views::View* pane = new views::View();
592 pane->SetLayoutManager(
593 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
594 // Add site identity section.
595 identity_info_content_ = new views::View();
596 pane->AddChildView(identity_info_content_);
598 // Add connection section.
599 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL));
600 connection_info_content_ = new views::View();
601 pane->AddChildView(connection_info_content_);
603 // Add page info section.
604 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL));
605 page_info_content_ = new views::View();
606 pane->AddChildView(page_info_content_);
608 // Add help center link.
609 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL));
610 help_center_link_ = new views::Link(
611 l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER_LINK));
612 help_center_link_->set_listener(this);
613 views::View* link_section = new views::View();
614 const int kLinkMarginTop = 4;
615 link_section->SetLayoutManager(
616 new views::BoxLayout(views::BoxLayout::kHorizontal,
617 kConnectionSectionPaddingLeft,
620 link_section->AddChildView(help_center_link_);
621 pane->AddChildView(link_section);
625 views::View* WebsiteSettingsPopupView::CreateSection(
626 const string16& headline_text,
627 views::View* content,
629 views::View* container = new views::View();
630 views::GridLayout* layout = new views::GridLayout(container);
631 container->SetLayoutManager(layout);
632 const int content_column = 0;
633 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
634 column_set->AddPaddingColumn(0, kPermissionsSectionPaddingLeft);
635 column_set->AddColumn(views::GridLayout::FILL,
636 views::GridLayout::FILL,
638 views::GridLayout::USE_PREF,
642 layout->AddPaddingRow(1, kPermissionsSectionPaddingTop);
643 layout->StartRow(1, content_column);
644 views::Label* headline = new views::Label(headline_text);
645 headline->SetFont(headline->font().DeriveFont(0, gfx::Font::BOLD));
646 layout->AddView(headline, 1, 1, views::GridLayout::LEADING,
647 views::GridLayout::CENTER);
649 layout->AddPaddingRow(1, kPermissionsSectionHeadlineMarginBottom);
650 layout->StartRow(1, content_column);
651 layout->AddView(content, 1, 1, views::GridLayout::LEADING,
652 views::GridLayout::CENTER);
655 layout->AddPaddingRow(1, 4);
656 layout->StartRow(1, content_column);
657 layout->AddView(link, 1, 1, views::GridLayout::LEADING,
658 views::GridLayout::CENTER);
661 layout->AddPaddingRow(1, kPermissionsSectionPaddingBottom);
665 void WebsiteSettingsPopupView::ResetConnectionSection(
666 views::View* section_container,
667 const gfx::Image& icon,
668 const string16& headline,
669 const string16& text,
671 section_container->RemoveAllChildViews(true);
673 views::GridLayout* layout = new views::GridLayout(section_container);
674 section_container->SetLayoutManager(layout);
675 views::ColumnSet* column_set = layout->AddColumnSet(0);
676 column_set->AddPaddingColumn(0, kConnectionSectionPaddingLeft);
677 column_set->AddColumn(views::GridLayout::LEADING,
678 views::GridLayout::LEADING,
680 views::GridLayout::USE_PREF,
683 column_set->AddPaddingColumn(0, kIconMarginLeft);
684 column_set->AddColumn(views::GridLayout::FILL,
685 views::GridLayout::FILL,
687 views::GridLayout::USE_PREF,
690 column_set->AddPaddingColumn(0, kConnectionSectionPaddingRight);
693 layout->AddPaddingRow(0, kConnectionSectionPaddingTop);
694 layout->StartRow(1, 0);
697 views::ImageView* icon_view = new views::ImageView();
698 icon_view->SetImage(*icon.ToImageSkia());
699 layout->AddView(icon_view, 1, 1, views::GridLayout::LEADING,
700 views::GridLayout::LEADING);
702 // Add section content.
703 views::View* content_pane = new views::View();
704 views::GridLayout* content_layout = new views::GridLayout(content_pane);
705 content_pane->SetLayoutManager(content_layout);
706 views::ColumnSet* content_column_set = content_layout->AddColumnSet(0);
707 content_column_set->AddColumn(views::GridLayout::LEADING,
708 views::GridLayout::LEADING,
710 views::GridLayout::USE_PREF,
713 if (!headline.empty()) {
714 views::Label* headline_label = new views::Label(headline);
715 headline_label->SetFont(
716 headline_label->font().DeriveFont(0, gfx::Font::BOLD));
717 headline_label->SetMultiLine(true);
718 headline_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
719 // Allow linebreaking in the middle of words if necessary, so that extremely
720 // long hostnames (longer than one line) will still be completely shown.
721 headline_label->SetAllowCharacterBreak(true);
722 content_layout->StartRow(1, 0);
723 content_layout->AddView(headline_label);
726 views::Label* description_label = new views::Label(text);
727 description_label->SetMultiLine(true);
728 description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
729 description_label->SetAllowCharacterBreak(true);
730 content_layout->StartRow(1, 0);
731 content_layout->AddView(description_label);
734 content_layout->StartRow(1, 0);
735 content_layout->AddView(link);
738 layout->AddView(content_pane, 1, 1, views::GridLayout::LEADING,
739 views::GridLayout::LEADING);
740 layout->AddPaddingRow(0, kConnectionSectionPaddingBottom);
743 // Used to asynchronously handle clicks since these calls may cause the
744 // destruction of the settings view and the base class window still
745 // needs to be alive to finish handling the mouse click.
746 void WebsiteSettingsPopupView::HandleLinkClickedAsync(views::Link* source) {
747 if (source == cookie_dialog_link_) {
748 // Count how often the Collected Cookies dialog is opened.
749 content::RecordAction(
750 content::UserMetricsAction("WebsiteSettings_CookiesDialogOpened"));
751 new CollectedCookiesViews(web_contents_);
752 } else if (source == certificate_dialog_link_) {
753 gfx::NativeWindow parent =
754 GetAnchorView() ? GetAnchorView()->GetWidget()->GetNativeWindow() :
756 ShowCertificateViewerByID(web_contents_, parent, cert_id_);
757 } else if (source == help_center_link_) {
758 browser_->OpenURL(content::OpenURLParams(
759 GURL(chrome::kPageInfoHelpCenterURL),
762 content::PAGE_TRANSITION_LINK,