OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/payments/shipping_address_editor_view_controll er.h" | 5 #include "chrome/browser/ui/views/payments/shipping_address_editor_view_controll er.h" |
6 | 6 |
7 #include <utility> | |
8 | |
9 #include "base/bind.h" | 7 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
11 #include "base/callback.h" | 9 #include "base/callback.h" |
12 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
13 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
14 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" |
15 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" | 13 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" |
16 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" | 14 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" |
17 #include "chrome/browser/ui/views/payments/validating_combobox.h" | 15 #include "chrome/browser/ui/views/payments/validating_combobox.h" |
18 #include "chrome/browser/ui/views/payments/validating_textfield.h" | 16 #include "chrome/browser/ui/views/payments/validating_textfield.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 BackNavigationType back_navigation_type, | 70 BackNavigationType back_navigation_type, |
73 base::OnceClosure on_edited, | 71 base::OnceClosure on_edited, |
74 base::OnceCallback<void(const autofill::AutofillProfile&)> on_added, | 72 base::OnceCallback<void(const autofill::AutofillProfile&)> on_added, |
75 autofill::AutofillProfile* profile) | 73 autofill::AutofillProfile* profile) |
76 : EditorViewController(spec, state, dialog, back_navigation_type), | 74 : EditorViewController(spec, state, dialog, back_navigation_type), |
77 on_edited_(std::move(on_edited)), | 75 on_edited_(std::move(on_edited)), |
78 on_added_(std::move(on_added)), | 76 on_added_(std::move(on_added)), |
79 profile_to_edit_(profile), | 77 profile_to_edit_(profile), |
80 chosen_country_index_(0), | 78 chosen_country_index_(0), |
81 failed_to_load_region_data_(false) { | 79 failed_to_load_region_data_(false) { |
80 autofill::CountryComboboxModel model; | |
Mathieu
2017/05/16 20:10:06
I would put lines 80-112 inside a private function
MAD
2017/05/17 12:38:11
Done.
| |
81 model.SetCountries(*state->GetPersonalDataManager(), | |
82 base::Callback<bool(const std::string&)>(), | |
83 state->GetApplicationLocale()); | |
84 for (size_t i = 0; i < model.countries().size(); ++i) { | |
85 autofill::AutofillCountry* country(model.countries()[i].get()); | |
86 if (country) { | |
87 countries_.push_back( | |
88 std::make_pair(country->country_code(), country->name())); | |
89 } else { | |
90 // Separator. | |
91 countries_.push_back(std::make_pair("", base::UTF8ToUTF16(""))); | |
92 } | |
93 } | |
94 // If there is a profile to edit, make sure to use its country for the initial | |
95 // |chosen_country_index_|. | |
96 if (profile_to_edit_) { | |
97 autofill::AutofillType country_type(autofill::ADDRESS_HOME_COUNTRY); | |
98 base::string16 chosen_country( | |
99 profile_to_edit_->GetInfo(country_type, state->GetApplicationLocale())); | |
100 for (chosen_country_index_ = 0; chosen_country_index_ < countries_.size(); | |
101 ++chosen_country_index_) { | |
102 if (chosen_country == countries_[chosen_country_index_].second) | |
103 break; | |
104 } | |
105 if (chosen_country_index_ >= countries_.size()) { | |
106 LOG(ERROR) << "Unexpected country: " << chosen_country; | |
107 CHECK_GT(countries_.size(), 0); | |
Mathieu
2017/05/16 20:10:06
could this ever happen in the wild? Crashing is pr
MAD
2017/05/17 12:38:10
It would crash below otherwise...
But now that y
| |
108 chosen_country_index_ = 0; | |
109 profile_to_edit_->SetInfo(country_type, | |
110 countries_[chosen_country_index_].second, | |
111 state->GetApplicationLocale()); | |
112 } | |
113 } | |
82 UpdateEditorFields(); | 114 UpdateEditorFields(); |
83 } | 115 } |
84 | 116 |
85 ShippingAddressEditorViewController::~ShippingAddressEditorViewController() {} | 117 ShippingAddressEditorViewController::~ShippingAddressEditorViewController() {} |
86 | 118 |
87 std::vector<EditorField> | 119 std::vector<EditorField> |
88 ShippingAddressEditorViewController::GetFieldDefinitions() { | 120 ShippingAddressEditorViewController::GetFieldDefinitions() { |
89 return editor_fields_; | 121 return editor_fields_; |
90 } | 122 } |
91 | 123 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 std::unique_ptr<ui::ComboboxModel> | 176 std::unique_ptr<ui::ComboboxModel> |
145 ShippingAddressEditorViewController::GetComboboxModelForType( | 177 ShippingAddressEditorViewController::GetComboboxModelForType( |
146 const autofill::ServerFieldType& type) { | 178 const autofill::ServerFieldType& type) { |
147 switch (type) { | 179 switch (type) { |
148 case autofill::ADDRESS_HOME_COUNTRY: { | 180 case autofill::ADDRESS_HOME_COUNTRY: { |
149 std::unique_ptr<autofill::CountryComboboxModel> model = | 181 std::unique_ptr<autofill::CountryComboboxModel> model = |
150 base::MakeUnique<autofill::CountryComboboxModel>(); | 182 base::MakeUnique<autofill::CountryComboboxModel>(); |
151 model->SetCountries(*state()->GetPersonalDataManager(), | 183 model->SetCountries(*state()->GetPersonalDataManager(), |
152 base::Callback<bool(const std::string&)>(), | 184 base::Callback<bool(const std::string&)>(), |
153 state()->GetApplicationLocale()); | 185 state()->GetApplicationLocale()); |
154 country_codes_.clear(); | |
155 for (size_t i = 0; i < model->countries().size(); ++i) { | |
156 if (model->countries()[i].get()) | |
157 country_codes_.push_back(model->countries()[i]->country_code()); | |
158 else | |
159 country_codes_.push_back(""); // Separator. | |
160 } | |
161 return std::move(model); | 186 return std::move(model); |
162 } | 187 } |
163 case autofill::ADDRESS_HOME_STATE: { | 188 case autofill::ADDRESS_HOME_STATE: { |
164 std::unique_ptr<autofill::RegionComboboxModel> model = | 189 std::unique_ptr<autofill::RegionComboboxModel> model = |
165 base::MakeUnique<autofill::RegionComboboxModel>(); | 190 base::MakeUnique<autofill::RegionComboboxModel>(); |
166 model->LoadRegionData(country_codes_[chosen_country_index_], | 191 model->LoadRegionData(countries_[chosen_country_index_].first, |
167 state()->GetRegionDataLoader(), | 192 state()->GetRegionDataLoader(), |
168 /*timeout_ms=*/5000); | 193 /*timeout_ms=*/5000); |
169 if (!model->IsPendingRegionDataLoad()) { | 194 if (!model->IsPendingRegionDataLoad()) { |
170 // If the data was already pre-loaded, the observer won't get notified | 195 // If the data was already pre-loaded, the observer won't get notified |
171 // so we have to check for failure here. | 196 // so we have to check for failure here. |
172 failed_to_load_region_data_ = model->failed_to_load_data(); | 197 failed_to_load_region_data_ = model->failed_to_load_data(); |
173 if (failed_to_load_region_data_) { | 198 if (failed_to_load_region_data_) { |
174 // We can update the view synchronously while building the view. | 199 // We can't update the view synchronously while building the view. |
175 OnDataChanged(/*synchronous=*/false); | 200 OnDataChanged(/*synchronous=*/false); |
176 } | 201 } |
177 } | 202 } |
178 return std::move(model); | 203 return std::move(model); |
179 } | 204 } |
180 default: | 205 default: |
181 NOTREACHED(); | 206 NOTREACHED(); |
182 break; | 207 break; |
183 } | 208 } |
184 return std::unique_ptr<ui::ComboboxModel>(); | 209 return std::unique_ptr<ui::ComboboxModel>(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 ShippingAddressEditorViewController::CreatePrimaryButton() { | 247 ShippingAddressEditorViewController::CreatePrimaryButton() { |
223 std::unique_ptr<views::Button> button( | 248 std::unique_ptr<views::Button> button( |
224 EditorViewController::CreatePrimaryButton()); | 249 EditorViewController::CreatePrimaryButton()); |
225 button->set_id(static_cast<int>(DialogViewID::SAVE_ADDRESS_BUTTON)); | 250 button->set_id(static_cast<int>(DialogViewID::SAVE_ADDRESS_BUTTON)); |
226 return button; | 251 return button; |
227 } | 252 } |
228 | 253 |
229 void ShippingAddressEditorViewController::UpdateEditorFields() { | 254 void ShippingAddressEditorViewController::UpdateEditorFields() { |
230 editor_fields_.clear(); | 255 editor_fields_.clear(); |
231 std::string chosen_country_code; | 256 std::string chosen_country_code; |
232 if (chosen_country_index_ < country_codes_.size()) | 257 if (chosen_country_index_ < countries_.size()) |
233 chosen_country_code = country_codes_[chosen_country_index_]; | 258 chosen_country_code = countries_[chosen_country_index_].first; |
234 | 259 |
235 std::unique_ptr<base::ListValue> components(new base::ListValue); | 260 std::unique_ptr<base::ListValue> components(new base::ListValue); |
236 std::string unused; | 261 std::string unused; |
237 autofill::GetAddressComponents(chosen_country_code, | 262 autofill::GetAddressComponents(chosen_country_code, |
238 state()->GetApplicationLocale(), | 263 state()->GetApplicationLocale(), |
239 components.get(), &unused); | 264 components.get(), &unused); |
240 for (size_t line_index = 0; line_index < components->GetSize(); | 265 for (size_t line_index = 0; line_index < components->GetSize(); |
241 ++line_index) { | 266 ++line_index) { |
242 const base::ListValue* line = nullptr; | 267 const base::ListValue* line = nullptr; |
243 if (!components->GetList(line_index, &line)) { | 268 if (!components->GetList(line_index, &line)) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 FROM_HERE, | 341 FROM_HERE, |
317 base::BindOnce(&ShippingAddressEditorViewController::UpdateEditorView, | 342 base::BindOnce(&ShippingAddressEditorViewController::UpdateEditorView, |
318 base::Unretained(this))); | 343 base::Unretained(this))); |
319 } | 344 } |
320 } | 345 } |
321 | 346 |
322 bool ShippingAddressEditorViewController::SaveFieldsToProfile( | 347 bool ShippingAddressEditorViewController::SaveFieldsToProfile( |
323 autofill::AutofillProfile* profile, | 348 autofill::AutofillProfile* profile, |
324 bool ignore_errors) { | 349 bool ignore_errors) { |
325 const std::string& locale = state()->GetApplicationLocale(); | 350 const std::string& locale = state()->GetApplicationLocale(); |
351 // The country must be set first, because the profile uses the country to | |
352 // interpret some of the data (e.g., phone numbers) passed to SetInfo. | |
353 views::Combobox* combobox = static_cast<views::Combobox*>( | |
354 dialog()->GetViewByID(autofill::ADDRESS_HOME_COUNTRY)); | |
355 // The combobox can be null when saving to temporary profile while updating | |
356 // the view. | |
357 if (combobox) { | |
358 base::string16 country(combobox->GetTextForRow(combobox->selected_index())); | |
359 bool success = | |
360 profile->SetInfo(autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY), | |
361 country, locale); | |
362 LOG_IF(ERROR, !success && !ignore_errors) | |
363 << "Can't set profile country to: " << country; | |
364 if (!success && !ignore_errors) | |
365 return false; | |
366 } else { | |
367 DCHECK_EQ(temporary_profile_.get(), profile); | |
368 } | |
369 | |
326 bool success = true; | 370 bool success = true; |
327 for (const auto& field : text_fields()) { | 371 for (const auto& field : text_fields()) { |
328 // Force a blur in case the value was left untouched. | 372 // Force a blur in case the value was left untouched. |
329 field.first->OnBlur(); | 373 field.first->OnBlur(); |
330 // ValidatingTextfield* is the key, EditorField is the value. | 374 // ValidatingTextfield* is the key, EditorField is the value. |
331 if (field.first->invalid()) { | 375 if (field.first->invalid()) { |
332 success = false; | 376 success = false; |
333 } else { | 377 } else { |
334 success = profile->SetInfo(autofill::AutofillType(field.second.type), | 378 success = profile->SetInfo(autofill::AutofillType(field.second.type), |
335 field.first->text(), locale); | 379 field.first->text(), locale); |
336 } | 380 } |
337 LOG_IF(ERROR, !success && !ignore_errors) | 381 LOG_IF(ERROR, !success && !ignore_errors) |
338 << "Can't setinfo(" << field.second.type << ", " << field.first->text(); | 382 << "Can't setinfo(" << field.second.type << ", " << field.first->text(); |
339 if (!success && !ignore_errors) | 383 if (!success && !ignore_errors) |
340 return false; | 384 return false; |
341 } | 385 } |
342 for (const auto& field : comboboxes()) { | 386 for (const auto& field : comboboxes()) { |
343 // ValidatingCombobox* is the key, EditorField is the value. | 387 // ValidatingCombobox* is the key, EditorField is the value. |
344 ValidatingCombobox* combobox = field.first; | 388 ValidatingCombobox* combobox = field.first; |
389 // The country has already been dealt with. | |
390 if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY) | |
391 continue; | |
345 if (combobox->invalid()) { | 392 if (combobox->invalid()) { |
346 success = false; | 393 success = false; |
347 } else { | 394 } else { |
348 if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY) { | 395 success = profile->SetInfo( |
349 success = profile->SetInfo( | 396 autofill::AutofillType(field.second.type), |
350 autofill::AutofillType(field.second.type), | 397 combobox->GetTextForRow(combobox->selected_index()), locale); |
351 base::UTF8ToUTF16(country_codes_[combobox->selected_index()]), | |
352 locale); | |
353 } else { | |
354 success = profile->SetInfo( | |
355 autofill::AutofillType(field.second.type), | |
356 combobox->GetTextForRow(combobox->selected_index()), locale); | |
357 } | |
358 } | 398 } |
359 LOG_IF(ERROR, !success && !ignore_errors) | 399 LOG_IF(ERROR, !success && !ignore_errors) |
360 << "Can't setinfo(" << field.second.type << ", " | 400 << "Can't setinfo(" << field.second.type << ", " |
361 << combobox->GetTextForRow(combobox->selected_index()); | 401 << combobox->GetTextForRow(combobox->selected_index()); |
362 if (!success && !ignore_errors) | 402 if (!success && !ignore_errors) |
363 return false; | 403 return false; |
364 } | 404 } |
365 return success; | 405 return success; |
366 } | 406 } |
367 | 407 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 void ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: | 448 void ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: |
409 ComboboxModelChanged(views::Combobox* combobox) { | 449 ComboboxModelChanged(views::Combobox* combobox) { |
410 controller_->OnComboboxModelChanged(combobox); | 450 controller_->OnComboboxModelChanged(combobox); |
411 } | 451 } |
412 | 452 |
413 bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: | 453 bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: |
414 ValidateValue(const base::string16& value) { | 454 ValidateValue(const base::string16& value) { |
415 if (!value.empty()) { | 455 if (!value.empty()) { |
416 if (field_.type == autofill::PHONE_HOME_WHOLE_NUMBER && | 456 if (field_.type == autofill::PHONE_HOME_WHOLE_NUMBER && |
417 !autofill::IsValidPhoneNumber( | 457 !autofill::IsValidPhoneNumber( |
418 value, | 458 value, controller_->countries_[controller_->chosen_country_index_] |
419 controller_->country_codes_[controller_->chosen_country_index_])) { | 459 .first)) { |
420 controller_->DisplayErrorMessageForField( | 460 controller_->DisplayErrorMessageForField( |
421 field_, l10n_util::GetStringUTF16( | 461 field_, l10n_util::GetStringUTF16( |
422 IDS_PAYMENTS_PHONE_INVALID_VALIDATION_MESSAGE)); | 462 IDS_PAYMENTS_PHONE_INVALID_VALIDATION_MESSAGE)); |
423 return false; | 463 return false; |
424 } | 464 } |
425 // As long as other field types are non-empty, they are valid. | 465 // As long as other field types are non-empty, they are valid. |
426 controller_->DisplayErrorMessageForField(field_, base::ASCIIToUTF16("")); | 466 controller_->DisplayErrorMessageForField(field_, base::ASCIIToUTF16("")); |
427 return true; | 467 return true; |
428 } | 468 } |
429 bool is_required_valid = !field_.required; | 469 bool is_required_valid = !field_.required; |
430 const base::string16 displayed_message = | 470 const base::string16 displayed_message = |
431 is_required_valid ? base::ASCIIToUTF16("") | 471 is_required_valid ? base::ASCIIToUTF16("") |
432 : l10n_util::GetStringUTF16( | 472 : l10n_util::GetStringUTF16( |
433 IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE); | 473 IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE); |
434 controller_->DisplayErrorMessageForField(field_, displayed_message); | 474 controller_->DisplayErrorMessageForField(field_, displayed_message); |
435 return is_required_valid; | 475 return is_required_valid; |
436 } | 476 } |
437 | 477 |
438 } // namespace payments | 478 } // namespace payments |
OLD | NEW |