website_settings_popup_view.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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 "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/cert_store.h" 20#include "content/public/browser/user_metrics.h" 21#include "grit/chromium_strings.h" 22#include "grit/generated_resources.h" 23#include "grit/theme_resources.h" 24#include "grit/ui_resources.h" 25#include "ui/base/l10n/l10n_util.h" 26#include "ui/base/models/simple_menu_model.h" 27#include "ui/base/resource/resource_bundle.h" 28#include "ui/gfx/canvas.h" 29#include "ui/gfx/font.h" 30#include "ui/gfx/image/image.h" 31#include "ui/gfx/insets.h" 32#include "ui/views/controls/button/image_button.h" 33#include "ui/views/controls/button/menu_button.h" 34#include "ui/views/controls/button/menu_button_listener.h" 35#include "ui/views/controls/image_view.h" 36#include "ui/views/controls/label.h" 37#include "ui/views/controls/link.h" 38#include "ui/views/controls/menu/menu_model_adapter.h" 39#include "ui/views/controls/menu/menu_runner.h" 40#include "ui/views/controls/separator.h" 41#include "ui/views/controls/tabbed_pane/tabbed_pane.h" 42#include "ui/views/layout/box_layout.h" 43#include "ui/views/layout/grid_layout.h" 44#include "ui/views/layout/layout_manager.h" 45#include "ui/views/view.h" 46#include "ui/views/widget/widget.h" 47#include "url/gurl.h" 48 49namespace { 50 51// Padding values for sections on the connection tab. 52const int kConnectionSectionPaddingBottom = 16; 53const int kConnectionSectionPaddingLeft = 18; 54const int kConnectionSectionPaddingTop = 16; 55const int kConnectionSectionPaddingRight = 18; 56 57// Font size of the label for the site identity. 58const int kIdentityNameFontSize = 14; 59// The text color that is used for the site identity status text, if the site's 60// identity was sucessfully verified. 61const int kIdentityVerifiedTextColor = 0xFF298a27; 62 63// Left icon margin. 64const int kIconMarginLeft = 6; 65 66// Margin and padding values for the |PopupHeaderView|. 67const int kHeaderMarginBottom = 10; 68const int kHeaderPaddingBottom = 12; 69const int kHeaderPaddingLeft = 18; 70const int kHeaderPaddingRight = 8; 71const int kHeaderPaddingTop = 12; 72 73// Spacing between the site identity label and the site identity status text in 74// the popup header. 75const int kHeaderRowSpacing = 4; 76 77// To make the bubble's arrow point directly at the location icon rather than at 78// the Omnibox's edge, inset the bubble's anchor rect by this amount of pixels. 79const int kLocationIconVerticalMargin = 5; 80 81// The max possible width of the popup. 82const int kMaxPopupWidth = 500; 83 84// The margins between the popup border and the popup content. 85const int kPopupMarginTop = 4; 86const int kPopupMarginLeft = 0; 87const int kPopupMarginBottom = 10; 88const int kPopupMarginRight = 0; 89 90// Padding values for sections on the permissions tab. 91const int kPermissionsSectionContentMinWidth = 300; 92const int kPermissionsSectionPaddingBottom = 6; 93const int kPermissionsSectionPaddingLeft = 18; 94const int kPermissionsSectionPaddingTop = 16; 95 96// Space between the headline and the content of a section on the permissions 97// tab. 98const int kPermissionsSectionHeadlineMarginBottom = 10; 99// The content of the "Permissions" section and the "Cookies and Site Data" 100// section is structured in individual rows. |kPermissionsSectionRowSpacing| 101// is the space between these rows. 102const int kPermissionsSectionRowSpacing = 2; 103 104const int kSiteDataIconColumnWidth = 20; 105const int kSiteDataSectionRowSpacing = 11; 106 107} // namespace 108 109// |PopupHeaderView| is the UI element (view) that represents the header of the 110// |WebsiteSettingsPopupView|. The header shows the status of the site's 111// identity check and the name of the site's identity. 112class PopupHeaderView : public views::View { 113 public: 114 explicit PopupHeaderView(views::ButtonListener* close_button_listener); 115 virtual ~PopupHeaderView(); 116 117 // Sets the name of the site's identity. 118 void SetIdentityName(const string16& name); 119 120 // Sets the |status_text| for the identity check of this site and the 121 // |text_color|. 122 void SetIdentityStatus(const string16& status_text, SkColor text_color); 123 124 private: 125 // The label that displays the name of the site's identity. 126 views::Label* name_; 127 // The label that displays the status of the identity check for this site. 128 views::Label* status_; 129 130 DISALLOW_COPY_AND_ASSIGN(PopupHeaderView); 131}; 132 133// Website Settings are not supported for internal Chrome pages. Instead of the 134// |WebsiteSettingsPopupView|, the |InternalPageInfoPopupView| is 135// displayed. 136class InternalPageInfoPopupView : public views::BubbleDelegateView { 137 public: 138 explicit InternalPageInfoPopupView(views::View* anchor_view); 139 virtual ~InternalPageInfoPopupView(); 140 141 private: 142 DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupView); 143}; 144 145//////////////////////////////////////////////////////////////////////////////// 146// Popup Header 147//////////////////////////////////////////////////////////////////////////////// 148 149PopupHeaderView::PopupHeaderView(views::ButtonListener* close_button_listener) 150 : name_(NULL), status_(NULL) { 151 views::GridLayout* layout = new views::GridLayout(this); 152 SetLayoutManager(layout); 153 154 const int label_column = 0; 155 views::ColumnSet* column_set = layout->AddColumnSet(label_column); 156 column_set->AddPaddingColumn(0, kHeaderPaddingLeft); 157 column_set->AddColumn(views::GridLayout::FILL, 158 views::GridLayout::FILL, 159 1, 160 views::GridLayout::USE_PREF, 161 0, 162 0); 163 column_set->AddPaddingColumn(1,0); 164 column_set->AddColumn(views::GridLayout::FILL, 165 views::GridLayout::FILL, 166 1, 167 views::GridLayout::USE_PREF, 168 0, 169 0); 170 column_set->AddPaddingColumn(0, kHeaderPaddingRight); 171 172 layout->AddPaddingRow(0, kHeaderPaddingTop); 173 174 layout->StartRow(0, label_column); 175 name_ = new views::Label(string16()); 176 gfx::Font headline_font(name_->font().GetFontName(), kIdentityNameFontSize); 177 name_->SetFont(headline_font.DeriveFont(0, gfx::Font::BOLD)); 178 layout->AddView(name_, 1, 1, views::GridLayout::LEADING, 179 views::GridLayout::TRAILING); 180 views::ImageButton* close_button = 181 new views::ImageButton(close_button_listener); 182 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 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); 191 192 layout->AddPaddingRow(0, kHeaderRowSpacing); 193 194 layout->StartRow(0, label_column); 195 status_ = new views::Label(string16()); 196 layout->AddView(status_, 197 1, 198 1, 199 views::GridLayout::LEADING, 200 views::GridLayout::CENTER); 201 202 layout->AddPaddingRow(0, kHeaderPaddingBottom); 203} 204 205PopupHeaderView::~PopupHeaderView() { 206} 207 208void PopupHeaderView::SetIdentityName(const string16& name) { 209 name_->SetText(name); 210} 211 212void PopupHeaderView::SetIdentityStatus(const string16& status, 213 SkColor text_color) { 214 status_->SetText(status); 215 status_->SetEnabledColor(text_color); 216} 217 218//////////////////////////////////////////////////////////////////////////////// 219// InternalPageInfoPopupView 220//////////////////////////////////////////////////////////////////////////////// 221 222InternalPageInfoPopupView::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)); 227 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); 235 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); 242 243 views::BubbleDelegateView::CreateBubble(this)->Show(); 244 SizeToContents(); 245} 246 247InternalPageInfoPopupView::~InternalPageInfoPopupView() { 248} 249 250//////////////////////////////////////////////////////////////////////////////// 251// WebsiteSettingsPopupView 252//////////////////////////////////////////////////////////////////////////////// 253 254WebsiteSettingsPopupView::~WebsiteSettingsPopupView() { 255} 256 257// static 258void 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); 269 } 270} 271 272WebsiteSettingsPopupView::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 // Compensate for built-in vertical padding in the anchor view's image. 295 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin, 0, 296 kLocationIconVerticalMargin, 0)); 297 298 views::GridLayout* layout = new views::GridLayout(this); 299 SetLayoutManager(layout); 300 const int content_column = 0; 301 views::ColumnSet* column_set = layout->AddColumnSet(content_column); 302 column_set->AddColumn(views::GridLayout::FILL, 303 views::GridLayout::FILL, 304 1, 305 views::GridLayout::USE_PREF, 306 0, 307 0); 308 309 header_ = new PopupHeaderView(this); 310 layout->StartRow(1, content_column); 311 layout->AddView(header_); 312 313 layout->AddPaddingRow(1, kHeaderMarginBottom); 314 tabbed_pane_ = new views::TabbedPane(false); 315 layout->StartRow(1, content_column); 316 layout->AddView(tabbed_pane_); 317 // Tabs must be added after the tabbed_pane_ was added to the views 318 // hierachy. Adding the |tabbed_pane_| to the views hierachy triggers the 319 // initialization of the native tab UI element. If the native tab UI 320 // element is not initalized adding a tab will result in a NULL pointer 321 // exception. 322 tabbed_pane_->AddTabAtIndex( 323 TAB_ID_PERMISSIONS, 324 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS), 325 CreatePermissionsTab()); 326 connection_tab_ = CreateConnectionTab(); 327 tabbed_pane_->AddTabAtIndex( 328 TAB_ID_CONNECTION, 329 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION), 330 connection_tab_); 331 DCHECK_EQ(tabbed_pane_->GetTabCount(), NUM_TAB_IDS); 332 tabbed_pane_->set_listener(this); 333 334 set_margins(gfx::Insets(kPopupMarginTop, kPopupMarginLeft, 335 kPopupMarginBottom, kPopupMarginRight)); 336 337 views::BubbleDelegateView::CreateBubble(this)->Show(); 338 SizeToContents(); 339 340 presenter_.reset(new WebsiteSettings( 341 this, profile, 342 TabSpecificContentSettings::FromWebContents(web_contents), 343 InfoBarService::FromWebContents(web_contents), url, ssl, 344 content::CertStore::GetInstance())); 345} 346 347void WebsiteSettingsPopupView::OnPermissionChanged( 348 PermissionSelectorView* permission_selector) { 349 DCHECK(permission_selector); 350 presenter_->OnSitePermissionChanged(permission_selector->type(), 351 permission_selector->current_setting()); 352} 353 354void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget* widget) { 355 presenter_->OnUIClosing(); 356} 357 358void WebsiteSettingsPopupView::ButtonPressed( 359 views::Button* button, 360 const ui::Event& event) { 361 GetWidget()->Close(); 362} 363 364void WebsiteSettingsPopupView::LinkClicked(views::Link* source, 365 int event_flags) { 366 if (source == cookie_dialog_link_) { 367 // Count how often the Collected Cookies dialog is opened. 368 content::RecordAction( 369 content::UserMetricsAction("WebsiteSettings_CookiesDialogOpened")); 370 new CollectedCookiesViews(web_contents_); 371 } else if (source == certificate_dialog_link_) { 372 gfx::NativeWindow parent = 373 anchor_view() ? anchor_view()->GetWidget()->GetNativeWindow() : NULL; 374 ShowCertificateViewerByID(web_contents_, parent, cert_id_); 375 } else if (source == help_center_link_) { 376 browser_->OpenURL(content::OpenURLParams( 377 GURL(chrome::kPageInfoHelpCenterURL), 378 content::Referrer(), 379 NEW_FOREGROUND_TAB, 380 content::PAGE_TRANSITION_LINK, 381 false)); 382 } 383 // The popup closes automatically when the collected cookies dialog or the 384 // certificate viewer opens. 385} 386 387void WebsiteSettingsPopupView::TabSelectedAt(int index) { 388 tabbed_pane_->GetSelectedTab()->Layout(); 389 SizeToContents(); 390} 391 392gfx::Size WebsiteSettingsPopupView::GetPreferredSize() { 393 if (header_ == NULL && tabbed_pane_ == NULL) 394 return views::View::GetPreferredSize(); 395 396 int height = 0; 397 if (header_) 398 height += header_->GetPreferredSize().height(); 399 if (tabbed_pane_) 400 height += tabbed_pane_->GetPreferredSize().height(); 401 402 int width = kPermissionsSectionContentMinWidth; 403 if (site_data_content_) 404 width = std::max(width, site_data_content_->GetPreferredSize().width()); 405 if (permissions_content_) 406 width = std::max(width, permissions_content_->GetPreferredSize().width()); 407 width += kPermissionsSectionPaddingLeft; 408 width = std::min(width, kMaxPopupWidth); 409 410 return gfx::Size(width, height); 411} 412 413void WebsiteSettingsPopupView::SetCookieInfo( 414 const CookieInfoList& cookie_info_list) { 415 site_data_content_->RemoveAllChildViews(true); 416 417 views::GridLayout* layout = new views::GridLayout(site_data_content_); 418 site_data_content_->SetLayoutManager(layout); 419 420 const int site_data_content_column = 0; 421 views::ColumnSet* column_set = 422 layout->AddColumnSet(site_data_content_column); 423 column_set->AddColumn(views::GridLayout::FILL, 424 views::GridLayout::FILL, 425 1, 426 views::GridLayout::FIXED, 427 kSiteDataIconColumnWidth, 428 0); 429 column_set->AddPaddingColumn(0, kIconMarginLeft); 430 column_set->AddColumn(views::GridLayout::FILL, 431 views::GridLayout::FILL, 432 1, 433 views::GridLayout::USE_PREF, 434 0, 435 0); 436 437 layout->AddPaddingRow(1, 5); 438 for (CookieInfoList::const_iterator i(cookie_info_list.begin()); 439 i != cookie_info_list.end(); 440 ++i) { 441 string16 label_text = l10n_util::GetStringFUTF16( 442 IDS_WEBSITE_SETTINGS_SITE_DATA_STATS_LINE, 443 UTF8ToUTF16(i->cookie_source), 444 base::IntToString16(i->allowed), 445 base::IntToString16(i->blocked)); 446 if (i != cookie_info_list.begin()) 447 layout->AddPaddingRow(1, kSiteDataSectionRowSpacing); 448 layout->StartRow(1, site_data_content_column); 449 views::ImageView* icon = new views::ImageView(); 450 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon( 451 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_ALLOW); 452 icon->SetImage(image.ToImageSkia()); 453 layout->AddView(icon, 1, 1, views::GridLayout::CENTER, 454 views::GridLayout::CENTER); 455 layout->AddView(new views::Label(label_text), 1, 1, 456 views::GridLayout::LEADING, views::GridLayout::CENTER); 457 } 458 layout->AddPaddingRow(1, 6); 459 460 layout->Layout(site_data_content_); 461 SizeToContents(); 462} 463 464void WebsiteSettingsPopupView::SetPermissionInfo( 465 const PermissionInfoList& permission_info_list) { 466 permissions_content_->RemoveAllChildViews(true); 467 468 views::GridLayout* layout = 469 new views::GridLayout(permissions_content_); 470 permissions_content_->SetLayoutManager(layout); 471 const int content_column = 0; 472 views::ColumnSet* column_set = 473 layout->AddColumnSet(content_column); 474 column_set->AddColumn(views::GridLayout::FILL, 475 views::GridLayout::FILL, 476 1, 477 views::GridLayout::USE_PREF, 478 0, 479 0); 480 for (PermissionInfoList::const_iterator permission = 481 permission_info_list.begin(); 482 permission != permission_info_list.end(); 483 ++permission) { 484 layout->StartRow(1, content_column); 485 PermissionSelectorView* selector = new PermissionSelectorView( 486 web_contents_ ? web_contents_->GetURL() : GURL::EmptyGURL(), 487 permission->type, 488 permission->default_setting, 489 permission->setting, 490 permission->source); 491 selector->AddObserver(this); 492 layout->AddView(selector, 493 1, 494 1, 495 views::GridLayout::LEADING, 496 views::GridLayout::CENTER); 497 layout->AddPaddingRow(1, kPermissionsSectionRowSpacing); 498 } 499 500 SizeToContents(); 501} 502 503void WebsiteSettingsPopupView::SetIdentityInfo( 504 const IdentityInfo& identity_info) { 505 string16 identity_status_text; 506 SkColor text_color = SK_ColorBLACK; 507 switch (identity_info.identity_status) { 508 case WebsiteSettings::SITE_IDENTITY_STATUS_CERT: 509 case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT: 510 identity_status_text = 511 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_VERIFIED); 512 text_color = kIdentityVerifiedTextColor; 513 break; 514 case WebsiteSettings::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT: 515 identity_status_text = 516 l10n_util::GetStringUTF16(IDS_CERT_POLICY_PROVIDED_CERT_HEADER); 517 break; 518 default: 519 identity_status_text = 520 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_NOT_VERIFIED); 521 break; 522 } 523 header_->SetIdentityName(UTF8ToUTF16(identity_info.site_identity)); 524 header_->SetIdentityStatus(identity_status_text, text_color); 525 526 // The headline and the certificate dialog link of the site's identity 527 // section is only displayed if the site's identity was verified. If the 528 // site's identity was verified, then the headline contains the organization 529 // name from the provided certificate. If the organization name is not 530 // available than the hostname of the site is used instead. 531 string16 headline; 532 if (identity_info.cert_id) { 533 cert_id_ = identity_info.cert_id; 534 certificate_dialog_link_ = new views::Link( 535 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON)); 536 certificate_dialog_link_->set_listener(this); 537 headline = UTF8ToUTF16(identity_info.site_identity); 538 } 539 ResetConnectionSection( 540 identity_info_content_, 541 WebsiteSettingsUI::GetIdentityIcon(identity_info.identity_status), 542 string16(), // The identity section has no headline. 543 UTF8ToUTF16(identity_info.identity_status_description), 544 certificate_dialog_link_); 545 546 ResetConnectionSection( 547 connection_info_content_, 548 WebsiteSettingsUI::GetConnectionIcon(identity_info.connection_status), 549 string16(), // The connection section has no headline. 550 UTF8ToUTF16(identity_info.connection_status_description), 551 NULL); 552 553 connection_tab_->InvalidateLayout(); 554 Layout(); 555 SizeToContents(); 556} 557 558void WebsiteSettingsPopupView::SetFirstVisit(const string16& first_visit) { 559 ResetConnectionSection( 560 page_info_content_, 561 WebsiteSettingsUI::GetFirstVisitIcon(first_visit), 562 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE), 563 first_visit, 564 NULL); 565 connection_tab_->InvalidateLayout(); 566 Layout(); 567 SizeToContents(); 568} 569 570void WebsiteSettingsPopupView::SetSelectedTab(TabId tab_id) { 571 tabbed_pane_->SelectTabAt(tab_id); 572} 573 574views::View* WebsiteSettingsPopupView::CreatePermissionsTab() { 575 views::View* pane = new views::View(); 576 pane->SetLayoutManager( 577 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); 578 // Add cookies and site data section. 579 cookie_dialog_link_ = new views::Link( 580 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_SHOW_SITE_DATA)); 581 cookie_dialog_link_->set_listener(this); 582 site_data_content_ = new views::View(); 583 views::View* site_data_section = 584 CreateSection(l10n_util::GetStringUTF16( 585 IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA), 586 site_data_content_, 587 cookie_dialog_link_); 588 pane->AddChildView(site_data_section); 589 // Add permissions section. 590 permissions_content_ = new views::View(); 591 views::View* permissions_section = 592 CreateSection(l10n_util::GetStringUTF16( 593 IDS_WEBSITE_SETTINGS_TITLE_SITE_PERMISSIONS), 594 permissions_content_, 595 NULL); 596 pane->AddChildView(permissions_section); 597 return pane; 598} 599 600views::View* WebsiteSettingsPopupView::CreateConnectionTab() { 601 views::View* pane = new views::View(); 602 pane->SetLayoutManager( 603 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); 604 // Add site identity section. 605 identity_info_content_ = new views::View(); 606 pane->AddChildView(identity_info_content_); 607 608 // Add connection section. 609 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL)); 610 connection_info_content_ = new views::View(); 611 pane->AddChildView(connection_info_content_); 612 613 // Add page info section. 614 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL)); 615 page_info_content_ = new views::View(); 616 pane->AddChildView(page_info_content_); 617 618 // Add help center link. 619 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL)); 620 help_center_link_ = new views::Link( 621 l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER_LINK)); 622 help_center_link_->set_listener(this); 623 views::View* link_section = new views::View(); 624 const int kLinkMarginTop = 4; 625 link_section->SetLayoutManager( 626 new views::BoxLayout(views::BoxLayout::kHorizontal, 627 kConnectionSectionPaddingLeft, 628 kLinkMarginTop, 629 0)); 630 link_section->AddChildView(help_center_link_); 631 pane->AddChildView(link_section); 632 return pane; 633} 634 635views::View* WebsiteSettingsPopupView::CreateSection( 636 const string16& headline_text, 637 views::View* content, 638 views::Link* link) { 639 views::View* container = new views::View(); 640 views::GridLayout* layout = new views::GridLayout(container); 641 container->SetLayoutManager(layout); 642 const int content_column = 0; 643 views::ColumnSet* column_set = layout->AddColumnSet(content_column); 644 column_set->AddPaddingColumn(0, kPermissionsSectionPaddingLeft); 645 column_set->AddColumn(views::GridLayout::FILL, 646 views::GridLayout::FILL, 647 1, 648 views::GridLayout::USE_PREF, 649 0, 650 0); 651 652 layout->AddPaddingRow(1, kPermissionsSectionPaddingTop); 653 layout->StartRow(1, content_column); 654 views::Label* headline = new views::Label(headline_text); 655 headline->SetFont(headline->font().DeriveFont(0, gfx::Font::BOLD)); 656 layout->AddView(headline, 1, 1, views::GridLayout::LEADING, 657 views::GridLayout::CENTER); 658 659 layout->AddPaddingRow(1, kPermissionsSectionHeadlineMarginBottom); 660 layout->StartRow(1, content_column); 661 layout->AddView(content, 1, 1, views::GridLayout::LEADING, 662 views::GridLayout::CENTER); 663 664 if (link) { 665 layout->AddPaddingRow(1, 4); 666 layout->StartRow(1, content_column); 667 layout->AddView(link, 1, 1, views::GridLayout::LEADING, 668 views::GridLayout::CENTER); 669 } 670 671 layout->AddPaddingRow(1, kPermissionsSectionPaddingBottom); 672 return container; 673} 674 675void WebsiteSettingsPopupView::ResetConnectionSection( 676 views::View* section_container, 677 const gfx::Image& icon, 678 const string16& headline, 679 const string16& text, 680 views::Link* link) { 681 section_container->RemoveAllChildViews(true); 682 683 views::GridLayout* layout = new views::GridLayout(section_container); 684 section_container->SetLayoutManager(layout); 685 views::ColumnSet* column_set = layout->AddColumnSet(0); 686 column_set->AddPaddingColumn(0, kConnectionSectionPaddingLeft); 687 column_set->AddColumn(views::GridLayout::LEADING, 688 views::GridLayout::LEADING, 689 0, 690 views::GridLayout::USE_PREF, 691 0, 692 0); 693 column_set->AddPaddingColumn(0, kIconMarginLeft); 694 column_set->AddColumn(views::GridLayout::FILL, 695 views::GridLayout::FILL, 696 1, 697 views::GridLayout::USE_PREF, 698 0, 699 0); 700 column_set->AddPaddingColumn(0, kConnectionSectionPaddingRight); 701 702 703 layout->AddPaddingRow(0, kConnectionSectionPaddingTop); 704 layout->StartRow(1, 0); 705 706 // Add status icon. 707 views::ImageView* icon_view = new views::ImageView(); 708 icon_view->SetImage(*icon.ToImageSkia()); 709 layout->AddView(icon_view, 1, 1, views::GridLayout::LEADING, 710 views::GridLayout::LEADING); 711 712 // Add section content. 713 views::View* content_pane = new views::View(); 714 views::GridLayout* content_layout = new views::GridLayout(content_pane); 715 content_pane->SetLayoutManager(content_layout); 716 views::ColumnSet* content_column_set = content_layout->AddColumnSet(0); 717 content_column_set->AddColumn(views::GridLayout::LEADING, 718 views::GridLayout::LEADING, 719 1, 720 views::GridLayout::USE_PREF, 721 0, 722 0); 723 if (!headline.empty()) { 724 views::Label* headline_label = new views::Label(headline); 725 headline_label->SetFont( 726 headline_label->font().DeriveFont(0, gfx::Font::BOLD)); 727 headline_label->SetMultiLine(true); 728 headline_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 729 // Allow linebreaking in the middle of words if necessary, so that extremely 730 // long hostnames (longer than one line) will still be completely shown. 731 headline_label->SetAllowCharacterBreak(true); 732 content_layout->StartRow(1, 0); 733 content_layout->AddView(headline_label); 734 } 735 736 views::Label* description_label = new views::Label(text); 737 description_label->SetMultiLine(true); 738 description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 739 description_label->SetAllowCharacterBreak(true); 740 content_layout->StartRow(1, 0); 741 content_layout->AddView(description_label); 742 743 if (link) { 744 content_layout->StartRow(1, 0); 745 content_layout->AddView(link); 746 } 747 748 layout->AddView(content_pane, 1, 1, views::GridLayout::LEADING, 749 views::GridLayout::LEADING); 750 layout->AddPaddingRow(0, kConnectionSectionPaddingBottom); 751} 752