| Index: chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
|
| diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
|
| index 94732c0d02ea5cdebfef4dd08cdf11d99f8a05a3..486e308e03f624cd9a3e1f60c89a31570b161647 100644
|
| --- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
|
| +++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
|
| @@ -4,8 +4,6 @@
|
|
|
| #include "chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h"
|
|
|
| -#include <utility>
|
| -
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| #include "base/callback.h"
|
| @@ -63,6 +61,11 @@ autofill::ServerFieldType GetFieldTypeFromString(const std::string& type) {
|
| return autofill::UNKNOWN_TYPE;
|
| }
|
|
|
| +// size_t doesn't have a defined maximum value, so this is a trick to create one
|
| +// as is done for std::string::npos.
|
| +// http://www.cplusplus.com/reference/string/string/npos
|
| +const size_t kInvalidCountryIndex = static_cast<size_t>(-1);
|
| +
|
| } // namespace
|
|
|
| ShippingAddressEditorViewController::ShippingAddressEditorViewController(
|
| @@ -77,8 +80,9 @@ ShippingAddressEditorViewController::ShippingAddressEditorViewController(
|
| on_edited_(std::move(on_edited)),
|
| on_added_(std::move(on_added)),
|
| profile_to_edit_(profile),
|
| - chosen_country_index_(0),
|
| + chosen_country_index_(kInvalidCountryIndex),
|
| failed_to_load_region_data_(false) {
|
| + UpdateCountries(/*model=*/nullptr);
|
| UpdateEditorFields();
|
| }
|
|
|
| @@ -151,29 +155,28 @@ ShippingAddressEditorViewController::GetComboboxModelForType(
|
| model->SetCountries(*state()->GetPersonalDataManager(),
|
| base::Callback<bool(const std::string&)>(),
|
| state()->GetApplicationLocale());
|
| - country_codes_.clear();
|
| - for (size_t i = 0; i < model->countries().size(); ++i) {
|
| - if (model->countries()[i].get())
|
| - country_codes_.push_back(model->countries()[i]->country_code());
|
| - else
|
| - country_codes_.push_back(""); // Separator.
|
| - }
|
| + if (model->countries().size() != countries_.size())
|
| + UpdateCountries(model.get());
|
| return std::move(model);
|
| }
|
| case autofill::ADDRESS_HOME_STATE: {
|
| std::unique_ptr<autofill::RegionComboboxModel> model =
|
| base::MakeUnique<autofill::RegionComboboxModel>();
|
| - model->LoadRegionData(country_codes_[chosen_country_index_],
|
| - state()->GetRegionDataLoader(),
|
| - /*timeout_ms=*/5000);
|
| - if (!model->IsPendingRegionDataLoad()) {
|
| - // If the data was already pre-loaded, the observer won't get notified
|
| - // so we have to check for failure here.
|
| - failed_to_load_region_data_ = model->failed_to_load_data();
|
| - if (failed_to_load_region_data_) {
|
| - // We can update the view synchronously while building the view.
|
| - OnDataChanged(/*synchronous=*/false);
|
| + if (chosen_country_index_ < countries_.size()) {
|
| + model->LoadRegionData(countries_[chosen_country_index_].first,
|
| + state()->GetRegionDataLoader(),
|
| + /*timeout_ms=*/5000);
|
| + if (!model->IsPendingRegionDataLoad()) {
|
| + // If the data was already pre-loaded, the observer won't get notified
|
| + // so we have to check for failure here.
|
| + failed_to_load_region_data_ = model->failed_to_load_data();
|
| }
|
| + } else {
|
| + failed_to_load_region_data_ = true;
|
| + }
|
| + if (failed_to_load_region_data_) {
|
| + // We can't update the view synchronously while building the view.
|
| + OnDataChanged(/*synchronous=*/false);
|
| }
|
| return std::move(model);
|
| }
|
| @@ -201,14 +204,21 @@ void ShippingAddressEditorViewController::OnPerformAction(
|
|
|
| void ShippingAddressEditorViewController::UpdateEditorView() {
|
| EditorViewController::UpdateEditorView();
|
| - if (chosen_country_index_ > 0UL) {
|
| + if (chosen_country_index_ > 0UL &&
|
| + chosen_country_index_ < countries_.size()) {
|
| views::Combobox* country_combo_box = static_cast<views::Combobox*>(
|
| dialog()->GetViewByID(autofill::ADDRESS_HOME_COUNTRY));
|
| DCHECK(country_combo_box);
|
| + DCHECK_EQ(countries_.size(),
|
| + static_cast<size_t>(country_combo_box->GetRowCount()));
|
| country_combo_box->SetSelectedIndex(chosen_country_index_);
|
| + } else if (countries_.size() > 0UL) {
|
| + chosen_country_index_ = 0UL;
|
| + } else {
|
| + chosen_country_index_ = kInvalidCountryIndex;
|
| }
|
| // Ignore temporary profile once the editor view has been updated.
|
| - temporary_profile_.reset(nullptr);
|
| + temporary_profile_.reset();
|
| }
|
|
|
| base::string16 ShippingAddressEditorViewController::GetSheetTitle() {
|
| @@ -226,11 +236,62 @@ ShippingAddressEditorViewController::CreatePrimaryButton() {
|
| return button;
|
| }
|
|
|
| +void ShippingAddressEditorViewController::UpdateCountries(
|
| + autofill::CountryComboboxModel* model) {
|
| + autofill::CountryComboboxModel local_model;
|
| + if (!model) {
|
| + local_model.SetCountries(*state()->GetPersonalDataManager(),
|
| + base::Callback<bool(const std::string&)>(),
|
| + state()->GetApplicationLocale());
|
| + model = &local_model;
|
| + }
|
| +
|
| + for (size_t i = 0; i < model->countries().size(); ++i) {
|
| + autofill::AutofillCountry* country(model->countries()[i].get());
|
| + if (country) {
|
| + countries_.push_back(
|
| + std::make_pair(country->country_code(), country->name()));
|
| + } else {
|
| + // Separator, kept to make sure the size of the vector stays the same.
|
| + countries_.push_back(std::make_pair("", base::UTF8ToUTF16("")));
|
| + }
|
| + }
|
| + // If there is a profile to edit, make sure to use its country for the initial
|
| + // |chosen_country_index_|.
|
| + if (profile_to_edit_) {
|
| + autofill::AutofillType country_type(autofill::ADDRESS_HOME_COUNTRY);
|
| + base::string16 chosen_country(profile_to_edit_->GetInfo(
|
| + country_type, state()->GetApplicationLocale()));
|
| + for (chosen_country_index_ = 0; chosen_country_index_ < countries_.size();
|
| + ++chosen_country_index_) {
|
| + if (chosen_country == countries_[chosen_country_index_].second)
|
| + break;
|
| + }
|
| + // Make sure the the country was actually found in |countries_|, otherwise
|
| + // set |chosen_country_index_| as the default country at index 0.
|
| + if (chosen_country_index_ >= countries_.size()) {
|
| + // But only if there is at least one country.
|
| + if (countries_.size() > 0) {
|
| + LOG(ERROR) << "Unexpected country: " << chosen_country;
|
| + chosen_country_index_ = 0;
|
| + profile_to_edit_->SetInfo(country_type,
|
| + countries_[chosen_country_index_].second,
|
| + state()->GetApplicationLocale());
|
| + } else {
|
| + LOG(ERROR) << "Unexpected empty country list!";
|
| + chosen_country_index_ = kInvalidCountryIndex;
|
| + }
|
| + }
|
| + } else if (countries_.size() > 0) {
|
| + chosen_country_index_ = 0;
|
| + }
|
| +}
|
| +
|
| void ShippingAddressEditorViewController::UpdateEditorFields() {
|
| editor_fields_.clear();
|
| std::string chosen_country_code;
|
| - if (chosen_country_index_ < country_codes_.size())
|
| - chosen_country_code = country_codes_[chosen_country_index_];
|
| + if (chosen_country_index_ < countries_.size())
|
| + chosen_country_code = countries_[chosen_country_index_].first;
|
|
|
| std::unique_ptr<base::ListValue> components(new base::ListValue);
|
| std::string unused;
|
| @@ -323,6 +384,25 @@ bool ShippingAddressEditorViewController::SaveFieldsToProfile(
|
| autofill::AutofillProfile* profile,
|
| bool ignore_errors) {
|
| const std::string& locale = state()->GetApplicationLocale();
|
| + // The country must be set first, because the profile uses the country to
|
| + // interpret some of the data (e.g., phone numbers) passed to SetInfo.
|
| + views::Combobox* combobox = static_cast<views::Combobox*>(
|
| + dialog()->GetViewByID(autofill::ADDRESS_HOME_COUNTRY));
|
| + // The combobox can be null when saving to temporary profile while updating
|
| + // the view.
|
| + if (combobox) {
|
| + base::string16 country(combobox->GetTextForRow(combobox->selected_index()));
|
| + bool success =
|
| + profile->SetInfo(autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY),
|
| + country, locale);
|
| + LOG_IF(ERROR, !success && !ignore_errors)
|
| + << "Can't set profile country to: " << country;
|
| + if (!success && !ignore_errors)
|
| + return false;
|
| + } else {
|
| + DCHECK_EQ(temporary_profile_.get(), profile);
|
| + }
|
| +
|
| bool success = true;
|
| for (const auto& field : text_fields()) {
|
| // Force a blur in case the value was left untouched.
|
| @@ -342,19 +422,15 @@ bool ShippingAddressEditorViewController::SaveFieldsToProfile(
|
| for (const auto& field : comboboxes()) {
|
| // ValidatingCombobox* is the key, EditorField is the value.
|
| ValidatingCombobox* combobox = field.first;
|
| + // The country has already been dealt with.
|
| + if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY)
|
| + continue;
|
| if (combobox->invalid()) {
|
| success = false;
|
| } else {
|
| - if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY) {
|
| - success = profile->SetInfo(
|
| - autofill::AutofillType(field.second.type),
|
| - base::UTF8ToUTF16(country_codes_[combobox->selected_index()]),
|
| - locale);
|
| - } else {
|
| - success = profile->SetInfo(
|
| - autofill::AutofillType(field.second.type),
|
| - combobox->GetTextForRow(combobox->selected_index()), locale);
|
| - }
|
| + success = profile->SetInfo(
|
| + autofill::AutofillType(field.second.type),
|
| + combobox->GetTextForRow(combobox->selected_index()), locale);
|
| }
|
| LOG_IF(ERROR, !success && !ignore_errors)
|
| << "Can't setinfo(" << field.second.type << ", "
|
| @@ -414,9 +490,10 @@ bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate::
|
| ValidateValue(const base::string16& value) {
|
| if (!value.empty()) {
|
| if (field_.type == autofill::PHONE_HOME_WHOLE_NUMBER &&
|
| + controller_->chosen_country_index_ < controller_->countries_.size() &&
|
| !autofill::IsValidPhoneNumber(
|
| - value,
|
| - controller_->country_codes_[controller_->chosen_country_index_])) {
|
| + value, controller_->countries_[controller_->chosen_country_index_]
|
| + .first)) {
|
| controller_->DisplayErrorMessageForField(
|
| field_, l10n_util::GetStringUTF16(
|
| IDS_PAYMENTS_PHONE_INVALID_VALIDATION_MESSAGE));
|
|
|