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