Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: chrome/browser/ui/gtk/content_setting_bubble_gtk.cc

Issue 12208010: Adding device selection menus to the content setting bubble (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/gtk/content_setting_bubble_gtk.h" 5 #include "chrome/browser/ui/gtk/content_setting_bubble_gtk.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h"
11 #include "base/i18n/rtl.h" 12 #include "base/i18n/rtl.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/stl_util.h"
12 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/content_settings/host_content_settings_map.h" 16 #include "chrome/browser/content_settings/host_content_settings_map.h"
14 #include "chrome/browser/plugins/plugin_finder.h" 17 #include "chrome/browser/plugins/plugin_finder.h"
15 #include "chrome/browser/plugins/plugin_metadata.h" 18 #include "chrome/browser/plugins/plugin_metadata.h"
16 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" 20 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
21 #include "chrome/browser/ui/content_settings/content_setting_media_menu_model.h"
18 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" 22 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
19 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 23 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
20 #include "chrome/browser/ui/gtk/gtk_util.h" 24 #include "chrome/browser/ui/gtk/gtk_util.h"
21 #include "chrome/common/content_settings.h" 25 #include "chrome/common/content_settings.h"
22 #include "content/public/browser/notification_source.h" 26 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/notification_types.h" 27 #include "content/public/browser/notification_types.h"
24 #include "content/public/browser/plugin_service.h" 28 #include "content/public/browser/plugin_service.h"
25 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
26 #include "grit/generated_resources.h" 30 #include "grit/generated_resources.h"
27 #include "grit/ui_resources.h" 31 #include "grit/ui_resources.h"
28 #include "ui/base/gtk/gtk_hig_constants.h" 32 #include "ui/base/gtk/gtk_hig_constants.h"
29 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/models/simple_menu_model.h"
30 #include "ui/base/text/text_elider.h" 35 #include "ui/base/text/text_elider.h"
31 #include "ui/gfx/gtk_util.h" 36 #include "ui/gfx/gtk_util.h"
32 37
33 using content::PluginService; 38 using content::PluginService;
34 using content::WebContents; 39 using content::WebContents;
35 40
36 namespace { 41 namespace {
37 42
38 // The maximum width of a title entry in the content box. We elide anything 43 // The maximum width of a title entry in the content box. We elide anything
39 // longer than this. 44 // longer than this.
40 const int kMaxLinkPixelSize = 500; 45 const int kMaxLinkPixelSize = 500;
41 46
47 // The width in characters of the label of media menu button.
48 const int kMediaMenuButtonLabelWidthInChars = 16;
49
50 // The width of the media menu button.
51 const int kMediaMenuButtonWidth = 150;
52
42 std::string BuildElidedText(const std::string& input) { 53 std::string BuildElidedText(const std::string& input) {
43 return UTF16ToUTF8(ui::ElideText( 54 return UTF16ToUTF8(ui::ElideText(
44 UTF8ToUTF16(input), 55 UTF8ToUTF16(input),
45 gfx::Font(), 56 gfx::Font(),
46 kMaxLinkPixelSize, 57 kMaxLinkPixelSize,
47 ui::ELIDE_AT_END)); 58 ui::ELIDE_AT_END));
48 } 59 }
49 60
50 } // namespace 61 } // namespace
51 62
(...skipping 11 matching lines...) Expand all
63 bubble_(NULL) { 74 bubble_(NULL) {
64 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 75 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
65 content::Source<WebContents>(web_contents)); 76 content::Source<WebContents>(web_contents));
66 BuildBubble(); 77 BuildBubble();
67 } 78 }
68 79
69 ContentSettingBubbleGtk::~ContentSettingBubbleGtk() { 80 ContentSettingBubbleGtk::~ContentSettingBubbleGtk() {
70 } 81 }
71 82
72 void ContentSettingBubbleGtk::Close() { 83 void ContentSettingBubbleGtk::Close() {
84 STLDeleteValues(&media_menus_);
85
73 if (bubble_) 86 if (bubble_)
74 bubble_->Close(); 87 bubble_->Close();
75 } 88 }
76 89
90 void ContentSettingBubbleGtk::UpdateMenuLabel(content::MediaStreamType type,
91 const std::string& label) {
92 GtkMediaMenuMap::const_iterator it = media_menus_.begin();
93 for (; it != media_menus_.end(); ++it) {
94 if (it->second->type == type) {
95 gtk_label_set_text(GTK_LABEL(it->second->label.get()), label.c_str());
96 return;
97 }
98 }
99 NOTREACHED();
100 }
101
77 void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble, 102 void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble,
78 bool closed_by_escape) { 103 bool closed_by_escape) {
79 delegate_->BubbleClosing(bubble, closed_by_escape); 104 delegate_->BubbleClosing(bubble, closed_by_escape);
80 delete this; 105 delete this;
81 } 106 }
82 107
83 void ContentSettingBubbleGtk::Observe( 108 void ContentSettingBubbleGtk::Observe(
84 int type, 109 int type,
85 const content::NotificationSource& source, 110 const content::NotificationSource& source,
86 const content::NotificationDetails& details) { 111 const content::NotificationDetails& details) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 if (!content.radio_group_enabled) 214 if (!content.radio_group_enabled)
190 gtk_widget_set_sensitive(radio, FALSE); 215 gtk_widget_set_sensitive(radio, FALSE);
191 radio_group_gtk_.push_back(radio); 216 radio_group_gtk_.push_back(radio);
192 } 217 }
193 for (std::vector<GtkWidget*>::const_iterator i = radio_group_gtk_.begin(); 218 for (std::vector<GtkWidget*>::const_iterator i = radio_group_gtk_.begin();
194 i != radio_group_gtk_.end(); ++i) { 219 i != radio_group_gtk_.end(); ++i) {
195 // We can attach signal handlers now that all defaults are set. 220 // We can attach signal handlers now that all defaults are set.
196 g_signal_connect(*i, "toggled", G_CALLBACK(OnRadioToggledThunk), this); 221 g_signal_connect(*i, "toggled", G_CALLBACK(OnRadioToggledThunk), this);
197 } 222 }
198 223
224 // Layout code for the media device menus.
225 if (content_setting_bubble_model_->content_type() ==
226 CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
227 GtkWidget* table = gtk_table_new(content.media_menus.size(), 2, FALSE);
228 int row = 0;
229 for (ContentSettingBubbleModel::MediaMenuMap::const_iterator
230 i(content.media_menus.begin());
231 i != content.media_menus.end();
232 ++i, ++row) {
233 GtkWidget* label = theme_provider->BuildLabel(
234 i->second.label.c_str(), ui::kGdkBlack);
235 gtk_table_attach(GTK_TABLE(table), gtk_util::LeftAlignMisc(label), 0, 1,
236 row, row + 1, GTK_FILL, GTK_FILL,
237 ui::kControlSpacing / 2, ui::kControlSpacing / 2);
238
239 // Build up the gtk menu button.
240 MediaMenuGtk* gtk_menu = new MediaMenuGtk(i->first);
241 gtk_menu->label.Own(
242 gtk_label_new(i->second.selected_device.name.c_str()));
243
244 GtkWidget* button = gtk_button_new();
245 GtkWidget* button_content = gtk_hbox_new(FALSE, 0);
246 gtk_box_pack_start(GTK_BOX(button_content),
247 gtk_util::LeftAlignMisc(gtk_menu->label.get()),
248 FALSE, FALSE, 0);
249 gtk_label_set_width_chars(GTK_LABEL(gtk_menu->label.get()),
250 kMediaMenuButtonLabelWidthInChars);
251 GtkWidget* arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
252 gtk_box_pack_end(GTK_BOX(button_content), arrow, FALSE, FALSE, 0);
253 gtk_widget_set_size_request(button_content, kMediaMenuButtonWidth, -1);
254 gtk_container_add(GTK_CONTAINER(button), button_content);
255
256 // Store the gtk menu to the map.
257 media_menus_[button] = gtk_menu;
258
259 g_signal_connect(button, "clicked", G_CALLBACK(OnMenuButtonClickedThunk),
260 this);
261 gtk_table_attach(GTK_TABLE(table), button, 1, 2, row, row + 1,
262 GTK_FILL, GTK_FILL, ui::kControlSpacing * 2,
263 ui::kControlSpacing / 2);
264 }
265
266 gtk_box_pack_start(GTK_BOX(bubble_content), table, FALSE, FALSE, 0);
267 }
268
199 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i = 269 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i =
200 content.domain_lists.begin(); 270 content.domain_lists.begin();
201 i != content.domain_lists.end(); ++i) { 271 i != content.domain_lists.end(); ++i) {
202 // Put each list into its own vbox to allow spacing between lists. 272 // Put each list into its own vbox to allow spacing between lists.
203 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing); 273 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing);
204 274
205 GtkWidget* label = theme_provider->BuildLabel( 275 GtkWidget* label = theme_provider->BuildLabel(
206 BuildElidedText(i->title).c_str(), ui::kGdkBlack); 276 BuildElidedText(i->title).c_str(), ui::kGdkBlack);
207 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); 277 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
208 GtkWidget* label_box = gtk_hbox_new(FALSE, 0); 278 GtkWidget* label_box = gtk_hbox_new(FALSE, 0);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 theme_provider->BuildChromeLinkButton(content.manage_link.c_str()); 316 theme_provider->BuildChromeLinkButton(content.manage_link.c_str());
247 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk), 317 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk),
248 this); 318 this);
249 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0); 319 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0);
250 320
251 GtkWidget* button = gtk_button_new_with_label( 321 GtkWidget* button = gtk_button_new_with_label(
252 l10n_util::GetStringUTF8(IDS_DONE).c_str()); 322 l10n_util::GetStringUTF8(IDS_DONE).c_str());
253 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk), 323 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk),
254 this); 324 this);
255 gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0); 325 gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0);
256
257 gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0); 326 gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0);
258 gtk_widget_grab_focus(bottom_box); 327 gtk_widget_grab_focus(bottom_box);
259 gtk_widget_grab_focus(button); 328 gtk_widget_grab_focus(button);
260 329
261 bubble_ = BubbleGtk::Show(anchor_, 330 bubble_ = BubbleGtk::Show(anchor_,
262 NULL, 331 NULL,
263 bubble_content, 332 bubble_content,
264 BubbleGtk::ANCHOR_TOP_RIGHT, 333 BubbleGtk::ANCHOR_TOP_RIGHT,
265 BubbleGtk::MATCH_SYSTEM_THEME | 334 BubbleGtk::MATCH_SYSTEM_THEME |
266 BubbleGtk::POPUP_WINDOW | 335 BubbleGtk::POPUP_WINDOW |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 378
310 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) { 379 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) {
311 content_setting_bubble_model_->OnCustomLinkClicked(); 380 content_setting_bubble_model_->OnCustomLinkClicked();
312 Close(); 381 Close();
313 } 382 }
314 383
315 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) { 384 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) {
316 content_setting_bubble_model_->OnManageLinkClicked(); 385 content_setting_bubble_model_->OnManageLinkClicked();
317 Close(); 386 Close();
318 } 387 }
388
389 void ContentSettingBubbleGtk::OnMenuButtonClicked(GtkWidget* button) {
390 GtkMediaMenuMap::iterator i(media_menus_.find(button));
391 DCHECK(i != media_menus_.end());
392 i->second->menu_model.reset(new ContentSettingMediaMenuModel(
393 profile_->GetPrefs(),
394 i->second->type,
395 content_setting_bubble_model_.get(),
396 base::Bind(&ContentSettingBubbleGtk::UpdateMenuLabel,
397 base::Unretained(this))));
398 i->second->menu.reset(new MenuGtk(NULL, i->second->menu_model.get()));
399 i->second->menu->PopupForWidget(button, 1, gtk_get_current_event_time());
400 }
401
402 ContentSettingBubbleGtk::MediaMenuGtk::MediaMenuGtk(
403 content::MediaStreamType type)
404 : type(type) {
405 }
406
407 ContentSettingBubbleGtk::MediaMenuGtk::~MediaMenuGtk() {
408 }
Evan Stade 2013/02/11 20:40:15 can put } on previous line, here and above.
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/content_setting_bubble_gtk.h ('k') | chrome/browser/ui/views/content_setting_bubble_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698