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

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: fix clang build 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 { 22 namespace {
19 23
20 GtkWidget* CreateTextLabel(const std::string& text, 24 ContentSetting CommandIdToContentSetting(int command_id) {
21 GtkThemeService* theme_service) { 25 switch (command_id) {
22 GtkWidget* label = theme_service->BuildLabel(text, ui::kGdkBlack); 26 case PermissionMenuModel::COMMAND_SET_TO_DEFAULT:
23 gtk_label_set_selectable(GTK_LABEL(label), TRUE); 27 return CONTENT_SETTING_DEFAULT;
24 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR); 28 case PermissionMenuModel::COMMAND_SET_TO_ALLOW:
25 return label; 29 return CONTENT_SETTING_ALLOW;
30 case PermissionMenuModel::COMMAND_SET_TO_BLOCK:
31 return CONTENT_SETTING_BLOCK;
32 default:
33 NOTREACHED();
34 return CONTENT_SETTING_DEFAULT;
35 }
26 } 36 }
27 37
28 } // namespace 38 } // namespace
29 39
30 PermissionSelector::PermissionSelector(GtkThemeService* theme_service, 40 PermissionSelector::PermissionSelector(GtkThemeService* theme_service,
31 ContentSettingsType type, 41 ContentSettingsType type,
32 ContentSetting setting, 42 ContentSetting setting,
33 ContentSetting default_setting) 43 ContentSetting default_setting,
34 : theme_service_(theme_service), 44 content_settings::SettingSource source)
45 : widget_(NULL),
46 menu_button_(NULL),
47 icon_(NULL),
35 type_(type), 48 type_(type),
36 setting_(setting),
37 default_setting_(default_setting), 49 default_setting_(default_setting),
38 icon_(NULL) { 50 setting_(setting) {
39 DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT); 51 DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT);
52
53 // Create permission info box.
54 const int kChildSpacing = 4;
55 widget_ = gtk_hbox_new(FALSE, kChildSpacing);
56
57 // Add permission type icon.
58 ContentSetting effective_setting = setting;
59 if (effective_setting == CONTENT_SETTING_DEFAULT)
60 effective_setting = default_setting;
61 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
62 type, effective_setting).ToGdkPixbuf();
63 icon_ = gtk_image_new_from_pixbuf(pixbuf);
64 gtk_box_pack_start(GTK_BOX(widget_), icon_, FALSE, FALSE, 0);
65
66 // Add a label for the permission type.
67 GtkWidget* label = theme_service->BuildLabel(l10n_util::GetStringFUTF8(
68 IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
69 WebsiteSettingsUI::PermissionTypeToUIString(type)),
70 ui::kGdkBlack);
71 gtk_label_set_selectable(GTK_LABEL(label), TRUE);
72 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
73
74 gtk_box_pack_start(GTK_BOX(widget_), label, FALSE, FALSE, 0);
75
76 // Add the menu button.
77 menu_button_ = gtk_button_new_with_label(
78 UTF16ToUTF8(WebsiteSettingsUI::PermissionActionToUIString(
79 setting, default_setting, source)).c_str());
80 bool user_setting = source == content_settings::SETTING_SOURCE_USER;
81 gtk_widget_set_sensitive(GTK_WIDGET(menu_button_), user_setting);
82 if (user_setting) {
83 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
84 pixbuf = rb.GetNativeImageNamed(IDR_APP_DROPARROW).ToGdkPixbuf();
85 GtkWidget* arrow = gtk_image_new_from_pixbuf(pixbuf);
86 gtk_button_set_image(GTK_BUTTON(menu_button_), arrow);
87 gtk_button_set_image_position(GTK_BUTTON(menu_button_),
88 base::i18n::IsRTL() ? GTK_POS_LEFT
89 : GTK_POS_RIGHT);
90 }
91 gtk_button_set_relief(GTK_BUTTON(menu_button_), GTK_RELIEF_NONE);
92 gtk_box_pack_start(GTK_BOX(widget_), menu_button_, FALSE, FALSE, 0);
93
94 menu_model_.reset(new PermissionMenuModel(this, type, default_setting,
95 setting));
96 MenuGtk::Delegate* delegate = new MenuGtk::Delegate();
97 menu_.reset(new MenuGtk(delegate, menu_model_.get()));
98 g_signal_connect(menu_button_, "button-press-event",
99 G_CALLBACK(OnMenuButtonPressEventThunk), this);
40 } 100 }
41 101
42 PermissionSelector::~PermissionSelector() { 102 PermissionSelector::~PermissionSelector() {
43 } 103 }
44 104
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) { 105 void PermissionSelector::AddObserver(PermissionSelectorObserver* observer) {
133 observer_list_.AddObserver(observer); 106 observer_list_.AddObserver(observer);
134 } 107 }
135 108
136 void PermissionSelector::OnPermissionChanged(GtkWidget* widget) { 109 ContentSetting PermissionSelector::GetSetting() const {
137 // Get the selected setting. 110 return setting_;
138 GtkTreeIter it; 111 }
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 112
147 // Change the permission icon according the the selected setting. 113 ContentSettingsType PermissionSelector::GetType() const {
114 return type_;
115 }
116
117 gboolean PermissionSelector::OnMenuButtonPressEvent(GtkWidget* button,
118 GdkEventButton* event) {
119 if (event->button != 1)
120 return FALSE;
121 menu_->PopupForWidget(button, event->button, event->time);
122 return TRUE;
123 }
124
125 void PermissionSelector::ExecuteCommand(int command_id) {
126 setting_ = CommandIdToContentSetting(command_id);
127
128 // Change the permission icon to reflect the selected setting.
148 ContentSetting effective_setting = setting_; 129 ContentSetting effective_setting = setting_;
149 if (effective_setting == CONTENT_SETTING_DEFAULT) 130 if (effective_setting == CONTENT_SETTING_DEFAULT)
150 effective_setting = default_setting_; 131 effective_setting = default_setting_;
151 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon( 132 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
152 type_, effective_setting).ToGdkPixbuf(); 133 type_, effective_setting).ToGdkPixbuf();
153 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf); 134 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf);
154 135
136 // Change the text of the menu button to reflect the selected setting.
137 gtk_button_set_label(GTK_BUTTON(menu_button_), UTF16ToUTF8(
138 WebsiteSettingsUI::PermissionActionToUIString(
139 setting_,
140 default_setting_,
141 content_settings::SETTING_SOURCE_USER)).c_str());
142
155 FOR_EACH_OBSERVER(PermissionSelectorObserver, 143 FOR_EACH_OBSERVER(PermissionSelectorObserver,
156 observer_list_, 144 observer_list_,
157 OnPermissionChanged(this)); 145 OnPermissionChanged(this));
158 } 146 }
159 147
160 void PermissionSelector::OnComboBoxShown(GtkWidget* widget, 148 bool PermissionSelector::IsCommandIdChecked(int command_id) {
161 GParamSpec* property) { 149 return setting_ == CommandIdToContentSetting(command_id);
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 } 150 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698