OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/autofill/autofill_dialog_controller_impl.h" | 5 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/string_number_conversions.h" | |
10 #include "base/string_split.h" | 11 #include "base/string_split.h" |
11 #include "base/string_util.h" | 12 #include "base/string_util.h" |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/autofill/autofill_country.h" | 14 #include "chrome/browser/autofill/autofill_country.h" |
14 #include "chrome/browser/autofill/autofill_manager.h" | 15 #include "chrome/browser/autofill/autofill_manager.h" |
15 #include "chrome/browser/autofill/autofill_type.h" | 16 #include "chrome/browser/autofill/autofill_type.h" |
16 #include "chrome/browser/autofill/personal_data_manager.h" | 17 #include "chrome/browser/autofill/personal_data_manager.h" |
17 #include "chrome/browser/autofill/personal_data_manager_factory.h" | 18 #include "chrome/browser/autofill/personal_data_manager_factory.h" |
18 #include "chrome/browser/autofill/validation.h" | 19 #include "chrome/browser/autofill/validation.h" |
19 #include "chrome/browser/autofill/wallet/full_wallet.h" | 20 #include "chrome/browser/autofill/wallet/full_wallet.h" |
20 #include "chrome/browser/autofill/wallet/wallet_items.h" | 21 #include "chrome/browser/autofill/wallet/wallet_items.h" |
21 #include "chrome/browser/autofill/wallet/wallet_service_url.h" | 22 #include "chrome/browser/autofill/wallet/wallet_service_url.h" |
22 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/browser/ui/autofill/autofill_dialog_view.h" | 24 #include "chrome/browser/ui/autofill/autofill_dialog_view.h" |
25 #include "chrome/browser/ui/autofill/data_model_wrapper.h" | |
24 #include "chrome/common/form_data.h" | 26 #include "chrome/common/form_data.h" |
25 #include "content/public/browser/navigation_controller.h" | 27 #include "content/public/browser/navigation_controller.h" |
26 #include "content/public/browser/navigation_details.h" | 28 #include "content/public/browser/navigation_details.h" |
27 #include "content/public/browser/navigation_entry.h" | 29 #include "content/public/browser/navigation_entry.h" |
28 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
29 #include "content/public/browser/notification_types.h" | 31 #include "content/public/browser/notification_types.h" |
30 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
31 #include "content/public/common/url_constants.h" | 33 #include "content/public/common/url_constants.h" |
32 #include "grit/chromium_strings.h" | 34 #include "grit/chromium_strings.h" |
33 #include "grit/generated_resources.h" | 35 #include "grit/generated_resources.h" |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 return string16(); | 378 return string16(); |
377 | 379 |
378 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | 380 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
379 std::string item_key = model->GetItemKeyAt(model->checked_item()); | 381 std::string item_key = model->GetItemKeyAt(model->checked_item()); |
380 if (item_key.empty()) | 382 if (item_key.empty()) |
381 return string16(); | 383 return string16(); |
382 | 384 |
383 if (section == SECTION_EMAIL) | 385 if (section == SECTION_EMAIL) |
384 return model->GetLabelAt(model->checked_item()); | 386 return model->GetLabelAt(model->checked_item()); |
385 | 387 |
388 scoped_ptr<DataModelWrapper> wrapper(CreateWrapper(section)); | |
389 return wrapper->GetDisplayText(); | |
390 } | |
391 | |
392 DataModelWrapper* AutofillDialogControllerImpl::CreateWrapper( | |
393 DialogSection section) { | |
394 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | |
395 std::string item_key = model->GetItemKeyAt(model->checked_item()); | |
396 if (item_key.empty()) | |
397 return NULL; | |
398 | |
399 if (CanPayWithWallet()) { | |
400 int index; | |
401 if (!base::StringToInt(item_key, &index)) | |
402 NOTREACHED(); | |
Ilya Sherman
2013/02/12 22:50:34
Optional nit: IMO these two lines would be clearer
Evan Stade
2013/02/13 00:11:58
Done.
| |
403 | |
404 if (section == SECTION_CC) | |
405 return new WalletInstrumentWrapper(wallet_items_->instruments()[index]); | |
Ilya Sherman
2013/02/12 22:50:34
nit: Is it worth DCHECK'ing that the index is in b
Evan Stade
2013/02/13 00:11:58
IMO no, because it's already self-evident that we
| |
406 | |
407 return new WalletAddressWrapper(wallet_items_->addresses()[index]); | |
408 } | |
409 | |
386 if (section == SECTION_CC) { | 410 if (section == SECTION_CC) { |
387 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); | 411 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); |
388 return card->TypeAndLastFourDigits(); | 412 DCHECK(card); |
413 return new AutofillCreditCardWrapper(card); | |
389 } | 414 } |
390 | 415 |
391 const std::string app_locale = AutofillCountry::ApplicationLocale(); | 416 // Calculate the variant by looking at how many items come from the same |
417 // FormGroup. TODO(estade): add a test for this. | |
418 size_t variant = 0; | |
419 for (int i = model->checked_item() - 1; i >= 0; --i) { | |
420 if (model->GetItemKeyAt(i) == item_key) | |
421 variant++; | |
422 else | |
423 break; | |
424 } | |
425 | |
392 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key); | 426 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key); |
393 string16 comma = ASCIIToUTF16(", "); | 427 DCHECK(profile); |
394 string16 label = profile->GetInfo(NAME_FULL, app_locale) + | 428 return new AutofillDataModelWrapper(profile, variant); |
395 comma + profile->GetInfo(ADDRESS_HOME_LINE1, app_locale); | |
396 string16 address2 = profile->GetInfo(ADDRESS_HOME_LINE2, app_locale); | |
397 if (!address2.empty()) | |
398 label += comma + address2; | |
399 label += ASCIIToUTF16("\n") + | |
400 profile->GetInfo(ADDRESS_HOME_CITY, app_locale) + comma + | |
401 profile->GetInfo(ADDRESS_HOME_STATE, app_locale) + ASCIIToUTF16(" ") + | |
402 profile->GetInfo(ADDRESS_HOME_ZIP, app_locale); | |
403 return label; | |
404 } | 429 } |
405 | 430 |
406 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection( | 431 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection( |
407 DialogSection section) { | 432 DialogSection section) { |
408 if (section != SECTION_CC) | 433 if (section != SECTION_CC) |
409 return gfx::Image(); | 434 return gfx::Image(); |
410 | 435 |
411 std::string item_key = | 436 scoped_ptr<DataModelWrapper> model(CreateWrapper(section)); |
412 suggested_cc_.GetItemKeyAt(suggested_cc_.checked_item()); | 437 if (!model.get()) |
413 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 438 return gfx::Image(); |
414 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); | 439 |
415 return rb.GetImageNamed(card->IconResourceId()); | 440 return model->GetIcon(); |
416 } | 441 } |
417 | 442 |
418 void AutofillDialogControllerImpl::EditClickedForSection( | 443 void AutofillDialogControllerImpl::EditClickedForSection( |
419 DialogSection section) { | 444 DialogSection section) { |
420 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | 445 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
421 DetailInputs* inputs = MutableRequestedFieldsForSection(section); | 446 DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
422 | 447 |
423 if (section == SECTION_EMAIL) { | 448 if (section == SECTION_EMAIL) { |
424 // TODO(estade): shouldn't need to make this check. | 449 // TODO(estade): shouldn't need to make this check. |
425 if (inputs->empty()) | 450 if (inputs->empty()) |
426 return; | 451 return; |
427 | 452 |
428 (*inputs)[0].autofilled_value = model->GetLabelAt(model->checked_item()); | 453 (*inputs)[0].autofilled_value = model->GetLabelAt(model->checked_item()); |
429 } else { | 454 } else { |
430 std::string guid = model->GetItemKeyAt(model->checked_item()); | 455 scoped_ptr<DataModelWrapper> model(CreateWrapper(section)); |
431 DCHECK(!guid.empty()); | 456 model->FillInputs(inputs); |
432 | |
433 FormGroup* form_group = section == SECTION_CC ? | |
434 static_cast<FormGroup*>(GetManager()->GetCreditCardByGUID(guid)) : | |
435 static_cast<FormGroup*>(GetManager()->GetProfileByGUID(guid)); | |
436 DCHECK(form_group); | |
437 FillInputFromFormGroup(form_group, inputs); | |
438 } | 457 } |
439 | 458 |
440 section_editing_state_[section] = true; | 459 section_editing_state_[section] = true; |
441 view_->UpdateSection(section); | 460 view_->UpdateSection(section); |
442 } | 461 } |
443 | 462 |
444 bool AutofillDialogControllerImpl::InputIsValid(AutofillFieldType type, | 463 bool AutofillDialogControllerImpl::InputIsValid(AutofillFieldType type, |
445 const string16& value) { | 464 const string16& value) { |
446 // TODO(groby): Add the missing checks. | 465 // TODO(groby): Add the missing checks. |
447 switch (type) { | 466 switch (type) { |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
694 WalletRequestCompleted(true); | 713 WalletRequestCompleted(true); |
695 } | 714 } |
696 | 715 |
697 void AutofillDialogControllerImpl::OnDidGetWalletItems( | 716 void AutofillDialogControllerImpl::OnDidGetWalletItems( |
698 scoped_ptr<wallet::WalletItems> wallet_items) { | 717 scoped_ptr<wallet::WalletItems> wallet_items) { |
699 bool items_changed = !wallet_items_ || *wallet_items != *wallet_items_; | 718 bool items_changed = !wallet_items_ || *wallet_items != *wallet_items_; |
700 wallet_items_ = wallet_items.Pass(); | 719 wallet_items_ = wallet_items.Pass(); |
701 WalletRequestCompleted(true); | 720 WalletRequestCompleted(true); |
702 | 721 |
703 if (items_changed) { | 722 if (items_changed) { |
723 GenerateSuggestionsModels(); | |
724 view_->ModelChanged(); | |
704 view_->UpdateAccountChooser(); | 725 view_->UpdateAccountChooser(); |
705 view_->UpdateNotificationArea(); | 726 view_->UpdateNotificationArea(); |
706 } | 727 } |
707 } | 728 } |
708 | 729 |
709 void AutofillDialogControllerImpl::OnDidSaveAddress( | 730 void AutofillDialogControllerImpl::OnDidSaveAddress( |
710 const std::string& address_id) { | 731 const std::string& address_id) { |
711 NOTIMPLEMENTED() << " address_id=" << address_id; | 732 NOTIMPLEMENTED() << " address_id=" << address_id; |
712 WalletRequestCompleted(true); | 733 WalletRequestCompleted(true); |
713 } | 734 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 } | 825 } |
805 | 826 |
806 wallet_client_.GetWalletItems(this); | 827 wallet_client_.GetWalletItems(this); |
807 refresh_wallet_items_queued_ = false; | 828 refresh_wallet_items_queued_ = false; |
808 } | 829 } |
809 | 830 |
810 void AutofillDialogControllerImpl::WalletRequestCompleted(bool success) { | 831 void AutofillDialogControllerImpl::WalletRequestCompleted(bool success) { |
811 if (!success) { | 832 if (!success) { |
812 had_wallet_error_ = true; | 833 had_wallet_error_ = true; |
813 wallet_items_.reset(); | 834 wallet_items_.reset(); |
835 GenerateSuggestionsModels(); | |
836 view_->ModelChanged(); | |
814 view_->UpdateAccountChooser(); | 837 view_->UpdateAccountChooser(); |
815 view_->UpdateNotificationArea(); | 838 view_->UpdateNotificationArea(); |
816 return; | 839 return; |
817 } | 840 } |
818 | 841 |
819 if (refresh_wallet_items_queued_) | 842 if (refresh_wallet_items_queued_) |
820 ScheduleRefreshWalletItems(); | 843 ScheduleRefreshWalletItems(); |
821 } | 844 } |
822 | 845 |
823 void AutofillDialogControllerImpl::GenerateSuggestionsModels() { | 846 void AutofillDialogControllerImpl::GenerateSuggestionsModels() { |
824 suggested_cc_.Reset(); | 847 suggested_cc_.Reset(); |
825 suggested_billing_.Reset(); | 848 suggested_billing_.Reset(); |
826 suggested_email_.Reset(); | 849 suggested_email_.Reset(); |
827 suggested_shipping_.Reset(); | 850 suggested_shipping_.Reset(); |
828 | 851 |
829 PersonalDataManager* manager = GetManager(); | 852 if (CanPayWithWallet()) { |
830 const std::vector<CreditCard*>& cards = manager->credit_cards(); | 853 if (wallet_items_.get()) { |
831 for (size_t i = 0; i < cards.size(); ++i) { | 854 // TODO(estade): seems we need to hardcode the email address. |
832 suggested_cc_.AddKeyedItem(cards[i]->guid(), cards[i]->Label()); | 855 // TODO(estade): CC and billing need to be combined into one section, |
833 } | 856 // and suggestions added here. |
834 // TODO(estade): real strings and i18n. | 857 const std::vector<wallet::Address*>& addresses = |
835 suggested_cc_.AddKeyedItem("", ASCIIToUTF16("Enter new card")); | 858 wallet_items_->addresses(); |
836 | 859 for (size_t i = 0; i < addresses.size(); ++i) { |
837 const std::vector<AutofillProfile*>& profiles = manager->GetProfiles(); | 860 suggested_billing_.AddKeyedItem(base::IntToString(i), |
838 const std::string app_locale = AutofillCountry::ApplicationLocale(); | 861 addresses[i]->DisplayName()); |
839 for (size_t i = 0; i < profiles.size(); ++i) { | 862 suggested_shipping_.AddKeyedItem(base::IntToString(i), |
840 if (!IsCompleteProfile(*profiles[i])) | 863 addresses[i]->DisplayName()); |
841 continue; | 864 } |
842 | 865 } |
843 // Add all email addresses. | 866 } else { |
844 std::vector<string16> values; | 867 PersonalDataManager* manager = GetManager(); |
845 profiles[i]->GetMultiInfo(EMAIL_ADDRESS, app_locale, &values); | 868 const std::vector<CreditCard*>& cards = manager->credit_cards(); |
846 for (size_t j = 0; j < values.size(); ++j) { | 869 for (size_t i = 0; i < cards.size(); ++i) { |
847 if (!values[j].empty()) | 870 suggested_cc_.AddKeyedItem(cards[i]->guid(), cards[i]->Label()); |
848 suggested_email_.AddKeyedItem(profiles[i]->guid(), values[j]); | |
849 } | 871 } |
850 | 872 |
851 // Don't add variants for addresses: the email variants are handled above, | 873 const std::vector<AutofillProfile*>& profiles = manager->GetProfiles(); |
852 // name is part of credit card and we'll just ignore phone number variants. | 874 const std::string app_locale = AutofillCountry::ApplicationLocale(); |
853 suggested_billing_.AddKeyedItem(profiles[i]->guid(), profiles[i]->Label()); | 875 for (size_t i = 0; i < profiles.size(); ++i) { |
854 suggested_shipping_.AddKeyedItem(profiles[i]->guid(), profiles[i]->Label()); | 876 if (!IsCompleteProfile(*profiles[i])) |
877 continue; | |
878 | |
879 // Add all email addresses. | |
880 std::vector<string16> values; | |
881 profiles[i]->GetMultiInfo(EMAIL_ADDRESS, app_locale, &values); | |
882 for (size_t j = 0; j < values.size(); ++j) { | |
883 if (!values[j].empty()) | |
884 suggested_email_.AddKeyedItem(profiles[i]->guid(), values[j]); | |
885 } | |
886 | |
887 // Don't add variants for addresses: the email variants are handled above, | |
888 // name is part of credit card and we'll just ignore phone number | |
889 // variants. | |
890 suggested_billing_.AddKeyedItem(profiles[i]->guid(), | |
891 profiles[i]->Label()); | |
892 suggested_shipping_.AddKeyedItem(profiles[i]->guid(), | |
893 profiles[i]->Label()); | |
894 } | |
855 } | 895 } |
856 | 896 |
857 // TODO(estade): real strings and i18n. | 897 // TODO(estade): real strings and i18n. |
898 suggested_cc_.AddKeyedItem("", ASCIIToUTF16("Enter new card")); | |
858 suggested_billing_.AddKeyedItem("", ASCIIToUTF16("Enter new billing")); | 899 suggested_billing_.AddKeyedItem("", ASCIIToUTF16("Enter new billing")); |
859 suggested_email_.AddKeyedItem("", ASCIIToUTF16("Enter new email")); | 900 suggested_email_.AddKeyedItem("", ASCIIToUTF16("Enter new email")); |
860 suggested_shipping_.AddKeyedItem("", ASCIIToUTF16("Enter new shipping")); | 901 suggested_shipping_.AddKeyedItem("", ASCIIToUTF16("Enter new shipping")); |
861 } | 902 } |
862 | 903 |
863 bool AutofillDialogControllerImpl::IsCompleteProfile( | 904 bool AutofillDialogControllerImpl::IsCompleteProfile( |
864 const AutofillProfile& profile) { | 905 const AutofillProfile& profile) { |
865 const std::string app_locale = AutofillCountry::ApplicationLocale(); | 906 const std::string app_locale = AutofillCountry::ApplicationLocale(); |
866 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { | 907 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { |
867 if (profile.GetInfo(requested_shipping_fields_[i].type, | 908 if (profile.GetInfo(requested_shipping_fields_[i].type, |
868 app_locale).empty()) { | 909 app_locale).empty()) { |
869 return false; | 910 return false; |
870 } | 911 } |
871 } | 912 } |
872 | 913 |
873 return true; | 914 return true; |
874 } | 915 } |
875 | 916 |
876 void AutofillDialogControllerImpl::FillOutputForSectionWithComparator( | 917 void AutofillDialogControllerImpl::FillOutputForSectionWithComparator( |
877 DialogSection section, | 918 DialogSection section, |
878 const InputFieldComparator& compare) { | 919 const InputFieldComparator& compare) { |
879 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | 920 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
880 std::string guid = model->GetItemKeyAt(model->checked_item()); | 921 std::string item_key = model->GetItemKeyAt(model->checked_item()); |
881 PersonalDataManager* manager = GetManager(); | 922 PersonalDataManager* manager = GetManager(); |
Ilya Sherman
2013/02/12 22:50:34
nit: Move this into the else stmt?
Evan Stade
2013/02/13 00:11:58
Done.
| |
882 if (!guid.empty() && !section_editing_state_[section]) { | 923 if (!item_key.empty() && !section_editing_state_[section]) { |
883 FormGroup* form_group = section == SECTION_CC ? | 924 scoped_ptr<DataModelWrapper> model(CreateWrapper(section)); |
884 static_cast<FormGroup*>(manager->GetCreditCardByGUID(guid)) : | 925 // Only fill in data that is associated with this section. |
885 static_cast<FormGroup*>(manager->GetProfileByGUID(guid)); | 926 const DetailInputs& inputs = RequestedFieldsForSection(section); |
886 DCHECK(form_group); | 927 model->FillFormStructure(inputs, compare, &form_structure_); |
887 | |
888 // Calculate the variant by looking at how many items come from the same | |
889 // FormGroup. TODO(estade): add a test for this. | |
890 size_t variant = 0; | |
891 for (int i = model->checked_item() - 1; i >= 0; --i) { | |
892 if (model->GetItemKeyAt(i) == guid) | |
893 variant++; | |
894 else | |
895 break; | |
896 } | |
897 | |
898 FillFormStructureForSection(*form_group, variant, section, compare); | |
899 | 928 |
900 // CVC needs special-casing because the CreditCard class doesn't store | 929 // CVC needs special-casing because the CreditCard class doesn't store |
901 // or handle them. | 930 // or handle them. |
902 if (section == SECTION_CC) | 931 if (section == SECTION_CC) |
903 SetCvcResult(view_->GetCvc()); | 932 SetCvcResult(view_->GetCvc()); |
904 } else { | 933 } else { |
905 // The user manually input data. | 934 // The user manually input data. |
906 DetailOutputMap output; | 935 DetailOutputMap output; |
907 view_->GetUserInput(section, &output); | 936 view_->GetUserInput(section, &output); |
908 | 937 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1008 DialogSection section) { | 1037 DialogSection section) { |
1009 return const_cast<DetailInputs*>(&RequestedFieldsForSection(section)); | 1038 return const_cast<DetailInputs*>(&RequestedFieldsForSection(section)); |
1010 } | 1039 } |
1011 | 1040 |
1012 void AutofillDialogControllerImpl::HidePopup() { | 1041 void AutofillDialogControllerImpl::HidePopup() { |
1013 if (popup_controller_) | 1042 if (popup_controller_) |
1014 popup_controller_->Hide(); | 1043 popup_controller_->Hide(); |
1015 } | 1044 } |
1016 | 1045 |
1017 } // namespace autofill | 1046 } // namespace autofill |
OLD | NEW |