From 189d4fd8fad9e3c776873be51938cd31a42b6177 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 20 May 2021 09:47:09 +0200 Subject: BASELINE: Update Chromium to 90.0.4430.221 Change-Id: Iff4d9d18d2fcf1a576f3b1f453010f744a232920 Reviewed-by: Allan Sandfeld Jensen --- chromium/ui/base/models/dialog_model.cc | 20 +-- chromium/ui/base/models/dialog_model.h | 52 ++++--- chromium/ui/base/models/dialog_model_field.cc | 57 +++---- chromium/ui/base/models/dialog_model_field.h | 109 +++++++++----- chromium/ui/base/models/dialog_model_host.h | 11 +- chromium/ui/base/models/dialog_model_unittest.cc | 164 +++++++++++++++++++++ chromium/ui/base/models/list_selection_model.cc | 40 ++--- chromium/ui/base/models/list_selection_model.h | 9 +- .../base/models/list_selection_model_unittest.cc | 22 ++- chromium/ui/base/models/menu_model.cc | 4 + chromium/ui/base/models/menu_model.h | 4 + chromium/ui/base/models/simple_menu_model.cc | 9 ++ chromium/ui/base/models/simple_menu_model.h | 5 + 13 files changed, 369 insertions(+), 137 deletions(-) create mode 100644 chromium/ui/base/models/dialog_model_unittest.cc (limited to 'chromium/ui/base/models') diff --git a/chromium/ui/base/models/dialog_model.cc b/chromium/ui/base/models/dialog_model.cc index b1077c7788f..ceccc112e59 100644 --- a/chromium/ui/base/models/dialog_model.cc +++ b/chromium/ui/base/models/dialog_model.cc @@ -10,7 +10,7 @@ namespace ui { DialogModel::Builder::Builder(std::unique_ptr delegate) - : model_(std::make_unique(util::PassKey(), + : model_(std::make_unique(base::PassKey(), std::move(delegate))) {} DialogModel::Builder::Builder() : Builder(nullptr) {} @@ -75,7 +75,7 @@ DialogModel::Builder& DialogModel::Builder::SetInitiallyFocusedField( return *this; } -DialogModel::DialogModel(util::PassKey, +DialogModel::DialogModel(base::PassKey, std::unique_ptr delegate) : delegate_(std::move(delegate)) { if (delegate_) @@ -88,9 +88,11 @@ void DialogModel::AddBodyText(const DialogModelLabel& label) { AddField(std::make_unique(GetPassKey(), this, label)); } -void DialogModel::AddCheckbox(int unique_id, const DialogModelLabel& label) { +void DialogModel::AddCheckbox(int unique_id, + const DialogModelLabel& label, + const DialogModelCheckbox::Params& params) { AddField(std::make_unique(GetPassKey(), this, unique_id, - label)); + label, params)); } void DialogModel::AddCombobox(base::string16 label, @@ -118,7 +120,7 @@ DialogModelField* DialogModel::GetFieldByUniqueId(int unique_id) { if (field->unique_id_ == unique_id) return field.get(); } - NOTREACHED(); + NOTREACHED() << "No field with unique_id: " << unique_id; return nullptr; } @@ -134,22 +136,22 @@ DialogModelTextfield* DialogModel::GetTextfieldByUniqueId(int unique_id) { return GetFieldByUniqueId(unique_id)->AsTextfield(); } -void DialogModel::OnDialogAccepted(util::PassKey) { +void DialogModel::OnDialogAccepted(base::PassKey) { if (accept_callback_) std::move(accept_callback_).Run(); } -void DialogModel::OnDialogCancelled(util::PassKey) { +void DialogModel::OnDialogCancelled(base::PassKey) { if (cancel_callback_) std::move(cancel_callback_).Run(); } -void DialogModel::OnDialogClosed(util::PassKey) { +void DialogModel::OnDialogClosed(base::PassKey) { if (close_callback_) std::move(close_callback_).Run(); } -void DialogModel::OnWindowClosing(util::PassKey) { +void DialogModel::OnWindowClosing(base::PassKey) { if (window_closing_callback_) std::move(window_closing_callback_).Run(); } diff --git a/chromium/ui/base/models/dialog_model.h b/chromium/ui/base/models/dialog_model.h index 4a5be0d6837..f219925a6ce 100644 --- a/chromium/ui/base/models/dialog_model.h +++ b/chromium/ui/base/models/dialog_model.h @@ -11,7 +11,7 @@ #include "base/component_export.h" #include "base/containers/flat_map.h" #include "base/strings/string16.h" -#include "base/util/type_safety/pass_key.h" +#include "base/types/pass_key.h" #include "ui/base/models/dialog_model_field.h" #include "ui/base/models/dialog_model_host.h" #include "ui/base/models/image_model.h" @@ -191,8 +191,11 @@ class COMPONENT_EXPORT(UI_BASE) DialogModel final { } // Adds a checkbox. See DialogModel::AddCheckbox(). - Builder& AddCheckbox(int unique_id, const DialogModelLabel& label) { - model_->AddCheckbox(unique_id, label); + Builder& AddCheckbox(int unique_id, + const DialogModelLabel& label, + const DialogModelCheckbox::Params& params = + DialogModelCheckbox::Params()) { + model_->AddCheckbox(unique_id, label, params); return *this; } @@ -222,7 +225,7 @@ class COMPONENT_EXPORT(UI_BASE) DialogModel final { std::unique_ptr model_; }; - DialogModel(util::PassKey, + DialogModel(base::PassKey, std::unique_ptr delegate); DialogModel(const DialogModel&) = delete; @@ -238,7 +241,10 @@ class COMPONENT_EXPORT(UI_BASE) DialogModel final { void AddBodyText(const DialogModelLabel& label); // Adds a checkbox ([checkbox] label) at the end of the dialog model. - void AddCheckbox(int unique_id, const DialogModelLabel& label); + void AddCheckbox(int unique_id, + const DialogModelLabel& label, + const DialogModelCheckbox::Params& params = + DialogModelCheckbox::Params()); // Adds a labeled combobox (label: [model]) at the end of the dialog model. void AddCombobox(base::string16 label, @@ -266,51 +272,51 @@ class COMPONENT_EXPORT(UI_BASE) DialogModel final { DialogModelCombobox* GetComboboxByUniqueId(int unique_id); DialogModelTextfield* GetTextfieldByUniqueId(int unique_id); - // Methods with util::PassKey are only intended to be called + // Methods with base::PassKey are only intended to be called // by the DialogModelHost implementation. - void OnDialogAccepted(util::PassKey); - void OnDialogCancelled(util::PassKey); - void OnDialogClosed(util::PassKey); - void OnWindowClosing(util::PassKey); + void OnDialogAccepted(base::PassKey); + void OnDialogCancelled(base::PassKey); + void OnDialogClosed(base::PassKey); + void OnWindowClosing(base::PassKey); // Called when added to a DialogModelHost. - void set_host(util::PassKey, DialogModelHost* host) { + void set_host(base::PassKey, DialogModelHost* host) { host_ = host; } const base::Optional& override_show_close_button( - util::PassKey) const { + base::PassKey) const { return override_show_close_button_; } - const base::string16& title(util::PassKey) const { + const base::string16& title(base::PassKey) const { return title_; } - const ImageModel& icon(util::PassKey) const { return icon_; } + const ImageModel& icon(base::PassKey) const { return icon_; } base::Optional initially_focused_field( - util::PassKey) const { + base::PassKey) const { return initially_focused_field_; } - bool is_alert_dialog(util::PassKey) const { + bool is_alert_dialog(base::PassKey) const { return is_alert_dialog_; } - DialogModelButton* ok_button(util::PassKey) { + DialogModelButton* ok_button(base::PassKey) { return ok_button_.has_value() ? &ok_button_.value() : nullptr; } - DialogModelButton* cancel_button(util::PassKey) { + DialogModelButton* cancel_button(base::PassKey) { return cancel_button_.has_value() ? &cancel_button_.value() : nullptr; } - DialogModelButton* extra_button(util::PassKey) { + DialogModelButton* extra_button(base::PassKey) { return extra_button_.has_value() ? &extra_button_.value() : nullptr; } - bool close_on_deactivate(util::PassKey) const { + bool close_on_deactivate(base::PassKey) const { return close_on_deactivate_; } @@ -318,13 +324,13 @@ class COMPONENT_EXPORT(UI_BASE) DialogModel final { // though they should be handled separately (OK button has fixed position in // dialog). const std::vector>& fields( - util::PassKey) { + base::PassKey) { return fields_; } private: - util::PassKey GetPassKey() { - return util::PassKey(); + base::PassKey GetPassKey() { + return base::PassKey(); } void AddField(std::unique_ptr field); diff --git a/chromium/ui/base/models/dialog_model_field.cc b/chromium/ui/base/models/dialog_model_field.cc index 3432b970aa8..a323903381f 100644 --- a/chromium/ui/base/models/dialog_model_field.cc +++ b/chromium/ui/base/models/dialog_model_field.cc @@ -33,7 +33,7 @@ DialogModelLabel::DialogModelLabel(base::string16 fixed_string) : message_id_(-1), string_(std::move(fixed_string)) {} const base::string16& DialogModelLabel::GetString( - util::PassKey) const { + base::PassKey) const { DCHECK(links_.empty()); return string_; } @@ -51,7 +51,7 @@ DialogModelLabel DialogModelLabel::CreateWithLinks(int message_id, return DialogModelLabel(message_id, std::move(links)); } -DialogModelField::DialogModelField(util::PassKey, +DialogModelField::DialogModelField(base::PassKey, DialogModel* model, Type type, int unique_id, @@ -65,27 +65,27 @@ DialogModelField::DialogModelField(util::PassKey, DialogModelField::~DialogModelField() = default; -DialogModelButton* DialogModelField::AsButton(util::PassKey) { +DialogModelButton* DialogModelField::AsButton(base::PassKey) { return AsButton(); } DialogModelBodyText* DialogModelField::AsBodyText( - util::PassKey) { + base::PassKey) { return AsBodyText(); } DialogModelCheckbox* DialogModelField::AsCheckbox( - util::PassKey) { + base::PassKey) { return AsCheckbox(); } DialogModelCombobox* DialogModelField::AsCombobox( - util::PassKey) { + base::PassKey) { return AsCombobox(); } DialogModelTextfield* DialogModelField::AsTextfield( - util::PassKey) { + base::PassKey) { return AsTextfield(); } @@ -131,7 +131,7 @@ DialogModelButton::Params& DialogModelButton::Params::AddAccelerator( } DialogModelButton::DialogModelButton( - util::PassKey pass_key, + base::PassKey pass_key, DialogModel* model, base::RepeatingCallback callback, base::string16 label, @@ -148,12 +148,12 @@ DialogModelButton::DialogModelButton( DialogModelButton::~DialogModelButton() = default; -void DialogModelButton::OnPressed(util::PassKey, +void DialogModelButton::OnPressed(base::PassKey, const Event& event) { callback_.Run(event); } -DialogModelBodyText::DialogModelBodyText(util::PassKey pass_key, +DialogModelBodyText::DialogModelBodyText(base::PassKey pass_key, DialogModel* model, const DialogModelLabel& label) : DialogModelField(pass_key, @@ -165,20 +165,23 @@ DialogModelBodyText::DialogModelBodyText(util::PassKey pass_key, DialogModelBodyText::~DialogModelBodyText() = default; -DialogModelCheckbox::DialogModelCheckbox(util::PassKey pass_key, - DialogModel* model, - int unique_id, - const DialogModelLabel& label) +DialogModelCheckbox::DialogModelCheckbox( + base::PassKey pass_key, + DialogModel* model, + int unique_id, + const DialogModelLabel& label, + const DialogModelCheckbox::Params& params) : DialogModelField(pass_key, model, kCheckbox, unique_id, base::flat_set()), - label_(label) {} + label_(label), + is_checked_(params.is_checked_) {} DialogModelCheckbox::~DialogModelCheckbox() = default; -void DialogModelCheckbox::OnChecked(util::PassKey, +void DialogModelCheckbox::OnChecked(base::PassKey, bool is_checked) { is_checked_ = is_checked; } @@ -205,14 +208,8 @@ DialogModelCombobox::Params& DialogModelCombobox::Params::AddAccelerator( return *this; } -DialogModelCombobox::Params& DialogModelCombobox::Params::SetAccessibleName( - base::string16 accessible_name) { - accessible_name_ = std::move(accessible_name); - return *this; -} - DialogModelCombobox::DialogModelCombobox( - util::PassKey pass_key, + base::PassKey pass_key, DialogModel* model, base::string16 label, std::unique_ptr combobox_model, @@ -230,12 +227,12 @@ DialogModelCombobox::DialogModelCombobox( DialogModelCombobox::~DialogModelCombobox() = default; -void DialogModelCombobox::OnSelectedIndexChanged(util::PassKey, +void DialogModelCombobox::OnSelectedIndexChanged(base::PassKey, int selected_index) { selected_index_ = selected_index; } -void DialogModelCombobox::OnPerformAction(util::PassKey) { +void DialogModelCombobox::OnPerformAction(base::PassKey) { if (callback_) callback_.Run(); } @@ -256,14 +253,8 @@ DialogModelTextfield::Params& DialogModelTextfield::Params::AddAccelerator( return *this; } -DialogModelTextfield::Params& DialogModelTextfield::Params::SetAccessibleName( - base::string16 accessible_name) { - accessible_name_ = accessible_name; - return *this; -} - DialogModelTextfield::DialogModelTextfield( - util::PassKey pass_key, + base::PassKey pass_key, DialogModel* model, base::string16 label, base::string16 text, @@ -279,7 +270,7 @@ DialogModelTextfield::DialogModelTextfield( DialogModelTextfield::~DialogModelTextfield() = default; -void DialogModelTextfield::OnTextChanged(util::PassKey, +void DialogModelTextfield::OnTextChanged(base::PassKey, base::string16 text) { text_ = std::move(text); } diff --git a/chromium/ui/base/models/dialog_model_field.h b/chromium/ui/base/models/dialog_model_field.h index 1e2c2c87d50..54b50c7670f 100644 --- a/chromium/ui/base/models/dialog_model_field.h +++ b/chromium/ui/base/models/dialog_model_field.h @@ -7,8 +7,9 @@ #include "base/callback.h" #include "base/containers/flat_set.h" +#include "base/gtest_prod_util.h" #include "base/strings/string16.h" -#include "base/util/type_safety/pass_key.h" +#include "base/types/pass_key.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/models/combobox_model.h" @@ -59,7 +60,7 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelLabel { // links() and message_id() to construct the final label. This is required to // style the final label appropriately and support link callbacks. The caller // is responsible for checking links().empty() before calling this. - const base::string16& GetString(util::PassKey) const; + const base::string16& GetString(base::PassKey) const; DialogModelLabel& set_is_secondary() { is_secondary_ = true; @@ -71,14 +72,14 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelLabel { return *this; } - int message_id(util::PassKey) const { return message_id_; } - const std::vector links(util::PassKey) const { + int message_id(base::PassKey) const { return message_id_; } + const std::vector links(base::PassKey) const { return links_; } - bool is_secondary(util::PassKey) const { + bool is_secondary(base::PassKey) const { return is_secondary_; } - bool allow_character_break(util::PassKey) const { + bool allow_character_break(base::PassKey) const { return allow_character_break_; } @@ -108,23 +109,24 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelField { DialogModelField& operator=(const DialogModelField&) = delete; virtual ~DialogModelField(); - // Methods with util::PassKey are only intended to be called + // Methods with base::PassKey are only intended to be called // by the DialogModelHost implementation. - Type type(util::PassKey) const { return type_; } + Type type(base::PassKey) const { return type_; } const base::flat_set& accelerators( - util::PassKey) const { + base::PassKey) const { return accelerators_; } - DialogModelButton* AsButton(util::PassKey); - DialogModelBodyText* AsBodyText(util::PassKey); - DialogModelCheckbox* AsCheckbox(util::PassKey); - DialogModelCombobox* AsCombobox(util::PassKey); - DialogModelTextfield* AsTextfield(util::PassKey); + int unique_id(base::PassKey) const { return unique_id_; } + DialogModelButton* AsButton(base::PassKey); + DialogModelBodyText* AsBodyText(base::PassKey); + DialogModelCheckbox* AsCheckbox(base::PassKey); + DialogModelCombobox* AsCombobox(base::PassKey); + DialogModelTextfield* AsTextfield(base::PassKey); protected: // Children of this class need to be constructed through DialogModel to help // enforce that they're added to the model. - DialogModelField(util::PassKey, + DialogModelField(base::PassKey, DialogModel* model, Type type, int unique_id, @@ -138,6 +140,7 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelField { private: friend class DialogModel; + FRIEND_TEST_ALL_PREFIXES(DialogModelButtonTest, UsesParamsUniqueId); DialogModel* const model_; const Type type_; @@ -159,7 +162,6 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelButton : public DialogModelField { Params& SetUniqueId(int unique_id); Params& AddAccelerator(Accelerator accelerator); - Params& SetAccessibleName(base::string16 accessible_name); private: friend class DialogModelButton; @@ -170,7 +172,7 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelButton : public DialogModelField { // Note that this is constructed through a DialogModel which adds it to model // fields. - DialogModelButton(util::PassKey pass_key, + DialogModelButton(base::PassKey pass_key, DialogModel* model, base::RepeatingCallback callback, base::string16 label, @@ -179,12 +181,12 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelButton : public DialogModelField { DialogModelButton& operator=(const DialogModelButton&) = delete; ~DialogModelButton() override; - // Methods with util::PassKey are only intended to be called + // Methods with base::PassKey are only intended to be called // by the DialogModelHost implementation. - const base::string16& label(util::PassKey) const { + const base::string16& label(base::PassKey) const { return label_; } - void OnPressed(util::PassKey, const Event& event); + void OnPressed(base::PassKey, const Event& event); private: friend class DialogModel; @@ -201,14 +203,14 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelBodyText : public DialogModelField { public: // Note that this is constructed through a DialogModel which adds it to model // fields. - DialogModelBodyText(util::PassKey pass_key, + DialogModelBodyText(base::PassKey pass_key, DialogModel* model, const DialogModelLabel& label); DialogModelBodyText(const DialogModelBodyText&) = delete; DialogModelBodyText& operator=(const DialogModelBodyText&) = delete; ~DialogModelBodyText() override; - const DialogModelLabel& label(util::PassKey) const { + const DialogModelLabel& label(base::PassKey) const { return label_; } @@ -219,26 +221,45 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelBodyText : public DialogModelField { // Field class representing a checkbox with descriptive text. class COMPONENT_EXPORT(UI_BASE) DialogModelCheckbox : public DialogModelField { public: + class COMPONENT_EXPORT(UI_BASE) Params { + public: + Params() = default; + Params(const Params&) = delete; + Params& operator=(const Params&) = delete; + ~Params() = default; + + Params& SetIsChecked(bool is_checked) { + is_checked_ = is_checked; + return *this; + } + + private: + friend class DialogModelCheckbox; + + bool is_checked_ = false; + }; + // Note that this is constructed through a DialogModel which adds it to model // fields. - DialogModelCheckbox(util::PassKey pass_key, + DialogModelCheckbox(base::PassKey pass_key, DialogModel* model, int unique_id, - const DialogModelLabel& label); + const DialogModelLabel& label, + const Params& params); DialogModelCheckbox(const DialogModelCheckbox&) = delete; DialogModelCheckbox& operator=(const DialogModelCheckbox&) = delete; ~DialogModelCheckbox() override; bool is_checked() const { return is_checked_; } - void OnChecked(util::PassKey, bool is_checked); - const DialogModelLabel& label(util::PassKey) const { + void OnChecked(base::PassKey, bool is_checked); + const DialogModelLabel& label(base::PassKey) const { return label_; } private: const DialogModelLabel label_; - bool is_checked_ = false; + bool is_checked_; }; // Field class representing a combobox and corresponding label to describe the @@ -258,7 +279,11 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelCombobox : public DialogModelField { Params& SetUniqueId(int unique_id); Params& AddAccelerator(Accelerator accelerator); - Params& SetAccessibleName(base::string16 accessible_name); + + Params& SetAccessibleName(base::string16 accessible_name) { + accessible_name_ = std::move(accessible_name); + return *this; + } // The combobox callback is invoked when an item has been selected. This // nominally happens when selecting an item in the combobox menu. The @@ -278,7 +303,7 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelCombobox : public DialogModelField { // Note that this is constructed through a DialogModel which adds it to model // fields. - DialogModelCombobox(util::PassKey pass_key, + DialogModelCombobox(base::PassKey pass_key, DialogModel* model, base::string16 label, std::unique_ptr combobox_model, @@ -290,17 +315,17 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelCombobox : public DialogModelField { int selected_index() const { return selected_index_; } ui::ComboboxModel* combobox_model() { return combobox_model_.get(); } - // Methods with util::PassKey are only intended to be called + // Methods with base::PassKey are only intended to be called // by the DialogModelHost implementation. - const base::string16& label(util::PassKey) const { + const base::string16& label(base::PassKey) const { return label_; } - const base::string16& accessible_name(util::PassKey) const { + const base::string16& accessible_name(base::PassKey) const { return accessible_name_; } - void OnSelectedIndexChanged(util::PassKey, + void OnSelectedIndexChanged(base::PassKey, int selected_index); - void OnPerformAction(util::PassKey); + void OnPerformAction(base::PassKey); private: friend class DialogModel; @@ -329,7 +354,11 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelTextfield : public DialogModelField { Params& SetUniqueId(int unique_id); Params& AddAccelerator(Accelerator accelerator); - Params& SetAccessibleName(base::string16 accessible_name); + + Params& SetAccessibleName(base::string16 accessible_name) { + accessible_name_ = std::move(accessible_name); + return *this; + } private: friend class DialogModelTextfield; @@ -341,7 +370,7 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelTextfield : public DialogModelField { // Note that this is constructed through a DialogModel which adds it to model // fields. - DialogModelTextfield(util::PassKey pass_key, + DialogModelTextfield(base::PassKey pass_key, DialogModel* model, base::string16 label, base::string16 text, @@ -352,15 +381,15 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelTextfield : public DialogModelField { const base::string16& text() const { return text_; } - // Methods with util::PassKey are only intended to be called + // Methods with base::PassKey are only intended to be called // by the DialogModelHost implementation. - const base::string16& label(util::PassKey) const { + const base::string16& label(base::PassKey) const { return label_; } - const base::string16& accessible_name(util::PassKey) const { + const base::string16& accessible_name(base::PassKey) const { return accessible_name_; } - void OnTextChanged(util::PassKey, base::string16 text); + void OnTextChanged(base::PassKey, base::string16 text); private: friend class DialogModel; diff --git a/chromium/ui/base/models/dialog_model_host.h b/chromium/ui/base/models/dialog_model_host.h index 30590f063ef..73e0a49b9b8 100644 --- a/chromium/ui/base/models/dialog_model_host.h +++ b/chromium/ui/base/models/dialog_model_host.h @@ -5,7 +5,7 @@ #ifndef UI_BASE_MODELS_DIALOG_MODEL_HOST_H_ #define UI_BASE_MODELS_DIALOG_MODEL_HOST_H_ -#include "base/util/type_safety/pass_key.h" +#include "base/types/pass_key.h" namespace ui { @@ -19,19 +19,14 @@ class COMPONENT_EXPORT(UI_BASE) DialogModelHost { // or DialogModelHost. virtual void Close() = 0; - // Selects all text of a textfield. - // TODO(pbos): Reconsider whether this should be implied by if the textfield - // is initially focused. - virtual void SelectAllText(int unique_id) = 0; - protected: friend class DialogModel; friend class DialogModelField; // This PassKey is used to make sure that some methods on DialogModel // are only called as part of the host integration. - static util::PassKey GetPassKey() { - return util::PassKey(); + static base::PassKey GetPassKey() { + return base::PassKey(); } // Called when various parts of the model changes. diff --git a/chromium/ui/base/models/dialog_model_unittest.cc b/chromium/ui/base/models/dialog_model_unittest.cc new file mode 100644 index 00000000000..83b8a0e9ff0 --- /dev/null +++ b/chromium/ui/base/models/dialog_model_unittest.cc @@ -0,0 +1,164 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/models/dialog_model.h" + +#include "base/strings/utf_string_conversions.h" +#include "base/test/bind.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/test/test_dialog_model_host.h" +#include "ui/events/event.h" + +namespace ui { + +class DialogModelButtonTest : public testing::Test {}; + +TEST_F(DialogModelButtonTest, UsesParamsUniqueId) { + constexpr int kUniqueId = 42; + // TODO(pbos): Replace AddOkButton() with AddButton() once buttons in dialogs + // are supported. + std::unique_ptr model = + DialogModel::Builder() + .AddOkButton(base::OnceClosure(), base::string16(), + DialogModelButton::Params().SetUniqueId(kUniqueId)) + .Build(); + EXPECT_EQ(kUniqueId, + model->ok_button(TestDialogModelHost::GetPassKey())->unique_id_); +} + +TEST_F(DialogModelButtonTest, UsesParamsAccelerators) { + const Accelerator accelerator_1; + const Accelerator accelerator_2(VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN); + + // TODO(pbos): Replace AddOkButton() with AddButton() once buttons in dialogs + // are supported. + std::unique_ptr model = + DialogModel::Builder() + .AddOkButton(base::OnceClosure(), base::string16(), + DialogModelButton::Params() + .AddAccelerator(accelerator_1) + .AddAccelerator(accelerator_2)) + .Build(); + EXPECT_THAT(model->ok_button(TestDialogModelHost::GetPassKey()) + ->accelerators(TestDialogModelHost::GetPassKey()), + testing::UnorderedElementsAre(accelerator_1, accelerator_2)); +} + +TEST_F(DialogModelButtonTest, UsesCallback) { + int callback_count = 0; + std::unique_ptr last_event; + // TODO(pbos): Replace AddExtraButton() with AddButton() once buttons in + // dialogs are supported. + std::unique_ptr model = + DialogModel::Builder() + .AddDialogExtraButton( + base::BindLambdaForTesting([&](const Event& event) { + ++callback_count; + last_event = std::make_unique(*event.AsKeyEvent()); + }), + base::string16()) + .Build(); + DialogModelButton* const button = + model->extra_button(TestDialogModelHost::GetPassKey()); + + KeyEvent first_event(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE); + button->OnPressed(TestDialogModelHost::GetPassKey(), first_event); + EXPECT_EQ(1, callback_count); + EXPECT_EQ(first_event.key_code(), last_event->key_code()); + + KeyEvent second_event(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE); + button->OnPressed(TestDialogModelHost::GetPassKey(), second_event); + EXPECT_EQ(2, callback_count); + EXPECT_EQ(second_event.key_code(), last_event->key_code()); +} + +class DialogModelDialogButtonTest : public testing::Test { + public: + enum DialogButtonId { + kCancelButton, + kExtraButton, + kOkButton, + }; + + void DialogButtonUsesArguments(DialogButtonId button_id) { + DialogModel::Builder builder; + + // Callback to verify that the first parameter is used. + bool callback_called = false; + base::OnceClosure callback = base::BindRepeating( + [](bool* callback_called) { *callback_called = true; }, + &callback_called); + + // Label to verify the second parameter. + base::string16 label = base::ASCIIToUTF16("my cool button"); + + // The presence of an accelerator in |params| will be used to verify that + // |params| are forwarded correctly to the DialogModelButton constructor. + DialogModelButton::Params params; + Accelerator accelerator(VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN); + params.AddAccelerator(accelerator); + + switch (button_id) { + case kCancelButton: + builder.AddCancelButton(std::move(callback), label, params); + break; + case kExtraButton: + // Wrap the callback into a repeating callback that'll only be called + // once so the same verification can be used for the extra button. + builder.AddDialogExtraButton( + base::BindRepeating( + [](base::OnceClosure* callback, const Event& event) { + std::move(*callback).Run(); + }, + &callback), + label, params); + break; + case kOkButton: + builder.AddOkButton(std::move(callback), label, params); + break; + } + std::unique_ptr model = builder.Build(); + + // Get the DialogModelButton and trigger the corresponding callback. + DialogModelButton* button = nullptr; + switch (button_id) { + case kCancelButton: + button = model->cancel_button(TestDialogModelHost::GetPassKey()); + model->OnDialogCancelled(TestDialogModelHost::GetPassKey()); + break; + case kExtraButton: + button = model->extra_button(TestDialogModelHost::GetPassKey()); + button->OnPressed(TestDialogModelHost::GetPassKey(), + KeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE)); + break; + case kOkButton: + button = model->ok_button(TestDialogModelHost::GetPassKey()); + model->OnDialogAccepted(TestDialogModelHost::GetPassKey()); + break; + } + ASSERT_TRUE(button); + + EXPECT_TRUE(callback_called) << "The callback parameter wasn't used."; + EXPECT_EQ(label, button->label(TestDialogModelHost::GetPassKey())) + << "The label parameter wasn't used."; + EXPECT_THAT(button->accelerators(TestDialogModelHost::GetPassKey()), + testing::UnorderedElementsAre(accelerator)) + << "The params parameter wasn't used."; + } +}; + +TEST_F(DialogModelDialogButtonTest, OkButtonUsesArguments) { + DialogButtonUsesArguments(kOkButton); +} + +TEST_F(DialogModelDialogButtonTest, ExtraButtonUsesArguments) { + DialogButtonUsesArguments(kExtraButton); +} + +TEST_F(DialogModelDialogButtonTest, CancelButtonUsesArguments) { + DialogButtonUsesArguments(kCancelButton); +} + +} // namespace ui \ No newline at end of file diff --git a/chromium/ui/base/models/list_selection_model.cc b/chromium/ui/base/models/list_selection_model.cc index 90c66420a9b..0138856da32 100644 --- a/chromium/ui/base/models/list_selection_model.cc +++ b/chromium/ui/base/models/list_selection_model.cc @@ -8,7 +8,7 @@ #include #include "base/check_op.h" -#include "base/stl_util.h" +#include "base/containers/contains.h" namespace ui { @@ -85,10 +85,11 @@ void ListSelectionModel::IncrementFrom(int index) { void ListSelectionModel::DecrementFrom(int index) { for (auto i = selected_indices_.begin(); i != selected_indices_.end();) { - if (DecrementFromImpl(index, &(*i))) + if (DecrementFromImpl(index, &(*i))) { i = selected_indices_.erase(i); - else + } else { ++i; + } } DecrementFromImpl(index, &anchor_); DecrementFromImpl(index, &active_); @@ -98,7 +99,7 @@ void ListSelectionModel::SetSelectedIndex(int index) { anchor_ = active_ = index; selected_indices_.clear(); if (index != kUnselectedIndex) - selected_indices_.push_back(index); + selected_indices_.insert(index); } bool ListSelectionModel::IsSelected(int index) const { @@ -106,16 +107,23 @@ bool ListSelectionModel::IsSelected(int index) const { } void ListSelectionModel::AddIndexToSelection(int index) { - if (!IsSelected(index)) { - selected_indices_.push_back(index); - std::sort(selected_indices_.begin(), selected_indices_.end()); + selected_indices_.insert(index); +} + +void ListSelectionModel::AddIndexRangeToSelection(int index_start, + int index_end) { + DCHECK_LE(index_start, index_end); + + if (index_start == index_end) + return AddIndexToSelection(index_start); + + for (int i = index_start; i <= index_end; ++i) { + selected_indices_.insert(i); } } void ListSelectionModel::RemoveIndexFromSelection(int index) { - auto i = std::find(selected_indices_.begin(), selected_indices_.end(), index); - if (i != selected_indices_.end()) - selected_indices_.erase(i); + selected_indices_.erase(index); } void ListSelectionModel::SetSelectionFromAnchorTo(int index) { @@ -123,9 +131,9 @@ void ListSelectionModel::SetSelectionFromAnchorTo(int index) { SetSelectedIndex(index); } else { int delta = std::abs(index - anchor_); - SelectedIndices new_selection(delta + 1, 0); + SelectedIndices new_selection; for (int i = 0, min = std::min(index, anchor_); i <= delta; ++i) - new_selection[i] = i + min; + new_selection.insert(i + min); selected_indices_.swap(new_selection); active_ = index; } @@ -137,10 +145,8 @@ void ListSelectionModel::AddSelectionFromAnchorTo(int index) { } else { for (int i = std::min(index, anchor_), end = std::max(index, anchor_); i <= end; ++i) { - if (!IsSelected(i)) - selected_indices_.push_back(i); + selected_indices_.insert(i); } - std::sort(selected_indices_.begin(), selected_indices_.end()); active_ = index; } } @@ -195,13 +201,11 @@ void ListSelectionModel::Move(int old_index, int new_index, int length) { // still sorted piecewise, and |pivot_value| is a lower bound for elements in // [low, middle), and an upper bound for [middle, high). std::rotate(low, middle, high); - DCHECK(std::is_sorted(selected_indices_.begin(), selected_indices_.end())); } void ListSelectionModel::Clear() { anchor_ = active_ = kUnselectedIndex; - SelectedIndices empty_selection; - selected_indices_.swap(empty_selection); + selected_indices_.clear(); } } // namespace ui diff --git a/chromium/ui/base/models/list_selection_model.h b/chromium/ui/base/models/list_selection_model.h index 4c98ae9f645..7c672f9006f 100644 --- a/chromium/ui/base/models/list_selection_model.h +++ b/chromium/ui/base/models/list_selection_model.h @@ -7,9 +7,8 @@ #include -#include - #include "base/component_export.h" +#include "base/containers/flat_set.h" namespace ui { @@ -27,7 +26,7 @@ namespace ui { // active index correspond to the same thing. class COMPONENT_EXPORT(UI_BASE) ListSelectionModel { public: - using SelectedIndices = std::vector; + using SelectedIndices = base::flat_set; // Used to identify no selection. static constexpr int kUnselectedIndex = -1; @@ -80,6 +79,10 @@ class COMPONENT_EXPORT(UI_BASE) ListSelectionModel { // indices. void AddIndexToSelection(int index); + // Adds indices between |index_start| and |index_end|, inclusive. + // This does not change the active or anchor indices. + void AddIndexRangeToSelection(int index_start, int index_end); + // Removes |index| from the selection. This does not change the active or // anchor indices. void RemoveIndexFromSelection(int index); diff --git a/chromium/ui/base/models/list_selection_model_unittest.cc b/chromium/ui/base/models/list_selection_model_unittest.cc index 8c52ba11939..898ae5ee8ca 100644 --- a/chromium/ui/base/models/list_selection_model_unittest.cc +++ b/chromium/ui/base/models/list_selection_model_unittest.cc @@ -24,10 +24,14 @@ static std::string StateAsString(const ListSelectionModel& model) { " selection="; const ListSelectionModel::SelectedIndices& selection( model.selected_indices()); - for (size_t i = 0; i < selection.size(); ++i) { - if (i != 0) + bool first = true; + for (int index : selection) { + if (first) { + first = false; + } else { result += " "; - result += base::NumberToString(selection[i]); + } + result += base::NumberToString(index); } return result; } @@ -98,6 +102,18 @@ TEST_F(ListSelectionModelTest, AddIndexToSelected) { EXPECT_EQ("active=-1 anchor=-1 selection=2 4", StateAsString(model)); } +TEST_F(ListSelectionModelTest, AddIndexRangeToSelection) { + ListSelectionModel model; + model.AddIndexRangeToSelection(2, 3); + EXPECT_EQ("active=-1 anchor=-1 selection=2 3", StateAsString(model)); + + model.AddIndexRangeToSelection(4, 5); + EXPECT_EQ("active=-1 anchor=-1 selection=2 3 4 5", StateAsString(model)); + + model.AddIndexRangeToSelection(1, 1); + EXPECT_EQ("active=-1 anchor=-1 selection=1 2 3 4 5", StateAsString(model)); +} + TEST_F(ListSelectionModelTest, RemoveIndexFromSelection) { ListSelectionModel model; model.SetSelectedIndex(2); diff --git a/chromium/ui/base/models/menu_model.cc b/chromium/ui/base/models/menu_model.cc index 32070758287..d73c88e4152 100644 --- a/chromium/ui/base/models/menu_model.cc +++ b/chromium/ui/base/models/menu_model.cc @@ -68,6 +68,10 @@ ImageModel MenuModel::GetMinorIconAt(int index) const { return ImageModel(); } +bool MenuModel::MayHaveMnemonicsAt(int index) const { + return true; +} + const gfx::FontList* MenuModel::GetLabelFontListAt(int index) const { return nullptr; } diff --git a/chromium/ui/base/models/menu_model.h b/chromium/ui/base/models/menu_model.h index c746b37d627..bf7988cab13 100644 --- a/chromium/ui/base/models/menu_model.h +++ b/chromium/ui/base/models/menu_model.h @@ -84,6 +84,10 @@ class COMPONENT_EXPORT(UI_BASE) MenuModel // updated each time the menu is shown. virtual bool IsItemDynamicAt(int index) const = 0; + // Returns whether the menu item at the specified index has a user-set title, + // in which case it should always be treated as plain text. + virtual bool MayHaveMnemonicsAt(int index) const; + // Returns the font list used for the label at the specified index. // If NULL, then the default font list should be used. virtual const gfx::FontList* GetLabelFontListAt(int index) const; diff --git a/chromium/ui/base/models/simple_menu_model.cc b/chromium/ui/base/models/simple_menu_model.cc index 0c37f6e2cae..7db4ef95402 100644 --- a/chromium/ui/base/models/simple_menu_model.cc +++ b/chromium/ui/base/models/simple_menu_model.cc @@ -325,6 +325,11 @@ void SimpleMenuModel::SetIsNewFeatureAt(int index, bool is_new_feature) { items_[ValidateItemIndex(index)].is_new_feature = is_new_feature; } +void SimpleMenuModel::SetMayHaveMnemonicsAt(int index, + bool may_have_mnemonics) { + items_[ValidateItemIndex(index)].may_have_mnemonics = may_have_mnemonics; +} + void SimpleMenuModel::Clear() { items_.clear(); MenuItemsChanged(); @@ -452,6 +457,10 @@ bool SimpleMenuModel::IsNewFeatureAt(int index) const { return items_[ValidateItemIndex(index)].is_new_feature; } +bool SimpleMenuModel::MayHaveMnemonicsAt(int index) const { + return items_[ValidateItemIndex(index)].may_have_mnemonics; +} + void SimpleMenuModel::ActivatedAt(int index) { ActivatedAt(index, 0); } diff --git a/chromium/ui/base/models/simple_menu_model.h b/chromium/ui/base/models/simple_menu_model.h index 31669898f91..7cefe1d152e 100644 --- a/chromium/ui/base/models/simple_menu_model.h +++ b/chromium/ui/base/models/simple_menu_model.h @@ -169,6 +169,9 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel { // Sets whether the item at |index| is new. void SetIsNewFeatureAt(int index, bool is_new_feature); + // Sets whether the item at |index| is may have mnemonics. + void SetMayHaveMnemonicsAt(int index, bool may_have_mnemonics); + // Clears all items. Note that it does not free MenuModel of submenu. void Clear(); @@ -195,6 +198,7 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel { bool IsVisibleAt(int index) const override; bool IsAlertedAt(int index) const override; bool IsNewFeatureAt(int index) const override; + bool MayHaveMnemonicsAt(int index) const override; void ActivatedAt(int index) override; void ActivatedAt(int index, int event_flags) override; MenuModel* GetSubmenuModelAt(int index) const override; @@ -229,6 +233,7 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel { bool enabled = true; bool visible = true; bool is_new_feature = false; + bool may_have_mnemonics = true; }; typedef std::vector ItemVector; -- cgit v1.2.1