Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/views/website_settings/permission_selector_view.h" | 5 #include "chrome/browser/ui/views/website_settings/permission_selector_view.h" |
| 6 | 6 |
| 7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h " | 10 #include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h " |
| 11 #include "chrome/browser/ui/website_settings/permission_menu_model.h" | 11 #include "chrome/browser/ui/website_settings/permission_menu_model.h" |
| 12 #include "chrome/browser/ui/website_settings/website_settings_ui.h" | 12 #include "chrome/browser/ui/website_settings/website_settings_ui.h" |
| 13 #include "chrome/grit/generated_resources.h" | 13 #include "chrome/grit/generated_resources.h" |
| 14 #include "ui/accessibility/ax_view_state.h" | 14 #include "ui/accessibility/ax_view_state.h" |
| 15 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
| 16 #include "ui/base/models/combobox_model.h" | |
| 16 #include "ui/gfx/image/image.h" | 17 #include "ui/gfx/image/image.h" |
| 17 #include "ui/views/controls/button/menu_button.h" | 18 #include "ui/views/controls/button/menu_button.h" |
| 19 #include "ui/views/controls/combobox/combobox.h" | |
| 20 #include "ui/views/controls/combobox/combobox_listener.h" | |
| 18 #include "ui/views/controls/image_view.h" | 21 #include "ui/views/controls/image_view.h" |
| 19 #include "ui/views/controls/label.h" | 22 #include "ui/views/controls/label.h" |
| 20 #include "ui/views/controls/menu/menu_runner.h" | 23 #include "ui/views/controls/menu/menu_runner.h" |
| 21 #include "ui/views/layout/grid_layout.h" | 24 #include "ui/views/layout/grid_layout.h" |
| 22 #include "ui/views/view.h" | 25 #include "ui/views/view.h" |
| 23 #include "ui/views/widget/widget.h" | 26 #include "ui/views/widget/widget.h" |
| 24 | 27 |
| 25 namespace internal { | 28 namespace internal { |
| 26 | 29 |
| 27 // The |PermissionMenuButton| provides a menu for selecting a setting a | 30 // The |PermissionMenuButton| provides a menu for selecting a setting a |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 if (menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), | 108 if (menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), |
| 106 this, | 109 this, |
| 107 gfx::Rect(p, gfx::Size()), | 110 gfx::Rect(p, gfx::Size()), |
| 108 views::MENU_ANCHOR_TOPLEFT, | 111 views::MENU_ANCHOR_TOPLEFT, |
| 109 ui::MENU_SOURCE_NONE) == | 112 ui::MENU_SOURCE_NONE) == |
| 110 views::MenuRunner::MENU_DELETED) { | 113 views::MenuRunner::MENU_DELETED) { |
| 111 return; | 114 return; |
| 112 } | 115 } |
| 113 } | 116 } |
| 114 | 117 |
| 118 // This class adapts a PermissionMenuModel into a ui::ComboboxModel so that | |
|
palmer
2016/05/25 18:34:38
Nit: Demarcate identifiers in comments with |foo|.
Elly Fong-Jones
2016/05/26 13:40:38
Done.
| |
| 119 // PermissionCombobox can use it. | |
| 120 class ComboboxModelAdapter : public ui::ComboboxModel { | |
| 121 public: | |
| 122 explicit ComboboxModelAdapter(PermissionMenuModel* model) : model_(model) {} | |
| 123 ~ComboboxModelAdapter() override {} | |
| 124 | |
| 125 void OnPerformAction(int index); | |
| 126 | |
| 127 // Returns the checked index of the underlying PermissionMenuModel, of which | |
| 128 // there must be exactly one. This is used to choose which index is selected | |
| 129 // in the PermissionCombobox. | |
| 130 int GetCheckedIndex(); | |
| 131 | |
| 132 // ui::ComboboxModel: | |
| 133 int GetItemCount() const override; | |
| 134 base::string16 GetItemAt(int index) override; | |
|
palmer
2016/05/25 18:34:38
Nit: Since this is not a collection of string16s,
Elly Fong-Jones
2016/05/26 13:40:38
Unfortunately, these two names are defined in ui::
| |
| 135 | |
| 136 private: | |
| 137 PermissionMenuModel* model_; | |
| 138 }; | |
| 139 | |
| 140 void ComboboxModelAdapter::OnPerformAction(int index) { | |
| 141 model_->ExecuteCommand(index, 0); | |
| 142 } | |
| 143 | |
| 144 int ComboboxModelAdapter::GetCheckedIndex() { | |
| 145 int checked_index = -1; | |
| 146 for (int i = 0; i < model_->GetItemCount(); i++) { | |
|
palmer
2016/05/25 18:34:39
Nit: I think the Chromium style calls for ++i.
Elly Fong-Jones
2016/05/26 13:40:38
Done.
| |
| 147 if (model_->IsCommandIdChecked(i)) { | |
| 148 DCHECK_EQ(checked_index, -1); | |
| 149 checked_index = i; | |
|
palmer
2016/05/25 18:34:38
I think you can early-return here instead:
re
Elly Fong-Jones
2016/05/26 13:40:38
I avoided early return so that I could DCHECK that
palmer
2016/05/26 19:10:52
Ahh, I see. Maybe add a comment to that effect.
| |
| 150 } | |
| 151 } | |
| 152 return checked_index; | |
| 153 } | |
| 154 | |
| 155 int ComboboxModelAdapter::GetItemCount() const { | |
| 156 DCHECK(model_); | |
| 157 return model_->GetItemCount(); | |
| 158 } | |
| 159 | |
| 160 base::string16 ComboboxModelAdapter::GetItemAt(int index) { | |
| 161 return model_->GetLabelAt(index); | |
| 162 } | |
| 163 | |
| 164 // The |PermissionCombobox| provides a combobox for selecting a permission type. | |
| 165 // This is only used on platforms where the permission dialog uses a combobox | |
| 166 // instead of a MenuButton (currently, Mac). | |
| 167 class PermissionCombobox : public views::Combobox, | |
| 168 public views::ComboboxListener { | |
| 169 public: | |
| 170 PermissionCombobox(const base::string16& text, | |
| 171 ComboboxModelAdapter* model, | |
| 172 bool enabled); | |
| 173 ~PermissionCombobox() override; | |
| 174 | |
| 175 void UpdateSelectedIndex(); | |
| 176 | |
| 177 private: | |
| 178 // views::ComboboxListener: | |
| 179 void OnPerformAction(Combobox* combobox) override; | |
| 180 | |
| 181 ComboboxModelAdapter* model_; | |
| 182 }; | |
| 183 | |
| 184 PermissionCombobox::PermissionCombobox(const base::string16& text, | |
| 185 ComboboxModelAdapter* model, | |
| 186 bool enabled) | |
| 187 : views::Combobox(model), model_(model) { | |
| 188 set_listener(this); | |
| 189 SetEnabled(enabled); | |
| 190 UpdateSelectedIndex(); | |
| 191 } | |
| 192 | |
| 193 PermissionCombobox::~PermissionCombobox() {} | |
| 194 | |
| 195 void PermissionCombobox::UpdateSelectedIndex() { | |
| 196 int index = model_->GetCheckedIndex(); | |
| 197 DCHECK_NE(index, -1); | |
| 198 SetSelectedIndex(index); | |
| 199 } | |
| 200 | |
| 201 void PermissionCombobox::OnPerformAction(Combobox* combobox) { | |
| 202 model_->OnPerformAction(combobox->selected_index()); | |
| 203 } | |
| 204 | |
| 115 } // namespace internal | 205 } // namespace internal |
| 116 | 206 |
| 117 /////////////////////////////////////////////////////////////////////////////// | 207 /////////////////////////////////////////////////////////////////////////////// |
| 118 // PermissionSelectorView | 208 // PermissionSelectorView |
| 119 /////////////////////////////////////////////////////////////////////////////// | 209 /////////////////////////////////////////////////////////////////////////////// |
| 120 | 210 |
| 121 PermissionSelectorView::PermissionSelectorView( | 211 PermissionSelectorView::PermissionSelectorView( |
| 122 const GURL& url, | 212 const GURL& url, |
| 123 const WebsiteSettingsUI::PermissionInfo& permission) | 213 const WebsiteSettingsUI::PermissionInfo& permission) |
| 124 : icon_(NULL), menu_button_(NULL) { | 214 : icon_(NULL), menu_button_(NULL), combobox_(NULL) { |
| 125 views::GridLayout* layout = new views::GridLayout(this); | 215 views::GridLayout* layout = new views::GridLayout(this); |
| 126 SetLayoutManager(layout); | 216 SetLayoutManager(layout); |
| 127 const int column_set_id = 0; | 217 const int column_set_id = 0; |
| 128 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); | 218 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); |
| 129 column_set->AddColumn(views::GridLayout::FILL, | 219 column_set->AddColumn(views::GridLayout::FILL, |
| 130 views::GridLayout::FILL, | 220 views::GridLayout::FILL, |
| 131 1, | 221 1, |
| 132 views::GridLayout::FIXED, | 222 views::GridLayout::FIXED, |
| 133 kPermissionIconColumnWidth, | 223 kPermissionIconColumnWidth, |
| 134 0); | 224 0); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 165 1, | 255 1, |
| 166 views::GridLayout::LEADING, | 256 views::GridLayout::LEADING, |
| 167 views::GridLayout::CENTER); | 257 views::GridLayout::CENTER); |
| 168 // Create the menu model. | 258 // Create the menu model. |
| 169 menu_model_.reset(new PermissionMenuModel( | 259 menu_model_.reset(new PermissionMenuModel( |
| 170 url, | 260 url, |
| 171 permission, | 261 permission, |
| 172 base::Bind(&PermissionSelectorView::PermissionChanged, | 262 base::Bind(&PermissionSelectorView::PermissionChanged, |
| 173 base::Unretained(this)))); | 263 base::Unretained(this)))); |
| 174 // Create the permission menu button. | 264 // Create the permission menu button. |
| 175 bool button_enabled = | 265 #if defined(OS_MACOSX) |
| 176 permission.source == content_settings::SETTING_SOURCE_USER; | 266 InitializeComboboxView(layout, permission); |
| 177 menu_button_ = new internal::PermissionMenuButton( | 267 #else |
| 178 WebsiteSettingsUI::PermissionActionToUIString( | 268 InitializeMenuButtonView(layout, permission); |
| 179 permission.type, permission.setting, permission.default_setting, | 269 #endif |
| 180 permission.source), | |
| 181 menu_model_.get(), button_enabled); | |
| 182 menu_button_->SetEnabled(button_enabled); | |
| 183 menu_button_->SetAccessibleName( | |
| 184 WebsiteSettingsUI::PermissionTypeToUIString(permission.type)); | |
| 185 layout->AddView(menu_button_); | |
| 186 } | 270 } |
| 187 | 271 |
| 188 void PermissionSelectorView::AddObserver( | 272 void PermissionSelectorView::AddObserver( |
| 189 PermissionSelectorViewObserver* observer) { | 273 PermissionSelectorViewObserver* observer) { |
| 190 observer_list_.AddObserver(observer); | 274 observer_list_.AddObserver(observer); |
| 191 } | 275 } |
| 192 | 276 |
| 193 void PermissionSelectorView::ChildPreferredSizeChanged(View* child) { | 277 void PermissionSelectorView::ChildPreferredSizeChanged(View* child) { |
| 194 SizeToPreferredSize(); | 278 SizeToPreferredSize(); |
| 195 // FIXME: The parent is only a plain |View| that is used as a | 279 // FIXME: The parent is only a plain |View| that is used as a |
| 196 // container/box/panel. The SizeToPreferredSize method of the parent is | 280 // container/box/panel. The SizeToPreferredSize method of the parent is |
| 197 // called here directly in order not to implement a custom |View| class with | 281 // called here directly in order not to implement a custom |View| class with |
| 198 // its own implementation of the ChildPreferredSizeChanged method. | 282 // its own implementation of the ChildPreferredSizeChanged method. |
| 199 parent()->SizeToPreferredSize(); | 283 parent()->SizeToPreferredSize(); |
| 200 } | 284 } |
| 201 | 285 |
| 202 PermissionSelectorView::~PermissionSelectorView() { | 286 PermissionSelectorView::~PermissionSelectorView() { |
| 287 // Gross. On paper the Combobox and the ComboboxModelAdapter are both owned by | |
| 288 // this class, but actually, the Combobox is owned by View and will be | |
| 289 // destroyed in ~View(), which runs *after* ~PermissionSelectorView() is done, | |
| 290 // which means the Combobox gets destroyed after its ComboboxModel, which | |
| 291 // causes an explosion when the Combobox attempts to stop observing the | |
| 292 // ComboboxModel. This hack ensures the Combobox is deleted before its | |
| 293 // ComboboxModel. | |
| 294 // Technically, the MenuButton has the same problem, but MenuButton doesn't | |
|
palmer
2016/05/25 18:34:38
Nit: Blank line before a new paragraph.
Elly Fong-Jones
2016/05/26 13:40:38
Done.
| |
| 295 // use its model in its destructor. | |
| 296 if (combobox_) | |
| 297 RemoveChildView(combobox_); | |
| 298 } | |
| 299 | |
| 300 void PermissionSelectorView::InitializeMenuButtonView( | |
| 301 views::GridLayout* layout, | |
| 302 const WebsiteSettingsUI::PermissionInfo& permission) { | |
| 303 bool button_enabled = | |
| 304 permission.source == content_settings::SETTING_SOURCE_USER; | |
| 305 menu_button_ = new internal::PermissionMenuButton( | |
| 306 WebsiteSettingsUI::PermissionActionToUIString( | |
| 307 permission.type, permission.setting, permission.default_setting, | |
| 308 permission.source), | |
| 309 menu_model_.get(), button_enabled); | |
| 310 menu_button_->SetEnabled(button_enabled); | |
| 311 menu_button_->SetAccessibleName( | |
| 312 WebsiteSettingsUI::PermissionTypeToUIString(permission.type)); | |
| 313 layout->AddView(menu_button_); | |
| 314 } | |
| 315 | |
| 316 void PermissionSelectorView::InitializeComboboxView( | |
| 317 views::GridLayout* layout, | |
| 318 const WebsiteSettingsUI::PermissionInfo& permission) { | |
| 319 bool button_enabled = | |
| 320 permission.source == content_settings::SETTING_SOURCE_USER; | |
| 321 combobox_model_adaptor_.reset( | |
| 322 new internal::ComboboxModelAdapter(menu_model_.get())); | |
| 323 combobox_ = new internal::PermissionCombobox( | |
| 324 WebsiteSettingsUI::PermissionActionToUIString( | |
| 325 permission.type, permission.setting, permission.default_setting, | |
| 326 permission.source), | |
| 327 combobox_model_adaptor_.get(), button_enabled); | |
| 328 combobox_->SetEnabled(button_enabled); | |
| 329 combobox_->SetAccessibleName( | |
| 330 WebsiteSettingsUI::PermissionTypeToUIString(permission.type)); | |
| 331 layout->AddView(combobox_); | |
| 203 } | 332 } |
| 204 | 333 |
| 205 void PermissionSelectorView::PermissionChanged( | 334 void PermissionSelectorView::PermissionChanged( |
| 206 const WebsiteSettingsUI::PermissionInfo& permission) { | 335 const WebsiteSettingsUI::PermissionInfo& permission) { |
| 207 // Change the permission icon to reflect the selected setting. | 336 // Change the permission icon to reflect the selected setting. |
| 208 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); | 337 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); |
| 209 icon_->SetImage(image.ToImageSkia()); | 338 icon_->SetImage(image.ToImageSkia()); |
| 210 | 339 |
| 211 // Update the menu button text to reflect the new setting. | 340 // Update the menu button text to reflect the new setting. |
| 212 menu_button_->SetText(WebsiteSettingsUI::PermissionActionToUIString( | 341 if (menu_button_) { |
| 213 permission.type, permission.setting, permission.default_setting, | 342 menu_button_->SetText(WebsiteSettingsUI::PermissionActionToUIString( |
| 214 content_settings::SETTING_SOURCE_USER)); | 343 permission.type, permission.setting, permission.default_setting, |
| 215 menu_button_->SizeToPreferredSize(); | 344 content_settings::SETTING_SOURCE_USER)); |
| 345 menu_button_->SizeToPreferredSize(); | |
| 346 } else if (combobox_) { | |
| 347 combobox_->UpdateSelectedIndex(); | |
| 348 } | |
| 216 | 349 |
| 217 FOR_EACH_OBSERVER(PermissionSelectorViewObserver, | 350 FOR_EACH_OBSERVER(PermissionSelectorViewObserver, |
| 218 observer_list_, | 351 observer_list_, |
| 219 OnPermissionChanged(permission)); | 352 OnPermissionChanged(permission)); |
| 220 } | 353 } |
| OLD | NEW |