Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / website_settings / website_settings_popup_view.cc
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.
4
5 #include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h"
6
7 #include <algorithm>
8
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"
53 #include "url/gurl.h"
54
55 namespace {
56
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;
62
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;
66
67 // Left icon margin.
68 const int kIconMarginLeft = 6;
69
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;
76
77 // Spacing between the site identity label and the site identity status text in
78 // the popup header.
79 const int kHeaderRowSpacing = 4;
80
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;
84
85 // The max possible width of the popup.
86 const int kMaxPopupWidth = 500;
87
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;
93
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;
99
100 // Space between the headline and the content of a section on the permissions
101 // tab.
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;
107
108 const int kSiteDataIconColumnWidth = 20;
109 const int kSiteDataSectionRowSpacing = 11;
110
111 }  // namespace
112
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 {
117  public:
118   explicit PopupHeaderView(views::ButtonListener* close_button_listener);
119   virtual ~PopupHeaderView();
120
121   // Sets the name of the site's identity.
122   void SetIdentityName(const base::string16& name);
123
124   // Sets the |status_text| for the identity check of this site and the
125   // |text_color|.
126   void SetIdentityStatus(const base::string16& status_text, SkColor text_color);
127
128  private:
129   // The label that displays the name of the site's identity.
130   views::Label* name_;
131   // The label that displays the status of the identity check for this site.
132   views::Label* status_;
133
134   DISALLOW_COPY_AND_ASSIGN(PopupHeaderView);
135 };
136
137 // Website Settings are not supported for internal Chrome pages. Instead of the
138 // |WebsiteSettingsPopupView|, the |InternalPageInfoPopupView| is
139 // displayed.
140 class InternalPageInfoPopupView : public views::BubbleDelegateView {
141  public:
142   explicit InternalPageInfoPopupView(views::View* anchor_view);
143   virtual ~InternalPageInfoPopupView();
144
145  private:
146   DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupView);
147 };
148
149 ////////////////////////////////////////////////////////////////////////////////
150 // Popup Header
151 ////////////////////////////////////////////////////////////////////////////////
152
153 PopupHeaderView::PopupHeaderView(views::ButtonListener* close_button_listener)
154     : name_(NULL), status_(NULL) {
155   views::GridLayout* layout = new views::GridLayout(this);
156   SetLayoutManager(layout);
157
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,
163                         1,
164                         views::GridLayout::USE_PREF,
165                         0,
166                         0);
167   column_set->AddPaddingColumn(1, 0);
168   column_set->AddColumn(views::GridLayout::FILL,
169                         views::GridLayout::FILL,
170                         1,
171                         views::GridLayout::USE_PREF,
172                         0,
173                         0);
174   column_set->AddPaddingColumn(0, kHeaderPaddingRight);
175
176   layout->AddPaddingRow(0, kHeaderPaddingTop);
177
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);
194
195   layout->AddPaddingRow(0, kHeaderRowSpacing);
196
197   layout->StartRow(0, label_column);
198   status_ = new views::Label(base::string16());
199   layout->AddView(status_,
200                   1,
201                   1,
202                   views::GridLayout::LEADING,
203                   views::GridLayout::CENTER);
204
205   layout->AddPaddingRow(0, kHeaderPaddingBottom);
206 }
207
208 PopupHeaderView::~PopupHeaderView() {
209 }
210
211 void PopupHeaderView::SetIdentityName(const base::string16& name) {
212   name_->SetText(name);
213 }
214
215 void PopupHeaderView::SetIdentityStatus(const base::string16& status,
216                                         SkColor text_color) {
217   status_->SetText(status);
218   status_->SetEnabledColor(text_color);
219 }
220
221 ////////////////////////////////////////////////////////////////////////////////
222 // InternalPageInfoPopupView
223 ////////////////////////////////////////////////////////////////////////////////
224
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));
230
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);
238
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);
244   AddChildView(label);
245
246   views::BubbleDelegateView::CreateBubble(this)->Show();
247   SizeToContents();
248 }
249
250 InternalPageInfoPopupView::~InternalPageInfoPopupView() {
251 }
252
253 ////////////////////////////////////////////////////////////////////////////////
254 // WebsiteSettingsPopupView
255 ////////////////////////////////////////////////////////////////////////////////
256
257 WebsiteSettingsPopupView::~WebsiteSettingsPopupView() {
258 }
259
260 // static
261 void WebsiteSettingsPopupView::ShowPopup(views::View* anchor_view,
262                                          Profile* profile,
263                                          content::WebContents* web_contents,
264                                          const GURL& url,
265                                          const content::SSLStatus& ssl,
266                                          Browser* browser) {
267   if (InternalChromePage(url)) {
268     new InternalPageInfoPopupView(anchor_view);
269   } else {
270     new WebsiteSettingsPopupView(anchor_view, profile, web_contents, url, ssl,
271                                  browser);
272   }
273 }
274
275 WebsiteSettingsPopupView::WebsiteSettingsPopupView(
276     views::View* anchor_view,
277     Profile* profile,
278     content::WebContents* web_contents,
279     const GURL& url,
280     const content::SSLStatus& ssl,
281     Browser* browser)
282     : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
283       web_contents_(web_contents),
284       browser_(browser),
285       header_(NULL),
286       tabbed_pane_(NULL),
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),
294       cert_id_(0),
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));
302
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,
309                         1,
310                         views::GridLayout::USE_PREF,
311                         0,
312                         0);
313
314   header_ = new PopupHeaderView(this);
315   layout->StartRow(1, content_column);
316   layout->AddView(header_);
317
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
326   // exception.
327   tabbed_pane_->AddTabAtIndex(
328       TAB_ID_PERMISSIONS,
329       l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS),
330       CreatePermissionsTab());
331   connection_tab_ = CreateConnectionTab();
332   tabbed_pane_->AddTabAtIndex(
333       TAB_ID_CONNECTION,
334       l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION),
335       connection_tab_);
336   DCHECK_EQ(tabbed_pane_->GetTabCount(), NUM_TAB_IDS);
337   tabbed_pane_->set_listener(this);
338
339   set_margins(gfx::Insets(kPopupMarginTop, kPopupMarginLeft,
340                           kPopupMarginBottom, kPopupMarginRight));
341
342   views::BubbleDelegateView::CreateBubble(this)->Show();
343   SizeToContents();
344
345   presenter_.reset(new WebsiteSettings(
346       this, profile,
347       TabSpecificContentSettings::FromWebContents(web_contents),
348       InfoBarService::FromWebContents(web_contents), url, ssl,
349       content::CertStore::GetInstance()));
350 }
351
352 void WebsiteSettingsPopupView::OnPermissionChanged(
353     PermissionSelectorView* permission_selector) {
354   DCHECK(permission_selector);
355   presenter_->OnSitePermissionChanged(permission_selector->type(),
356                                       permission_selector->current_setting());
357 }
358
359 void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget* widget) {
360   presenter_->OnUIClosing();
361 }
362
363 void WebsiteSettingsPopupView::ButtonPressed(
364     views::Button* button,
365     const ui::Event& event) {
366   GetWidget()->Close();
367 }
368
369 void WebsiteSettingsPopupView::LinkClicked(views::Link* source,
370                                            int event_flags) {
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));
378 }
379
380 void WebsiteSettingsPopupView::TabSelectedAt(int index) {
381   tabbed_pane_->GetSelectedTab()->Layout();
382   SizeToContents();
383 }
384
385 gfx::Size WebsiteSettingsPopupView::GetPreferredSize() {
386   if (header_ == NULL && tabbed_pane_ == NULL)
387     return views::View::GetPreferredSize();
388
389   int height = 0;
390   if (header_)
391     height += header_->GetPreferredSize().height();
392   if (tabbed_pane_)
393     height += tabbed_pane_->GetPreferredSize().height();
394
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);
402
403   return gfx::Size(width, height);
404 }
405
406 void WebsiteSettingsPopupView::SetCookieInfo(
407     const CookieInfoList& cookie_info_list) {
408   site_data_content_->RemoveAllChildViews(true);
409
410   views::GridLayout* layout = new views::GridLayout(site_data_content_);
411   site_data_content_->SetLayoutManager(layout);
412
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,
418                         1,
419                         views::GridLayout::FIXED,
420                         kSiteDataIconColumnWidth,
421                         0);
422   column_set->AddPaddingColumn(0, kIconMarginLeft);
423   column_set->AddColumn(views::GridLayout::FILL,
424                         views::GridLayout::FILL,
425                         1,
426                         views::GridLayout::USE_PREF,
427                         0,
428                         0);
429
430   layout->AddPaddingRow(1, 5);
431   for (CookieInfoList::const_iterator i(cookie_info_list.begin());
432        i != cookie_info_list.end();
433        ++i) {
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);
450   }
451   layout->AddPaddingRow(1, 6);
452
453   layout->Layout(site_data_content_);
454   SizeToContents();
455 }
456
457 void WebsiteSettingsPopupView::SetPermissionInfo(
458     const PermissionInfoList& permission_info_list) {
459   permissions_content_->RemoveAllChildViews(true);
460
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,
469                         1,
470                         views::GridLayout::USE_PREF,
471                         0,
472                         0);
473   for (PermissionInfoList::const_iterator permission =
474            permission_info_list.begin();
475        permission != permission_info_list.end();
476        ++permission) {
477     layout->StartRow(1, content_column);
478     PermissionSelectorView* selector = new PermissionSelectorView(
479         web_contents_ ? web_contents_->GetURL() : GURL::EmptyGURL(),
480         permission->type,
481         permission->default_setting,
482         permission->setting,
483         permission->source);
484     selector->AddObserver(this);
485     layout->AddView(selector,
486                     1,
487                     1,
488                     views::GridLayout::LEADING,
489                     views::GridLayout::CENTER);
490     layout->AddPaddingRow(1, kPermissionsSectionRowSpacing);
491   }
492
493   SizeToContents();
494 }
495
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;
506       break;
507     case WebsiteSettings::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT:
508       identity_status_text =
509           l10n_util::GetStringUTF16(IDS_CERT_POLICY_PROVIDED_CERT_HEADER);
510       break;
511     default:
512       identity_status_text =
513          l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_NOT_VERIFIED);
514       break;
515   }
516   header_->SetIdentityName(base::UTF8ToUTF16(identity_info.site_identity));
517   header_->SetIdentityStatus(identity_status_text, text_color);
518
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());
530
531     certificate_dialog_link_ = new views::Link(
532         l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON));
533     certificate_dialog_link_->set_listener(this);
534
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);
542     }
543
544     headline = base::UTF8ToUTF16(identity_info.site_identity);
545   }
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_);
553
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),
559       NULL,
560       NULL);
561
562   connection_tab_->InvalidateLayout();
563   Layout();
564   SizeToContents();
565 }
566
567 void WebsiteSettingsPopupView::SetFirstVisit(
568     const base::string16& first_visit) {
569   ResetConnectionSection(
570       page_info_content_,
571       WebsiteSettingsUI::GetFirstVisitIcon(first_visit),
572       l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE),
573       first_visit,
574       NULL,
575       NULL);
576   connection_tab_->InvalidateLayout();
577   Layout();
578   SizeToContents();
579 }
580
581 void WebsiteSettingsPopupView::SetSelectedTab(TabId tab_id) {
582   tabbed_pane_->SelectTabAt(tab_id);
583 }
584
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),
597                     site_data_content_,
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_,
606                     NULL);
607   pane->AddChildView(permissions_section);
608   return pane;
609 }
610
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_);
618
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_);
623
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_);
628
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,
639                            kLinkMarginTop,
640                            0));
641   link_section->AddChildView(help_center_link_);
642   pane->AddChildView(link_section);
643   return pane;
644 }
645
646 views::View* WebsiteSettingsPopupView::CreateSection(
647     const base::string16& headline_text,
648     views::View* content,
649     views::Link* link) {
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,
658                         1,
659                         views::GridLayout::USE_PREF,
660                         0,
661                         0);
662
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);
670
671   layout->AddPaddingRow(1, kPermissionsSectionHeadlineMarginBottom);
672   layout->StartRow(1, content_column);
673   layout->AddView(content, 1, 1, views::GridLayout::LEADING,
674                   views::GridLayout::CENTER);
675
676   if (link) {
677     layout->AddPaddingRow(1, 4);
678     layout->StartRow(1, content_column);
679     layout->AddView(link, 1, 1, views::GridLayout::LEADING,
680                     views::GridLayout::CENTER);
681   }
682
683   layout->AddPaddingRow(1, kPermissionsSectionPaddingBottom);
684   return container;
685 }
686
687 void WebsiteSettingsPopupView::ResetConnectionSection(
688     views::View* section_container,
689     const gfx::Image& icon,
690     const base::string16& headline,
691     const base::string16& text,
692     views::Link* link,
693     views::Link* secondary_link) {
694   section_container->RemoveAllChildViews(true);
695
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,
702                         0,
703                         views::GridLayout::USE_PREF,
704                         0,
705                         0);
706   column_set->AddPaddingColumn(0, kIconMarginLeft);
707   column_set->AddColumn(views::GridLayout::FILL,
708                         views::GridLayout::FILL,
709                         1,
710                         views::GridLayout::USE_PREF,
711                         0,
712                         0);
713   column_set->AddPaddingColumn(0, kConnectionSectionPaddingRight);
714
715
716   layout->AddPaddingRow(0, kConnectionSectionPaddingTop);
717   layout->StartRow(1, 0);
718
719   // Add status icon.
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);
724
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,
732                                 1,
733                                 views::GridLayout::USE_PREF,
734                                 0,
735                                 0);
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);
747   }
748
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);
755
756   if (link) {
757     content_layout->StartRow(1, 0);
758     content_layout->AddView(link);
759   }
760
761   if (secondary_link) {
762     content_layout->StartRow(1, 0);
763     content_layout->AddView(secondary_link);
764   }
765
766   layout->AddView(content_pane, 1, 1, views::GridLayout::LEADING,
767                   views::GridLayout::LEADING);
768   layout->AddPaddingRow(0, kConnectionSectionPaddingBottom);
769 }
770
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() :
783             NULL;
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),
791         content::Referrer(),
792         NEW_FOREGROUND_TAB,
793         content::PAGE_TRANSITION_LINK,
794         false));
795   }
796 }