Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2363)

Unified Diff: chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc

Issue 2883333003: Payment request shipping address editor now properly handles countries (Closed)
Patch Set: Final nits Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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));

Powered by Google App Engine
This is Rietveld 408576698