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.
5 #include "chrome/browser/ui/gtk/website_settings/permission_selector.h"
7 #include "base/compiler_specific.h"
8 #include "base/i18n/rtl.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
11 #include "chrome/browser/ui/gtk/gtk_util.h"
12 #include "chrome/browser/ui/gtk/menu_gtk.h"
13 #include "chrome/browser/ui/website_settings/website_settings_ui.h"
14 #include "grit/generated_resources.h"
15 #include "grit/theme_resources.h"
16 #include "ui/base/gtk/gtk_hig_constants.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"
20 #include "ui/gfx/image/image.h"
24 ContentSetting CommandIdToContentSetting(int command_id) {
26 case PermissionMenuModel::COMMAND_SET_TO_DEFAULT:
27 return CONTENT_SETTING_DEFAULT;
28 case PermissionMenuModel::COMMAND_SET_TO_ALLOW:
29 return CONTENT_SETTING_ALLOW;
30 case PermissionMenuModel::COMMAND_SET_TO_BLOCK:
31 return CONTENT_SETTING_BLOCK;
34 return CONTENT_SETTING_DEFAULT;
40 PermissionSelector::PermissionSelector(GtkThemeService* theme_service,
42 ContentSettingsType type,
43 ContentSetting setting,
44 ContentSetting default_setting,
45 content_settings::SettingSource source)
50 default_setting_(default_setting),
52 DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT);
54 // Create permission info box.
55 const int kChildSpacing = 4;
56 widget_ = gtk_hbox_new(FALSE, kChildSpacing);
58 // Add permission type icon.
59 ContentSetting effective_setting = setting;
60 if (effective_setting == CONTENT_SETTING_DEFAULT)
61 effective_setting = default_setting;
62 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
63 type, effective_setting).ToGdkPixbuf();
64 icon_ = gtk_image_new_from_pixbuf(pixbuf);
65 gtk_box_pack_start(GTK_BOX(widget_), icon_, FALSE, FALSE, 0);
67 // Add a label for the permission type.
68 GtkWidget* label = theme_service->BuildLabel(l10n_util::GetStringFUTF8(
69 IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
70 WebsiteSettingsUI::PermissionTypeToUIString(type)),
72 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
74 gtk_box_pack_start(GTK_BOX(widget_), label, FALSE, FALSE, 0);
76 // Add the menu button.
77 menu_button_ = theme_service->BuildChromeButton();
78 GtkWidget* button_hbox = gtk_hbox_new(FALSE, 0);
79 gtk_container_add(GTK_CONTAINER(menu_button_), button_hbox);
81 GtkWidget* button_label = theme_service->BuildLabel(
82 UTF16ToUTF8(WebsiteSettingsUI::PermissionActionToUIString(
83 setting, default_setting, source)),
85 gtk_box_pack_start(GTK_BOX(button_hbox), button_label, FALSE, FALSE,
88 bool user_setting = source == content_settings::SETTING_SOURCE_USER;
89 gtk_widget_set_sensitive(GTK_WIDGET(menu_button_), user_setting);
91 GtkWidget* arrow = NULL;
92 // We don't handle theme changes, which is a bug but they are very unlikely
93 // to occur while a bubble is grabbing input.
94 if (theme_service->UsingNativeTheme()) {
95 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
97 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
98 arrow = gtk_image_new_from_pixbuf(
99 rb.GetNativeImageNamed(IDR_APP_DROPARROW).ToGdkPixbuf());
101 gtk_box_pack_start(GTK_BOX(button_hbox), arrow, FALSE, FALSE, 0);
103 gtk_button_set_relief(GTK_BUTTON(menu_button_), GTK_RELIEF_NONE);
104 gtk_box_pack_start(GTK_BOX(widget_), menu_button_, FALSE, FALSE, 0);
106 menu_model_.reset(new PermissionMenuModel(this, url, type, default_setting,
108 MenuGtk::Delegate* delegate = new MenuGtk::Delegate();
109 menu_.reset(new MenuGtk(delegate, menu_model_.get()));
110 g_signal_connect(menu_button_, "button-press-event",
111 G_CALLBACK(OnMenuButtonPressEventThunk), this);
114 PermissionSelector::~PermissionSelector() {
117 void PermissionSelector::AddObserver(PermissionSelectorObserver* observer) {
118 observer_list_.AddObserver(observer);
121 ContentSetting PermissionSelector::GetSetting() const {
125 ContentSettingsType PermissionSelector::GetType() const {
129 gboolean PermissionSelector::OnMenuButtonPressEvent(GtkWidget* button,
130 GdkEventButton* event) {
131 if (event->button != 1)
133 menu_->PopupForWidget(button, event->button, event->time);
137 void PermissionSelector::ExecuteCommand(int command_id) {
138 setting_ = CommandIdToContentSetting(command_id);
140 // Change the permission icon to reflect the selected setting.
141 ContentSetting effective_setting = setting_;
142 if (effective_setting == CONTENT_SETTING_DEFAULT)
143 effective_setting = default_setting_;
144 GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
145 type_, effective_setting).ToGdkPixbuf();
146 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf);
148 // Change the text of the menu button to reflect the selected setting.
149 gtk_button_set_label(GTK_BUTTON(menu_button_), UTF16ToUTF8(
150 WebsiteSettingsUI::PermissionActionToUIString(
153 content_settings::SETTING_SOURCE_USER)).c_str());
155 FOR_EACH_OBSERVER(PermissionSelectorObserver,
157 OnPermissionChanged(this));
160 bool PermissionSelector::IsCommandIdChecked(int command_id) {
161 return setting_ == CommandIdToContentSetting(command_id);