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