| OLD | NEW |
| (Empty) |
| 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/gtk/website_settings/website_settings_popup_gtk.h" | |
| 6 | |
| 7 #include "base/i18n/rtl.h" | |
| 8 #include "base/strings/string_number_conversions.h" | |
| 9 #include "base/strings/utf_string_conversions.h" | |
| 10 #include "chrome/browser/certificate_viewer.h" | |
| 11 #include "chrome/browser/chrome_notification_types.h" | |
| 12 #include "chrome/browser/infobars/infobar_service.h" | |
| 13 #include "chrome/browser/ui/browser.h" | |
| 14 #include "chrome/browser/ui/browser_list.h" | |
| 15 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h" | |
| 16 #include "chrome/browser/ui/gtk/browser_window_gtk.h" | |
| 17 #include "chrome/browser/ui/gtk/collected_cookies_gtk.h" | |
| 18 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" | |
| 19 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | |
| 20 #include "chrome/browser/ui/gtk/gtk_util.h" | |
| 21 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" | |
| 22 #include "chrome/browser/ui/gtk/nine_box.h" | |
| 23 #include "chrome/browser/ui/gtk/website_settings/permission_selector.h" | |
| 24 #include "chrome/browser/ui/website_settings/website_settings.h" | |
| 25 #include "chrome/browser/ui/website_settings/website_settings_utils.h" | |
| 26 #include "chrome/common/url_constants.h" | |
| 27 #include "content/public/browser/cert_store.h" | |
| 28 #include "content/public/browser/notification_service.h" | |
| 29 #include "content/public/browser/user_metrics.h" | |
| 30 #include "grit/chromium_strings.h" | |
| 31 #include "grit/generated_resources.h" | |
| 32 #include "grit/locale_settings.h" | |
| 33 #include "grit/theme_resources.h" | |
| 34 #include "grit/ui_resources.h" | |
| 35 #include "ui/base/gtk/gtk_hig_constants.h" | |
| 36 #include "ui/base/l10n/l10n_util.h" | |
| 37 #include "ui/base/resource/resource_bundle.h" | |
| 38 #include "ui/gfx/image/cairo_cached_surface.h" | |
| 39 #include "ui/gfx/image/image.h" | |
| 40 #include "url/gurl.h" | |
| 41 | |
| 42 using content::OpenURLParams; | |
| 43 | |
| 44 namespace { | |
| 45 | |
| 46 // The width of the popup. | |
| 47 const int kPopupWidth = 400; | |
| 48 | |
| 49 // Spacing between consecutive tabs in the tabstrip. | |
| 50 const int kInterTabSpacing = 2; | |
| 51 | |
| 52 // Spacing between start of tab and tab text. | |
| 53 const int kTabTextHorizontalMargin = 12; | |
| 54 | |
| 55 // The vertical lift of the tab's text off the bottom of the tab. | |
| 56 const int kTabTextBaseline = 4; | |
| 57 | |
| 58 // The max width of the text labels on the connection tab. | |
| 59 const int kConnectionTabTextWidth = 300; | |
| 60 | |
| 61 // The text color of the site identity status label for websites with a | |
| 62 // verified identity. | |
| 63 const GdkColor kGdkGreen = GDK_COLOR_RGB(0x29, 0x8a, 0x27); | |
| 64 | |
| 65 GtkWidget* CreateTextLabel(const std::string& text, | |
| 66 int width, | |
| 67 GtkThemeService* theme_service, | |
| 68 const GdkColor& color) { | |
| 69 GtkWidget* label = theme_service->BuildLabel(text, color); | |
| 70 if (width > 0) | |
| 71 gtk_util::SetLabelWidth(label, width); | |
| 72 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR); | |
| 73 return label; | |
| 74 } | |
| 75 | |
| 76 void ClearContainer(GtkWidget* container) { | |
| 77 GList* child = gtk_container_get_children(GTK_CONTAINER(container)); | |
| 78 for (GList* item = child; item; item = g_list_next(item)) | |
| 79 gtk_container_remove(GTK_CONTAINER(container), GTK_WIDGET(item->data)); | |
| 80 | |
| 81 g_list_free(child); | |
| 82 } | |
| 83 | |
| 84 void SetConnectionSection(GtkWidget* section_box, | |
| 85 const gfx::Image& icon, | |
| 86 GtkWidget* content_box) { | |
| 87 DCHECK(section_box); | |
| 88 ClearContainer(section_box); | |
| 89 gtk_container_set_border_width(GTK_CONTAINER(section_box), | |
| 90 ui::kContentAreaBorder); | |
| 91 | |
| 92 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); | |
| 93 | |
| 94 GdkPixbuf* pixbuf = icon.ToGdkPixbuf(); | |
| 95 GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); | |
| 96 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); | |
| 97 gtk_misc_set_alignment(GTK_MISC(image), 0, 0); | |
| 98 | |
| 99 gtk_box_pack_start(GTK_BOX(hbox), content_box, TRUE, TRUE, 0); | |
| 100 | |
| 101 gtk_box_pack_start(GTK_BOX(section_box), hbox, TRUE, TRUE, 0); | |
| 102 gtk_widget_show_all(section_box); | |
| 103 } | |
| 104 | |
| 105 GtkWidget* CreatePermissionTabSection(std::string section_title, | |
| 106 GtkWidget* section_content, | |
| 107 GtkThemeService* theme_service) { | |
| 108 GtkWidget* section_box = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 109 | |
| 110 // Add Section title | |
| 111 GtkWidget* title_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); | |
| 112 | |
| 113 GtkWidget* label = theme_service->BuildLabel(section_title, ui::kGdkBlack); | |
| 114 PangoAttrList* attributes = pango_attr_list_new(); | |
| 115 pango_attr_list_insert(attributes, | |
| 116 pango_attr_weight_new(PANGO_WEIGHT_BOLD)); | |
| 117 gtk_label_set_attributes(GTK_LABEL(label), attributes); | |
| 118 pango_attr_list_unref(attributes); | |
| 119 gtk_box_pack_start(GTK_BOX(section_box), title_hbox, FALSE, FALSE, 0); | |
| 120 | |
| 121 gtk_box_pack_start(GTK_BOX(title_hbox), label, FALSE, FALSE, 0); | |
| 122 | |
| 123 // Add section content | |
| 124 gtk_box_pack_start(GTK_BOX(section_box), section_content, FALSE, FALSE, 0); | |
| 125 return section_box; | |
| 126 } | |
| 127 | |
| 128 // A popup that is shown for internal pages (like chrome://). | |
| 129 class InternalPageInfoPopupGtk : public BubbleDelegateGtk { | |
| 130 public: | |
| 131 explicit InternalPageInfoPopupGtk(gfx::NativeWindow parent, | |
| 132 Profile* profile); | |
| 133 virtual ~InternalPageInfoPopupGtk(); | |
| 134 | |
| 135 private: | |
| 136 // BubbleDelegateGtk implementation. | |
| 137 virtual void BubbleClosing(BubbleGtk* bubble, bool closed_by_escape) OVERRIDE; | |
| 138 | |
| 139 // The popup bubble container. | |
| 140 BubbleGtk* bubble_; | |
| 141 | |
| 142 DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupGtk); | |
| 143 }; | |
| 144 | |
| 145 InternalPageInfoPopupGtk::InternalPageInfoPopupGtk( | |
| 146 gfx::NativeWindow parent, Profile* profile) { | |
| 147 GtkWidget* contents = gtk_hbox_new(FALSE, ui::kLabelSpacing); | |
| 148 gtk_container_set_border_width(GTK_CONTAINER(contents), | |
| 149 ui::kContentAreaBorder); | |
| 150 // Add the popup icon. | |
| 151 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
| 152 GdkPixbuf* pixbuf = rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_26).ToGdkPixbuf(); | |
| 153 GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); | |
| 154 gtk_box_pack_start(GTK_BOX(contents), image, FALSE, FALSE, 0); | |
| 155 gtk_misc_set_alignment(GTK_MISC(image), 0, 0); | |
| 156 | |
| 157 // Add the popup text. | |
| 158 GtkThemeService* theme_service = GtkThemeService::GetFrom(profile); | |
| 159 GtkWidget* label = theme_service->BuildLabel( | |
| 160 l10n_util::GetStringUTF8(IDS_PAGE_INFO_INTERNAL_PAGE), ui::kGdkBlack); | |
| 161 gtk_box_pack_start(GTK_BOX(contents), label, FALSE, FALSE, 0); | |
| 162 | |
| 163 gtk_widget_show_all(contents); | |
| 164 | |
| 165 // Create the bubble. | |
| 166 BrowserWindowGtk* browser_window = | |
| 167 BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent); | |
| 168 GtkWidget* anchor = browser_window-> | |
| 169 GetToolbar()->GetLocationBarView()->location_icon_widget(); | |
| 170 bubble_ = BubbleGtk::Show(anchor, | |
| 171 NULL, // |rect| | |
| 172 contents, | |
| 173 BubbleGtk::ANCHOR_TOP_LEFT, | |
| 174 BubbleGtk::MATCH_SYSTEM_THEME | | |
| 175 BubbleGtk::POPUP_WINDOW | | |
| 176 BubbleGtk::GRAB_INPUT, | |
| 177 theme_service, | |
| 178 this); // |delegate| | |
| 179 DCHECK(bubble_); | |
| 180 } | |
| 181 | |
| 182 InternalPageInfoPopupGtk::~InternalPageInfoPopupGtk() { | |
| 183 } | |
| 184 | |
| 185 void InternalPageInfoPopupGtk::BubbleClosing(BubbleGtk* bubble, | |
| 186 bool closed_by_escape) { | |
| 187 delete this; | |
| 188 } | |
| 189 | |
| 190 } // namespace | |
| 191 | |
| 192 // static | |
| 193 void WebsiteSettingsPopupGtk::Show(gfx::NativeWindow parent, | |
| 194 Profile* profile, | |
| 195 content::WebContents* web_contents, | |
| 196 const GURL& url, | |
| 197 const content::SSLStatus& ssl) { | |
| 198 if (InternalChromePage(url)) | |
| 199 new InternalPageInfoPopupGtk(parent, profile); | |
| 200 else | |
| 201 new WebsiteSettingsPopupGtk(parent, profile, web_contents, url, ssl); | |
| 202 } | |
| 203 | |
| 204 WebsiteSettingsPopupGtk::WebsiteSettingsPopupGtk( | |
| 205 gfx::NativeWindow parent, | |
| 206 Profile* profile, | |
| 207 content::WebContents* web_contents, | |
| 208 const GURL& url, | |
| 209 const content::SSLStatus& ssl) | |
| 210 : parent_(parent), | |
| 211 contents_(NULL), | |
| 212 theme_service_(GtkThemeService::GetFrom(profile)), | |
| 213 profile_(profile), | |
| 214 web_contents_(web_contents), | |
| 215 browser_(NULL), | |
| 216 cert_id_(0), | |
| 217 header_box_(NULL), | |
| 218 cookies_section_contents_(NULL), | |
| 219 permissions_section_contents_(NULL), | |
| 220 identity_contents_(NULL), | |
| 221 connection_contents_(NULL), | |
| 222 first_visit_contents_(NULL), | |
| 223 notebook_(NULL) { | |
| 224 BrowserWindowGtk* browser_window = | |
| 225 BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent); | |
| 226 browser_ = browser_window->browser(); | |
| 227 anchor_ = browser_window-> | |
| 228 GetToolbar()->GetLocationBarView()->location_icon_widget(); | |
| 229 | |
| 230 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, | |
| 231 content::Source<ThemeService>(theme_service_)); | |
| 232 | |
| 233 InitContents(); | |
| 234 | |
| 235 bubble_ = BubbleGtk::Show(anchor_, | |
| 236 NULL, // |rect| | |
| 237 contents_, | |
| 238 BubbleGtk::ANCHOR_TOP_LEFT, | |
| 239 BubbleGtk::MATCH_SYSTEM_THEME | | |
| 240 BubbleGtk::POPUP_WINDOW | | |
| 241 BubbleGtk::GRAB_INPUT, | |
| 242 theme_service_, | |
| 243 this); // |delegate| | |
| 244 if (!bubble_) { | |
| 245 NOTREACHED(); | |
| 246 return; | |
| 247 } | |
| 248 | |
| 249 presenter_.reset(new WebsiteSettings( | |
| 250 this, profile, TabSpecificContentSettings::FromWebContents(web_contents), | |
| 251 InfoBarService::FromWebContents(web_contents), url, ssl, | |
| 252 content::CertStore::GetInstance())); | |
| 253 } | |
| 254 | |
| 255 WebsiteSettingsPopupGtk::~WebsiteSettingsPopupGtk() { | |
| 256 } | |
| 257 | |
| 258 void WebsiteSettingsPopupGtk::BubbleClosing(BubbleGtk* bubble, | |
| 259 bool closed_by_escape) { | |
| 260 if (presenter_.get()) { | |
| 261 presenter_->OnUIClosing(); | |
| 262 presenter_.reset(); | |
| 263 } | |
| 264 | |
| 265 // Slightly delay destruction to allow the event stack to unwind and release | |
| 266 // references to owned widgets. | |
| 267 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | |
| 268 } | |
| 269 | |
| 270 void WebsiteSettingsPopupGtk::InitContents() { | |
| 271 if (!contents_) | |
| 272 contents_ = gtk_vbox_new(FALSE, 0); | |
| 273 else | |
| 274 gtk_util::RemoveAllChildren(contents_); | |
| 275 | |
| 276 // Create popup header. | |
| 277 header_box_ = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 278 gtk_box_pack_start(GTK_BOX(contents_), header_box_, FALSE, FALSE, 0); | |
| 279 gtk_container_set_border_width(GTK_CONTAINER(header_box_), | |
| 280 ui::kContentAreaBorder); | |
| 281 | |
| 282 // Create the container for the contents of the permissions tab. | |
| 283 GtkWidget* permission_tab_contents = | |
| 284 gtk_vbox_new(FALSE, ui::kContentAreaSpacing); | |
| 285 gtk_container_set_border_width(GTK_CONTAINER(permission_tab_contents), | |
| 286 ui::kContentAreaBorder); | |
| 287 cookies_section_contents_ = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 288 std::string title = l10n_util::GetStringUTF8( | |
| 289 IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA); | |
| 290 gtk_box_pack_start(GTK_BOX(permission_tab_contents), | |
| 291 CreatePermissionTabSection(title, | |
| 292 cookies_section_contents_, | |
| 293 theme_service_), | |
| 294 FALSE, FALSE, 0); | |
| 295 permissions_section_contents_ = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 296 title = l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TITLE_SITE_PERMISSIONS); | |
| 297 gtk_box_pack_start(GTK_BOX(permission_tab_contents), | |
| 298 CreatePermissionTabSection(title, | |
| 299 permissions_section_contents_, | |
| 300 theme_service_), | |
| 301 FALSE, FALSE, 0); | |
| 302 | |
| 303 // Create the container for the contents of the connection tab. | |
| 304 GtkWidget* connection_tab = gtk_vbox_new(FALSE, 0); | |
| 305 identity_contents_ = gtk_vbox_new(FALSE, 0); | |
| 306 gtk_box_pack_start(GTK_BOX(connection_tab), identity_contents_, FALSE, FALSE, | |
| 307 0); | |
| 308 gtk_box_pack_start(GTK_BOX(connection_tab), gtk_hseparator_new(), FALSE, | |
| 309 FALSE, 0); | |
| 310 connection_contents_ = gtk_vbox_new(FALSE, 0); | |
| 311 gtk_box_pack_start(GTK_BOX(connection_tab), connection_contents_, FALSE, | |
| 312 FALSE, 0); | |
| 313 gtk_box_pack_start(GTK_BOX(connection_tab), gtk_hseparator_new(), FALSE, | |
| 314 FALSE, 0); | |
| 315 first_visit_contents_ = gtk_vbox_new(FALSE, 0); | |
| 316 gtk_box_pack_start(GTK_BOX(connection_tab), first_visit_contents_, FALSE, | |
| 317 FALSE, 0); | |
| 318 gtk_box_pack_start(GTK_BOX(connection_tab), gtk_hseparator_new(), FALSE, | |
| 319 FALSE, 0); | |
| 320 | |
| 321 GtkWidget* help_link = theme_service_->BuildChromeLinkButton( | |
| 322 l10n_util::GetStringUTF8(IDS_PAGE_INFO_HELP_CENTER_LINK)); | |
| 323 GtkWidget* help_link_hbox = gtk_hbox_new(FALSE, 0); | |
| 324 gtk_container_set_border_width(GTK_CONTAINER(help_link_hbox), | |
| 325 ui::kContentAreaBorder); | |
| 326 gtk_box_pack_start(GTK_BOX(help_link_hbox), help_link, FALSE, FALSE, 0); | |
| 327 gtk_box_pack_start(GTK_BOX(connection_tab), help_link_hbox, FALSE, FALSE, 0); | |
| 328 g_signal_connect(help_link, "clicked", | |
| 329 G_CALLBACK(OnHelpLinkClickedThunk), this); | |
| 330 | |
| 331 // Create tabstrip (used only for Chrome-theme mode). | |
| 332 GtkWidget* tabstrip = gtk_hbox_new(FALSE, kInterTabSpacing); | |
| 333 tabstrip_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); | |
| 334 gtk_alignment_set_padding(GTK_ALIGNMENT(tabstrip_alignment_), 0, 0, | |
| 335 ui::kContentAreaBorder, ui::kContentAreaBorder); | |
| 336 int tab_height = ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( | |
| 337 IDR_WEBSITE_SETTINGS_TAB_LEFT2).ToImageSkia()->height(); | |
| 338 gtk_widget_set_size_request(tabstrip_alignment_, -1, tab_height); | |
| 339 g_signal_connect(tabstrip_alignment_, "expose-event", | |
| 340 G_CALLBACK(&OnTabstripExposeThunk), this); | |
| 341 gtk_container_add(GTK_CONTAINER(tabstrip_alignment_), tabstrip); | |
| 342 gtk_box_pack_start(GTK_BOX(contents_), tabstrip_alignment_, FALSE, FALSE, 0); | |
| 343 | |
| 344 gtk_box_pack_start(GTK_BOX(tabstrip), | |
| 345 BuildTab(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS), | |
| 346 FALSE, FALSE, 0); | |
| 347 gtk_box_pack_start(GTK_BOX(tabstrip), | |
| 348 BuildTab(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION), | |
| 349 FALSE, FALSE, 0); | |
| 350 | |
| 351 // Create tab container and add all tabs. | |
| 352 notebook_ = gtk_notebook_new(); | |
| 353 gtk_notebook_set_tab_hborder(GTK_NOTEBOOK(notebook_), 0); | |
| 354 | |
| 355 GtkWidget* label = gtk_label_new(l10n_util::GetStringUTF8( | |
| 356 IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS).c_str()); | |
| 357 gtk_misc_set_padding(GTK_MISC(label), kTabTextHorizontalMargin, 0); | |
| 358 gtk_notebook_insert_page(GTK_NOTEBOOK(notebook_), permission_tab_contents, | |
| 359 label, TAB_ID_PERMISSIONS); | |
| 360 | |
| 361 label = gtk_label_new(l10n_util::GetStringUTF8( | |
| 362 IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION).c_str()); | |
| 363 gtk_misc_set_padding(GTK_MISC(label), kTabTextHorizontalMargin, 0); | |
| 364 gtk_notebook_insert_page(GTK_NOTEBOOK(notebook_), connection_tab, label, | |
| 365 TAB_ID_CONNECTION); | |
| 366 | |
| 367 DCHECK_EQ(gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_)), NUM_TAB_IDS); | |
| 368 | |
| 369 gtk_box_pack_start(GTK_BOX(contents_), notebook_, FALSE, FALSE, 0); | |
| 370 | |
| 371 theme_service_->InitThemesFor(this); | |
| 372 gtk_widget_show_all(contents_); | |
| 373 } | |
| 374 | |
| 375 GtkWidget* WebsiteSettingsPopupGtk::BuildTab(int ids) { | |
| 376 GtkWidget* tab = gtk_event_box_new(); | |
| 377 gtk_event_box_set_visible_window(GTK_EVENT_BOX(tab), FALSE); | |
| 378 GtkWidget* label = gtk_label_new(l10n_util::GetStringUTF8(ids).c_str()); | |
| 379 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &ui::kGdkBlack); | |
| 380 gtk_misc_set_padding(GTK_MISC(label), | |
| 381 kTabTextHorizontalMargin, kTabTextBaseline); | |
| 382 gtk_misc_set_alignment(GTK_MISC(label), 0.5, 1.0); | |
| 383 gtk_container_add(GTK_CONTAINER(tab), label); | |
| 384 g_signal_connect(tab, "button-press-event", | |
| 385 G_CALLBACK(&OnTabButtonPressThunk), this); | |
| 386 g_signal_connect(tab, "expose-event", | |
| 387 G_CALLBACK(&OnTabExposeThunk), this); | |
| 388 return tab; | |
| 389 } | |
| 390 | |
| 391 void WebsiteSettingsPopupGtk::Observe( | |
| 392 int type, | |
| 393 const content::NotificationSource& source, | |
| 394 const content::NotificationDetails& details) { | |
| 395 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type); | |
| 396 | |
| 397 if (theme_service_->UsingNativeTheme()) { | |
| 398 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook_), TRUE); | |
| 399 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook_), TRUE); | |
| 400 gtk_widget_set_no_show_all(tabstrip_alignment_, TRUE); | |
| 401 } else { | |
| 402 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook_), FALSE); | |
| 403 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook_), FALSE); | |
| 404 gtk_widget_set_no_show_all(tabstrip_alignment_, FALSE); | |
| 405 gtk_widget_show_all(tabstrip_alignment_); | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 void WebsiteSettingsPopupGtk::OnPermissionChanged( | |
| 410 PermissionSelector* selector) { | |
| 411 presenter_->OnSitePermissionChanged(selector->GetType(), | |
| 412 selector->GetSetting()); | |
| 413 } | |
| 414 | |
| 415 void WebsiteSettingsPopupGtk::SetCookieInfo( | |
| 416 const CookieInfoList& cookie_info_list) { | |
| 417 DCHECK(cookies_section_contents_); | |
| 418 ClearContainer(cookies_section_contents_); | |
| 419 | |
| 420 // Create cookies info rows. | |
| 421 for (CookieInfoList::const_iterator it = cookie_info_list.begin(); | |
| 422 it != cookie_info_list.end(); | |
| 423 ++it) { | |
| 424 // Create the cookies info box. | |
| 425 GtkWidget* cookies_info = gtk_hbox_new(FALSE, 0); | |
| 426 | |
| 427 // Add the icon to the cookies info box | |
| 428 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon( | |
| 429 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_ALLOW).ToGdkPixbuf(); | |
| 430 GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); | |
| 431 gtk_misc_set_alignment(GTK_MISC(image), 0, 0); | |
| 432 gtk_box_pack_start(GTK_BOX(cookies_info), image, FALSE, FALSE, 0); | |
| 433 | |
| 434 // Add the allowed and blocked cookies counts to the cookies info box. | |
| 435 std::string info_str = l10n_util::GetStringFUTF8( | |
| 436 IDS_WEBSITE_SETTINGS_SITE_DATA_STATS_LINE, | |
| 437 base::UTF8ToUTF16(it->cookie_source), | |
| 438 base::IntToString16(it->allowed), | |
| 439 base::IntToString16(it->blocked)); | |
| 440 | |
| 441 GtkWidget* info = theme_service_->BuildLabel(info_str, ui::kGdkBlack); | |
| 442 const int kPadding = 4; | |
| 443 gtk_box_pack_start(GTK_BOX(cookies_info), info, FALSE, FALSE, kPadding); | |
| 444 | |
| 445 // Add the cookies info box to the section box. | |
| 446 gtk_box_pack_start(GTK_BOX(cookies_section_contents_), | |
| 447 cookies_info, | |
| 448 FALSE, FALSE, 0); | |
| 449 } | |
| 450 | |
| 451 // Create row with links for cookie settings and for the cookies dialog. | |
| 452 GtkWidget* link_hbox = gtk_hbox_new(FALSE, 0); | |
| 453 | |
| 454 GtkWidget* view_cookies_link = theme_service_->BuildChromeLinkButton( | |
| 455 l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_SHOW_SITE_DATA)); | |
| 456 g_signal_connect(view_cookies_link, "clicked", | |
| 457 G_CALLBACK(OnCookiesLinkClickedThunk), this); | |
| 458 gtk_box_pack_start(GTK_BOX(link_hbox), view_cookies_link, | |
| 459 FALSE, FALSE, 0); | |
| 460 | |
| 461 gtk_box_pack_start(GTK_BOX(cookies_section_contents_), link_hbox, | |
| 462 TRUE, FALSE, 0); | |
| 463 | |
| 464 gtk_widget_show_all(cookies_section_contents_); | |
| 465 } | |
| 466 | |
| 467 void WebsiteSettingsPopupGtk::SetIdentityInfo( | |
| 468 const IdentityInfo& identity_info) { | |
| 469 // Create popup header. | |
| 470 DCHECK(header_box_); | |
| 471 ClearContainer(header_box_); | |
| 472 | |
| 473 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); | |
| 474 GtkWidget* identity_label = theme_service_->BuildLabel( | |
| 475 identity_info.site_identity, ui::kGdkBlack); | |
| 476 gtk_label_set_selectable(GTK_LABEL(identity_label), TRUE); | |
| 477 PangoAttrList* attributes = pango_attr_list_new(); | |
| 478 pango_attr_list_insert(attributes, | |
| 479 pango_attr_weight_new(PANGO_WEIGHT_BOLD)); | |
| 480 gtk_label_set_attributes(GTK_LABEL(identity_label), attributes); | |
| 481 pango_attr_list_unref(attributes); | |
| 482 gtk_box_pack_start(GTK_BOX(hbox), identity_label, FALSE, FALSE, 0); | |
| 483 close_button_.reset(CustomDrawButton::CloseButtonBubble(theme_service_)); | |
| 484 g_signal_connect(close_button_->widget(), "clicked", | |
| 485 G_CALLBACK(OnCloseButtonClickedThunk), this); | |
| 486 gtk_box_pack_start(GTK_BOX(hbox), close_button_->widget(), FALSE, FALSE, 0); | |
| 487 int label_width = kPopupWidth - close_button_->SurfaceWidth(); | |
| 488 gtk_util::SetLabelWidth(identity_label, label_width); | |
| 489 gtk_box_pack_start(GTK_BOX(header_box_), hbox, FALSE, FALSE, 0); | |
| 490 | |
| 491 std::string identity_status_text; | |
| 492 const GdkColor* color = &ui::kGdkBlack; | |
| 493 | |
| 494 switch (identity_info.identity_status) { | |
| 495 case WebsiteSettings::SITE_IDENTITY_STATUS_CERT: | |
| 496 case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT: | |
| 497 identity_status_text = | |
| 498 l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_IDENTITY_VERIFIED); | |
| 499 color = &kGdkGreen; | |
| 500 break; | |
| 501 case WebsiteSettings::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT: | |
| 502 identity_status_text = | |
| 503 l10n_util::GetStringUTF8(IDS_CERT_POLICY_PROVIDED_CERT_HEADER); | |
| 504 break; | |
| 505 default: | |
| 506 identity_status_text = | |
| 507 l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_IDENTITY_NOT_VERIFIED); | |
| 508 break; | |
| 509 } | |
| 510 GtkWidget* status_label = CreateTextLabel( | |
| 511 identity_status_text, kPopupWidth, theme_service_, *color); | |
| 512 gtk_box_pack_start( | |
| 513 GTK_BOX(header_box_), status_label, FALSE, FALSE, 0); | |
| 514 gtk_widget_show_all(header_box_); | |
| 515 | |
| 516 // Create identity section. | |
| 517 GtkWidget* section_content = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 518 GtkWidget* identity_description = | |
| 519 CreateTextLabel(identity_info.identity_status_description, | |
| 520 kConnectionTabTextWidth, theme_service_, ui::kGdkBlack); | |
| 521 gtk_box_pack_start(GTK_BOX(section_content), identity_description, FALSE, | |
| 522 FALSE, 0); | |
| 523 if (identity_info.cert_id) { | |
| 524 cert_id_ = identity_info.cert_id; | |
| 525 GtkWidget* view_cert_link = theme_service_->BuildChromeLinkButton( | |
| 526 l10n_util::GetStringUTF8(IDS_PAGEINFO_CERT_INFO_BUTTON)); | |
| 527 g_signal_connect(view_cert_link, "clicked", | |
| 528 G_CALLBACK(OnViewCertLinkClickedThunk), this); | |
| 529 GtkWidget* link_hbox = gtk_hbox_new(FALSE, 0); | |
| 530 gtk_box_pack_start(GTK_BOX(link_hbox), view_cert_link, | |
| 531 FALSE, FALSE, 0); | |
| 532 gtk_box_pack_start(GTK_BOX(section_content), link_hbox, FALSE, FALSE, 0); | |
| 533 } | |
| 534 SetConnectionSection( | |
| 535 identity_contents_, | |
| 536 WebsiteSettingsUI::GetIdentityIcon(identity_info.identity_status), | |
| 537 section_content); | |
| 538 | |
| 539 // Create connection section. | |
| 540 GtkWidget* connection_description = | |
| 541 CreateTextLabel(identity_info.connection_status_description, | |
| 542 kConnectionTabTextWidth, theme_service_, ui::kGdkBlack); | |
| 543 section_content = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 544 gtk_box_pack_start(GTK_BOX(section_content), connection_description, FALSE, | |
| 545 FALSE, 0); | |
| 546 SetConnectionSection( | |
| 547 connection_contents_, | |
| 548 WebsiteSettingsUI::GetConnectionIcon(identity_info.connection_status), | |
| 549 section_content); | |
| 550 } | |
| 551 | |
| 552 void WebsiteSettingsPopupGtk::SetFirstVisit(const base::string16& first_visit) { | |
| 553 GtkWidget* title = theme_service_->BuildLabel( | |
| 554 l10n_util::GetStringUTF8(IDS_PAGE_INFO_SITE_INFO_TITLE), | |
| 555 ui::kGdkBlack); | |
| 556 PangoAttrList* attributes = pango_attr_list_new(); | |
| 557 pango_attr_list_insert(attributes, | |
| 558 pango_attr_weight_new(PANGO_WEIGHT_BOLD)); | |
| 559 gtk_label_set_attributes(GTK_LABEL(title), attributes); | |
| 560 pango_attr_list_unref(attributes); | |
| 561 gtk_misc_set_alignment(GTK_MISC(title), 0, 0); | |
| 562 | |
| 563 GtkWidget* first_visit_label = CreateTextLabel(base::UTF16ToUTF8(first_visit), | |
| 564 kConnectionTabTextWidth, | |
| 565 theme_service_, | |
| 566 ui::kGdkBlack); | |
| 567 GtkWidget* section_contents = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 568 gtk_box_pack_start(GTK_BOX(section_contents), title, FALSE, FALSE, 0); | |
| 569 gtk_box_pack_start( | |
| 570 GTK_BOX(section_contents), first_visit_label, FALSE, FALSE, 0); | |
| 571 | |
| 572 SetConnectionSection( | |
| 573 first_visit_contents_, | |
| 574 WebsiteSettingsUI::GetFirstVisitIcon(first_visit), | |
| 575 section_contents); | |
| 576 } | |
| 577 | |
| 578 void WebsiteSettingsPopupGtk::SetPermissionInfo( | |
| 579 const PermissionInfoList& permission_info_list) { | |
| 580 DCHECK(permissions_section_contents_); | |
| 581 ClearContainer(permissions_section_contents_); | |
| 582 // Clear the map since the UI is reconstructed. | |
| 583 selectors_.clear(); | |
| 584 | |
| 585 for (PermissionInfoList::const_iterator permission = | |
| 586 permission_info_list.begin(); | |
| 587 permission != permission_info_list.end(); | |
| 588 ++permission) { | |
| 589 PermissionSelector* selector = | |
| 590 new PermissionSelector( | |
| 591 theme_service_, | |
| 592 web_contents_ ? web_contents_->GetURL() : GURL::EmptyGURL(), | |
| 593 permission->type, | |
| 594 permission->setting, | |
| 595 permission->default_setting, | |
| 596 permission->source); | |
| 597 selector->AddObserver(this); | |
| 598 GtkWidget* hbox = selector->widget(); | |
| 599 selectors_.push_back(selector); | |
| 600 gtk_box_pack_start(GTK_BOX(permissions_section_contents_), hbox, FALSE, | |
| 601 FALSE, 0); | |
| 602 } | |
| 603 | |
| 604 gtk_widget_show_all(permissions_section_contents_); | |
| 605 } | |
| 606 | |
| 607 void WebsiteSettingsPopupGtk::SetSelectedTab(TabId tab_id) { | |
| 608 DCHECK(notebook_); | |
| 609 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), | |
| 610 static_cast<gint>(tab_id)); | |
| 611 } | |
| 612 | |
| 613 int WebsiteSettingsPopupGtk::TabstripButtonToTabIndex(GtkWidget* button) { | |
| 614 GList* tabs = gtk_container_get_children(GTK_CONTAINER(button->parent)); | |
| 615 int i = 0; | |
| 616 for (GList* it = tabs; it; it = g_list_next(it), ++i) { | |
| 617 if (it->data == button) | |
| 618 break; | |
| 619 } | |
| 620 g_list_free(tabs); | |
| 621 | |
| 622 return i; | |
| 623 } | |
| 624 | |
| 625 gboolean WebsiteSettingsPopupGtk::OnTabButtonPress( | |
| 626 GtkWidget* widget, GdkEvent* event) { | |
| 627 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), | |
| 628 TabstripButtonToTabIndex(widget)); | |
| 629 gtk_widget_queue_draw(tabstrip_alignment_); | |
| 630 return FALSE; | |
| 631 } | |
| 632 | |
| 633 gboolean WebsiteSettingsPopupGtk::OnTabExpose( | |
| 634 GtkWidget* widget, GdkEventExpose* event) { | |
| 635 if (gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook_)) != | |
| 636 TabstripButtonToTabIndex(widget)) { | |
| 637 return FALSE; | |
| 638 } | |
| 639 | |
| 640 NineBox nine(IDR_WEBSITE_SETTINGS_TAB_LEFT2, | |
| 641 IDR_WEBSITE_SETTINGS_TAB_CENTER2, | |
| 642 IDR_WEBSITE_SETTINGS_TAB_RIGHT2, | |
| 643 0, 0, 0, 0, 0, 0); | |
| 644 nine.RenderToWidget(widget); | |
| 645 | |
| 646 return FALSE; | |
| 647 } | |
| 648 | |
| 649 gboolean WebsiteSettingsPopupGtk::OnTabstripExpose( | |
| 650 GtkWidget* widget, GdkEventExpose* event) { | |
| 651 int tab_idx = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook_)); | |
| 652 GtkWidget* tabstrip = gtk_bin_get_child(GTK_BIN(tabstrip_alignment_)); | |
| 653 GList* tabs = gtk_container_get_children(GTK_CONTAINER(tabstrip)); | |
| 654 GtkWidget* selected_tab = GTK_WIDGET(g_list_nth_data(tabs, tab_idx)); | |
| 655 g_list_free(tabs); | |
| 656 GtkAllocation tab_bounds; | |
| 657 gtk_widget_get_allocation(selected_tab, &tab_bounds); | |
| 658 | |
| 659 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget))); | |
| 660 GtkAllocation allocation; | |
| 661 gtk_widget_get_allocation(widget, &allocation); | |
| 662 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 663 | |
| 664 // Draw the shadows that abut the selected tab. | |
| 665 gfx::CairoCachedSurface* left_tab_shadow = | |
| 666 rb.GetNativeImageNamed(IDR_WEBSITE_SETTINGS_TABSTRIP_LEFT).ToCairo(); | |
| 667 int tab_shadow_width = left_tab_shadow->Width(); | |
| 668 left_tab_shadow->SetSource(cr, widget, | |
| 669 tab_bounds.x - tab_shadow_width, allocation.y); | |
| 670 cairo_paint(cr); | |
| 671 | |
| 672 gfx::CairoCachedSurface* right_tab_shadow = | |
| 673 rb.GetNativeImageNamed(IDR_WEBSITE_SETTINGS_TABSTRIP_RIGHT).ToCairo(); | |
| 674 right_tab_shadow->SetSource(cr, widget, | |
| 675 tab_bounds.x + tab_bounds.width, allocation.y); | |
| 676 cairo_paint(cr); | |
| 677 | |
| 678 // Draw the shadow for the inactive part of the tabstrip. | |
| 679 gfx::CairoCachedSurface* tiling_shadow = | |
| 680 rb.GetNativeImageNamed(IDR_WEBSITE_SETTINGS_TABSTRIP_CENTER).ToCairo(); | |
| 681 | |
| 682 tiling_shadow->SetSource(cr, widget, allocation.x, allocation.y); | |
| 683 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); | |
| 684 | |
| 685 GdkRectangle left_tiling_area = | |
| 686 { allocation.x, allocation.y, | |
| 687 tab_bounds.x - tab_shadow_width, allocation.height }; | |
| 688 GdkRectangle invalid_left_tiling_area; | |
| 689 if (gdk_rectangle_intersect(&left_tiling_area, &event->area, | |
| 690 &invalid_left_tiling_area)) { | |
| 691 gdk_cairo_rectangle(cr, &invalid_left_tiling_area); | |
| 692 cairo_fill(cr); | |
| 693 } | |
| 694 | |
| 695 GdkRectangle right_tiling_area = | |
| 696 { tab_bounds.x + tab_bounds.width + tab_shadow_width, | |
| 697 allocation.y, | |
| 698 allocation.width, | |
| 699 allocation.height }; | |
| 700 GdkRectangle invalid_right_tiling_area; | |
| 701 if (gdk_rectangle_intersect(&right_tiling_area, &event->area, | |
| 702 &invalid_right_tiling_area)) { | |
| 703 gdk_cairo_rectangle(cr, &invalid_right_tiling_area); | |
| 704 cairo_fill(cr); | |
| 705 } | |
| 706 | |
| 707 cairo_destroy(cr); | |
| 708 return FALSE; | |
| 709 } | |
| 710 | |
| 711 void WebsiteSettingsPopupGtk::OnCookiesLinkClicked(GtkWidget* widget) { | |
| 712 // Count how often the Collected Cookies dialog is opened. | |
| 713 content::RecordAction( | |
| 714 base::UserMetricsAction("WebsiteSettings_CookiesDialogOpened")); | |
| 715 | |
| 716 new CollectedCookiesGtk(GTK_WINDOW(parent_), web_contents_); | |
| 717 bubble_->Close(); | |
| 718 } | |
| 719 | |
| 720 void WebsiteSettingsPopupGtk::OnViewCertLinkClicked(GtkWidget* widget) { | |
| 721 DCHECK_NE(cert_id_, 0); | |
| 722 ShowCertificateViewerByID(web_contents_, GTK_WINDOW(parent_), cert_id_); | |
| 723 bubble_->Close(); | |
| 724 } | |
| 725 | |
| 726 void WebsiteSettingsPopupGtk::OnCloseButtonClicked(GtkWidget* widget) { | |
| 727 bubble_->Close(); | |
| 728 } | |
| 729 | |
| 730 void WebsiteSettingsPopupGtk::OnHelpLinkClicked(GtkWidget* widget) { | |
| 731 browser_->OpenURL(OpenURLParams(GURL(chrome::kPageInfoHelpCenterURL), | |
| 732 content::Referrer(), | |
| 733 NEW_FOREGROUND_TAB, | |
| 734 content::PAGE_TRANSITION_LINK, | |
| 735 false)); | |
| 736 bubble_->Close(); | |
| 737 } | |
| OLD | NEW |