website_settings_popup_view.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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 "googleurl/src/gurl.h" 22#include "grit/chromium_strings.h" 23#include "grit/generated_resources.h" 24#include "grit/theme_resources.h" 25#include "grit/ui_resources.h" 26#include "ui/base/l10n/l10n_util.h" 27#include "ui/base/models/simple_menu_model.h" 28#include "ui/base/resource/resource_bundle.h" 29#include "ui/gfx/canvas.h" 30#include "ui/gfx/font.h" 31#include "ui/gfx/image/image.h" 32#include "ui/gfx/insets.h" 33#include "ui/views/controls/button/image_button.h" 34#include "ui/views/controls/button/menu_button.h" 35#include "ui/views/controls/button/menu_button_listener.h" 36#include "ui/views/controls/image_view.h" 37#include "ui/views/controls/label.h" 38#include "ui/views/controls/link.h" 39#include "ui/views/controls/menu/menu_model_adapter.h" 40#include "ui/views/controls/menu/menu_runner.h" 41#include "ui/views/controls/separator.h" 42#include "ui/views/controls/tabbed_pane/tabbed_pane.h" 43#include "ui/views/layout/box_layout.h" 44#include "ui/views/layout/grid_layout.h" 45#include "ui/views/layout/layout_manager.h" 46#include "ui/views/view.h" 47#include "ui/views/widget/widget.h" 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 271WebsiteSettingsPopupView::WebsiteSettingsPopupView( 272 views::View* anchor_view, 273 Profile* profile, 274 content::WebContents* web_contents, 275 const GURL& url, 276 const content::SSLStatus& ssl, 277 Browser* browser) 278 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT), 279 web_contents_(web_contents), 280 browser_(browser), 281 header_(NULL), 282 tabbed_pane_(NULL), 283 site_data_content_(NULL), 284 cookie_dialog_link_(NULL), 285 permissions_content_(NULL), 286 connection_tab_(NULL), 287 identity_info_content_(NULL), 288 certificate_dialog_link_(NULL), 289 cert_id_(0), 290 help_center_link_(NULL), 291 connection_info_content_(NULL), 292 page_info_content_(NULL) { 293 // Compensate for built-in vertical padding in the anchor view's image. 294 set_anchor_view_insets(gfx::Insets(kLocationIconVerticalMargin, 0, 295 kLocationIconVerticalMargin, 0)); 296 297 views::GridLayout* layout = new views::GridLayout(this); 298 SetLayoutManager(layout); 299 const int content_column = 0; 300 views::ColumnSet* column_set = layout->AddColumnSet(content_column); 301 column_set->AddColumn(views::GridLayout::FILL, 302 views::GridLayout::FILL, 303 1, 304 views::GridLayout::USE_PREF, 305 0, 306 0); 307 308 header_ = new PopupHeaderView(this); 309 layout->StartRow(1, content_column); 310 layout->AddView(header_); 311 312 layout->AddPaddingRow(1, kHeaderMarginBottom); 313 tabbed_pane_ = new views::TabbedPane(false); 314 layout->StartRow(1, content_column); 315 layout->AddView(tabbed_pane_); 316 // Tabs must be added after the tabbed_pane_ was added to the views 317 // hierachy. Adding the |tabbed_pane_| to the views hierachy triggers the 318 // initialization of the native tab UI element. If the native tab UI 319 // element is not initalized adding a tab will result in a NULL pointer 320 // exception. 321 tabbed_pane_->AddTabAtIndex( 322 TAB_ID_PERMISSIONS, 323 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS), 324 CreatePermissionsTab()); 325 connection_tab_ = CreateConnectionTab(); 326 tabbed_pane_->AddTabAtIndex( 327 TAB_ID_CONNECTION, 328 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION), 329 connection_tab_); 330 DCHECK_EQ(tabbed_pane_->GetTabCount(), NUM_TAB_IDS); 331 tabbed_pane_->set_listener(this); 332 333 set_margins(gfx::Insets(kPopupMarginTop, kPopupMarginLeft, 334 kPopupMarginBottom, kPopupMarginRight)); 335 336 views::BubbleDelegateView::CreateBubble(this)->Show(); 337 SizeToContents(); 338 339 TabSpecificContentSettings* content_settings = 340 TabSpecificContentSettings::FromWebContents(web_contents); 341 InfoBarService* infobar_service = 342 InfoBarService::FromWebContents(web_contents); 343 presenter_.reset(new WebsiteSettings(this, profile, 344 content_settings, 345 infobar_service, 346 url, 347 ssl, 348 content::CertStore::GetInstance())); 349} 350 351void WebsiteSettingsPopupView::OnPermissionChanged( 352 PermissionSelectorView* permission_selector) { 353 DCHECK(permission_selector); 354 presenter_->OnSitePermissionChanged(permission_selector->type(), 355 permission_selector->current_setting()); 356} 357 358void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget* widget) { 359 presenter_->OnUIClosing(); 360} 361 362void WebsiteSettingsPopupView::ButtonPressed( 363 views::Button* button, 364 const ui::Event& event) { 365 GetWidget()->Close(); 366} 367 368void WebsiteSettingsPopupView::LinkClicked(views::Link* source, 369 int event_flags) { 370 if (source == cookie_dialog_link_) { 371 // Count how often the Collected Cookies dialog is opened. 372 content::RecordAction( 373 content::UserMetricsAction("WebsiteSettings_CookiesDialogOpened")); 374 new CollectedCookiesViews(web_contents_); 375 } else if (source == certificate_dialog_link_) { 376 gfx::NativeWindow parent = 377 anchor_view() ? anchor_view()->GetWidget()->GetNativeWindow() : NULL; 378 ShowCertificateViewerByID(web_contents_, parent, cert_id_); 379 } else if (source == help_center_link_) { 380 browser_->OpenURL(content::OpenURLParams( 381 GURL(chrome::kPageInfoHelpCenterURL), 382 content::Referrer(), 383 NEW_FOREGROUND_TAB, 384 content::PAGE_TRANSITION_LINK, 385 false)); 386 } 387 // The popup closes automatically when the collected cookies dialog or the 388 // certificate viewer opens. 389} 390 391void WebsiteSettingsPopupView::TabSelectedAt(int index) { 392 tabbed_pane_->GetSelectedTab()->Layout(); 393 SizeToContents(); 394} 395 396gfx::Size WebsiteSettingsPopupView::GetPreferredSize() { 397 if (header_ == NULL && tabbed_pane_ == NULL) 398 return views::View::GetPreferredSize(); 399 400 int height = 0; 401 if (header_) 402 height += header_->GetPreferredSize().height(); 403 if (tabbed_pane_) 404 height += tabbed_pane_->GetPreferredSize().height(); 405 406 int width = kPermissionsSectionContentMinWidth; 407 if (site_data_content_) 408 width = std::max(width, site_data_content_->GetPreferredSize().width()); 409 if (permissions_content_) 410 width = std::max(width, permissions_content_->GetPreferredSize().width()); 411 width += kPermissionsSectionPaddingLeft; 412 width = std::min(width, kMaxPopupWidth); 413 414 return gfx::Size(width, height); 415} 416 417void WebsiteSettingsPopupView::SetCookieInfo( 418 const CookieInfoList& cookie_info_list) { 419 site_data_content_->RemoveAllChildViews(true); 420 421 views::GridLayout* layout = new views::GridLayout(site_data_content_); 422 site_data_content_->SetLayoutManager(layout); 423 424 const int site_data_content_column = 0; 425 views::ColumnSet* column_set = 426 layout->AddColumnSet(site_data_content_column); 427 column_set->AddColumn(views::GridLayout::FILL, 428 views::GridLayout::FILL, 429 1, 430 views::GridLayout::FIXED, 431 kSiteDataIconColumnWidth, 432 0); 433 column_set->AddPaddingColumn(0, kIconMarginLeft); 434 column_set->AddColumn(views::GridLayout::FILL, 435 views::GridLayout::FILL, 436 1, 437 views::GridLayout::USE_PREF, 438 0, 439 0); 440 441 layout->AddPaddingRow(1, 5); 442 for (CookieInfoList::const_iterator i(cookie_info_list.begin()); 443 i != cookie_info_list.end(); 444 ++i) { 445 string16 label_text = l10n_util::GetStringFUTF16( 446 IDS_WEBSITE_SETTINGS_SITE_DATA_STATS_LINE, 447 UTF8ToUTF16(i->cookie_source), 448 base::IntToString16(i->allowed), 449 base::IntToString16(i->blocked)); 450 if (i != cookie_info_list.begin()) 451 layout->AddPaddingRow(1, kSiteDataSectionRowSpacing); 452 layout->StartRow(1, site_data_content_column); 453 views::ImageView* icon = new views::ImageView(); 454 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon( 455 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_ALLOW); 456 icon->SetImage(image.ToImageSkia()); 457 layout->AddView(icon, 1, 1, views::GridLayout::CENTER, 458 views::GridLayout::CENTER); 459 layout->AddView(new views::Label(label_text), 1, 1, 460 views::GridLayout::LEADING, views::GridLayout::CENTER); 461 } 462 layout->AddPaddingRow(1, 6); 463 464 layout->Layout(site_data_content_); 465 SizeToContents(); 466} 467 468void WebsiteSettingsPopupView::SetPermissionInfo( 469 const PermissionInfoList& permission_info_list) { 470 permissions_content_->RemoveAllChildViews(true); 471 472 views::GridLayout* layout = 473 new views::GridLayout(permissions_content_); 474 permissions_content_->SetLayoutManager(layout); 475 const int content_column = 0; 476 views::ColumnSet* column_set = 477 layout->AddColumnSet(content_column); 478 column_set->AddColumn(views::GridLayout::FILL, 479 views::GridLayout::FILL, 480 1, 481 views::GridLayout::USE_PREF, 482 0, 483 0); 484 for (PermissionInfoList::const_iterator permission = 485 permission_info_list.begin(); 486 permission != permission_info_list.end(); 487 ++permission) { 488 layout->StartRow(1, content_column); 489 PermissionSelectorView* selector = new PermissionSelectorView( 490 web_contents_ ? web_contents_->GetURL() : GURL::EmptyGURL(), 491 permission->type, 492 permission->default_setting, 493 permission->setting, 494 permission->source); 495 selector->AddObserver(this); 496 layout->AddView(selector, 497 1, 498 1, 499 views::GridLayout::LEADING, 500 views::GridLayout::CENTER); 501 layout->AddPaddingRow(1, kPermissionsSectionRowSpacing); 502 } 503 504 SizeToContents(); 505} 506 507void WebsiteSettingsPopupView::SetIdentityInfo( 508 const IdentityInfo& identity_info) { 509 string16 identity_status_text; 510 SkColor text_color = SK_ColorBLACK; 511 switch (identity_info.identity_status) { 512 case WebsiteSettings::SITE_IDENTITY_STATUS_CERT: 513 case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT: 514 identity_status_text = 515 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_VERIFIED); 516 text_color = kIdentityVerifiedTextColor; 517 break; 518 case WebsiteSettings::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT: 519 identity_status_text = 520 l10n_util::GetStringUTF16(IDS_CERT_POLICY_PROVIDED_CERT_HEADER); 521 break; 522 default: 523 identity_status_text = 524 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_IDENTITY_NOT_VERIFIED); 525 break; 526 } 527 header_->SetIdentityName(UTF8ToUTF16(identity_info.site_identity)); 528 header_->SetIdentityStatus(identity_status_text, text_color); 529 530 // The headline and the certificate dialog link of the site's identity 531 // section is only displayed if the site's identity was verified. If the 532 // site's identity was verified, then the headline contains the organization 533 // name from the provided certificate. If the organization name is not 534 // available than the hostname of the site is used instead. 535 string16 headline; 536 if (identity_info.cert_id) { 537 cert_id_ = identity_info.cert_id; 538 certificate_dialog_link_ = new views::Link( 539 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON)); 540 certificate_dialog_link_->set_listener(this); 541 headline = UTF8ToUTF16(identity_info.site_identity); 542 } 543 ResetConnectionSection( 544 identity_info_content_, 545 WebsiteSettingsUI::GetIdentityIcon(identity_info.identity_status), 546 string16(), // The identity section has no headline. 547 UTF8ToUTF16(identity_info.identity_status_description), 548 certificate_dialog_link_); 549 550 ResetConnectionSection( 551 connection_info_content_, 552 WebsiteSettingsUI::GetConnectionIcon(identity_info.connection_status), 553 string16(), // The connection section has no headline. 554 UTF8ToUTF16(identity_info.connection_status_description), 555 NULL); 556 557 connection_tab_->InvalidateLayout(); 558 Layout(); 559 SizeToContents(); 560} 561 562void WebsiteSettingsPopupView::SetFirstVisit(const string16& first_visit) { 563 ResetConnectionSection( 564 page_info_content_, 565 WebsiteSettingsUI::GetFirstVisitIcon(first_visit), 566 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE), 567 first_visit, 568 NULL); 569 connection_tab_->InvalidateLayout(); 570 Layout(); 571 SizeToContents(); 572} 573 574void WebsiteSettingsPopupView::SetSelectedTab(TabId tab_id) { 575 tabbed_pane_->SelectTabAt(tab_id); 576} 577 578views::View* WebsiteSettingsPopupView::CreatePermissionsTab() { 579 views::View* pane = new views::View(); 580 pane->SetLayoutManager( 581 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); 582 // Add cookies and site data section. 583 cookie_dialog_link_ = new views::Link( 584 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_SHOW_SITE_DATA)); 585 cookie_dialog_link_->set_listener(this); 586 site_data_content_ = new views::View(); 587 views::View* site_data_section = 588 CreateSection(l10n_util::GetStringUTF16( 589 IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA), 590 site_data_content_, 591 cookie_dialog_link_); 592 pane->AddChildView(site_data_section); 593 // Add permissions section. 594 permissions_content_ = new views::View(); 595 views::View* permissions_section = 596 CreateSection(l10n_util::GetStringUTF16( 597 IDS_WEBSITE_SETTINGS_TITLE_SITE_PERMISSIONS), 598 permissions_content_, 599 NULL); 600 pane->AddChildView(permissions_section); 601 return pane; 602} 603 604views::View* WebsiteSettingsPopupView::CreateConnectionTab() { 605 views::View* pane = new views::View(); 606 pane->SetLayoutManager( 607 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); 608 // Add site identity section. 609 identity_info_content_ = new views::View(); 610 pane->AddChildView(identity_info_content_); 611 612 // Add connection section. 613 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL)); 614 connection_info_content_ = new views::View(); 615 pane->AddChildView(connection_info_content_); 616 617 // Add page info section. 618 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL)); 619 page_info_content_ = new views::View(); 620 pane->AddChildView(page_info_content_); 621 622 // Add help center link. 623 pane->AddChildView(new views::Separator(views::Separator::HORIZONTAL)); 624 help_center_link_ = new views::Link( 625 l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER_LINK)); 626 help_center_link_->set_listener(this); 627 views::View* link_section = new views::View(); 628 const int kLinkMarginTop = 4; 629 link_section->SetLayoutManager( 630 new views::BoxLayout(views::BoxLayout::kHorizontal, 631 kConnectionSectionPaddingLeft, 632 kLinkMarginTop, 633 0)); 634 link_section->AddChildView(help_center_link_); 635 pane->AddChildView(link_section); 636 return pane; 637} 638 639views::View* WebsiteSettingsPopupView::CreateSection( 640 const string16& headline_text, 641 views::View* content, 642 views::Link* link) { 643 views::View* container = new views::View(); 644 views::GridLayout* layout = new views::GridLayout(container); 645 container->SetLayoutManager(layout); 646 const int content_column = 0; 647 views::ColumnSet* column_set = layout->AddColumnSet(content_column); 648 column_set->AddPaddingColumn(0, kPermissionsSectionPaddingLeft); 649 column_set->AddColumn(views::GridLayout::FILL, 650 views::GridLayout::FILL, 651 1, 652 views::GridLayout::USE_PREF, 653 0, 654 0); 655 656 layout->AddPaddingRow(1, kPermissionsSectionPaddingTop); 657 layout->StartRow(1, content_column); 658 views::Label* headline = new views::Label(headline_text); 659 headline->SetFont(headline->font().DeriveFont(0, gfx::Font::BOLD)); 660 layout->AddView(headline, 1, 1, views::GridLayout::LEADING, 661 views::GridLayout::CENTER); 662 663 layout->AddPaddingRow(1, kPermissionsSectionHeadlineMarginBottom); 664 layout->StartRow(1, content_column); 665 layout->AddView(content, 1, 1, views::GridLayout::LEADING, 666 views::GridLayout::CENTER); 667 668 if (link) { 669 layout->AddPaddingRow(1, 4); 670 layout->StartRow(1, content_column); 671 layout->AddView(link, 1, 1, views::GridLayout::LEADING, 672 views::GridLayout::CENTER); 673 } 674 675 layout->AddPaddingRow(1, kPermissionsSectionPaddingBottom); 676 return container; 677} 678 679void WebsiteSettingsPopupView::ResetConnectionSection( 680 views::View* section_container, 681 const gfx::Image& icon, 682 const string16& headline, 683 const string16& text, 684 views::Link* link) { 685 section_container->RemoveAllChildViews(true); 686 687 views::GridLayout* layout = new views::GridLayout(section_container); 688 section_container->SetLayoutManager(layout); 689 views::ColumnSet* column_set = layout->AddColumnSet(0); 690 column_set->AddPaddingColumn(0, kConnectionSectionPaddingLeft); 691 column_set->AddColumn(views::GridLayout::LEADING, 692 views::GridLayout::LEADING, 693 0, 694 views::GridLayout::USE_PREF, 695 0, 696 0); 697 column_set->AddPaddingColumn(0, kIconMarginLeft); 698 column_set->AddColumn(views::GridLayout::FILL, 699 views::GridLayout::FILL, 700 1, 701 views::GridLayout::USE_PREF, 702 0, 703 0); 704 column_set->AddPaddingColumn(0, kConnectionSectionPaddingRight); 705 706 707 layout->AddPaddingRow(0, kConnectionSectionPaddingTop); 708 layout->StartRow(1, 0); 709 710 // Add status icon. 711 views::ImageView* icon_view = new views::ImageView(); 712 icon_view->SetImage(*icon.ToImageSkia()); 713 layout->AddView(icon_view, 1, 1, views::GridLayout::LEADING, 714 views::GridLayout::LEADING); 715 716 // Add section content. 717 views::View* content_pane = new views::View(); 718 views::GridLayout* content_layout = new views::GridLayout(content_pane); 719 content_pane->SetLayoutManager(content_layout); 720 views::ColumnSet* content_column_set = content_layout->AddColumnSet(0); 721 content_column_set->AddColumn(views::GridLayout::LEADING, 722 views::GridLayout::LEADING, 723 1, 724 views::GridLayout::USE_PREF, 725 0, 726 0); 727 if (!headline.empty()) { 728 views::Label* headline_label = new views::Label(headline); 729 headline_label->SetFont( 730 headline_label->font().DeriveFont(0, gfx::Font::BOLD)); 731 headline_label->SetMultiLine(true); 732 headline_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 733 // Allow linebreaking in the middle of words if necessary, so that extremely 734 // long hostnames (longer than one line) will still be completely shown. 735 headline_label->SetAllowCharacterBreak(true); 736 content_layout->StartRow(1, 0); 737 content_layout->AddView(headline_label); 738 } 739 740 views::Label* description_label = new views::Label(text); 741 description_label->SetMultiLine(true); 742 description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 743 description_label->SetAllowCharacterBreak(true); 744 content_layout->StartRow(1, 0); 745 content_layout->AddView(description_label); 746 747 if (link) { 748 content_layout->StartRow(1, 0); 749 content_layout->AddView(link); 750 } 751 752 layout->AddView(content_pane, 1, 1, views::GridLayout::LEADING, 753 views::GridLayout::LEADING); 754 layout->AddPaddingRow(0, kConnectionSectionPaddingBottom); 755} 756