Index: chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
index 05b1c243f25f596af7249c08fb4506d0f19e4610..3e931396cf6385408d7a53a86e602ae2d77baf82 100644 |
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
@@ -604,21 +604,10 @@ void AutofillDialogControllerImpl::Show() { |
AutofillMetrics::SECURITY_METRIC_CROSS_ORIGIN_FRAME); |
} |
- // TODO(dbeam): use GetManager()->GetDefaultCountryCodeForNewAddress() |
- // instead when the country combobox is visible. http://crbug.com/331544 |
- std::string country_code = "US"; |
- common::BuildInputsForSection(SECTION_CC, |
- country_code, |
- &requested_cc_fields_); |
- common::BuildInputsForSection(SECTION_BILLING, |
- country_code, |
- &requested_billing_fields_); |
- common::BuildInputsForSection(SECTION_CC_BILLING, |
- country_code, |
- &requested_cc_billing_fields_); |
- common::BuildInputsForSection(SECTION_SHIPPING, |
- country_code, |
- &requested_shipping_fields_); |
+ // TODO(dbeam): does SECTION_CC need to be internationalized? |
Evan Stade
2014/01/15 23:12:29
I don't think so. I think you can leave out this T
Dan Beam
2014/01/16 01:39:13
Done.
|
+ common::BuildInputsForSection(SECTION_CC, "US", &requested_cc_fields_); |
Evan Stade
2014/01/15 23:12:29
pass an empty country code to make it clear it's n
Dan Beam
2014/01/16 01:39:13
Done.
|
+ OnComboboxModelChanged(&billing_country_combobox_model_); |
+ OnComboboxModelChanged(&shipping_country_combobox_model_); |
// Test whether we need to show the shipping section. If filling that section |
// would be a no-op, don't show it. |
@@ -643,7 +632,10 @@ void AutofillDialogControllerImpl::Show() { |
SubmitButtonDelayBegin(); |
view_.reset(CreateView()); |
view_->Show(); |
+ |
GetManager()->AddObserver(this); |
+ billing_country_combobox_model_.AddObserver(this); |
+ shipping_country_combobox_model_.AddObserver(this); |
if (!account_chooser_model_->WalletIsSelected()) |
LogDialogLatencyToShow(); |
@@ -1098,8 +1090,6 @@ void AutofillDialogControllerImpl::ConstructLegalDocumentsText() { |
} |
void AutofillDialogControllerImpl::ResetSectionInput(DialogSection section) { |
- SetEditingExistingData(section, false); |
- |
DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
for (DetailInputs::iterator it = inputs->begin(); it != inputs->end(); ++it) { |
it->initial_value = common::GetHardcodedValueForType(it->type); |
@@ -1170,6 +1160,20 @@ void AutofillDialogControllerImpl::RestoreUserInputFromSnapshot( |
if (snapshot.empty()) |
return; |
+ FieldValueMap::const_iterator it = snapshot.find(ADDRESS_BILLING_COUNTRY); |
+ if (it != snapshot.end()) { |
+ billing_country_combobox_model_.SetDefaultCountry( |
+ AutofillCountry::GetCountryCode( |
+ it->second, g_browser_process->GetApplicationLocale())); |
+ } |
+ |
+ FieldValueMap::const_iterator ship_it = snapshot.find(ADDRESS_HOME_COUNTRY); |
+ if (ship_it != snapshot.end()) { |
+ shipping_country_combobox_model_.SetDefaultCountry( |
+ AutofillCountry::GetCountryCode( |
+ ship_it->second, g_browser_process->GetApplicationLocale())); |
+ } |
+ |
FieldMapWrapper wrapper(snapshot); |
for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
DialogSection section = static_cast<DialogSection>(i); |
@@ -1303,9 +1307,11 @@ ui::ComboboxModel* AutofillDialogControllerImpl::ComboboxModelForAutofillType( |
case CREDIT_CARD_EXP_4_DIGIT_YEAR: |
return &cc_exp_year_combobox_model_; |
- case ADDRESS_HOME_COUNTRY: |
case ADDRESS_BILLING_COUNTRY: |
- return &country_combobox_model_; |
+ return &billing_country_combobox_model_; |
+ |
+ case ADDRESS_HOME_COUNTRY: |
+ return &shipping_country_combobox_model_; |
default: |
return NULL; |
@@ -1699,23 +1705,29 @@ base::string16 AutofillDialogControllerImpl::InputValidityMessage( |
return base::string16(); // Line 2 is optional - always valid. |
case ADDRESS_HOME_CITY: |
+ case ADDRESS_HOME_DEPENDENT_LOCALITY: |
case ADDRESS_HOME_COUNTRY: |
break; |
case ADDRESS_HOME_STATE: |
- if (!value.empty() && !autofill::IsValidState(value)) { |
+ if (!value.empty() && !autofill::IsValidState(value) && |
+ CountryCodeForSection(section) == "US") { |
return l10n_util::GetStringUTF16( |
IDS_AUTOFILL_DIALOG_VALIDATION_INVALID_REGION); |
} |
break; |
case ADDRESS_HOME_ZIP: |
- if (!value.empty() && !autofill::IsValidZip(value)) { |
+ if (!value.empty() && !autofill::IsValidZip(value) && |
+ CountryCodeForSection(section) == "US") { |
return l10n_util::GetStringUTF16( |
IDS_AUTOFILL_DIALOG_VALIDATION_INVALID_ZIP_CODE); |
} |
break; |
+ case ADDRESS_HOME_SORTING_CODE: |
+ break; |
+ |
case NAME_FULL: |
// Wallet requires a first and last billing name. |
if (section == SECTION_CC_BILLING && !value.empty() && |
@@ -1747,18 +1759,18 @@ ValidityMessages AutofillDialogControllerImpl::InputsAreValid( |
DialogSection section, |
const FieldValueMap& inputs) { |
ValidityMessages messages; |
- std::map<ServerFieldType, base::string16> field_values; |
+ FieldValueMap field_values; |
for (FieldValueMap::const_iterator iter = inputs.begin(); |
iter != inputs.end(); ++iter) { |
const ServerFieldType type = iter->first; |
base::string16 text = InputValidityMessage(section, type, iter->second); |
- // Skip empty/unchanged fields in edit mode. Ignore country code as it |
- // always has a value. If the individual field does not have validation |
- // errors, assume it to be valid unless later proven otherwise. |
+ // Skip empty/unchanged fields in edit mode. Ignore country as it always has |
+ // a value. If the individual field does not have validation errors, assume |
+ // it to be valid unless later proven otherwise. |
bool sure = InputWasEdited(type, iter->second) || |
- ComboboxModelForAutofillType(type) == &country_combobox_model_; |
+ AutofillType(type).GetStorableType() == ADDRESS_HOME_COUNTRY; |
// Consider only individually valid fields for inter-field validation. |
if (text.empty()) { |
@@ -1853,6 +1865,20 @@ void AutofillDialogControllerImpl::UserEditedOrActivatedInput( |
const gfx::Rect& content_bounds, |
const base::string16& field_contents, |
bool was_edit) { |
+ ScopedViewUpdates updates(view_.get()); |
+ |
+ if (type == ADDRESS_BILLING_COUNTRY || type == ADDRESS_HOME_COUNTRY) { |
+ FieldValueMap snapshot = TakeUserInputSnapshot(); |
+ snapshot[type] = field_contents; |
+ RestoreUserInputFromSnapshot(snapshot); |
+ const bool is_billing = type == ADDRESS_BILLING_COUNTRY; |
+ UpdateSection(is_billing ? ActiveBillingSection() : SECTION_SHIPPING); |
+ } |
+ |
+ // The rest of this method applies only to textfields. If a combobox, bail. |
+ if (ComboboxModelForAutofillType(type)) |
+ return; |
+ |
// If the field is edited down to empty, don't show a popup. |
if (was_edit && field_contents.empty()) { |
HidePopup(); |
@@ -1931,6 +1957,8 @@ bool AutofillDialogControllerImpl::ShouldShowErrorBubble() const { |
void AutofillDialogControllerImpl::ViewClosed() { |
GetManager()->RemoveObserver(this); |
Evan Stade
2014/01/15 23:12:29
why is this here and not in the destructor?
why a
Dan Beam
2014/01/16 01:39:13
Done.
|
+ billing_country_combobox_model_.RemoveObserver(this); |
+ shipping_country_combobox_model_.RemoveObserver(this); |
// Called from here rather than in ~AutofillDialogControllerImpl as this |
// relies on virtual methods that change to their base class in the dtor. |
@@ -2158,6 +2186,35 @@ void AutofillDialogControllerImpl::DidAcceptSuggestion( |
pair.second)); |
} |
+ if (i18ninput::Enabled()) { |
+ // If country will change while filling, rebuild inputs now. |
Evan Stade
2014/01/15 23:12:29
I can't make sense of this sentence.
Dan Beam
2014/01/16 01:39:13
Removed.
|
+ base::string16 billing_country; |
+ if (!billing_country_combobox_model_.GetDefaultIndex()) |
+ billing_country = wrapper->GetInfo(AutofillType(ADDRESS_BILLING_COUNTRY)); |
+ |
+ base::string16 shipping_country; |
+ if (!shipping_country_combobox_model_.GetDefaultIndex()) |
+ shipping_country = wrapper->GetInfo(AutofillType(ADDRESS_HOME_COUNTRY)); |
+ |
+ if (!billing_country.empty() || !shipping_country.empty()) { |
+ FieldValueMap snapshot = TakeUserInputSnapshot(); |
+ |
+ if (!billing_country.empty()) |
+ snapshot[ADDRESS_BILLING_COUNTRY] = billing_country; |
+ |
+ if (!shipping_country.empty()) |
+ snapshot[ADDRESS_HOME_COUNTRY] = shipping_country; |
+ |
+ RestoreUserInputFromSnapshot(snapshot); |
+ |
+ if (!billing_country.empty()) |
+ UpdateSection(ActiveBillingSection()); |
+ |
+ if (!shipping_country.empty()) |
+ UpdateSection(SECTION_SHIPPING); |
+ } |
+ } |
+ |
for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
DialogSection section = static_cast<DialogSection>(i); |
wrapper->FillInputs(MutableRequestedFieldsForSection(section)); |
@@ -2237,8 +2294,19 @@ void AutofillDialogControllerImpl::SuggestionItemSelected( |
} |
model->SetCheckedIndex(index); |
+ |
DialogSection section = SectionForSuggestionsMenuModel(*model); |
+ SetEditingExistingData(section, false); |
+ |
+ if (i18ninput::Enabled()) { |
+ if (section == SECTION_SHIPPING) |
+ shipping_country_combobox_model_.ResetDefault(); |
+ else if (section == SECTION_BILLING || section == SECTION_CC_BILLING) |
+ billing_country_combobox_model_.ResetDefault(); |
+ } |
+ |
ResetSectionInput(section); |
+ |
ShowEditUiIfBadSuggestion(section); |
UpdateSection(section); |
view_->UpdateNotificationArea(); |
@@ -2521,7 +2589,8 @@ AutofillDialogControllerImpl::AutofillDialogControllerImpl( |
wallet_items_requested_(false), |
handling_use_wallet_link_click_(false), |
passive_failed_(false), |
- country_combobox_model_(*GetManager()), |
+ billing_country_combobox_model_(*GetManager()), |
+ shipping_country_combobox_model_(*GetManager()), |
suggested_cc_(this), |
suggested_billing_(this), |
suggested_cc_billing_(this), |
@@ -2609,6 +2678,10 @@ void AutofillDialogControllerImpl::OpenTabWithUrl(const GURL& url) { |
chrome::Navigate(¶ms); |
} |
+DialogSection AutofillDialogControllerImpl::ActiveBillingSection() const { |
+ return IsPayingWithWallet() ? SECTION_CC_BILLING : SECTION_BILLING; |
+} |
+ |
bool AutofillDialogControllerImpl::IsEditingExistingData( |
DialogSection section) const { |
return section_editing_state_.count(section) > 0; |
@@ -2821,7 +2894,9 @@ void AutofillDialogControllerImpl::SuggestionsUpdated() { |
view_->ModelChanged(); |
for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
- ResetSectionInput(static_cast<DialogSection>(i)); |
+ DialogSection section = static_cast<DialogSection>(i); |
+ SetEditingExistingData(section, false); |
+ ResetSectionInput(section); |
} |
RestoreUserInputFromSnapshot(snapshot); |
@@ -2844,11 +2919,13 @@ void AutofillDialogControllerImpl::FillOutputForSectionWithComparator( |
if (!SectionIsActive(section)) |
return; |
- const DetailInputs& inputs = RequestedFieldsForSection(section); |
+ DetailInputs inputs; |
+ std::string country_code = CountryCodeForSection(section); |
+ common::BuildInputsForSection(section, country_code, &inputs); |
+ |
scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); |
if (wrapper) { |
// Only fill in data that is associated with this section. |
- const DetailInputs& inputs = RequestedFieldsForSection(section); |
wrapper->FillFormStructure(inputs, compare, &form_structure_); |
// CVC needs special-casing because the CreditCard class doesn't store or |
@@ -2991,6 +3068,51 @@ DetailInputs* AutofillDialogControllerImpl::MutableRequestedFieldsForSection( |
return const_cast<DetailInputs*>(&RequestedFieldsForSection(section)); |
} |
+void AutofillDialogControllerImpl::OnComboboxModelChanged( |
+ ui::ComboboxModel* model) { |
+ DCHECK(model == &billing_country_combobox_model_ || |
+ model == &shipping_country_combobox_model_); |
+ |
+ const bool is_shipping = model == &shipping_country_combobox_model_; |
+ const std::string country_code = AutofillCountry::GetCountryCode( |
+ model->GetItemAt(model->GetDefaultIndex()), |
+ g_browser_process->GetApplicationLocale()); |
+ |
+ for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
+ DialogSection section = static_cast<DialogSection>(i); |
+ |
+ if ((is_shipping && section != SECTION_SHIPPING) || |
Evan Stade
2014/01/15 23:12:29
this is the second place in this CL I've seen so f
Dan Beam
2014/01/16 01:39:13
Done.
|
+ (!is_shipping && (section != SECTION_BILLING && |
+ section != SECTION_CC_BILLING))) { |
+ continue; |
+ } |
+ |
+ DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
+ inputs->clear(); |
+ |
+ common::BuildInputsForSection(section, country_code, inputs); |
+ } |
+} |
+ |
+std::string AutofillDialogControllerImpl::CountryCodeForSection( |
+ DialogSection section) { |
+ if (section == SECTION_CC) |
+ return "US"; |
Evan Stade
2014/01/15 23:12:29
ditto -- return "" as it's international.
Dan Beam
2014/01/16 01:39:13
Done.
|
+ |
+ base::string16 country_name; |
+ if (IsEditingExistingData(section)) { |
+ ServerFieldType type = SECTION_SHIPPING ? ADDRESS_HOME_COUNTRY : |
+ ADDRESS_BILLING_COUNTRY; |
+ return AutofillCountry::GetCountryCode( |
+ CreateWrapper(section)->GetInfo(AutofillType(type)), |
+ g_browser_process->GetApplicationLocale()); |
+ } |
+ |
+ CountryComboboxModel* model = section == SECTION_SHIPPING ? |
Evan Stade
2014/01/15 23:12:29
third place
Dan Beam
2014/01/16 01:39:13
Done.
|
+ &shipping_country_combobox_model_ : &billing_country_combobox_model_; |
+ return model->countries()[model->GetDefaultIndex()]->country_code(); |
+} |
+ |
void AutofillDialogControllerImpl::HidePopup() { |
if (popup_controller_.get()) |
popup_controller_->Hide(); |