Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / website_settings / website_settings_popup_view.cc
blob10485fdfb3be1862782b4a6e4746c7fafbebb13c
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 <algorithm>
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/certificate_viewer.h"
12 #include "chrome/browser/infobars/infobar_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/views/collected_cookies_views.h"
16 #include "chrome/browser/ui/views/website_settings/permission_selector_view.h"
17 #include "chrome/browser/ui/website_settings/website_settings.h"
18 #include "chrome/browser/ui/website_settings/website_settings_utils.h"
19 #include "chrome/common/content_settings_types.h"
20 #include "chrome/common/url_constants.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/cert_store.h"
23 #include "content/public/browser/user_metrics.h"
24 #include "grit/chromium_strings.h"
25 #include "grit/generated_resources.h"
26 #include "grit/theme_resources.h"
27 #include "grit/ui_resources.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/models/simple_menu_model.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/font_list.h"
33 #include "ui/gfx/image/image.h"
34 #include "ui/gfx/insets.h"
35 #include "ui/views/controls/button/image_button.h"
36 #include "ui/views/controls/button/menu_button.h"
37 #include "ui/views/controls/button/menu_button_listener.h"
38 #include "ui/views/controls/image_view.h"
39 #include "ui/views/controls/label.h"
40 #include "ui/views/controls/link.h"
41 #include "ui/views/controls/menu/menu_model_adapter.h"
42 #include "ui/views/controls/menu/menu_runner.h"
43 #include "ui/views/controls/separator.h"
44 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
45 #include "ui/views/layout/box_layout.h"
46 #include "ui/views/layout/grid_layout.h"
47 #include "ui/views/layout/layout_manager.h"
48 #include "ui/views/view.h"
49 #include "ui/views/widget/widget.h"
50 #include "url/gurl.h"
52 namespace {
54 // Padding values for sections on the connection tab.
55 const int kConnectionSectionPaddingBottom = 16;
56 const int kConnectionSectionPaddingLeft = 18;
57 const int kConnectionSectionPaddingTop = 16;
58 const int kConnectionSectionPaddingRight = 18;
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;
64 // Left icon margin.
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
75 // the popup header.
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
98 // tab.
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;
108 } // namespace
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 {
114 public:
115 explicit PopupHeaderView(views::ButtonListener* close_button_listener);
116 virtual ~PopupHeaderView();
118 // Sets the name of the site's identity.
119 void SetIdentityName(const base::string16& name);
121 // Sets the |status_text| for the identity check of this site and the
122 // |text_color|.
123 void SetIdentityStatus(const base::string16& status_text, SkColor text_color);
125 private:
126 // The label that displays the name of the site's identity.
127 views::Label* name_;
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
136 // displayed.
137 class InternalPageInfoPopupView : public views::BubbleDelegateView {
138 public:
139 explicit InternalPageInfoPopupView(views::View* anchor_view);
140 virtual ~InternalPageInfoPopupView();
142 private:
143 DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupView);
146 ////////////////////////////////////////////////////////////////////////////////
147 // Popup Header
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 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
177 name_ = new views::Label(
178 base::string16(), rb.GetFontList(ui::ResourceBundle::BoldFont));
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 close_button->SetImage(views::CustomButton::STATE_NORMAL,
184 rb.GetImageNamed(IDR_CLOSE_2).ToImageSkia());
185 close_button->SetImage(views::CustomButton::STATE_HOVERED,
186 rb.GetImageNamed(IDR_CLOSE_2_H).ToImageSkia());
187 close_button->SetImage(views::CustomButton::STATE_PRESSED,
188 rb.GetImageNamed(IDR_CLOSE_2_P).ToImageSkia());
189 layout->AddView(close_button, 1, 1, views::GridLayout::TRAILING,
190 views::GridLayout::LEADING);
192 layout->AddPaddingRow(0, kHeaderRowSpacing);
194 layout->StartRow(0, label_column);
195 status_ = new views::Label(base::string16());
196 layout->AddView(status_,
199 views::GridLayout::LEADING,
200 views::GridLayout::CENTER);
202 layout->AddPaddingRow(0, kHeaderPaddingBottom);
205 PopupHeaderView::~PopupHeaderView() {
208 void PopupHeaderView::SetIdentityName(const base::string16& name) {
209 name_->SetText(name);
212 void PopupHeaderView::SetIdentityStatus(const base::string16& status,
213 SkColor text_color) {
214 status_->SetText(status);
215 status_->SetEnabledColor(text_color);
218 ////////////////////////////////////////////////////////////////////////////////
219 // InternalPageInfoPopupView
220 ////////////////////////////////////////////////////////////////////////////////
222 InternalPageInfoPopupView::InternalPageInfoPopupView(views::View* anchor_view)
223 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT) {
224 // Compensate for built-in vertical padding in the anchor view's image.
225 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin, 0,
226 kLocationIconVerticalMargin, 0));
228 const int kSpacing = 4;
229 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, kSpacing,
230 kSpacing, kSpacing));
231 views::ImageView* icon_view = new views::ImageView();
232 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
233 icon_view->SetImage(rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_26));
234 AddChildView(icon_view);
236 views::Label* label =
237 new views::Label(l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE));
238 label->SetMultiLine(true);
239 label->SetAllowCharacterBreak(true);
240 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
241 AddChildView(label);
243 views::BubbleDelegateView::CreateBubble(this)->Show();
244 SizeToContents();
247 InternalPageInfoPopupView::~InternalPageInfoPopupView() {
250 ////////////////////////////////////////////////////////////////////////////////
251 // WebsiteSettingsPopupView
252 ////////////////////////////////////////////////////////////////////////////////
254 WebsiteSettingsPopupView::~WebsiteSettingsPopupView() {
257 // static
258 void WebsiteSettingsPopupView::ShowPopup(views::View* anchor_view,
259 Profile* profile,
260 content::WebContents* web_contents,
261 const GURL& url,
262 const content::SSLStatus& ssl,
263 Browser* browser) {
264 if (InternalChromePage(url)) {
265 new InternalPageInfoPopupView(anchor_view);
266 } else {
267 new WebsiteSettingsPopupView(anchor_view, profile, web_contents, url, ssl,
268 browser);
272 WebsiteSettingsPopupView::WebsiteSettingsPopupView(
273 views::View* anchor_view,
274 Profile* profile,
275 content::WebContents* web_contents,
276 const GURL& url,
277 const content::SSLStatus& ssl,
278 Browser* browser)
279 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
280 web_contents_(web_contents),
281 browser_(browser),
282 header_(NULL),
283 tabbed_pane_(NULL),
284 site_data_content_(NULL),
285 cookie_dialog_link_(NULL),
286 permissions_content_(NULL),
287 connection_tab_(NULL),
288 identity_info_content_(NULL),
289 certificate_dialog_link_(NULL),
290 cert_id_(0),
291 help_center_link_(NULL),
292 connection_info_content_(NULL),
293 page_info_content_(NULL),
294 weak_factory_(this) {
295 // Compensate for built-in vertical padding in the anchor view's image.
296 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin, 0,
297 kLocationIconVerticalMargin, 0));
299 views::GridLayout* layout = new views::GridLayout(this);
300 SetLayoutManager(layout);
301 const int content_column = 0;
302 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
303 column_set->AddColumn(views::GridLayout::FILL,
304 views::GridLayout::FILL,
306 views::GridLayout::USE_PREF,
310 header_ = new PopupHeaderView(this);
311 layout->StartRow(1, content_column);
312 layout->AddView(header_);
314 layout->AddPaddingRow(1, kHeaderMarginBottom);
315 tabbed_pane_ = new views::TabbedPane();
316 layout->StartRow(1, content_column);
317 layout->AddView(tabbed_pane_);
318 // Tabs must be added after the tabbed_pane_ was added to the views
319 // hierachy. Adding the |tabbed_pane_| to the views hierachy triggers the
320 // initialization of the native tab UI element. If the native tab UI
321 // element is not initalized adding a tab will result in a NULL pointer
322 // exception.
323 tabbed_pane_->AddTabAtIndex(
324 TAB_ID_PERMISSIONS,
325 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS),
326 CreatePermissionsTab());
327 connection_tab_ = CreateConnectionTab();
328 tabbed_pane_->AddTabAtIndex(
329 TAB_ID_CONNECTION,
330 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION),
331 connection_tab_);
332 DCHECK_EQ(tabbed_pane_->GetTabCount(), NUM_TAB_IDS);
333 tabbed_pane_->set_listener(this);
335 set_margins(gfx::Insets(kPopupMarginTop, kPopupMarginLeft,
336 kPopupMarginBottom, kPopupMarginRight));
338 views::BubbleDelegateView::CreateBubble(this)->Show();
339 SizeToContents();
341 presenter_.reset(new WebsiteSettings(
342 this, profile,
343 TabSpecificContentSettings::FromWebContents(web_contents),
344 InfoBarService::FromWebContents(web_contents), url, ssl,
345 content::CertStore::GetInstance()));
348 void WebsiteSettingsPopupView::OnPermissionChanged(
349 PermissionSelectorView* permission_selector) {
350 DCHECK(permission_selector);
351 presenter_->OnSitePermissionChanged(permission_selector->type(),
352 permission_selector->current_setting());
355 void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget* widget) {
356 presenter_->OnUIClosing();
359 void WebsiteSettingsPopupView::ButtonPressed(
360 views::Button* button,
361 const ui::Event& event) {
362 GetWidget()->Close();
365 void WebsiteSettingsPopupView::LinkClicked(views::Link* source,
366 int event_flags) {
367 // The popup closes automatically when the collected cookies dialog or the
368 // certificate viewer opens. So delay handling of the link clicked to avoid
369 // a crash in the base class which needs to complete the mouse event handling.
370 content::BrowserThread::PostTask(
371 content::BrowserThread::UI, FROM_HERE,
372 base::Bind(&WebsiteSettingsPopupView::HandleLinkClickedAsync,
373 weak_factory_.GetWeakPtr(), source));
376 void WebsiteSettingsPopupView::TabSelectedAt(int index) {
377 tabbed_pane_->GetSelectedTab()->Layout();
378 SizeToContents();
381 gfx::Size WebsiteSettingsPopupView::GetPreferredSize() {
382 if (header_ == NULL && tabbed_pane_ == NULL)
383 return views::View::GetPreferredSize();
385 int height = 0;
386 if (header_)
387 height += header_->GetPreferredSize().height();
388 if (tabbed_pane_)
389 height += tabbed_pane_->GetPreferredSize().height();
391 int width = kPermissionsSectionContentMinWidth;
392 if (site_data_content_)
393 width = std::max(width, site_data_content_->GetPreferredSize().width());
394 if (permissions_content_)
395 width = std::max(width, permissions_content_->GetPreferredSize().width());
396 width += kPermissionsSectionPaddingLeft;
397 width = std::min(width, kMaxPopupWidth);
399 return gfx::Size(width, height);
402 void WebsiteSettingsPopupView::SetCookieInfo(
403 const CookieInfoList& cookie_info_list) {
404 site_data_content_->RemoveAllChildViews(true);
406 views::GridLayout* layout = new views::GridLayout(site_data_content_);
407 site_data_content_->SetLayoutManager(layout);
409 const int site_data_content_column = 0;
410 views::ColumnSet* column_set =
411 layout->AddColumnSet(site_data_content_column);
412 column_set->AddColumn(views::GridLayout::FILL,
413 views::GridLayout::FILL,
415 views::GridLayout::FIXED,
416 kSiteDataIconColumnWidth,
418 column_set->AddPaddingColumn(0, kIconMarginLeft);
419 column_set->AddColumn(views::GridLayout::FILL,
420 views::GridLayout::FILL,
422 views::GridLayout::USE_PREF,
426 layout->AddPaddingRow(1, 5);
427 for (CookieInfoList::const_iterator i(cookie_info_list.begin());
428 i != cookie_info_list.end();
429 ++i) {
430 base::string16 label_text = l10n_util::GetStringFUTF16(
431 IDS_WEBSITE_SETTINGS_SITE_DATA_STATS_LINE,
432 base::UTF8ToUTF16(i->cookie_source),
433 base::IntToString16(i->allowed),
434 base::IntToString16(i->blocked));
435 if (i != cookie_info_list.begin())
436 layout->AddPaddingRow(1, kSiteDataSectionRowSpacing);
437 layout->StartRow(1, site_data_content_column);
438 views::ImageView* icon = new views::ImageView();
439 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(
440 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_ALLOW);
441 icon->SetImage(image.ToImageSkia());
442 layout->AddView(icon, 1, 1, views::GridLayout::CENTER,
443 views::GridLayout::CENTER);
444 layout->AddView(new views::Label(label_text), 1, 1,
445 views::GridLayout::LEADING, views::GridLayout::CENTER);
447 layout->AddPaddingRow(1, 6);
449 layout->Layout(site_data_content_);
450 SizeToContents();
453 void WebsiteSettingsPopupView::SetPermissionInfo(
454 const PermissionInfoList& permission_info_list) {
455 permissions_content_->RemoveAllChildViews(true);
457 views::GridLayout* layout =
458 new views::GridLayout(permissions_content_);
459 permissions_content_->SetLayoutManager(layout);
460 const int content_column = 0;
461 views::ColumnSet* column_set =
462 layout->AddColumnSet(content_column);
463 column_set->AddColumn(views::GridLayout::FILL,
464 views::GridLayout::FILL,
466 views::GridLayout::USE_PREF,
469 for (PermissionInfoList::const_iterator permission =
470 permission_info_list.begin();
471 permission != permission_info_list.end();
472 ++permission) {
473 layout->StartRow(1, content_column);
474 PermissionSelectorView* selector = new PermissionSelectorView(
475 web_contents_ ? web_contents_->GetURL() : GURL::EmptyGURL(),
476 permission->type,
477 permission->default_setting,
478 permission->setting,
479 permission->source);
480 selector->AddObserver(this);
481 layout->AddView(selector,
484 views::GridLayout::LEADING,
485 views::GridLayout::CENTER);
486 layout->AddPaddingRow(1, kPermissionsSectionRowSpacing);
489 SizeToContents();
492 void WebsiteSettingsPopupView::SetIdentityInfo(
493 const IdentityInfo& identity_info) {
494 base::string16 identity_status_text;
495 SkColor text_color = SK_ColorBLACK;
496 switch (identity_info.identity_status) {
497 case WebsiteSettings::SITE_IDENTITY_STATUS_CERT:
498 case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT:
499 identity_status_text =
500 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_VERIFIED);
501 text_color = kIdentityVerifiedTextColor;
502 break;
503 case WebsiteSettings::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT:
504 identity_status_text =
505 l10n_util::GetStringUTF16(IDS_CERT_POLICY_PROVIDED_CERT_HEADER);
506 break;
507 default:
508 identity_status_text =
509 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_NOT_VERIFIED);
510 break;
512 header_->SetIdentityName(base::UTF8ToUTF16(identity_info.site_identity));
513 header_->SetIdentityStatus(identity_status_text, text_color);
515 // The headline and the certificate dialog link of the site's identity
516 // section is only displayed if the site's identity was verified. If the
517 // site's identity was verified, then the headline contains the organization
518 // name from the provided certificate. If the organization name is not
519 // available than the hostname of the site is used instead.
520 base::string16 headline;
521 if (identity_info.cert_id) {
522 cert_id_ = identity_info.cert_id;
523 signed_certificate_timestamp_ids_.assign(
524 identity_info.signed_certificate_timestamp_ids.begin(),
525 identity_info.signed_certificate_timestamp_ids.end());
527 certificate_dialog_link_ = new views::Link(
528 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON));
529 certificate_dialog_link_->set_listener(this);
531 // XXX(eranm): Wire the SCT Viewer here.
533 headline = base::UTF8ToUTF16(identity_info.site_identity);
535 ResetConnectionSection(
536 identity_info_content_,
537 WebsiteSettingsUI::GetIdentityIcon(identity_info.identity_status),
538 base::string16(), // The identity section has no headline.
539 base::UTF8ToUTF16(identity_info.identity_status_description),
540 certificate_dialog_link_);
542 ResetConnectionSection(
543 connection_info_content_,
544 WebsiteSettingsUI::GetConnectionIcon(identity_info.connection_status),
545 base::string16(), // The connection section has no headline.
546 base::UTF8ToUTF16(identity_info.connection_status_description),
547 NULL);
549 connection_tab_->InvalidateLayout();
550 Layout();
551 SizeToContents();
554 void WebsiteSettingsPopupView::SetFirstVisit(
555 const base::string16& first_visit) {
556 ResetConnectionSection(
557 page_info_content_,
558 WebsiteSettingsUI::GetFirstVisitIcon(first_visit),
559 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE),
560 first_visit,
561 NULL);
562 connection_tab_->InvalidateLayout();
563 Layout();
564 SizeToContents();
567 void WebsiteSettingsPopupView::SetSelectedTab(TabId tab_id) {
568 tabbed_pane_->SelectTabAt(tab_id);
571 views::View* WebsiteSettingsPopupView::CreatePermissionsTab() {
572 views::View* pane = new views::View();
573 pane->SetLayoutManager(
574 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
575 // Add cookies and site data section.
576 cookie_dialog_link_ = new views::Link(
577 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_SHOW_SITE_DATA));
578 cookie_dialog_link_->set_listener(this);
579 site_data_content_ = new views::View();
580 views::View* site_data_section =
581 CreateSection(l10n_util::GetStringUTF16(
582 IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA),
583 site_data_content_,
584 cookie_dialog_link_);
585 pane->AddChildView(site_data_section);
586 // Add permissions section.
587 permissions_content_ = new views::View();
588 views::View* permissions_section =
589 CreateSection(l10n_util::GetStringUTF16(
590 IDS_WEBSITE_SETTINGS_TITLE_SITE_PERMISSIONS),
591 permissions_content_,
592 NULL);
593 pane->AddChildView(permissions_section);
594 return pane;
597 views::View* WebsiteSettingsPopupView::CreateConnectionTab() {
598 views::View* pane = new views::View();
599 pane->SetLayoutManager(
600 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
601 // Add site identity section.
602 identity_info_content_ = new views::View();
603 pane->AddChildView(identity_info_content_);
605 // Add connection section.
606 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL));
607 connection_info_content_ = new views::View();
608 pane->AddChildView(connection_info_content_);
610 // Add page info section.
611 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL));
612 page_info_content_ = new views::View();
613 pane->AddChildView(page_info_content_);
615 // Add help center link.
616 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL));
617 help_center_link_ = new views::Link(
618 l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER_LINK));
619 help_center_link_->set_listener(this);
620 views::View* link_section = new views::View();
621 const int kLinkMarginTop = 4;
622 link_section->SetLayoutManager(
623 new views::BoxLayout(views::BoxLayout::kHorizontal,
624 kConnectionSectionPaddingLeft,
625 kLinkMarginTop,
626 0));
627 link_section->AddChildView(help_center_link_);
628 pane->AddChildView(link_section);
629 return pane;
632 views::View* WebsiteSettingsPopupView::CreateSection(
633 const base::string16& headline_text,
634 views::View* content,
635 views::Link* link) {
636 views::View* container = new views::View();
637 views::GridLayout* layout = new views::GridLayout(container);
638 container->SetLayoutManager(layout);
639 const int content_column = 0;
640 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
641 column_set->AddPaddingColumn(0, kPermissionsSectionPaddingLeft);
642 column_set->AddColumn(views::GridLayout::FILL,
643 views::GridLayout::FILL,
645 views::GridLayout::USE_PREF,
649 layout->AddPaddingRow(1, kPermissionsSectionPaddingTop);
650 layout->StartRow(1, content_column);
651 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
652 views::Label* headline = new views::Label(
653 headline_text, rb.GetFontList(ui::ResourceBundle::BoldFont));
654 layout->AddView(headline, 1, 1, views::GridLayout::LEADING,
655 views::GridLayout::CENTER);
657 layout->AddPaddingRow(1, kPermissionsSectionHeadlineMarginBottom);
658 layout->StartRow(1, content_column);
659 layout->AddView(content, 1, 1, views::GridLayout::LEADING,
660 views::GridLayout::CENTER);
662 if (link) {
663 layout->AddPaddingRow(1, 4);
664 layout->StartRow(1, content_column);
665 layout->AddView(link, 1, 1, views::GridLayout::LEADING,
666 views::GridLayout::CENTER);
669 layout->AddPaddingRow(1, kPermissionsSectionPaddingBottom);
670 return container;
673 void WebsiteSettingsPopupView::ResetConnectionSection(
674 views::View* section_container,
675 const gfx::Image& icon,
676 const base::string16& headline,
677 const base::string16& text,
678 views::Link* link) {
679 section_container->RemoveAllChildViews(true);
681 views::GridLayout* layout = new views::GridLayout(section_container);
682 section_container->SetLayoutManager(layout);
683 views::ColumnSet* column_set = layout->AddColumnSet(0);
684 column_set->AddPaddingColumn(0, kConnectionSectionPaddingLeft);
685 column_set->AddColumn(views::GridLayout::LEADING,
686 views::GridLayout::LEADING,
688 views::GridLayout::USE_PREF,
691 column_set->AddPaddingColumn(0, kIconMarginLeft);
692 column_set->AddColumn(views::GridLayout::FILL,
693 views::GridLayout::FILL,
695 views::GridLayout::USE_PREF,
698 column_set->AddPaddingColumn(0, kConnectionSectionPaddingRight);
701 layout->AddPaddingRow(0, kConnectionSectionPaddingTop);
702 layout->StartRow(1, 0);
704 // Add status icon.
705 views::ImageView* icon_view = new views::ImageView();
706 icon_view->SetImage(*icon.ToImageSkia());
707 layout->AddView(icon_view, 1, 1, views::GridLayout::LEADING,
708 views::GridLayout::LEADING);
710 // Add section content.
711 views::View* content_pane = new views::View();
712 views::GridLayout* content_layout = new views::GridLayout(content_pane);
713 content_pane->SetLayoutManager(content_layout);
714 views::ColumnSet* content_column_set = content_layout->AddColumnSet(0);
715 content_column_set->AddColumn(views::GridLayout::LEADING,
716 views::GridLayout::LEADING,
718 views::GridLayout::USE_PREF,
721 if (!headline.empty()) {
722 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
723 views::Label* headline_label = new views::Label(
724 headline, rb.GetFontList(ui::ResourceBundle::BoldFont));
725 headline_label->SetMultiLine(true);
726 headline_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
727 // Allow linebreaking in the middle of words if necessary, so that extremely
728 // long hostnames (longer than one line) will still be completely shown.
729 headline_label->SetAllowCharacterBreak(true);
730 content_layout->StartRow(1, 0);
731 content_layout->AddView(headline_label);
734 views::Label* description_label = new views::Label(text);
735 description_label->SetMultiLine(true);
736 description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
737 description_label->SetAllowCharacterBreak(true);
738 content_layout->StartRow(1, 0);
739 content_layout->AddView(description_label);
741 if (link) {
742 content_layout->StartRow(1, 0);
743 content_layout->AddView(link);
746 layout->AddView(content_pane, 1, 1, views::GridLayout::LEADING,
747 views::GridLayout::LEADING);
748 layout->AddPaddingRow(0, kConnectionSectionPaddingBottom);
751 // Used to asynchronously handle clicks since these calls may cause the
752 // destruction of the settings view and the base class window still
753 // needs to be alive to finish handling the mouse click.
754 void WebsiteSettingsPopupView::HandleLinkClickedAsync(views::Link* source) {
755 if (source == cookie_dialog_link_) {
756 // Count how often the Collected Cookies dialog is opened.
757 content::RecordAction(
758 base::UserMetricsAction("WebsiteSettings_CookiesDialogOpened"));
759 new CollectedCookiesViews(web_contents_);
760 } else if (source == certificate_dialog_link_) {
761 gfx::NativeWindow parent =
762 GetAnchorView() ? GetAnchorView()->GetWidget()->GetNativeWindow() :
763 NULL;
764 ShowCertificateViewerByID(web_contents_, parent, cert_id_);
765 } else if (source == help_center_link_) {
766 browser_->OpenURL(content::OpenURLParams(
767 GURL(chrome::kPageInfoHelpCenterURL),
768 content::Referrer(),
769 NEW_FOREGROUND_TAB,
770 content::PAGE_TRANSITION_LINK,
771 false));