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 |