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

Side by Side Diff: chrome/browser/ui/gtk/website_settings/permission_selector.cc

Issue 10887027: (GTK only) Replace checkboxes with menus and add support for managed settings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: " Created 8 years, 3 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/website_settings/permission_selector.h" 5 #include "chrome/browser/ui/gtk/website_settings/permission_selector.h"
6 6
7 #include <gtk/gtk.h>
8
9 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/i18n/rtl.h"
9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 10 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
11 #include "chrome/browser/ui/gtk/gtk_util.h" 11 #include "chrome/browser/ui/gtk/gtk_util.h"
12 #include "chrome/browser/ui/gtk/menu_gtk.h"
12 #include "chrome/browser/ui/website_settings/website_settings_ui.h" 13 #include "chrome/browser/ui/website_settings/website_settings_ui.h"
13 #include "grit/generated_resources.h" 14 #include "grit/generated_resources.h"
15 #include "grit/theme_resources.h"
14 #include "ui/base/gtk/gtk_hig_constants.h" 16 #include "ui/base/gtk/gtk_hig_constants.h"
15 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/models/menu_model.h"
19 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/gfx/image/image.h" 20 #include "ui/gfx/image/image.h"
17 21
18 namespace {
19
20 GtkWidget* CreateTextLabel(const std::string& text,
21 GtkThemeService* theme_service) {
22 GtkWidget* label = theme_service->BuildLabel(text, ui::kGdkBlack);
23 gtk_label_set_selectable(GTK_LABEL(label), TRUE);
24 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
25 return label;
26 }
27
28 } // namespace
29
30 PermissionSelector::PermissionSelector(GtkThemeService* theme_service, 22 PermissionSelector::PermissionSelector(GtkThemeService* theme_service,
31 ContentSettingsType type, 23 ContentSettingsType type,
32 ContentSetting setting, 24 ContentSetting setting,
33 ContentSetting default_setting) 25 ContentSetting default_setting,
34 : theme_service_(theme_service), 26 content_settings::SettingSource source)
35 type_(type), 27 : widget_(NULL),
36 setting_(setting), 28 menu_button_(NULL),
37 default_setting_(default_setting),
38 icon_(NULL) { 29 icon_(NULL) {
39 DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT); 30 DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT);
31
32 // Create permission info box.
33 const int kChildSpacing = 4;
34 widget_ = gtk_hbox_new(FALSE, kChildSpacing);
35
36 // Add permission type icon.
37 ContentSetting effective_setting = setting;
38 if (effective_setting == CONTENT_SETTING_DEFAULT)
39 effective_setting = default_setting;
40 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
41 type, effective_setting).ToGdkPixbuf();
42 icon_ = gtk_image_new_from_pixbuf(pixbuf);
43 gtk_box_pack_start(GTK_BOX(widget_), icon_, FALSE, FALSE, 0);
44
45 // Add a label for the permission type.
46 GtkWidget* label = theme_service->BuildLabel(l10n_util::GetStringFUTF8(
47 IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
48 WebsiteSettingsUI::PermissionTypeToUIString(type)),
49 ui::kGdkBlack);
50 gtk_label_set_selectable(GTK_LABEL(label), TRUE);
51 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
52
53 gtk_box_pack_start(GTK_BOX(widget_), label, FALSE, FALSE, 0);
54
55 // Add the menu button.
56 menu_button_ = gtk_button_new_with_label(
57 UTF16ToUTF8(WebsiteSettingsUI::PermissionActionToUIString(
58 setting, default_setting, source)).c_str());
59 bool user_setting = source == content_settings::SETTING_SOURCE_USER;
60 gtk_widget_set_sensitive(GTK_WIDGET(menu_button_), user_setting);
61 if (user_setting) {
62 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
63 pixbuf = rb.GetNativeImageNamed(IDR_APP_DROPARROW).ToGdkPixbuf();
64 GtkWidget* arrow = gtk_image_new_from_pixbuf(pixbuf);
65 gtk_button_set_image(GTK_BUTTON(menu_button_), arrow);
66 gtk_button_set_image_position(GTK_BUTTON(menu_button_),
67 base::i18n::IsRTL() ? GTK_POS_LEFT
68 : GTK_POS_RIGHT);
69 }
70 gtk_button_set_relief(GTK_BUTTON(menu_button_), GTK_RELIEF_NONE);
71 gtk_box_pack_start(GTK_BOX(widget_), menu_button_, FALSE, FALSE, 0);
72
73 menu_model_.reset(new PermissionMenuModel(this, type, default_setting,
74 setting));
75 MenuGtk::Delegate* delegate = new MenuGtk::Delegate();
76 menu_.reset(new MenuGtk(delegate, menu_model_.get()));
77 g_signal_connect(menu_button_, "button-press-event",
78 G_CALLBACK(OnMenuButtonPressEventThunk), this);
40 } 79 }
41 80
42 PermissionSelector::~PermissionSelector() { 81 PermissionSelector::~PermissionSelector() {
43 } 82 }
44 83
45 GtkWidget* PermissionSelector::CreateUI() {
46 // Create permission info box.
47 const int kChildSpacing = 4;
48 GtkWidget* hbox = gtk_hbox_new(FALSE, kChildSpacing);
49
50 // Add permission type icon.
51 ContentSetting effective_setting = setting_;
52 if (effective_setting == CONTENT_SETTING_DEFAULT)
53 effective_setting = default_setting_;
54 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
55 type_, effective_setting).ToGdkPixbuf();
56 icon_ = gtk_image_new_from_pixbuf(pixbuf);
57 gtk_box_pack_start(GTK_BOX(hbox), icon_, FALSE, FALSE, 0);
58
59 // Add a label for the permission type.
60 GtkWidget* label = CreateTextLabel(
61 l10n_util::GetStringFUTF8(
62 IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
63 WebsiteSettingsUI::PermissionTypeToUIString(type_)),
64 theme_service_);
65 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
66
67 GtkListStore* store =
68 gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
69 GtkTreeIter iter;
70 // Add option for permission "Global Default" to the combobox model.
71 std::string setting_str = l10n_util::GetStringFUTF8(
72 IDS_WEBSITE_SETTINGS_DEFAULT_PERMISSION_LABEL,
73 WebsiteSettingsUI::PermissionValueToUIString(default_setting_));
74 gtk_list_store_append(store, &iter);
75 gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
76 CONTENT_SETTING_DEFAULT, -1);
77 GtkWidget* combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
78 // Add option for permission "Allow" to the combobox model.
79 setting_str = l10n_util::GetStringFUTF8(
80 IDS_WEBSITE_SETTINGS_PERMISSION_LABEL,
81 WebsiteSettingsUI::PermissionValueToUIString(CONTENT_SETTING_ALLOW));
82 gtk_list_store_append(store, &iter);
83 gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
84 CONTENT_SETTING_ALLOW, -1);
85 // The content settings type fullscreen does not support the concept of
86 // blocking.
87 if (type_ != CONTENT_SETTINGS_TYPE_FULLSCREEN) {
88 // Add option for permission "BLOCK" to the combobox model.
89 setting_str = l10n_util::GetStringFUTF8(
90 IDS_WEBSITE_SETTINGS_PERMISSION_LABEL,
91 WebsiteSettingsUI::PermissionValueToUIString(CONTENT_SETTING_BLOCK));
92 gtk_list_store_append(store, &iter);
93 gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
94 CONTENT_SETTING_BLOCK, -1);
95 }
96 // Remove reference to the store to prevent leaking.
97 g_object_unref(G_OBJECT(store));
98
99 GtkCellRenderer* cell = gtk_cell_renderer_text_new();
100 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell, TRUE );
101 gtk_cell_layout_set_attributes(
102 GTK_CELL_LAYOUT(combo_box), cell, "text", 0, NULL);
103
104 // Select the combobox entry for the currently configured permission value.
105 int active = -1;
106 switch (setting_) {
107 case CONTENT_SETTING_DEFAULT: active = 0;
108 break;
109 case CONTENT_SETTING_ALLOW: active = 1;
110 break;
111 case CONTENT_SETTING_BLOCK: active = 2;
112 break;
113 default:
114 NOTREACHED() << "Bad content setting:" << setting_;
115 break;
116 }
117 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), active);
118
119 // Add change listener to the combobox.
120 g_signal_connect(combo_box, "changed",
121 G_CALLBACK(OnPermissionChangedThunk), this);
122 // Once the popup (window) for a combobox is shown, the bubble container
123 // (window) loses it's focus. Therefore it necessary to reset the focus to
124 // the bubble container after the combobox popup is closed.
125 g_signal_connect(combo_box, "notify::popup-shown",
126 G_CALLBACK(OnComboBoxShownThunk), this);
127 gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, FALSE, 0);
128
129 return hbox;
130 }
131
132 void PermissionSelector::AddObserver(PermissionSelectorObserver* observer) { 84 void PermissionSelector::AddObserver(PermissionSelectorObserver* observer) {
133 observer_list_.AddObserver(observer); 85 observer_list_.AddObserver(observer);
134 } 86 }
135 87
136 void PermissionSelector::OnPermissionChanged(GtkWidget* widget) { 88 ContentSetting PermissionSelector::GetSetting() const {
137 // Get the selected setting. 89 return menu_model_->current_setting();
138 GtkTreeIter it; 90 }
139 bool has_active = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &it);
140 DCHECK(has_active);
141 GtkTreeModel* store =
142 GTK_TREE_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(widget)));
143 int value = -1;
144 gtk_tree_model_get(store, &it, 1, &value, -1);
145 setting_ = ContentSetting(value);
146 91
147 // Change the permission icon according the the selected setting. 92 ContentSettingsType PermissionSelector::GetType() const {
148 ContentSetting effective_setting = setting_; 93 return menu_model_->type();
94 }
95
96 gboolean PermissionSelector::OnMenuButtonPressEvent(GtkWidget* button,
97 GdkEventButton* event) {
98 if (event->button != 1)
99 return FALSE;
100 menu_->PopupForWidget(button, event->button, event->time);
101 return TRUE;
102 }
103
104 void PermissionSelector::OnPermissionSelected() {
105 ContentSetting setting = menu_model_->current_setting();
106
107 // Change the permission icon to reflect the selected setting.
108 ContentSetting effective_setting = setting;
149 if (effective_setting == CONTENT_SETTING_DEFAULT) 109 if (effective_setting == CONTENT_SETTING_DEFAULT)
150 effective_setting = default_setting_; 110 effective_setting = menu_model_->default_setting();
151 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon( 111 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
152 type_, effective_setting).ToGdkPixbuf(); 112 menu_model_->type(), effective_setting).ToGdkPixbuf();
153 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf); 113 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf);
154 114
115 // Change the text of the menu button to reflect the selected setting.
116 gtk_button_set_label(GTK_BUTTON(menu_button_),
117 UTF16ToUTF8(WebsiteSettingsUI::PermissionActionToUIString(
118 menu_model_->current_setting(),
119 menu_model_->default_setting(),
120 content_settings::SETTING_SOURCE_USER)).c_str());
121
155 FOR_EACH_OBSERVER(PermissionSelectorObserver, 122 FOR_EACH_OBSERVER(PermissionSelectorObserver,
156 observer_list_, 123 observer_list_,
157 OnPermissionChanged(this)); 124 OnPermissionChanged(this));
158 } 125 }
159
160 void PermissionSelector::OnComboBoxShown(GtkWidget* widget,
161 GParamSpec* property) {
162 // GtkComboBox grabs the keyboard and pointer when it displays its popup,
163 // which steals the grabs that BubbleGtk had installed. When the popup is
164 // hidden, we notify BubbleGtk so it can try to reacquire the grabs
165 // (otherwise, GTK won't activate our widgets when the user clicks in them).
166 // When then combobox popup is closed we notify the
167 // |PermissionSelectorObserver|s so that BubbleGtk can grab the keyboard and
168 // pointer.
169 gboolean popup_shown = FALSE;
170 g_object_get(G_OBJECT(GTK_COMBO_BOX(widget)), "popup-shown", &popup_shown,
171 NULL);
172 if (!popup_shown) {
173 FOR_EACH_OBSERVER(PermissionSelectorObserver,
174 observer_list_,
175 OnComboboxShown());
176 }
177 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698