Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 634 | 634 |
| 635 legal_document_link_ranges_.clear(); | 635 legal_document_link_ranges_.clear(); |
| 636 for (size_t i = 0; i < documents.size(); ++i) { | 636 for (size_t i = 0; i < documents.size(); ++i) { |
| 637 size_t link_start = text.find(documents[i]->display_name()); | 637 size_t link_start = text.find(documents[i]->display_name()); |
| 638 legal_document_link_ranges_.push_back(ui::Range( | 638 legal_document_link_ranges_.push_back(ui::Range( |
| 639 link_start, link_start + documents[i]->display_name().size())); | 639 link_start, link_start + documents[i]->display_name().size())); |
| 640 } | 640 } |
| 641 legal_documents_text_ = text; | 641 legal_documents_text_ = text; |
| 642 } | 642 } |
| 643 | 643 |
| 644 void AutofillDialogControllerImpl::ResetManualInputForSection( | 644 void AutofillDialogControllerImpl::PrepareDetailInputsForSection( |
| 645 DialogSection section) { | 645 DialogSection section) { |
| 646 // Reset all previously entered data and stop editing |section|. | |
| 646 DetailInputs* inputs = MutableRequestedFieldsForSection(section); | 647 DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
| 647 for (size_t i = 0; i < inputs->size(); ++i) | 648 for (size_t i = 0; i < inputs->size(); ++i) { |
| 648 (*inputs)[i].initial_value.clear(); | 649 (*inputs)[i].initial_value.clear(); |
| 650 } | |
| 649 section_editing_state_[section] = false; | 651 section_editing_state_[section] = false; |
| 652 | |
| 653 // If the chosen item in |model| yields an empty suggestion text, it is | |
| 654 // invalid. In this case, show the editing UI with invalid fields highlighted. | |
| 655 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | |
| 656 if (IsASuggestionItemKey(model->GetItemKeyForCheckedItem()) && | |
| 657 SuggestionTextForSection(section).empty()) { | |
| 658 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); | |
| 659 wrapper->FillInputs(MutableRequestedFieldsForSection(section)); | |
| 660 section_editing_state_[section] = true; | |
| 661 } | |
| 662 | |
| 663 if (view_) | |
| 664 view_->UpdateSection(section); | |
| 650 } | 665 } |
| 651 | 666 |
| 652 const DetailInputs& AutofillDialogControllerImpl::RequestedFieldsForSection( | 667 const DetailInputs& AutofillDialogControllerImpl::RequestedFieldsForSection( |
| 653 DialogSection section) const { | 668 DialogSection section) const { |
| 654 switch (section) { | 669 switch (section) { |
| 655 case SECTION_EMAIL: | 670 case SECTION_EMAIL: |
| 656 return requested_email_fields_; | 671 return requested_email_fields_; |
| 657 case SECTION_CC: | 672 case SECTION_CC: |
| 658 return requested_cc_fields_; | 673 return requested_cc_fields_; |
| 659 case SECTION_BILLING: | 674 case SECTION_BILLING: |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 744 ExtraSuggestionIconForSection(section), | 759 ExtraSuggestionIconForSection(section), |
| 745 EditEnabledForSection(section)); | 760 EditEnabledForSection(section)); |
| 746 } | 761 } |
| 747 | 762 |
| 748 string16 AutofillDialogControllerImpl::SuggestionTextForSection( | 763 string16 AutofillDialogControllerImpl::SuggestionTextForSection( |
| 749 DialogSection section) { | 764 DialogSection section) { |
| 750 string16 action_text = RequiredActionTextForSection(section); | 765 string16 action_text = RequiredActionTextForSection(section); |
| 751 if (!action_text.empty()) | 766 if (!action_text.empty()) |
| 752 return action_text; | 767 return action_text; |
| 753 | 768 |
| 754 // When the user has clicked 'edit', don't show a suggestion (even though | 769 // When the user has clicked 'edit' or a suggestion is somehow invalid (e.g. a |
| 755 // there is a profile selected in the model). | 770 // user selects a credit card that has expired), don't show a suggestion (even |
| 771 // though there is a profile selected in the model). | |
| 756 if (section_editing_state_[section]) | 772 if (section_editing_state_[section]) |
| 757 return string16(); | 773 return string16(); |
| 758 | 774 |
| 759 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | 775 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
| 760 std::string item_key = model->GetItemKeyForCheckedItem(); | 776 std::string item_key = model->GetItemKeyForCheckedItem(); |
| 761 if (item_key == kSameAsBillingKey) { | 777 if (item_key == kSameAsBillingKey) { |
| 762 return l10n_util::GetStringUTF16( | 778 return l10n_util::GetStringUTF16( |
| 763 IDS_AUTOFILL_DIALOG_USING_BILLING_FOR_SHIPPING); | 779 IDS_AUTOFILL_DIALOG_USING_BILLING_FOR_SHIPPING); |
| 764 } | 780 } |
| 765 | 781 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 } | 911 } |
| 896 | 912 |
| 897 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) | 913 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) |
| 898 return false; | 914 return false; |
| 899 | 915 |
| 900 return true; | 916 return true; |
| 901 } | 917 } |
| 902 | 918 |
| 903 void AutofillDialogControllerImpl::EditClickedForSection( | 919 void AutofillDialogControllerImpl::EditClickedForSection( |
| 904 DialogSection section) { | 920 DialogSection section) { |
| 905 DetailInputs* inputs = MutableRequestedFieldsForSection(section); | 921 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); |
| 906 scoped_ptr<DataModelWrapper> model = CreateWrapper(section); | 922 wrapper->FillInputs(MutableRequestedFieldsForSection(section)); |
| 907 model->FillInputs(inputs); | |
| 908 section_editing_state_[section] = true; | 923 section_editing_state_[section] = true; |
| 909 view_->UpdateSection(section); | 924 view_->UpdateSection(section); |
| 910 | 925 |
| 911 GetMetricLogger().LogDialogUiEvent( | 926 GetMetricLogger().LogDialogUiEvent( |
| 912 dialog_type_, DialogSectionToUiEditEvent(section)); | 927 dialog_type_, DialogSectionToUiEditEvent(section)); |
| 913 } | 928 } |
| 914 | 929 |
| 915 void AutofillDialogControllerImpl::EditCancelledForSection( | 930 void AutofillDialogControllerImpl::EditCancelledForSection( |
| 916 DialogSection section) { | 931 DialogSection section) { |
| 917 ResetManualInputForSection(section); | 932 PrepareDetailInputsForSection(section); |
| 918 view_->UpdateSection(section); | |
| 919 } | 933 } |
| 920 | 934 |
| 921 gfx::Image AutofillDialogControllerImpl::IconForField( | 935 gfx::Image AutofillDialogControllerImpl::IconForField( |
| 922 AutofillFieldType type, const string16& user_input) const { | 936 AutofillFieldType type, const string16& user_input) const { |
| 923 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 937 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 924 if (type == CREDIT_CARD_VERIFICATION_CODE) | 938 if (type == CREDIT_CARD_VERIFICATION_CODE) |
| 925 return rb.GetImageNamed(IDR_CREDIT_CARD_CVC_HINT); | 939 return rb.GetImageNamed(IDR_CREDIT_CARD_CVC_HINT); |
| 926 | 940 |
| 927 // For the credit card, we show a few grayscale images, and possibly one | 941 // For the credit card, we show a few grayscale images, and possibly one |
| 928 // color image if |user_input| is a valid card number. | 942 // color image if |user_input| is a valid card number. |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1388 chrome::kAutofillSubPage)); | 1402 chrome::kAutofillSubPage)); |
| 1389 } else { | 1403 } else { |
| 1390 // TODO(estade): show a wallet URL. | 1404 // TODO(estade): show a wallet URL. |
| 1391 NOTIMPLEMENTED(); | 1405 NOTIMPLEMENTED(); |
| 1392 } | 1406 } |
| 1393 | 1407 |
| 1394 return; | 1408 return; |
| 1395 } | 1409 } |
| 1396 | 1410 |
| 1397 model->SetCheckedIndex(index); | 1411 model->SetCheckedIndex(index); |
| 1398 EditCancelledForSection(SectionForSuggestionsMenuModel(*model)); | 1412 |
| 1413 const DialogSection section = SectionForSuggestionsMenuModel(*model); | |
| 1414 PrepareDetailInputsForSection(section); | |
| 1399 | 1415 |
| 1400 LogSuggestionItemSelectedMetric(*model); | 1416 LogSuggestionItemSelectedMetric(*model); |
| 1401 } | 1417 } |
| 1402 | 1418 |
| 1403 //////////////////////////////////////////////////////////////////////////////// | 1419 //////////////////////////////////////////////////////////////////////////////// |
| 1404 // wallet::WalletClientDelegate implementation. | 1420 // wallet::WalletClientDelegate implementation. |
| 1405 | 1421 |
| 1406 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const { | 1422 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const { |
| 1407 return metric_logger_; | 1423 return metric_logger_; |
| 1408 } | 1424 } |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1565 // PersonalDataManagerObserver implementation. | 1581 // PersonalDataManagerObserver implementation. |
| 1566 | 1582 |
| 1567 void AutofillDialogControllerImpl::OnPersonalDataChanged() { | 1583 void AutofillDialogControllerImpl::OnPersonalDataChanged() { |
| 1568 SuggestionsUpdated(); | 1584 SuggestionsUpdated(); |
| 1569 } | 1585 } |
| 1570 | 1586 |
| 1571 //////////////////////////////////////////////////////////////////////////////// | 1587 //////////////////////////////////////////////////////////////////////////////// |
| 1572 // AccountChooserModelDelegate implementation. | 1588 // AccountChooserModelDelegate implementation. |
| 1573 | 1589 |
| 1574 void AutofillDialogControllerImpl::AccountChoiceChanged() { | 1590 void AutofillDialogControllerImpl::AccountChoiceChanged() { |
| 1575 // Whenever the user changes the account, all manual inputs should be reset. | |
| 1576 ResetManualInputForSection(SECTION_EMAIL); | |
| 1577 ResetManualInputForSection(SECTION_CC); | |
| 1578 ResetManualInputForSection(SECTION_BILLING); | |
| 1579 ResetManualInputForSection(SECTION_CC_BILLING); | |
| 1580 ResetManualInputForSection(SECTION_SHIPPING); | |
|
Dan Beam
2013/05/01 00:46:22
these weren't necessary
| |
| 1581 | |
| 1582 if (is_submitting_) | 1591 if (is_submitting_) |
| 1583 GetWalletClient()->CancelRequests(); | 1592 GetWalletClient()->CancelRequests(); |
| 1584 | 1593 |
| 1585 SetIsSubmitting(false); | 1594 SetIsSubmitting(false); |
| 1586 | 1595 |
| 1587 if (!signin_helper_ && account_chooser_model_.WalletIsSelected()) { | 1596 if (!signin_helper_ && account_chooser_model_.WalletIsSelected()) { |
| 1588 if (account_chooser_model_.IsActiveWalletAccountSelected()) { | 1597 if (account_chooser_model_.IsActiveWalletAccountSelected()) { |
| 1589 // If the user has chosen an already active Wallet account, and we don't | 1598 // If the user has chosen an already active Wallet account, and we don't |
| 1590 // have the Wallet items, an attempt to fetch the Wallet data is made to | 1599 // have the Wallet items, an attempt to fetch the Wallet data is made to |
| 1591 // see if the user is still signed in. This will trigger a passive sign-in | 1600 // see if the user is still signed in. This will trigger a passive sign-in |
| 1592 // if required. | 1601 // if required. |
| 1593 if (!wallet_items_) | 1602 if (!wallet_items_) |
| 1594 GetWalletItems(); | 1603 GetWalletItems(); |
| 1595 else | 1604 else |
| 1596 SignedInStateUpdated(); | 1605 SignedInStateUpdated(); |
| 1597 } else { | 1606 } else { |
| 1598 // TODO(aruslan): trigger the automatic sign-in process. | 1607 // TODO(aruslan): trigger the automatic sign-in process. |
| 1599 LOG(ERROR) << "failed to initiate an automatic sign-in"; | 1608 LOG(ERROR) << "failed to initiate an automatic sign-in"; |
| 1600 OnWalletSigninError(); | 1609 OnWalletSigninError(); |
| 1601 } | 1610 } |
| 1602 } | 1611 } |
| 1603 | 1612 |
| 1604 SuggestionsUpdated(); | 1613 SuggestionsUpdated(); |
|
Dan Beam
2013/05/01 00:46:22
as this calls PrepareDetailInputsForSection() on a
| |
| 1605 UpdateAccountChooserView(); | 1614 UpdateAccountChooserView(); |
| 1606 } | 1615 } |
| 1607 | 1616 |
| 1608 void AutofillDialogControllerImpl::UpdateAccountChooserView() { | 1617 void AutofillDialogControllerImpl::UpdateAccountChooserView() { |
| 1609 if (view_) { | 1618 if (view_) { |
| 1610 view_->UpdateAccountChooser(); | 1619 view_->UpdateAccountChooser(); |
| 1611 view_->UpdateNotificationArea(); | 1620 view_->UpdateNotificationArea(); |
| 1612 } | 1621 } |
| 1613 } | 1622 } |
| 1614 | 1623 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1727 } | 1736 } |
| 1728 | 1737 |
| 1729 const std::vector<wallet::Address*>& addresses = | 1738 const std::vector<wallet::Address*>& addresses = |
| 1730 wallet_items_->addresses(); | 1739 wallet_items_->addresses(); |
| 1731 for (size_t i = 0; i < addresses.size(); ++i) { | 1740 for (size_t i = 0; i < addresses.size(); ++i) { |
| 1732 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954 | 1741 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954 |
| 1733 suggested_shipping_.AddKeyedItemWithSublabel( | 1742 suggested_shipping_.AddKeyedItemWithSublabel( |
| 1734 base::IntToString(i), | 1743 base::IntToString(i), |
| 1735 addresses[i]->DisplayName(), | 1744 addresses[i]->DisplayName(), |
| 1736 addresses[i]->DisplayNameDetail()); | 1745 addresses[i]->DisplayNameDetail()); |
| 1737 | |
| 1738 } | 1746 } |
| 1739 | 1747 |
| 1740 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { | 1748 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { |
| 1741 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = | 1749 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = |
| 1742 wallet_items_->instruments(); | 1750 wallet_items_->instruments(); |
| 1743 for (size_t i = 0; i < instruments.size(); ++i) { | 1751 for (size_t i = 0; i < instruments.size(); ++i) { |
| 1744 // TODO(dbeam): respect the default address ID. http://crbug.com/232954 | 1752 // TODO(dbeam): respect the default address ID. http://crbug.com/232954 |
| 1745 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( | 1753 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( |
| 1746 base::IntToString(i), | 1754 base::IntToString(i), |
| 1747 instruments[i]->DisplayName(), | 1755 instruments[i]->DisplayName(), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1820 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS)); | 1828 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS)); |
| 1821 suggested_shipping_.AddKeyedItem( | 1829 suggested_shipping_.AddKeyedItem( |
| 1822 kManageItemsKey, | 1830 kManageItemsKey, |
| 1823 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS)); | 1831 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS)); |
| 1824 | 1832 |
| 1825 // Default shipping address is the first suggestion, if one exists. Otherwise | 1833 // Default shipping address is the first suggestion, if one exists. Otherwise |
| 1826 // it's the "Use shipping for billing" item. | 1834 // it's the "Use shipping for billing" item. |
| 1827 const std::string& first_real_suggestion_item_key = | 1835 const std::string& first_real_suggestion_item_key = |
| 1828 suggested_shipping_.GetItemKeyAt(1); | 1836 suggested_shipping_.GetItemKeyAt(1); |
| 1829 if (IsASuggestionItemKey(first_real_suggestion_item_key)) | 1837 if (IsASuggestionItemKey(first_real_suggestion_item_key)) |
| 1830 suggested_shipping_.SetCheckedItem(first_real_suggestion_item_key); | 1838 suggested_shipping_.SetCheckedItem(first_real_suggestion_item_key); |
| 1831 | 1839 |
| 1832 if (view_) | 1840 if (view_) |
| 1833 view_->ModelChanged(); | 1841 view_->ModelChanged(); |
| 1842 | |
| 1843 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) { | |
| 1844 PrepareDetailInputsForSection(static_cast<DialogSection>(section)); | |
| 1845 } | |
| 1834 } | 1846 } |
| 1835 | 1847 |
| 1848 | |
| 1836 bool AutofillDialogControllerImpl::IsCompleteProfile( | 1849 bool AutofillDialogControllerImpl::IsCompleteProfile( |
| 1837 const AutofillProfile& profile) { | 1850 const AutofillProfile& profile) { |
| 1838 const std::string app_locale = g_browser_process->GetApplicationLocale(); | 1851 const std::string app_locale = g_browser_process->GetApplicationLocale(); |
| 1839 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { | 1852 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { |
| 1840 AutofillFieldType type = requested_shipping_fields_[i].type; | 1853 AutofillFieldType type = requested_shipping_fields_[i].type; |
| 1841 if (type != ADDRESS_HOME_LINE2 && | 1854 if (type != ADDRESS_HOME_LINE2 && |
| 1842 profile.GetInfo(type, app_locale).empty()) { | 1855 profile.GetInfo(type, app_locale).empty()) { |
| 1843 return false; | 1856 return false; |
| 1844 } | 1857 } |
| 1845 } | 1858 } |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2308 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric( | 2321 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric( |
| 2309 const SuggestionsMenuModel& model) { | 2322 const SuggestionsMenuModel& model) { |
| 2310 DialogSection section = SectionForSuggestionsMenuModel(model); | 2323 DialogSection section = SectionForSuggestionsMenuModel(model); |
| 2311 | 2324 |
| 2312 AutofillMetrics::DialogUiEvent dialog_ui_event; | 2325 AutofillMetrics::DialogUiEvent dialog_ui_event; |
| 2313 if (model.GetItemKeyForCheckedItem() == kAddNewItemKey) { | 2326 if (model.GetItemKeyForCheckedItem() == kAddNewItemKey) { |
| 2314 // Selected to add a new item. | 2327 // Selected to add a new item. |
| 2315 dialog_ui_event = DialogSectionToUiItemAddedEvent(section); | 2328 dialog_ui_event = DialogSectionToUiItemAddedEvent(section); |
| 2316 } else if (IsASuggestionItemKey(model.GetItemKeyForCheckedItem())) { | 2329 } else if (IsASuggestionItemKey(model.GetItemKeyForCheckedItem())) { |
| 2317 // Selected an existing item. | 2330 // Selected an existing item. |
| 2318 DCHECK(!section_editing_state_[section]); | |
| 2319 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section); | 2331 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section); |
| 2320 } else { | 2332 } else { |
| 2321 // TODO(estade): add logging for "Manage items" or "Use billing for | 2333 // TODO(estade): add logging for "Manage items" or "Use billing for |
| 2322 // shipping"? | 2334 // shipping"? |
| 2323 return; | 2335 return; |
| 2324 } | 2336 } |
| 2325 | 2337 |
| 2326 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event); | 2338 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event); |
| 2327 } | 2339 } |
| 2328 | 2340 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2373 url, | 2385 url, |
| 2374 content::PAGE_TRANSITION_AUTO_BOOKMARK); | 2386 content::PAGE_TRANSITION_AUTO_BOOKMARK); |
| 2375 params.disposition = NEW_FOREGROUND_TAB; | 2387 params.disposition = NEW_FOREGROUND_TAB; |
| 2376 chrome::Navigate(¶ms); | 2388 chrome::Navigate(¶ms); |
| 2377 #else | 2389 #else |
| 2378 // TODO(estade): use TabModelList? | 2390 // TODO(estade): use TabModelList? |
| 2379 #endif | 2391 #endif |
| 2380 } | 2392 } |
| 2381 | 2393 |
| 2382 } // namespace autofill | 2394 } // namespace autofill |
| OLD | NEW |