Chromium Code Reviews| 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 7edf6c17f9bcbbab638d763a0d2a1e225e83a125..6a4a79f213c8d6ed963a04686c6718f9549aad69 100644 |
| --- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
| +++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
| @@ -18,6 +18,7 @@ |
| #include "chrome/browser/autofill/personal_data_manager_factory.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/extensions/shell_window_registry.h" |
| +#include "chrome/browser/prefs/scoped_user_pref_update.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/autofill/autofill_dialog_view.h" |
| #include "chrome/browser/ui/autofill/data_model_wrapper.h" |
| @@ -86,6 +87,11 @@ const char kAddNewItemKey[] = "add-new-item"; |
| const char kManageItemsKey[] = "manage-items"; |
| const char kSameAsBillingKey[] = "same-as-billing"; |
| +// Keys for the kAutofillDialogAutofillDefault pref dictionary (do not change |
| +// these values). |
| +const char kGuidPrefKey[] = "guid"; |
| +const char kVariantPrefKey[] = "variant"; |
| + |
| // Returns true if |input| should be shown when |field_type| has been requested. |
| bool InputTypeMatchesFieldType(const DetailInput& input, |
| AutofillFieldType field_type) { |
| @@ -227,6 +233,32 @@ string16 GetValueForType(const DetailOutputMap& output, |
| return string16(); |
| } |
| +// Returns a string descriptor for a DialogSection, for use with prefs (do not |
| +// change these values). |
| +std::string SectionToPrefString(DialogSection section) { |
| + switch (section) { |
| + case SECTION_CC: |
| + return "cc"; |
| + |
| + case SECTION_BILLING: |
| + return "billing"; |
| + |
| + case SECTION_CC_BILLING: |
| + // The SECTION_CC_BILLING section isn't active when using Autofill. |
| + NOTREACHED(); |
| + return std::string(); |
| + |
| + case SECTION_SHIPPING: |
| + return "shipping"; |
| + |
| + case SECTION_EMAIL: |
| + return "email"; |
| + } |
| + |
| + NOTREACHED(); |
| + return std::string(); |
| +} |
| + |
| } // namespace |
| AutofillDialogController::~AutofillDialogController() {} |
| @@ -265,6 +297,9 @@ void AutofillDialogControllerImpl::RegisterUserPrefs( |
| ::prefs::kAutofillDialogPayWithoutWallet, |
| kPayWithoutWalletDefault, |
| user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| + registry->RegisterDictionaryPref( |
| + ::prefs::kAutofillDialogAutofillDefault, |
| + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| } |
| void AutofillDialogControllerImpl::Show() { |
| @@ -938,18 +973,9 @@ scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper( |
| return scoped_ptr<DataModelWrapper>(new AutofillCreditCardWrapper(card)); |
| } |
| - // Calculate the variant by looking at how many items come from the same |
| - // data model. |
| - size_t variant = 0; |
| - for (int i = model->checked_item() - 1; i >= 0; --i) { |
| - if (model->GetItemKeyAt(i) == item_key) |
| - variant++; |
| - else |
| - break; |
| - } |
| - |
| AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key); |
| DCHECK(profile); |
| + size_t variant = GetSelectedVariantForModel(*model); |
| return scoped_ptr<DataModelWrapper>( |
| new AutofillProfileWrapper(profile, variant)); |
| } |
| @@ -1874,12 +1900,18 @@ void AutofillDialogControllerImpl::SuggestionsUpdated() { |
| l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS)); |
| if (!IsPayingWithWallet()) { |
| - // When using Autofill, the default option is the first suggestion, if |
| - // one exists. Otherwise it's the "Use shipping for billing" item. |
| - const std::string& first_real_suggestion_item_key = |
| - suggested_shipping_.GetItemKeyAt(1); |
| - if (IsASuggestionItemKey(first_real_suggestion_item_key)) |
| - suggested_shipping_.SetCheckedItem(first_real_suggestion_item_key); |
| + for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
| + DialogSection section = static_cast<DialogSection>(i); |
| + if (!SectionIsActive(section)) |
| + continue; |
| + |
| + std::string default_guid; |
| + int default_variant; |
| + SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
|
Ilya Sherman
2013/05/21 03:54:35
nit: Perhaps move this into the if-stmt, since it'
Evan Stade
2013/05/21 17:34:41
changed this code a bit.
|
| + GetAutofillChoice(section, &default_guid, &default_variant); |
| + if (!default_guid.empty()) |
| + model->SetCheckedItemNthWithKey(default_guid, default_variant + 1); |
| + } |
| } |
| if (view_) |
| @@ -1930,6 +1962,7 @@ void AutofillDialogControllerImpl::FillOutputForSectionWithComparator( |
| // billing section as CVC comes from |full_wallet_| in this case. |
| if (section == SECTION_CC) |
| SetCvcResult(view_->GetCvc()); |
| + |
|
Ilya Sherman
2013/05/21 03:54:35
nit: Spurious diff
Evan Stade
2013/05/21 17:34:41
Done.
|
| } else { |
| // The user manually input data. If using Autofill, save the info as new or |
| // edited data. Always fill local data into |form_structure_|. |
| @@ -2408,6 +2441,21 @@ void AutofillDialogControllerImpl::FinishSubmit() { |
| FillOutputForSection(SECTION_SHIPPING); |
| } |
| + if (!IsPayingWithWallet()) { |
| + for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
| + DialogSection section = static_cast<DialogSection>(i); |
| + if (!SectionIsActive(section)) |
| + continue; |
| + |
| + SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
| + std::string item_key = model->GetItemKeyForCheckedItem(); |
| + if (IsASuggestionItemKey(item_key) || item_key == kSameAsBillingKey) { |
| + int variant = GetSelectedVariantForModel(*model); |
| + PersistAutofillChoice(section, item_key, variant); |
| + } |
| + } |
| + } |
| + |
| callback_.Run(&form_structure_, !wallet_items_ ? std::string() : |
| wallet_items_->google_transaction_id()); |
| callback_ = base::Callback<void(const FormStructure*, const std::string&)>(); |
| @@ -2442,6 +2490,63 @@ void AutofillDialogControllerImpl::FinishSubmit() { |
| } |
| } |
| +void AutofillDialogControllerImpl::PersistAutofillChoice( |
| + DialogSection section, |
| + const std::string& guid, |
| + int variant) { |
| + DCHECK(!IsPayingWithWallet()); |
| + scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); |
| + value->SetString(kGuidPrefKey, guid); |
| + value->SetInteger(kVariantPrefKey, variant); |
| + |
| + DictionaryPrefUpdate updater(profile()->GetPrefs(), |
| + ::prefs::kAutofillDialogAutofillDefault); |
| + base::DictionaryValue* autofill_choice = updater.Get(); |
| + autofill_choice->Set(SectionToPrefString(section), value.release()); |
| +} |
| + |
| +void AutofillDialogControllerImpl::GetAutofillChoice(DialogSection section, |
| + std::string* guid, |
| + int* variant) { |
| + DCHECK(!IsPayingWithWallet()); |
| + // The default choice is the first thing in the menu that is a suggestion |
| + // item. |
| + *variant = 0; |
| + SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
| + for (int i = 0; i < model->GetItemCount(); ++i) { |
| + if (IsASuggestionItemKey(model->GetItemKeyAt(i))) { |
| + *guid = model->GetItemKeyAt(i); |
| + break; |
| + } |
| + } |
| + |
| + const base::DictionaryValue* choices = profile()->GetPrefs()->GetDictionary( |
| + ::prefs::kAutofillDialogAutofillDefault); |
| + if (!choices) |
| + return; |
| + |
| + const base::DictionaryValue* choice = NULL; |
| + if (!choices->GetDictionary(SectionToPrefString(section), &choice)) |
| + return; |
| + |
| + choice->GetString(kGuidPrefKey, guid); |
| + choice->GetInteger(kVariantPrefKey, variant); |
| +} |
| + |
| +size_t AutofillDialogControllerImpl::GetSelectedVariantForModel( |
| + const SuggestionsMenuModel& model) { |
| + size_t variant = 0; |
| + // Calculate the variant by looking at how many items come from the same |
| + // data model. |
| + for (int i = model.checked_item() - 1; i >= 0; --i) { |
| + if (model.GetItemKeyAt(i) == model.GetItemKeyForCheckedItem()) |
| + variant++; |
|
Ilya Sherman
2013/05/21 03:54:35
nit: ++variant
Evan Stade
2013/05/21 17:34:41
this is not a rule that I'm aware of.
"For simple
Ilya Sherman
2013/05/21 23:20:43
I prefer to always use pre-increment because it's
|
| + else |
| + break; |
| + } |
| + return variant; |
| +} |
| + |
| void AutofillDialogControllerImpl::LogOnFinishSubmitMetrics() { |
| GetMetricLogger().LogDialogUiDuration( |
| base::Time::Now() - dialog_shown_timestamp_, |