Home | History | Annotate | Download | only in website_settings
      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.
      4 
      5 #include "chrome/browser/ui/gtk/website_settings/permission_selector.h"
      6 
      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"
     21 
     22 namespace {
     23 
     24 ContentSetting CommandIdToContentSetting(int command_id) {
     25   switch (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;
     32     default:
     33       NOTREACHED();
     34       return CONTENT_SETTING_DEFAULT;
     35   }
     36 }
     37 
     38 }  // namespace
     39 
     40 PermissionSelector::PermissionSelector(GtkThemeService* theme_service,
     41                                        const GURL& url,
     42                                        ContentSettingsType type,
     43                                        ContentSetting setting,
     44                                        ContentSetting default_setting,
     45                                        content_settings::SettingSource source)
     46     : widget_(NULL),
     47       menu_button_(NULL),
     48       icon_(NULL),
     49       type_(type),
     50       default_setting_(default_setting),
     51       setting_(setting) {
     52   DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT);
     53 
     54   // Create permission info box.
     55   const int kChildSpacing = 4;
     56   widget_ = gtk_hbox_new(FALSE, kChildSpacing);
     57 
     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);
     66 
     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)),
     71       ui::kGdkBlack);
     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_ = theme_service->BuildChromeButton();
     78   GtkWidget* button_hbox = gtk_hbox_new(FALSE, 0);
     79   gtk_container_add(GTK_CONTAINER(menu_button_), button_hbox);
     80 
     81   GtkWidget* button_label = theme_service->BuildLabel(
     82       UTF16ToUTF8(WebsiteSettingsUI::PermissionActionToUIString(
     83           setting, default_setting, source)),
     84       ui::kGdkBlack);
     85   gtk_box_pack_start(GTK_BOX(button_hbox), button_label, FALSE, FALSE,
     86                      ui::kControlSpacing);
     87 
     88   bool user_setting = source == content_settings::SETTING_SOURCE_USER;
     89   gtk_widget_set_sensitive(GTK_WIDGET(menu_button_), user_setting);
     90   if (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);
     96     } else {
     97       ResourceBundle& rb = ResourceBundle::GetSharedInstance();
     98       arrow = gtk_image_new_from_pixbuf(
     99           rb.GetNativeImageNamed(IDR_APP_DROPARROW).ToGdkPixbuf());
    100     }
    101     gtk_box_pack_start(GTK_BOX(button_hbox), arrow, FALSE, FALSE, 0);
    102   }
    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);
    105 
    106   menu_model_.reset(new PermissionMenuModel(this, url, type, default_setting,
    107                                             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);
    112 }
    113 
    114 PermissionSelector::~PermissionSelector() {
    115 }
    116 
    117 void PermissionSelector::AddObserver(PermissionSelectorObserver* observer) {
    118   observer_list_.AddObserver(observer);
    119 }
    120 
    121 ContentSetting PermissionSelector::GetSetting() const {
    122   return setting_;
    123 }
    124 
    125 ContentSettingsType PermissionSelector::GetType() const {
    126   return type_;
    127 }
    128 
    129 gboolean PermissionSelector::OnMenuButtonPressEvent(GtkWidget* button,
    130                                                     GdkEventButton* event) {
    131   if (event->button != 1)
    132     return FALSE;
    133   menu_->PopupForWidget(button, event->button, event->time);
    134   return TRUE;
    135 }
    136 
    137 void PermissionSelector::ExecuteCommand(int command_id) {
    138   setting_ = CommandIdToContentSetting(command_id);
    139 
    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);
    147 
    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(
    151           setting_,
    152           default_setting_,
    153           content_settings::SETTING_SOURCE_USER)).c_str());
    154 
    155   FOR_EACH_OBSERVER(PermissionSelectorObserver,
    156                     observer_list_,
    157                     OnPermissionChanged(this));
    158 }
    159 
    160 bool PermissionSelector::IsCommandIdChecked(int command_id) {
    161   return setting_ == CommandIdToContentSetting(command_id);
    162 }
    163