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

Side by Side Diff: chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc

Issue 12208070: allow wallet items to appear in requestAutocomplete UI (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: clang fix Created 7 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 return string16(); 373 return string16();
372 374
373 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 375 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
374 std::string item_key = model->GetItemKeyAt(model->checked_item()); 376 std::string item_key = model->GetItemKeyAt(model->checked_item());
375 if (item_key.empty()) 377 if (item_key.empty())
376 return string16(); 378 return string16();
377 379
378 if (section == SECTION_EMAIL) 380 if (section == SECTION_EMAIL)
379 return model->GetLabelAt(model->checked_item()); 381 return model->GetLabelAt(model->checked_item());
380 382
381 if (section == SECTION_CC) { 383 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
384 return wrapper->GetDisplayText();
385 }
386
387 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper(
388 DialogSection section) {
389 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
390 std::string item_key = model->GetItemKeyAt(model->checked_item());
391 scoped_ptr<DataModelWrapper> wrapper;
392 if (item_key.empty())
393 return wrapper.Pass();
394
395 if (CanPayWithWallet()) {
396 int index;
397 bool success = !base::StringToInt(item_key, &index);
Dan Beam 2013/02/15 02:11:45 shouldn't this be without the "!" ?
Evan Stade 2013/02/20 00:03:39 yes
398 DCHECK(success);
399
400 if (section == SECTION_CC) {
401 wrapper.reset(
402 new WalletInstrumentWrapper(wallet_items_->instruments()[index]));
403 } else {
404 wrapper.reset(
405 new WalletAddressWrapper(wallet_items_->addresses()[index]));
406 }
407 } else if (section == SECTION_CC) {
382 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); 408 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key);
383 return card->TypeAndLastFourDigits(); 409 DCHECK(card);
410 wrapper.reset(new AutofillCreditCardWrapper(card));
411 } else {
412 // Calculate the variant by looking at how many items come from the same
413 // FormGroup. TODO(estade): add a test for this.
414 size_t variant = 0;
415 for (int i = model->checked_item() - 1; i >= 0; --i) {
416 if (model->GetItemKeyAt(i) == item_key)
417 variant++;
418 else
419 break;
420 }
421
422 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key);
423 DCHECK(profile);
424 wrapper.reset(new AutofillDataModelWrapper(profile, variant));
384 } 425 }
385 426
386 const std::string app_locale = AutofillCountry::ApplicationLocale(); 427 return wrapper.Pass();
387 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key);
388 string16 comma = ASCIIToUTF16(", ");
389 string16 label = profile->GetInfo(NAME_FULL, app_locale) +
390 comma + profile->GetInfo(ADDRESS_HOME_LINE1, app_locale);
391 string16 address2 = profile->GetInfo(ADDRESS_HOME_LINE2, app_locale);
392 if (!address2.empty())
393 label += comma + address2;
394 label += ASCIIToUTF16("\n") +
395 profile->GetInfo(ADDRESS_HOME_CITY, app_locale) + comma +
396 profile->GetInfo(ADDRESS_HOME_STATE, app_locale) + ASCIIToUTF16(" ") +
397 profile->GetInfo(ADDRESS_HOME_ZIP, app_locale);
398 return label;
399 } 428 }
400 429
401 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection( 430 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection(
402 DialogSection section) { 431 DialogSection section) {
403 if (section != SECTION_CC) 432 if (section != SECTION_CC)
404 return gfx::Image(); 433 return gfx::Image();
405 434
406 std::string item_key = 435 scoped_ptr<DataModelWrapper> model = CreateWrapper(section);
407 suggested_cc_.GetItemKeyAt(suggested_cc_.checked_item()); 436 if (!model.get())
408 if (item_key.empty())
409 return gfx::Image(); 437 return gfx::Image();
410 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 438
411 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); 439 return model->GetIcon();
412 return rb.GetImageNamed(card->IconResourceId());
413 } 440 }
414 441
415 void AutofillDialogControllerImpl::EditClickedForSection( 442 void AutofillDialogControllerImpl::EditClickedForSection(
416 DialogSection section) { 443 DialogSection section) {
417 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 444 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
418 DetailInputs* inputs = MutableRequestedFieldsForSection(section); 445 DetailInputs* inputs = MutableRequestedFieldsForSection(section);
419 446
420 if (section == SECTION_EMAIL) { 447 if (section == SECTION_EMAIL) {
421 // TODO(estade): shouldn't need to make this check. 448 // TODO(estade): shouldn't need to make this check.
422 if (inputs->empty()) 449 if (inputs->empty())
423 return; 450 return;
424 451
425 (*inputs)[0].autofilled_value = model->GetLabelAt(model->checked_item()); 452 (*inputs)[0].autofilled_value = model->GetLabelAt(model->checked_item());
426 } else { 453 } else {
427 std::string guid = model->GetItemKeyAt(model->checked_item()); 454 scoped_ptr<DataModelWrapper> model = CreateWrapper(section);
428 DCHECK(!guid.empty()); 455 model->FillInputs(inputs);
429
430 FormGroup* form_group = section == SECTION_CC ?
431 static_cast<FormGroup*>(GetManager()->GetCreditCardByGUID(guid)) :
432 static_cast<FormGroup*>(GetManager()->GetProfileByGUID(guid));
433 DCHECK(form_group);
434 FillInputFromFormGroup(form_group, inputs);
435 } 456 }
436 457
437 section_editing_state_[section] = true; 458 section_editing_state_[section] = true;
438 view_->UpdateSection(section); 459 view_->UpdateSection(section);
439 } 460 }
440 461
441 bool AutofillDialogControllerImpl::InputIsValid(AutofillFieldType type, 462 bool AutofillDialogControllerImpl::InputIsValid(AutofillFieldType type,
442 const string16& value) { 463 const string16& value) {
443 switch (type) { 464 switch (type) {
444 case EMAIL_ADDRESS: 465 case EMAIL_ADDRESS:
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 WalletRequestCompleted(true); 734 WalletRequestCompleted(true);
714 } 735 }
715 736
716 void AutofillDialogControllerImpl::OnDidGetWalletItems( 737 void AutofillDialogControllerImpl::OnDidGetWalletItems(
717 scoped_ptr<wallet::WalletItems> wallet_items) { 738 scoped_ptr<wallet::WalletItems> wallet_items) {
718 bool items_changed = !wallet_items_ || *wallet_items != *wallet_items_; 739 bool items_changed = !wallet_items_ || *wallet_items != *wallet_items_;
719 wallet_items_ = wallet_items.Pass(); 740 wallet_items_ = wallet_items.Pass();
720 WalletRequestCompleted(true); 741 WalletRequestCompleted(true);
721 742
722 if (items_changed) { 743 if (items_changed) {
744 GenerateSuggestionsModels();
745 view_->ModelChanged();
723 view_->UpdateAccountChooser(); 746 view_->UpdateAccountChooser();
724 view_->UpdateNotificationArea(); 747 view_->UpdateNotificationArea();
725 } 748 }
726 } 749 }
727 750
728 void AutofillDialogControllerImpl::OnDidSaveAddress( 751 void AutofillDialogControllerImpl::OnDidSaveAddress(
729 const std::string& address_id) { 752 const std::string& address_id) {
730 NOTIMPLEMENTED() << " address_id=" << address_id; 753 NOTIMPLEMENTED() << " address_id=" << address_id;
731 WalletRequestCompleted(true); 754 WalletRequestCompleted(true);
732 } 755 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 } 846 }
824 847
825 wallet_client_.GetWalletItems(this); 848 wallet_client_.GetWalletItems(this);
826 refresh_wallet_items_queued_ = false; 849 refresh_wallet_items_queued_ = false;
827 } 850 }
828 851
829 void AutofillDialogControllerImpl::WalletRequestCompleted(bool success) { 852 void AutofillDialogControllerImpl::WalletRequestCompleted(bool success) {
830 if (!success) { 853 if (!success) {
831 had_wallet_error_ = true; 854 had_wallet_error_ = true;
832 wallet_items_.reset(); 855 wallet_items_.reset();
856 GenerateSuggestionsModels();
857 view_->ModelChanged();
833 view_->UpdateAccountChooser(); 858 view_->UpdateAccountChooser();
834 view_->UpdateNotificationArea(); 859 view_->UpdateNotificationArea();
835 return; 860 return;
836 } 861 }
837 862
838 if (refresh_wallet_items_queued_) 863 if (refresh_wallet_items_queued_)
839 ScheduleRefreshWalletItems(); 864 ScheduleRefreshWalletItems();
840 } 865 }
841 866
842 void AutofillDialogControllerImpl::GenerateSuggestionsModels() { 867 void AutofillDialogControllerImpl::GenerateSuggestionsModels() {
843 suggested_cc_.Reset(); 868 suggested_cc_.Reset();
844 suggested_billing_.Reset(); 869 suggested_billing_.Reset();
845 suggested_email_.Reset(); 870 suggested_email_.Reset();
846 suggested_shipping_.Reset(); 871 suggested_shipping_.Reset();
847 872
848 PersonalDataManager* manager = GetManager(); 873 if (CanPayWithWallet()) {
849 const std::vector<CreditCard*>& cards = manager->credit_cards(); 874 if (wallet_items_.get()) {
850 for (size_t i = 0; i < cards.size(); ++i) { 875 // TODO(estade): seems we need to hardcode the email address.
851 suggested_cc_.AddKeyedItem(cards[i]->guid(), cards[i]->Label()); 876 // TODO(estade): CC and billing need to be combined into one section,
852 } 877 // and suggestions added here.
853 878 const std::vector<wallet::Address*>& addresses =
854 const std::vector<AutofillProfile*>& profiles = manager->GetProfiles(); 879 wallet_items_->addresses();
855 const std::string app_locale = AutofillCountry::ApplicationLocale(); 880 for (size_t i = 0; i < addresses.size(); ++i) {
856 for (size_t i = 0; i < profiles.size(); ++i) { 881 suggested_billing_.AddKeyedItem(base::IntToString(i),
857 if (!IsCompleteProfile(*profiles[i])) 882 addresses[i]->DisplayName());
858 continue; 883 suggested_shipping_.AddKeyedItem(base::IntToString(i),
859 884 addresses[i]->DisplayName());
860 // Add all email addresses. 885 }
861 std::vector<string16> values; 886 }
862 profiles[i]->GetMultiInfo(EMAIL_ADDRESS, app_locale, &values); 887 } else {
863 for (size_t j = 0; j < values.size(); ++j) { 888 PersonalDataManager* manager = GetManager();
864 if (!values[j].empty()) 889 const std::vector<CreditCard*>& cards = manager->credit_cards();
865 suggested_email_.AddKeyedItem(profiles[i]->guid(), values[j]); 890 for (size_t i = 0; i < cards.size(); ++i) {
891 suggested_cc_.AddKeyedItem(cards[i]->guid(), cards[i]->Label());
866 } 892 }
867 893
868 // Don't add variants for addresses: the email variants are handled above, 894 const std::vector<AutofillProfile*>& profiles = manager->GetProfiles();
869 // name is part of credit card and we'll just ignore phone number variants. 895 const std::string app_locale = AutofillCountry::ApplicationLocale();
870 suggested_billing_.AddKeyedItem(profiles[i]->guid(), profiles[i]->Label()); 896 for (size_t i = 0; i < profiles.size(); ++i) {
871 suggested_shipping_.AddKeyedItem(profiles[i]->guid(), profiles[i]->Label()); 897 if (!IsCompleteProfile(*profiles[i]))
898 continue;
899
900 // Add all email addresses.
901 std::vector<string16> values;
902 profiles[i]->GetMultiInfo(EMAIL_ADDRESS, app_locale, &values);
903 for (size_t j = 0; j < values.size(); ++j) {
904 if (!values[j].empty())
905 suggested_email_.AddKeyedItem(profiles[i]->guid(), values[j]);
906 }
907
908 // Don't add variants for addresses: the email variants are handled above,
909 // name is part of credit card and we'll just ignore phone number
910 // variants.
911 suggested_billing_.AddKeyedItem(profiles[i]->guid(),
912 profiles[i]->Label());
913 suggested_shipping_.AddKeyedItem(profiles[i]->guid(),
914 profiles[i]->Label());
915 }
872 } 916 }
873 917
874 suggested_email_.AddKeyedItem( 918 suggested_email_.AddKeyedItem(
875 std::string(), 919 std::string(),
876 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_EMAIL_ADDRESS)); 920 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_EMAIL_ADDRESS));
877 suggested_cc_.AddKeyedItem( 921 suggested_cc_.AddKeyedItem(
878 std::string(), 922 std::string(),
879 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_CREDIT_CARD)); 923 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_CREDIT_CARD));
880 suggested_billing_.AddKeyedItem( 924 suggested_billing_.AddKeyedItem(
881 std::string(), 925 std::string(),
(...skipping 13 matching lines...) Expand all
895 } 939 }
896 } 940 }
897 941
898 return true; 942 return true;
899 } 943 }
900 944
901 void AutofillDialogControllerImpl::FillOutputForSectionWithComparator( 945 void AutofillDialogControllerImpl::FillOutputForSectionWithComparator(
902 DialogSection section, 946 DialogSection section,
903 const InputFieldComparator& compare) { 947 const InputFieldComparator& compare) {
904 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 948 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
905 std::string guid = model->GetItemKeyAt(model->checked_item()); 949 std::string item_key = model->GetItemKeyAt(model->checked_item());
906 PersonalDataManager* manager = GetManager(); 950 if (!item_key.empty() && !section_editing_state_[section]) {
907 if (!guid.empty() && !section_editing_state_[section]) { 951 scoped_ptr<DataModelWrapper> model = CreateWrapper(section);
908 FormGroup* form_group = section == SECTION_CC ? 952 // Only fill in data that is associated with this section.
909 static_cast<FormGroup*>(manager->GetCreditCardByGUID(guid)) : 953 const DetailInputs& inputs = RequestedFieldsForSection(section);
910 static_cast<FormGroup*>(manager->GetProfileByGUID(guid)); 954 model->FillFormStructure(inputs, compare, &form_structure_);
911 DCHECK(form_group);
912
913 // Calculate the variant by looking at how many items come from the same
914 // FormGroup. TODO(estade): add a test for this.
915 size_t variant = 0;
916 for (int i = model->checked_item() - 1; i >= 0; --i) {
917 if (model->GetItemKeyAt(i) == guid)
918 variant++;
919 else
920 break;
921 }
922
923 FillFormStructureForSection(*form_group, variant, section, compare);
924 955
925 // CVC needs special-casing because the CreditCard class doesn't store 956 // CVC needs special-casing because the CreditCard class doesn't store
926 // or handle them. 957 // or handle them.
927 if (section == SECTION_CC) 958 if (section == SECTION_CC)
928 SetCvcResult(view_->GetCvc()); 959 SetCvcResult(view_->GetCvc());
929 } else { 960 } else {
930 // The user manually input data. 961 // The user manually input data.
962 PersonalDataManager* manager = GetManager();
931 DetailOutputMap output; 963 DetailOutputMap output;
932 view_->GetUserInput(section, &output); 964 view_->GetUserInput(section, &output);
933 965
934 // Save the info as new or edited data, then fill it into |form_structure_|. 966 // Save the info as new or edited data, then fill it into |form_structure_|.
935 if (section == SECTION_CC) { 967 if (section == SECTION_CC) {
936 CreditCard card; 968 CreditCard card;
937 FillFormGroupFromOutputs(output, &card); 969 FillFormGroupFromOutputs(output, &card);
938 if (view_->SaveDetailsLocally()) 970 if (view_->SaveDetailsLocally())
939 manager->SaveImportedCreditCard(card); 971 manager->SaveImportedCreditCard(card);
940 FillFormStructureForSection(card, 0, section, compare); 972 FillFormStructureForSection(card, 0, section, compare);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 DialogSection section) { 1065 DialogSection section) {
1034 return const_cast<DetailInputs*>(&RequestedFieldsForSection(section)); 1066 return const_cast<DetailInputs*>(&RequestedFieldsForSection(section));
1035 } 1067 }
1036 1068
1037 void AutofillDialogControllerImpl::HidePopup() { 1069 void AutofillDialogControllerImpl::HidePopup() {
1038 if (popup_controller_) 1070 if (popup_controller_)
1039 popup_controller_->Hide(); 1071 popup_controller_->Hide();
1040 } 1072 }
1041 1073
1042 } // namespace autofill 1074 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/ui/autofill/autofill_dialog_controller_impl.h ('k') | chrome/browser/ui/autofill/autofill_dialog_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698