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 base::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_
), base::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
);