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"
9 #include "base/command_line.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/certificate_viewer.h"
13 #include "chrome/browser/infobars/infobar_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_dialogs.h"
17 #include "chrome/browser/ui/views/collected_cookies_views.h"
18 #include "chrome/browser/ui/views/website_settings/permission_selector_view.h"
19 #include "chrome/browser/ui/website_settings/website_settings.h"
20 #include "chrome/browser/ui/website_settings/website_settings_utils.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/content_settings_types.h"
23 #include "chrome/common/url_constants.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/cert_store.h"
26 #include "content/public/browser/user_metrics.h"
27 #include "grit/chromium_strings.h"
28 #include "grit/generated_resources.h"
29 #include "grit/theme_resources.h"
30 #include "grit/ui_resources.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/models/simple_menu_model.h"
33 #include "ui/base/resource/resource_bundle.h"
34 #include "ui/gfx/canvas.h"
35 #include "ui/gfx/font_list.h"
36 #include "ui/gfx/image/image.h"
37 #include "ui/gfx/insets.h"
38 #include "ui/views/controls/button/image_button.h"
39 #include "ui/views/controls/button/menu_button.h"
40 #include "ui/views/controls/button/menu_button_listener.h"
41 #include "ui/views/controls/image_view.h"
42 #include "ui/views/controls/label.h"
43 #include "ui/views/controls/link.h"
44 #include "ui/views/controls/menu/menu_model_adapter.h"
45 #include "ui/views/controls/menu/menu_runner.h"
46 #include "ui/views/controls/separator.h"
47 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
48 #include "ui/views/layout/box_layout.h"
49 #include "ui/views/layout/grid_layout.h"
50 #include "ui/views/layout/layout_manager.h"
51 #include "ui/views/view.h"
52 #include "ui/views/widget/widget.h"
57 // Padding values for sections on the connection tab.
58 const int kConnectionSectionPaddingBottom
= 16;
59 const int kConnectionSectionPaddingLeft
= 18;
60 const int kConnectionSectionPaddingTop
= 16;
61 const int kConnectionSectionPaddingRight
= 18;
63 // The text color that is used for the site identity status text, if the site's
64 // identity was sucessfully verified.
65 const int kIdentityVerifiedTextColor
= 0xFF298a27;
68 const int kIconMarginLeft
= 6;
70 // Margin and padding values for the |PopupHeaderView|.
71 const int kHeaderMarginBottom
= 10;
72 const int kHeaderPaddingBottom
= 12;
73 const int kHeaderPaddingLeft
= 18;
74 const int kHeaderPaddingRight
= 8;
75 const int kHeaderPaddingTop
= 12;
77 // Spacing between the site identity label and the site identity status text in
79 const int kHeaderRowSpacing
= 4;
81 // To make the bubble's arrow point directly at the location icon rather than at
82 // the Omnibox's edge, inset the bubble's anchor rect by this amount of pixels.
83 const int kLocationIconVerticalMargin
= 5;
85 // The max possible width of the popup.
86 const int kMaxPopupWidth
= 500;
88 // The margins between the popup border and the popup content.
89 const int kPopupMarginTop
= 4;
90 const int kPopupMarginLeft
= 0;
91 const int kPopupMarginBottom
= 10;
92 const int kPopupMarginRight
= 0;
94 // Padding values for sections on the permissions tab.
95 const int kPermissionsSectionContentMinWidth
= 300;
96 const int kPermissionsSectionPaddingBottom
= 6;
97 const int kPermissionsSectionPaddingLeft
= 18;
98 const int kPermissionsSectionPaddingTop
= 16;
100 // Space between the headline and the content of a section on the permissions
102 const int kPermissionsSectionHeadlineMarginBottom
= 10;
103 // The content of the "Permissions" section and the "Cookies and Site Data"
104 // section is structured in individual rows. |kPermissionsSectionRowSpacing|
105 // is the space between these rows.
106 const int kPermissionsSectionRowSpacing
= 2;
108 const int kSiteDataIconColumnWidth
= 20;
109 const int kSiteDataSectionRowSpacing
= 11;
113 // |PopupHeaderView| is the UI element (view) that represents the header of the
114 // |WebsiteSettingsPopupView|. The header shows the status of the site's
115 // identity check and the name of the site's identity.
116 class PopupHeaderView
: public views::View
{
118 explicit PopupHeaderView(views::ButtonListener
* close_button_listener
);
119 virtual ~PopupHeaderView();
121 // Sets the name of the site's identity.
122 void SetIdentityName(const base::string16
& name
);
124 // Sets the |status_text| for the identity check of this site and the
126 void SetIdentityStatus(const base::string16
& status_text
, SkColor text_color
);
129 // The label that displays the name of the site's identity.
131 // The label that displays the status of the identity check for this site.
132 views::Label
* status_
;
134 DISALLOW_COPY_AND_ASSIGN(PopupHeaderView
);
137 // Website Settings are not supported for internal Chrome pages. Instead of the
138 // |WebsiteSettingsPopupView|, the |InternalPageInfoPopupView| is
140 class InternalPageInfoPopupView
: public views::BubbleDelegateView
{
142 explicit InternalPageInfoPopupView(views::View
* anchor_view
);
143 virtual ~InternalPageInfoPopupView();
146 DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupView
);
149 ////////////////////////////////////////////////////////////////////////////////
151 ////////////////////////////////////////////////////////////////////////////////
153 PopupHeaderView::PopupHeaderView(views::ButtonListener
* close_button_listener
)
154 : name_(NULL
), status_(NULL
) {
155 views::GridLayout
* layout
= new views::GridLayout(this);
156 SetLayoutManager(layout
);
158 const int label_column
= 0;
159 views::ColumnSet
* column_set
= layout
->AddColumnSet(label_column
);
160 column_set
->AddPaddingColumn(0, kHeaderPaddingLeft
);
161 column_set
->AddColumn(views::GridLayout::FILL
,
162 views::GridLayout::FILL
,
164 views::GridLayout::USE_PREF
,
167 column_set
->AddPaddingColumn(1, 0);
168 column_set
->AddColumn(views::GridLayout::FILL
,
169 views::GridLayout::FILL
,
171 views::GridLayout::USE_PREF
,
174 column_set
->AddPaddingColumn(0, kHeaderPaddingRight
);
176 layout
->AddPaddingRow(0, kHeaderPaddingTop
);
178 layout
->StartRow(0, label_column
);
179 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
180 name_
= new views::Label(
181 base::string16(), rb
.GetFontList(ui::ResourceBundle::BoldFont
));
182 layout
->AddView(name_
, 1, 1, views::GridLayout::LEADING
,
183 views::GridLayout::TRAILING
);
184 views::ImageButton
* close_button
=
185 new views::ImageButton(close_button_listener
);
186 close_button
->SetImage(views::CustomButton::STATE_NORMAL
,
187 rb
.GetImageNamed(IDR_CLOSE_2
).ToImageSkia());
188 close_button
->SetImage(views::CustomButton::STATE_HOVERED
,
189 rb
.GetImageNamed(IDR_CLOSE_2_H
).ToImageSkia());
190 close_button
->SetImage(views::CustomButton::STATE_PRESSED
,
191 rb
.GetImageNamed(IDR_CLOSE_2_P
).ToImageSkia());
192 layout
->AddView(close_button
, 1, 1, views::GridLayout::TRAILING
,
193 views::GridLayout::LEADING
);
195 layout
->AddPaddingRow(0, kHeaderRowSpacing
);
197 layout
->StartRow(0, label_column
);
198 status_
= new views::Label(base::string16());
199 layout
->AddView(status_
,
202 views::GridLayout::LEADING
,
203 views::GridLayout::CENTER
);
205 layout
->AddPaddingRow(0, kHeaderPaddingBottom
);
208 PopupHeaderView::~PopupHeaderView() {
211 void PopupHeaderView::SetIdentityName(const base::string16
& name
) {
212 name_
->SetText(name
);
215 void PopupHeaderView::SetIdentityStatus(const base::string16
& status
,
216 SkColor text_color
) {
217 status_
->SetText(status
);
218 status_
->SetEnabledColor(text_color
);
221 ////////////////////////////////////////////////////////////////////////////////
222 // InternalPageInfoPopupView
223 ////////////////////////////////////////////////////////////////////////////////
225 InternalPageInfoPopupView::InternalPageInfoPopupView(views::View
* anchor_view
)
226 : BubbleDelegateView(anchor_view
, views::BubbleBorder::TOP_LEFT
) {
227 // Compensate for built-in vertical padding in the anchor view's image.
228 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin
, 0,
229 kLocationIconVerticalMargin
, 0));
231 const int kSpacing
= 4;
232 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal
, kSpacing
,
233 kSpacing
, kSpacing
));
234 views::ImageView
* icon_view
= new views::ImageView();
235 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
236 icon_view
->SetImage(rb
.GetImageSkiaNamed(IDR_PRODUCT_LOGO_26
));
237 AddChildView(icon_view
);
239 views::Label
* label
=
240 new views::Label(l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE
));
241 label
->SetMultiLine(true);
242 label
->SetAllowCharacterBreak(true);
243 label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
246 views::BubbleDelegateView::CreateBubble(this)->Show();
250 InternalPageInfoPopupView::~InternalPageInfoPopupView() {
253 ////////////////////////////////////////////////////////////////////////////////
254 // WebsiteSettingsPopupView
255 ////////////////////////////////////////////////////////////////////////////////
257 WebsiteSettingsPopupView::~WebsiteSettingsPopupView() {
261 void WebsiteSettingsPopupView::ShowPopup(views::View
* anchor_view
,
263 content::WebContents
* web_contents
,
265 const content::SSLStatus
& ssl
,
267 if (InternalChromePage(url
)) {
268 new InternalPageInfoPopupView(anchor_view
);
270 new WebsiteSettingsPopupView(anchor_view
, profile
, web_contents
, url
, ssl
,
275 WebsiteSettingsPopupView::WebsiteSettingsPopupView(
276 views::View
* anchor_view
,
278 content::WebContents
* web_contents
,
280 const content::SSLStatus
& ssl
,
282 : BubbleDelegateView(anchor_view
, views::BubbleBorder::TOP_LEFT
),
283 web_contents_(web_contents
),
287 site_data_content_(NULL
),
288 cookie_dialog_link_(NULL
),
289 permissions_content_(NULL
),
290 connection_tab_(NULL
),
291 identity_info_content_(NULL
),
292 certificate_dialog_link_(NULL
),
293 signed_certificate_timestamps_link_(NULL
),
295 help_center_link_(NULL
),
296 connection_info_content_(NULL
),
297 page_info_content_(NULL
),
298 weak_factory_(this) {
299 // Compensate for built-in vertical padding in the anchor view's image.
300 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin
, 0,
301 kLocationIconVerticalMargin
, 0));
303 views::GridLayout
* layout
= new views::GridLayout(this);
304 SetLayoutManager(layout
);
305 const int content_column
= 0;
306 views::ColumnSet
* column_set
= layout
->AddColumnSet(content_column
);
307 column_set
->AddColumn(views::GridLayout::FILL
,
308 views::GridLayout::FILL
,
310 views::GridLayout::USE_PREF
,
314 header_
= new PopupHeaderView(this);
315 layout
->StartRow(1, content_column
);
316 layout
->AddView(header_
);
318 layout
->AddPaddingRow(1, kHeaderMarginBottom
);
319 tabbed_pane_
= new views::TabbedPane();
320 layout
->StartRow(1, content_column
);
321 layout
->AddView(tabbed_pane_
);
322 // Tabs must be added after the tabbed_pane_ was added to the views
323 // hierachy. Adding the |tabbed_pane_| to the views hierachy triggers the
324 // initialization of the native tab UI element. If the native tab UI
325 // element is not initalized adding a tab will result in a NULL pointer
327 tabbed_pane_
->AddTabAtIndex(
329 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS
),
330 CreatePermissionsTab());
331 connection_tab_
= CreateConnectionTab();
332 tabbed_pane_
->AddTabAtIndex(
334 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION
),
336 DCHECK_EQ(tabbed_pane_
->GetTabCount(), NUM_TAB_IDS
);
337 tabbed_pane_
->set_listener(this);
339 set_margins(gfx::Insets(kPopupMarginTop
, kPopupMarginLeft
,
340 kPopupMarginBottom
, kPopupMarginRight
));
342 views::BubbleDelegateView::CreateBubble(this)->Show();
345 presenter_
.reset(new WebsiteSettings(
347 TabSpecificContentSettings::FromWebContents(web_contents
),
348 InfoBarService::FromWebContents(web_contents
), url
, ssl
,
349 content::CertStore::GetInstance()));
352 void WebsiteSettingsPopupView::OnPermissionChanged(
353 PermissionSelectorView
* permission_selector
) {
354 DCHECK(permission_selector
);
355 presenter_
->OnSitePermissionChanged(permission_selector
->type(),
356 permission_selector
->current_setting());
359 void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget
* widget
) {
360 presenter_
->OnUIClosing();
363 void WebsiteSettingsPopupView::ButtonPressed(
364 views::Button
* button
,
365 const ui::Event
& event
) {
366 GetWidget()->Close();
369 void WebsiteSettingsPopupView::LinkClicked(views::Link
* source
,
371 // The popup closes automatically when the collected cookies dialog or the
372 // certificate viewer opens. So delay handling of the link clicked to avoid
373 // a crash in the base class which needs to complete the mouse event handling.
374 content::BrowserThread::PostTask(
375 content::BrowserThread::UI
, FROM_HERE
,
376 base::Bind(&WebsiteSettingsPopupView::HandleLinkClickedAsync
,
377 weak_factory_
.GetWeakPtr(), source
));
380 void WebsiteSettingsPopupView::TabSelectedAt(int index
) {
381 tabbed_pane_
->GetSelectedTab()->Layout();
385 gfx::Size
WebsiteSettingsPopupView::GetPreferredSize() {
386 if (header_
== NULL
&& tabbed_pane_
== NULL
)
387 return views::View::GetPreferredSize();
391 height
+= header_
->GetPreferredSize().height();
393 height
+= tabbed_pane_
->GetPreferredSize().height();
395 int width
= kPermissionsSectionContentMinWidth
;
396 if (site_data_content_
)
397 width
= std::max(width
, site_data_content_
->GetPreferredSize().width());
398 if (permissions_content_
)
399 width
= std::max(width
, permissions_content_
->GetPreferredSize().width());
400 width
+= kPermissionsSectionPaddingLeft
;
401 width
= std::min(width
, kMaxPopupWidth
);
403 return gfx::Size(width
, height
);
406 void WebsiteSettingsPopupView::SetCookieInfo(
407 const CookieInfoList
& cookie_info_list
) {
408 site_data_content_
->RemoveAllChildViews(true);
410 views::GridLayout
* layout
= new views::GridLayout(site_data_content_
);
411 site_data_content_
->SetLayoutManager(layout
);
413 const int site_data_content_column
= 0;
414 views::ColumnSet
* column_set
=
415 layout
->AddColumnSet(site_data_content_column
);
416 column_set
->AddColumn(views::GridLayout::FILL
,
417 views::GridLayout::FILL
,
419 views::GridLayout::FIXED
,
420 kSiteDataIconColumnWidth
,
422 column_set
->AddPaddingColumn(0, kIconMarginLeft
);
423 column_set
->AddColumn(views::GridLayout::FILL
,
424 views::GridLayout::FILL
,
426 views::GridLayout::USE_PREF
,
430 layout
->AddPaddingRow(1, 5);
431 for (CookieInfoList::const_iterator
i(cookie_info_list
.begin());
432 i
!= cookie_info_list
.end();
434 base::string16 label_text
= l10n_util::GetStringFUTF16(
435 IDS_WEBSITE_SETTINGS_SITE_DATA_STATS_LINE
,
436 base::UTF8ToUTF16(i
->cookie_source
),
437 base::IntToString16(i
->allowed
),
438 base::IntToString16(i
->blocked
));
439 if (i
!= cookie_info_list
.begin())
440 layout
->AddPaddingRow(1, kSiteDataSectionRowSpacing
);
441 layout
->StartRow(1, site_data_content_column
);
442 views::ImageView
* icon
= new views::ImageView();
443 const gfx::Image
& image
= WebsiteSettingsUI::GetPermissionIcon(
444 CONTENT_SETTINGS_TYPE_COOKIES
, CONTENT_SETTING_ALLOW
);
445 icon
->SetImage(image
.ToImageSkia());
446 layout
->AddView(icon
, 1, 1, views::GridLayout::CENTER
,
447 views::GridLayout::CENTER
);
448 layout
->AddView(new views::Label(label_text
), 1, 1,
449 views::GridLayout::LEADING
, views::GridLayout::CENTER
);
451 layout
->AddPaddingRow(1, 6);
453 layout
->Layout(site_data_content_
);
457 void WebsiteSettingsPopupView::SetPermissionInfo(
458 const PermissionInfoList
& permission_info_list
) {
459 permissions_content_
->RemoveAllChildViews(true);
461 views::GridLayout
* layout
=
462 new views::GridLayout(permissions_content_
);
463 permissions_content_
->SetLayoutManager(layout
);
464 const int content_column
= 0;
465 views::ColumnSet
* column_set
=
466 layout
->AddColumnSet(content_column
);
467 column_set
->AddColumn(views::GridLayout::FILL
,
468 views::GridLayout::FILL
,
470 views::GridLayout::USE_PREF
,
473 for (PermissionInfoList::const_iterator permission
=
474 permission_info_list
.begin();
475 permission
!= permission_info_list
.end();
477 layout
->StartRow(1, content_column
);
478 PermissionSelectorView
* selector
= new PermissionSelectorView(
479 web_contents_
? web_contents_
->GetURL() : GURL::EmptyGURL(),
481 permission
->default_setting
,
484 selector
->AddObserver(this);
485 layout
->AddView(selector
,
488 views::GridLayout::LEADING
,
489 views::GridLayout::CENTER
);
490 layout
->AddPaddingRow(1, kPermissionsSectionRowSpacing
);
496 void WebsiteSettingsPopupView::SetIdentityInfo(
497 const IdentityInfo
& identity_info
) {
498 base::string16 identity_status_text
;
499 SkColor text_color
= SK_ColorBLACK
;
500 switch (identity_info
.identity_status
) {
501 case WebsiteSettings::SITE_IDENTITY_STATUS_CERT
:
502 case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT
:
503 identity_status_text
=
504 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_VERIFIED
);
505 text_color
= kIdentityVerifiedTextColor
;
507 case WebsiteSettings::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT
:
508 identity_status_text
=
509 l10n_util::GetStringUTF16(IDS_CERT_POLICY_PROVIDED_CERT_HEADER
);
512 identity_status_text
=
513 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_NOT_VERIFIED
);
516 header_
->SetIdentityName(base::UTF8ToUTF16(identity_info
.site_identity
));
517 header_
->SetIdentityStatus(identity_status_text
, text_color
);
519 // The headline and the certificate dialog link of the site's identity
520 // section is only displayed if the site's identity was verified. If the
521 // site's identity was verified, then the headline contains the organization
522 // name from the provided certificate. If the organization name is not
523 // available than the hostname of the site is used instead.
524 base::string16 headline
;
525 if (identity_info
.cert_id
) {
526 cert_id_
= identity_info
.cert_id
;
527 signed_certificate_timestamp_ids_
.assign(
528 identity_info
.signed_certificate_timestamp_ids
.begin(),
529 identity_info
.signed_certificate_timestamp_ids
.end());
531 certificate_dialog_link_
= new views::Link(
532 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON
));
533 certificate_dialog_link_
->set_listener(this);
535 if (!signed_certificate_timestamp_ids_
.empty() &&
536 CommandLine::ForCurrentProcess()->HasSwitch(
537 switches::kEnableSignedCertificateTimestampsViewer
)) {
538 signed_certificate_timestamps_link_
=
539 new views::Link(l10n_util::GetStringUTF16(
540 IDS_PAGEINFO_CERT_TRANSPARENCY_INFO_BUTTON
));
541 signed_certificate_timestamps_link_
->set_listener(this);
544 headline
= base::UTF8ToUTF16(identity_info
.site_identity
);
546 ResetConnectionSection(
547 identity_info_content_
,
548 WebsiteSettingsUI::GetIdentityIcon(identity_info
.identity_status
),
549 base::string16(), // The identity section has no headline.
550 base::UTF8ToUTF16(identity_info
.identity_status_description
),
551 certificate_dialog_link_
,
552 signed_certificate_timestamps_link_
);
554 ResetConnectionSection(
555 connection_info_content_
,
556 WebsiteSettingsUI::GetConnectionIcon(identity_info
.connection_status
),
557 base::string16(), // The connection section has no headline.
558 base::UTF8ToUTF16(identity_info
.connection_status_description
),
562 connection_tab_
->InvalidateLayout();
567 void WebsiteSettingsPopupView::SetFirstVisit(
568 const base::string16
& first_visit
) {
569 ResetConnectionSection(
571 WebsiteSettingsUI::GetFirstVisitIcon(first_visit
),
572 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE
),
576 connection_tab_
->InvalidateLayout();
581 void WebsiteSettingsPopupView::SetSelectedTab(TabId tab_id
) {
582 tabbed_pane_
->SelectTabAt(tab_id
);
585 views::View
* WebsiteSettingsPopupView::CreatePermissionsTab() {
586 views::View
* pane
= new views::View();
587 pane
->SetLayoutManager(
588 new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 1));
589 // Add cookies and site data section.
590 cookie_dialog_link_
= new views::Link(
591 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_SHOW_SITE_DATA
));
592 cookie_dialog_link_
->set_listener(this);
593 site_data_content_
= new views::View();
594 views::View
* site_data_section
=
595 CreateSection(l10n_util::GetStringUTF16(
596 IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA
),
598 cookie_dialog_link_
);
599 pane
->AddChildView(site_data_section
);
600 // Add permissions section.
601 permissions_content_
= new views::View();
602 views::View
* permissions_section
=
603 CreateSection(l10n_util::GetStringUTF16(
604 IDS_WEBSITE_SETTINGS_TITLE_SITE_PERMISSIONS
),
605 permissions_content_
,
607 pane
->AddChildView(permissions_section
);
611 views::View
* WebsiteSettingsPopupView::CreateConnectionTab() {
612 views::View
* pane
= new views::View();
613 pane
->SetLayoutManager(
614 new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, 1));
615 // Add site identity section.
616 identity_info_content_
= new views::View();
617 pane
->AddChildView(identity_info_content_
);
619 // Add connection section.
620 pane
->AddChildView(new views::Separator(views::Separator::HORIZONTAL
));
621 connection_info_content_
= new views::View();
622 pane
->AddChildView(connection_info_content_
);
624 // Add page info section.
625 pane
->AddChildView(new views::Separator(views::Separator::HORIZONTAL
));
626 page_info_content_
= new views::View();
627 pane
->AddChildView(page_info_content_
);
629 // Add help center link.
630 pane
->AddChildView(new views::Separator(views::Separator::HORIZONTAL
));
631 help_center_link_
= new views::Link(
632 l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER_LINK
));
633 help_center_link_
->set_listener(this);
634 views::View
* link_section
= new views::View();
635 const int kLinkMarginTop
= 4;
636 link_section
->SetLayoutManager(
637 new views::BoxLayout(views::BoxLayout::kHorizontal
,
638 kConnectionSectionPaddingLeft
,
641 link_section
->AddChildView(help_center_link_
);
642 pane
->AddChildView(link_section
);
646 views::View
* WebsiteSettingsPopupView::CreateSection(
647 const base::string16
& headline_text
,
648 views::View
* content
,
650 views::View
* container
= new views::View();
651 views::GridLayout
* layout
= new views::GridLayout(container
);
652 container
->SetLayoutManager(layout
);
653 const int content_column
= 0;
654 views::ColumnSet
* column_set
= layout
->AddColumnSet(content_column
);
655 column_set
->AddPaddingColumn(0, kPermissionsSectionPaddingLeft
);
656 column_set
->AddColumn(views::GridLayout::FILL
,
657 views::GridLayout::FILL
,
659 views::GridLayout::USE_PREF
,
663 layout
->AddPaddingRow(1, kPermissionsSectionPaddingTop
);
664 layout
->StartRow(1, content_column
);
665 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
666 views::Label
* headline
= new views::Label(
667 headline_text
, rb
.GetFontList(ui::ResourceBundle::BoldFont
));
668 layout
->AddView(headline
, 1, 1, views::GridLayout::LEADING
,
669 views::GridLayout::CENTER
);
671 layout
->AddPaddingRow(1, kPermissionsSectionHeadlineMarginBottom
);
672 layout
->StartRow(1, content_column
);
673 layout
->AddView(content
, 1, 1, views::GridLayout::LEADING
,
674 views::GridLayout::CENTER
);
677 layout
->AddPaddingRow(1, 4);
678 layout
->StartRow(1, content_column
);
679 layout
->AddView(link
, 1, 1, views::GridLayout::LEADING
,
680 views::GridLayout::CENTER
);
683 layout
->AddPaddingRow(1, kPermissionsSectionPaddingBottom
);
687 void WebsiteSettingsPopupView::ResetConnectionSection(
688 views::View
* section_container
,
689 const gfx::Image
& icon
,
690 const base::string16
& headline
,
691 const base::string16
& text
,
693 views::Link
* secondary_link
) {
694 section_container
->RemoveAllChildViews(true);
696 views::GridLayout
* layout
= new views::GridLayout(section_container
);
697 section_container
->SetLayoutManager(layout
);
698 views::ColumnSet
* column_set
= layout
->AddColumnSet(0);
699 column_set
->AddPaddingColumn(0, kConnectionSectionPaddingLeft
);
700 column_set
->AddColumn(views::GridLayout::LEADING
,
701 views::GridLayout::LEADING
,
703 views::GridLayout::USE_PREF
,
706 column_set
->AddPaddingColumn(0, kIconMarginLeft
);
707 column_set
->AddColumn(views::GridLayout::FILL
,
708 views::GridLayout::FILL
,
710 views::GridLayout::USE_PREF
,
713 column_set
->AddPaddingColumn(0, kConnectionSectionPaddingRight
);
716 layout
->AddPaddingRow(0, kConnectionSectionPaddingTop
);
717 layout
->StartRow(1, 0);
720 views::ImageView
* icon_view
= new views::ImageView();
721 icon_view
->SetImage(*icon
.ToImageSkia());
722 layout
->AddView(icon_view
, 1, 1, views::GridLayout::LEADING
,
723 views::GridLayout::LEADING
);
725 // Add section content.
726 views::View
* content_pane
= new views::View();
727 views::GridLayout
* content_layout
= new views::GridLayout(content_pane
);
728 content_pane
->SetLayoutManager(content_layout
);
729 views::ColumnSet
* content_column_set
= content_layout
->AddColumnSet(0);
730 content_column_set
->AddColumn(views::GridLayout::LEADING
,
731 views::GridLayout::LEADING
,
733 views::GridLayout::USE_PREF
,
736 if (!headline
.empty()) {
737 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
738 views::Label
* headline_label
= new views::Label(
739 headline
, rb
.GetFontList(ui::ResourceBundle::BoldFont
));
740 headline_label
->SetMultiLine(true);
741 headline_label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
742 // Allow linebreaking in the middle of words if necessary, so that extremely
743 // long hostnames (longer than one line) will still be completely shown.
744 headline_label
->SetAllowCharacterBreak(true);
745 content_layout
->StartRow(1, 0);
746 content_layout
->AddView(headline_label
);
749 views::Label
* description_label
= new views::Label(text
);
750 description_label
->SetMultiLine(true);
751 description_label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
752 description_label
->SetAllowCharacterBreak(true);
753 content_layout
->StartRow(1, 0);
754 content_layout
->AddView(description_label
);
757 content_layout
->StartRow(1, 0);
758 content_layout
->AddView(link
);
761 if (secondary_link
) {
762 content_layout
->StartRow(1, 0);
763 content_layout
->AddView(secondary_link
);
766 layout
->AddView(content_pane
, 1, 1, views::GridLayout::LEADING
,
767 views::GridLayout::LEADING
);
768 layout
->AddPaddingRow(0, kConnectionSectionPaddingBottom
);
771 // Used to asynchronously handle clicks since these calls may cause the
772 // destruction of the settings view and the base class window still
773 // needs to be alive to finish handling the mouse click.
774 void WebsiteSettingsPopupView::HandleLinkClickedAsync(views::Link
* source
) {
775 if (source
== cookie_dialog_link_
) {
776 // Count how often the Collected Cookies dialog is opened.
777 content::RecordAction(
778 base::UserMetricsAction("WebsiteSettings_CookiesDialogOpened"));
779 new CollectedCookiesViews(web_contents_
);
780 } else if (source
== certificate_dialog_link_
) {
781 gfx::NativeWindow parent
=
782 GetAnchorView() ? GetAnchorView()->GetWidget()->GetNativeWindow() :
784 ShowCertificateViewerByID(web_contents_
, parent
, cert_id_
);
785 } else if (source
== signed_certificate_timestamps_link_
) {
786 chrome::ShowSignedCertificateTimestampsViewer(
787 web_contents_
, signed_certificate_timestamp_ids_
);
788 } else if (source
== help_center_link_
) {
789 browser_
->OpenURL(content::OpenURLParams(
790 GURL(chrome::kPageInfoHelpCenterURL
),
793 content::PAGE_TRANSITION_LINK
,