1 // Copyright 2020 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 "ui/base/models/dialog_model.h"
6
7 #include "base/callback_helpers.h"
8 #include "base/ranges/algorithm.h"
9
10 namespace ui {
11
Builder(std::unique_ptr<DialogModelDelegate> delegate)12 DialogModel::Builder::Builder(std::unique_ptr<DialogModelDelegate> delegate)
13 : model_(std::make_unique<DialogModel>(util::PassKey<Builder>(),
14 std::move(delegate))) {}
15
Builder()16 DialogModel::Builder::Builder() : Builder(nullptr) {}
17
~Builder()18 DialogModel::Builder::~Builder() {
19 DCHECK(!model_) << "Model should've been built.";
20 }
21
Build()22 std::unique_ptr<DialogModel> DialogModel::Builder::Build() {
23 DCHECK(model_);
24 return std::move(model_);
25 }
26
AddOkButton(base::OnceClosure callback,base::string16 label,const DialogModelButton::Params & params)27 DialogModel::Builder& DialogModel::Builder::AddOkButton(
28 base::OnceClosure callback,
29 base::string16 label,
30 const DialogModelButton::Params& params) {
31 DCHECK(!model_->accept_callback_);
32 model_->accept_callback_ = std::move(callback);
33 // NOTREACHED() is used below to make sure this callback isn't used.
34 // DialogModelHost should be using OnDialogAccepted() instead.
35 model_->ok_button_.emplace(
36 model_->GetPassKey(), model_.get(),
37 base::BindRepeating([](const Event&) { NOTREACHED(); }), std::move(label),
38 params);
39
40 return *this;
41 }
42
AddCancelButton(base::OnceClosure callback,base::string16 label,const DialogModelButton::Params & params)43 DialogModel::Builder& DialogModel::Builder::AddCancelButton(
44 base::OnceClosure callback,
45 base::string16 label,
46 const DialogModelButton::Params& params) {
47 DCHECK(!model_->cancel_callback_);
48 model_->cancel_callback_ = std::move(callback);
49 // NOTREACHED() is used below to make sure this callback isn't used.
50 // DialogModelHost should be using OnDialogCanceled() instead.
51 model_->cancel_button_.emplace(
52 model_->GetPassKey(), model_.get(),
53 base::BindRepeating([](const Event&) { NOTREACHED(); }), std::move(label),
54 params);
55
56 return *this;
57 }
58
AddDialogExtraButton(base::RepeatingCallback<void (const Event &)> callback,base::string16 label,const DialogModelButton::Params & params)59 DialogModel::Builder& DialogModel::Builder::AddDialogExtraButton(
60 base::RepeatingCallback<void(const Event&)> callback,
61 base::string16 label,
62 const DialogModelButton::Params& params) {
63 model_->extra_button_.emplace(model_->GetPassKey(), model_.get(),
64 std::move(callback), std::move(label), params);
65 return *this;
66 }
67
SetInitiallyFocusedField(int unique_id)68 DialogModel::Builder& DialogModel::Builder::SetInitiallyFocusedField(
69 int unique_id) {
70 // This must be called with unique_id >= 0 (-1 is "no ID").
71 DCHECK_GE(unique_id, 0);
72 // This can only be called once.
73 DCHECK(!model_->initially_focused_field_);
74 model_->initially_focused_field_ = unique_id;
75 return *this;
76 }
77
DialogModel(util::PassKey<Builder>,std::unique_ptr<DialogModelDelegate> delegate)78 DialogModel::DialogModel(util::PassKey<Builder>,
79 std::unique_ptr<DialogModelDelegate> delegate)
80 : delegate_(std::move(delegate)) {
81 if (delegate_)
82 delegate_->set_dialog_model(this);
83 }
84
85 DialogModel::~DialogModel() = default;
86
AddBodyText(const DialogModelLabel & label)87 void DialogModel::AddBodyText(const DialogModelLabel& label) {
88 AddField(std::make_unique<DialogModelBodyText>(GetPassKey(), this, label));
89 }
90
AddCheckbox(int unique_id,const DialogModelLabel & label)91 void DialogModel::AddCheckbox(int unique_id, const DialogModelLabel& label) {
92 AddField(std::make_unique<DialogModelCheckbox>(GetPassKey(), this, unique_id,
93 label));
94 }
95
AddCombobox(base::string16 label,std::unique_ptr<ui::ComboboxModel> combobox_model,const DialogModelCombobox::Params & params)96 void DialogModel::AddCombobox(base::string16 label,
97 std::unique_ptr<ui::ComboboxModel> combobox_model,
98 const DialogModelCombobox::Params& params) {
99 AddField(std::make_unique<DialogModelCombobox>(
100 GetPassKey(), this, std::move(label), std::move(combobox_model), params));
101 }
102
AddTextfield(base::string16 label,base::string16 text,const DialogModelTextfield::Params & params)103 void DialogModel::AddTextfield(base::string16 label,
104 base::string16 text,
105 const DialogModelTextfield::Params& params) {
106 AddField(std::make_unique<DialogModelTextfield>(
107 GetPassKey(), this, std::move(label), std::move(text), params));
108 }
109
HasField(int unique_id) const110 bool DialogModel::HasField(int unique_id) const {
111 return base::ranges::any_of(fields_, [unique_id](auto& field) {
112 return field->unique_id_ == unique_id;
113 });
114 }
115
GetFieldByUniqueId(int unique_id)116 DialogModelField* DialogModel::GetFieldByUniqueId(int unique_id) {
117 for (auto& field : fields_) {
118 if (field->unique_id_ == unique_id)
119 return field.get();
120 }
121 NOTREACHED();
122 return nullptr;
123 }
124
GetCheckboxByUniqueId(int unique_id)125 DialogModelCheckbox* DialogModel::GetCheckboxByUniqueId(int unique_id) {
126 return GetFieldByUniqueId(unique_id)->AsCheckbox();
127 }
128
GetComboboxByUniqueId(int unique_id)129 DialogModelCombobox* DialogModel::GetComboboxByUniqueId(int unique_id) {
130 return GetFieldByUniqueId(unique_id)->AsCombobox();
131 }
132
GetTextfieldByUniqueId(int unique_id)133 DialogModelTextfield* DialogModel::GetTextfieldByUniqueId(int unique_id) {
134 return GetFieldByUniqueId(unique_id)->AsTextfield();
135 }
136
OnDialogAccepted(util::PassKey<DialogModelHost>)137 void DialogModel::OnDialogAccepted(util::PassKey<DialogModelHost>) {
138 if (accept_callback_)
139 std::move(accept_callback_).Run();
140 }
141
OnDialogCancelled(util::PassKey<DialogModelHost>)142 void DialogModel::OnDialogCancelled(util::PassKey<DialogModelHost>) {
143 if (cancel_callback_)
144 std::move(cancel_callback_).Run();
145 }
146
OnDialogClosed(util::PassKey<DialogModelHost>)147 void DialogModel::OnDialogClosed(util::PassKey<DialogModelHost>) {
148 if (close_callback_)
149 std::move(close_callback_).Run();
150 }
151
OnWindowClosing(util::PassKey<DialogModelHost>)152 void DialogModel::OnWindowClosing(util::PassKey<DialogModelHost>) {
153 if (window_closing_callback_)
154 std::move(window_closing_callback_).Run();
155 }
156
AddField(std::unique_ptr<DialogModelField> field)157 void DialogModel::AddField(std::unique_ptr<DialogModelField> field) {
158 fields_.push_back(std::move(field));
159 if (host_)
160 host_->OnFieldAdded(fields_.back().get());
161 }
162
163 } // namespace ui