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

Side by Side Diff: chrome/browser/ui/views/autofill/autofill_dialog_views.cc

Issue 124533003: Add country combobox to change country and rebuild address inputs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comment Created 6 years, 11 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
« no previous file with comments | « chrome/browser/ui/views/autofill/autofill_dialog_views.h ('k') | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/views/autofill/autofill_dialog_views.h" 5 #include "chrome/browser/ui/views/autofill/autofill_dialog_views.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 1318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 } 1329 }
1330 1330
1331 void AutofillDialogViews::UpdateErrorBubble() { 1331 void AutofillDialogViews::UpdateErrorBubble() {
1332 if (!delegate_->ShouldShowErrorBubble()) 1332 if (!delegate_->ShouldShowErrorBubble())
1333 HideErrorBubble(); 1333 HideErrorBubble();
1334 } 1334 }
1335 1335
1336 void AutofillDialogViews::FillSection(DialogSection section, 1336 void AutofillDialogViews::FillSection(DialogSection section,
1337 ServerFieldType originating_type) { 1337 ServerFieldType originating_type) {
1338 DetailsGroup* group = GroupForSection(section); 1338 DetailsGroup* group = GroupForSection(section);
1339 // Make sure to overwrite the originating input. 1339 // Make sure to overwrite the originating input if it exists.
1340 TextfieldMap::iterator text_mapping = 1340 TextfieldMap::iterator text_mapping =
1341 group->textfields.find(originating_type); 1341 group->textfields.find(originating_type);
1342 if (text_mapping != group->textfields.end()) 1342 if (text_mapping != group->textfields.end())
1343 text_mapping->second->SetText(base::string16()); 1343 text_mapping->second->SetText(base::string16());
1344 1344
1345 // If the Autofill data comes from a credit card, make sure to overwrite the 1345 // If the Autofill data comes from a credit card, make sure to overwrite the
1346 // CC comboboxes (even if they already have something in them). If the 1346 // CC comboboxes (even if they already have something in them). If the
1347 // Autofill data comes from an AutofillProfile, leave the comboboxes alone. 1347 // Autofill data comes from an AutofillProfile, leave the comboboxes alone.
1348 if (section == GetCreditCardSection() && 1348 if (section == GetCreditCardSection() &&
1349 AutofillType(originating_type).group() == CREDIT_CARD) { 1349 AutofillType(originating_type).group() == CREDIT_CARD) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 } 1494 }
1495 1495
1496 void AutofillDialogViews::SetTextContentsOfSuggestionInput( 1496 void AutofillDialogViews::SetTextContentsOfSuggestionInput(
1497 DialogSection section, 1497 DialogSection section,
1498 const base::string16& text) { 1498 const base::string16& text) {
1499 GroupForSection(section)->suggested_info->decorated_textfield()-> 1499 GroupForSection(section)->suggested_info->decorated_textfield()->
1500 SetText(text); 1500 SetText(text);
1501 } 1501 }
1502 1502
1503 void AutofillDialogViews::ActivateInput(ServerFieldType type) { 1503 void AutofillDialogViews::ActivateInput(ServerFieldType type) {
1504 TextfieldEditedOrActivated(TextfieldForType(type), false); 1504 InputEditedOrActivated(type, gfx::Rect(), false);
1505 } 1505 }
1506 1506
1507 gfx::Size AutofillDialogViews::GetSize() const { 1507 gfx::Size AutofillDialogViews::GetSize() const {
1508 return GetWidget() ? GetWidget()->GetRootView()->size() : gfx::Size(); 1508 return GetWidget() ? GetWidget()->GetRootView()->size() : gfx::Size();
1509 } 1509 }
1510 1510
1511 content::WebContents* AutofillDialogViews::GetSignInWebContents() { 1511 content::WebContents* AutofillDialogViews::GetSignInWebContents() {
1512 return sign_in_web_view_->web_contents(); 1512 return sign_in_web_view_->web_contents();
1513 } 1513 }
1514 1514
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 1548
1549 // The rest (the |scrollable_area_|) takes up whatever's left. 1549 // The rest (the |scrollable_area_|) takes up whatever's left.
1550 if (scrollable_area_->visible()) { 1550 if (scrollable_area_->visible()) {
1551 int scroll_y = y; 1551 int scroll_y = y;
1552 if (notification_height > notification_area_->GetInsets().height()) 1552 if (notification_height > notification_area_->GetInsets().height())
1553 scroll_y += notification_height + views::kRelatedControlVerticalSpacing; 1553 scroll_y += notification_height + views::kRelatedControlVerticalSpacing;
1554 1554
1555 int scroll_bottom = content_bounds.bottom(); 1555 int scroll_bottom = content_bounds.bottom();
1556 DCHECK_EQ(scrollable_area_->contents(), details_container_); 1556 DCHECK_EQ(scrollable_area_->contents(), details_container_);
1557 details_container_->SizeToPreferredSize(); 1557 details_container_->SizeToPreferredSize();
1558 details_container_->Layout();
1558 // TODO(estade): remove this hack. See crbug.com/285996 1559 // TODO(estade): remove this hack. See crbug.com/285996
1559 details_container_->set_ignore_layouts(true); 1560 details_container_->set_ignore_layouts(true);
1560 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y); 1561 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y);
1561 details_container_->set_ignore_layouts(false); 1562 details_container_->set_ignore_layouts(false);
1562 } 1563 }
1563 1564
1564 if (error_bubble_) 1565 if (error_bubble_)
1565 error_bubble_->UpdatePosition(); 1566 error_bubble_->UpdatePosition();
1566 } 1567 }
1567 1568
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 // on all dialogs. 1705 // on all dialogs.
1705 views::NonClientFrameView* AutofillDialogViews::CreateNonClientFrameView( 1706 views::NonClientFrameView* AutofillDialogViews::CreateNonClientFrameView(
1706 views::Widget* widget) { 1707 views::Widget* widget) {
1707 return CreateConstrainedStyleNonClientFrameView( 1708 return CreateConstrainedStyleNonClientFrameView(
1708 widget, 1709 widget,
1709 delegate_->GetWebContents()->GetBrowserContext()); 1710 delegate_->GetWebContents()->GetBrowserContext());
1710 } 1711 }
1711 1712
1712 void AutofillDialogViews::ContentsChanged(views::Textfield* sender, 1713 void AutofillDialogViews::ContentsChanged(views::Textfield* sender,
1713 const base::string16& new_contents) { 1714 const base::string16& new_contents) {
1714 TextfieldEditedOrActivated(sender, true); 1715 InputEditedOrActivated(TypeForTextfield(sender),
1716 sender->GetBoundsInScreen(),
1717 true);
1715 } 1718 }
1716 1719
1717 bool AutofillDialogViews::HandleKeyEvent(views::Textfield* sender, 1720 bool AutofillDialogViews::HandleKeyEvent(views::Textfield* sender,
1718 const ui::KeyEvent& key_event) { 1721 const ui::KeyEvent& key_event) {
1719 ui::KeyEvent copy(key_event); 1722 ui::KeyEvent copy(key_event);
1720 content::NativeWebKeyboardEvent event(&copy); 1723 content::NativeWebKeyboardEvent event(&copy);
1721 return delegate_->HandleKeyPressEventInInput(event); 1724 return delegate_->HandleKeyPressEventInInput(event);
1722 } 1725 }
1723 1726
1724 bool AutofillDialogViews::HandleMouseEvent(views::Textfield* sender, 1727 bool AutofillDialogViews::HandleMouseEvent(views::Textfield* sender,
1725 const ui::MouseEvent& mouse_event) { 1728 const ui::MouseEvent& mouse_event) {
1726 if (mouse_event.IsLeftMouseButton() && sender->HasFocus()) { 1729 if (mouse_event.IsLeftMouseButton() && sender->HasFocus()) {
1727 TextfieldEditedOrActivated(sender, false); 1730 InputEditedOrActivated(TypeForTextfield(sender),
1731 sender->GetBoundsInScreen(),
1732 false);
1728 // Show an error bubble if a user clicks on an input that's already focused 1733 // Show an error bubble if a user clicks on an input that's already focused
1729 // (and invalid). 1734 // (and invalid).
1730 ShowErrorBubbleForViewIfNecessary(sender); 1735 ShowErrorBubbleForViewIfNecessary(sender);
1731 } 1736 }
1732 1737
1733 return false; 1738 return false;
1734 } 1739 }
1735 1740
1736 void AutofillDialogViews::OnWillChangeFocus( 1741 void AutofillDialogViews::OnWillChangeFocus(
1737 views::View* focused_before, 1742 views::View* focused_before,
(...skipping 13 matching lines...) Expand all
1751 } 1756 }
1752 1757
1753 // Show an error bubble when the user focuses the input. 1758 // Show an error bubble when the user focuses the input.
1754 if (focused_now) { 1759 if (focused_now) {
1755 focused_now->ScrollRectToVisible(focused_now->GetLocalBounds()); 1760 focused_now->ScrollRectToVisible(focused_now->GetLocalBounds());
1756 ShowErrorBubbleForViewIfNecessary(focused_now); 1761 ShowErrorBubbleForViewIfNecessary(focused_now);
1757 } 1762 }
1758 } 1763 }
1759 1764
1760 void AutofillDialogViews::OnSelectedIndexChanged(views::Combobox* combobox) { 1765 void AutofillDialogViews::OnSelectedIndexChanged(views::Combobox* combobox) {
1761 DetailsGroup* group = GroupForView(combobox); 1766 DialogSection section = GroupForView(combobox)->section;
1762 ValidateGroup(*group, VALIDATE_EDIT); 1767 InputEditedOrActivated(TypeForCombobox(combobox), gfx::Rect(), true);
1763 SetEditabilityForSection(group->section); 1768 // NOTE: |combobox| may have been deleted.
1769 ValidateGroup(*GroupForSection(section), VALIDATE_EDIT);
1770 SetEditabilityForSection(section);
1764 } 1771 }
1765 1772
1766 void AutofillDialogViews::StyledLabelLinkClicked(const gfx::Range& range, 1773 void AutofillDialogViews::StyledLabelLinkClicked(const gfx::Range& range,
1767 int event_flags) { 1774 int event_flags) {
1768 delegate_->LegalDocumentLinkClicked(range); 1775 delegate_->LegalDocumentLinkClicked(range);
1769 } 1776 }
1770 1777
1771 void AutofillDialogViews::OnMenuButtonClicked(views::View* source, 1778 void AutofillDialogViews::OnMenuButtonClicked(views::View* source,
1772 const gfx::Point& point) { 1779 const gfx::Point& point) {
1773 DCHECK_EQ(kSuggestedButtonClassName, source->GetClassName()); 1780 DCHECK_EQ(kSuggestedButtonClassName, source->GetClassName());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 AddChildView(sign_in_web_view_); 1918 AddChildView(sign_in_web_view_);
1912 1919
1913 overlay_view_ = new OverlayView(delegate_); 1920 overlay_view_ = new OverlayView(delegate_);
1914 overlay_view_->SetVisible(false); 1921 overlay_view_->SetVisible(false);
1915 } 1922 }
1916 1923
1917 views::View* AutofillDialogViews::CreateDetailsContainer() { 1924 views::View* AutofillDialogViews::CreateDetailsContainer() {
1918 details_container_ = new DetailsContainerView( 1925 details_container_ = new DetailsContainerView(
1919 base::Bind(&AutofillDialogViews::DetailsContainerBoundsChanged, 1926 base::Bind(&AutofillDialogViews::DetailsContainerBoundsChanged,
1920 base::Unretained(this))); 1927 base::Unretained(this)));
1928
1921 // A box layout is used because it respects widget visibility. 1929 // A box layout is used because it respects widget visibility.
1922 details_container_->SetLayoutManager( 1930 details_container_->SetLayoutManager(
1923 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 1931 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
1924 for (DetailGroupMap::iterator iter = detail_groups_.begin(); 1932 for (DetailGroupMap::iterator iter = detail_groups_.begin();
1925 iter != detail_groups_.end(); ++iter) { 1933 iter != detail_groups_.end(); ++iter) {
1926 CreateDetailsSection(iter->second.section); 1934 CreateDetailsSection(iter->second.section);
1927 details_container_->AddChildView(iter->second.container); 1935 details_container_->AddChildView(iter->second.container);
1928 } 1936 }
1929 1937
1930 return details_container_; 1938 return details_container_;
(...skipping 12 matching lines...) Expand all
1943 UpdateDetailsGroupState(*group); 1951 UpdateDetailsGroupState(*group);
1944 } 1952 }
1945 1953
1946 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) { 1954 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) {
1947 // The |info_view| holds |manual_inputs| and |suggested_info|, allowing the 1955 // The |info_view| holds |manual_inputs| and |suggested_info|, allowing the
1948 // dialog to toggle which is shown. 1956 // dialog to toggle which is shown.
1949 views::View* info_view = new views::View(); 1957 views::View* info_view = new views::View();
1950 info_view->SetLayoutManager( 1958 info_view->SetLayoutManager(
1951 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 1959 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
1952 1960
1953 views::View* manual_inputs = InitInputsView(section); 1961 DetailsGroup* group = GroupForSection(section);
1954 info_view->AddChildView(manual_inputs); 1962 group->manual_input = new views::View();
1955 SuggestionView* suggested_info = new SuggestionView(this); 1963 InitInputsView(section);
1956 info_view->AddChildView(suggested_info); 1964 info_view->AddChildView(group->manual_input);
1957 1965
1958 DetailsGroup* group = GroupForSection(section); 1966 group->suggested_info = new SuggestionView(this);
1967 info_view->AddChildView(group->suggested_info);
1968
1959 // TODO(estade): It might be slightly more OO if this button were created 1969 // TODO(estade): It might be slightly more OO if this button were created
1960 // and listened to by the section container. 1970 // and listened to by the section container.
1961 group->suggested_button = new SuggestedButton(this); 1971 group->suggested_button = new SuggestedButton(this);
1962 group->manual_input = manual_inputs;
1963 group->suggested_info = suggested_info;
1964 1972
1965 return info_view; 1973 return info_view;
1966 } 1974 }
1967 1975
1968 // TODO(estade): we should be using Chrome-style constrained window padding 1976 // TODO(estade): we should be using Chrome-style constrained window padding
1969 // values. 1977 // values.
1970 views::View* AutofillDialogViews::InitInputsView(DialogSection section) { 1978 void AutofillDialogViews::InitInputsView(DialogSection section) {
1971 const DetailInputs& inputs = delegate_->RequestedFieldsForSection(section); 1979 DetailsGroup* group = GroupForSection(section);
1972 TextfieldMap* textfields = &GroupForSection(section)->textfields; 1980 EraseInvalidViewsInGroup(group);
1973 ComboboxMap* comboboxes = &GroupForSection(section)->comboboxes;
1974 1981
1975 views::View* view = new views::View(); 1982 TextfieldMap* textfields = &group->textfields;
1983 textfields->clear();
1984
1985 ComboboxMap* comboboxes = &group->comboboxes;
1986 comboboxes->clear();
1987
1988 views::View* view = group->manual_input;
1989 view->RemoveAllChildViews(true);
1990
1976 views::GridLayout* layout = new views::GridLayout(view); 1991 views::GridLayout* layout = new views::GridLayout(view);
1977 view->SetLayoutManager(layout); 1992 view->SetLayoutManager(layout);
1978 1993
1979 int column_set_id = 0; 1994 int column_set_id = 0;
1995 const DetailInputs& inputs = delegate_->RequestedFieldsForSection(section);
1980 for (DetailInputs::const_iterator it = inputs.begin(); 1996 for (DetailInputs::const_iterator it = inputs.begin();
1981 it != inputs.end(); ++it) { 1997 it != inputs.end(); ++it) {
1982 const DetailInput& input = *it; 1998 const DetailInput& input = *it;
1999
1983 ui::ComboboxModel* input_model = 2000 ui::ComboboxModel* input_model =
1984 delegate_->ComboboxModelForAutofillType(input.type); 2001 delegate_->ComboboxModelForAutofillType(input.type);
1985 scoped_ptr<views::View> view_to_add; 2002 scoped_ptr<views::View> view_to_add;
1986 if (input_model) { 2003 if (input_model) {
1987 views::Combobox* combobox = new views::Combobox(input_model); 2004 views::Combobox* combobox = new views::Combobox(input_model);
1988 combobox->set_listener(this); 2005 combobox->set_listener(this);
1989 comboboxes->insert(std::make_pair(input.type, combobox)); 2006 comboboxes->insert(std::make_pair(input.type, combobox));
1990 SelectComboboxValueOrSetToDefault(combobox, input.initial_value); 2007 SelectComboboxValueOrSetToDefault(combobox, input.initial_value);
1991 view_to_add.reset(combobox); 2008 view_to_add.reset(combobox);
1992 } else { 2009 } else {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2035 views::GridLayout::FILL, views::GridLayout::FILL, 2052 views::GridLayout::FILL, views::GridLayout::FILL,
2036 1, 0); 2053 1, 0);
2037 2054
2038 if (input.length == DetailInput::LONG || 2055 if (input.length == DetailInput::LONG ||
2039 input.length == DetailInput::SHORT_EOL) { 2056 input.length == DetailInput::SHORT_EOL) {
2040 ++column_set_id; 2057 ++column_set_id;
2041 } 2058 }
2042 } 2059 }
2043 2060
2044 SetIconsForSection(section); 2061 SetIconsForSection(section);
2045
2046 return view;
2047 } 2062 }
2048 2063
2049 void AutofillDialogViews::ShowDialogInMode(DialogMode dialog_mode) { 2064 void AutofillDialogViews::ShowDialogInMode(DialogMode dialog_mode) {
2050 loading_shield_->SetVisible(dialog_mode == LOADING); 2065 loading_shield_->SetVisible(dialog_mode == LOADING);
2051 sign_in_web_view_->SetVisible(dialog_mode == SIGN_IN); 2066 sign_in_web_view_->SetVisible(dialog_mode == SIGN_IN);
2052 notification_area_->SetVisible(dialog_mode == DETAIL_INPUT); 2067 notification_area_->SetVisible(dialog_mode == DETAIL_INPUT);
2053 scrollable_area_->SetVisible(dialog_mode == DETAIL_INPUT); 2068 scrollable_area_->SetVisible(dialog_mode == DETAIL_INPUT);
2054 FocusInitialView(); 2069 FocusInitialView();
2055 } 2070 }
2056 2071
2057 void AutofillDialogViews::UpdateSectionImpl( 2072 void AutofillDialogViews::UpdateSectionImpl(
2058 DialogSection section, 2073 DialogSection section,
2059 bool clobber_inputs) { 2074 bool clobber_inputs) {
2060 // Reset all validity marks for this section.
2061 if (clobber_inputs)
2062 MarkInputsInvalid(section, ValidityMessages(), true);
2063
2064 const DetailInputs& updated_inputs =
2065 delegate_->RequestedFieldsForSection(section);
2066 DetailsGroup* group = GroupForSection(section); 2075 DetailsGroup* group = GroupForSection(section);
2067 2076
2068 for (DetailInputs::const_iterator iter = updated_inputs.begin(); 2077 if (clobber_inputs) {
2069 iter != updated_inputs.end(); ++iter) { 2078 InitInputsView(section);
2070 const DetailInput& input = *iter; 2079 } else {
2071 TextfieldMap::iterator text_mapping = group->textfields.find(input.type); 2080 const DetailInputs& updated_inputs =
2081 delegate_->RequestedFieldsForSection(section);
2072 2082
2073 if (text_mapping != group->textfields.end()) { 2083 for (DetailInputs::const_iterator iter = updated_inputs.begin();
2074 DecoratedTextfield* decorated = text_mapping->second; 2084 iter != updated_inputs.end(); ++iter) {
2075 if (decorated->text().empty() || clobber_inputs) 2085 const DetailInput& input = *iter;
2076 decorated->SetText(input.initial_value); 2086
2087 TextfieldMap::iterator text_mapping = group->textfields.find(input.type);
2088 if (text_mapping != group->textfields.end()) {
2089 DecoratedTextfield* decorated = text_mapping->second;
2090 if (decorated->text().empty())
2091 decorated->SetText(input.initial_value);
2092 }
2093
2094 ComboboxMap::iterator combo_mapping = group->comboboxes.find(input.type);
2095 if (combo_mapping != group->comboboxes.end()) {
2096 views::Combobox* combobox = combo_mapping->second;
2097 if (combobox->selected_index() == combobox->model()->GetDefaultIndex())
2098 SelectComboboxValueOrSetToDefault(combobox, input.initial_value);
2099 }
2077 } 2100 }
2078 2101
2079 ComboboxMap::iterator combo_mapping = group->comboboxes.find(input.type); 2102 SetIconsForSection(section);
2080 if (combo_mapping != group->comboboxes.end()) {
2081 views::Combobox* combobox = combo_mapping->second;
2082 if (combobox->selected_index() == combobox->model()->GetDefaultIndex() ||
2083 clobber_inputs) {
2084 SelectComboboxValueOrSetToDefault(combobox, input.initial_value);
2085 }
2086 }
2087 } 2103 }
2088 2104
2089 SetIconsForSection(section);
2090 SetEditabilityForSection(section); 2105 SetEditabilityForSection(section);
2091 UpdateDetailsGroupState(*group); 2106 UpdateDetailsGroupState(*group);
2092 } 2107 }
2093 2108
2094 void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) { 2109 void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) {
2095 const SuggestionState& suggestion_state = 2110 const SuggestionState& suggestion_state =
2096 delegate_->SuggestionStateForSection(group.section); 2111 delegate_->SuggestionStateForSection(group.section);
2097 group.suggested_info->SetState(suggestion_state); 2112 group.suggested_info->SetState(suggestion_state);
2098 group.manual_input->SetVisible(!suggestion_state.visible); 2113 group.manual_input->SetVisible(!suggestion_state.visible);
2099 2114
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2189 SetValidityForInput(iter->second, message.text); 2204 SetValidityForInput(iter->second, message.text);
2190 } 2205 }
2191 for (ComboboxMap::const_iterator iter = group->comboboxes.begin(); 2206 for (ComboboxMap::const_iterator iter = group->comboboxes.begin();
2192 iter != group->comboboxes.end(); ++iter) { 2207 iter != group->comboboxes.end(); ++iter) {
2193 const ValidityMessage& message = 2208 const ValidityMessage& message =
2194 messages.GetMessageOrDefault(iter->first); 2209 messages.GetMessageOrDefault(iter->first);
2195 if (overwrite_unsure || message.sure) 2210 if (overwrite_unsure || message.sure)
2196 SetValidityForInput(iter->second, message.text); 2211 SetValidityForInput(iter->second, message.text);
2197 } 2212 }
2198 } else { 2213 } else {
2199 // Purge invisible views from |validity_map_|. 2214 EraseInvalidViewsInGroup(group);
2200 std::map<views::View*, base::string16>::iterator it;
2201 for (it = validity_map_.begin(); it != validity_map_.end();) {
2202 DCHECK(GroupForView(it->first));
2203 if (GroupForView(it->first) == group)
2204 validity_map_.erase(it++);
2205 else
2206 ++it;
2207 }
2208 2215
2209 if (section == GetCreditCardSection()) { 2216 if (section == GetCreditCardSection()) {
2210 // Special case CVC as it's not part of |group->manual_input|. 2217 // Special case CVC as it's not part of |group->manual_input|.
2211 const ValidityMessage& message = 2218 const ValidityMessage& message =
2212 messages.GetMessageOrDefault(CREDIT_CARD_VERIFICATION_CODE); 2219 messages.GetMessageOrDefault(CREDIT_CARD_VERIFICATION_CODE);
2213 if (overwrite_unsure || message.sure) { 2220 if (overwrite_unsure || message.sure) {
2214 SetValidityForInput(group->suggested_info->decorated_textfield(), 2221 SetValidityForInput(group->suggested_info->decorated_textfield(),
2215 message.text); 2222 message.text);
2216 } 2223 }
2217 } 2224 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2267 if (!group.container->visible()) 2274 if (!group.container->visible())
2268 continue; 2275 continue;
2269 2276
2270 if (!ValidateGroup(group, VALIDATE_FINAL)) 2277 if (!ValidateGroup(group, VALIDATE_FINAL))
2271 all_valid = false; 2278 all_valid = false;
2272 } 2279 }
2273 2280
2274 return all_valid; 2281 return all_valid;
2275 } 2282 }
2276 2283
2277 void AutofillDialogViews::TextfieldEditedOrActivated( 2284 void AutofillDialogViews::InputEditedOrActivated(ServerFieldType type,
2278 views::Textfield* textfield, 2285 const gfx::Rect& bounds,
2279 bool was_edit) { 2286 bool was_edit) {
2280 DetailsGroup* group = GroupForView(textfield); 2287 DCHECK_NE(UNKNOWN_TYPE, type);
2288
2289 DecoratedTextfield* decorated = TextfieldForType(type);
2290 DetailsGroup* group = decorated ?
2291 GroupForView(decorated) : GroupForView(ComboboxForType(type));
2281 DCHECK(group); 2292 DCHECK(group);
2282 2293
2283 // Figure out the ServerFieldType this textfield represents. 2294 delegate_->UserEditedOrActivatedInput(group->section,
2284 ServerFieldType type = UNKNOWN_TYPE; 2295 type,
2285 DecoratedTextfield* decorated = NULL; 2296 GetWidget()->GetNativeView(),
2297 bounds,
2298 GetTextContentsOfInput(type),
2299 was_edit);
2286 2300
2287 // Look for the input in the manual inputs. 2301 // If the field is a textfield and is invalid, check if the text is now valid.
2288 for (TextfieldMap::const_iterator iter = group->textfields.begin();
2289 iter != group->textfields.end();
2290 ++iter) {
2291 decorated = iter->second;
2292 if (decorated == textfield) {
2293 delegate_->UserEditedOrActivatedInput(group->section,
2294 iter->first,
2295 GetWidget()->GetNativeView(),
2296 textfield->GetBoundsInScreen(),
2297 textfield->text(),
2298 was_edit);
2299 type = iter->first;
2300 break;
2301 }
2302 }
2303
2304 if (textfield == group->suggested_info->decorated_textfield()) {
2305 decorated = group->suggested_info->decorated_textfield();
2306 type = CREDIT_CARD_VERIFICATION_CODE;
2307 }
2308 DCHECK_NE(UNKNOWN_TYPE, type);
2309
2310 // If the field is marked as invalid, check if the text is now valid.
2311 // Many fields (i.e. CC#) are invalid for most of the duration of editing, 2302 // Many fields (i.e. CC#) are invalid for most of the duration of editing,
2312 // so flagging them as invalid prematurely is not helpful. However, 2303 // so flagging them as invalid prematurely is not helpful. However,
2313 // correcting a minor mistake (i.e. a wrong CC digit) should immediately 2304 // correcting a minor mistake (i.e. a wrong CC digit) should immediately
2314 // result in validation - positive user feedback. 2305 // result in validation - positive user feedback.
2315 if (decorated->invalid() && was_edit) { 2306 if (decorated && decorated->invalid() && was_edit) {
2316 SetValidityForInput( 2307 SetValidityForInput(
2317 decorated, 2308 decorated,
2318 delegate_->InputValidityMessage(group->section, type, 2309 delegate_->InputValidityMessage(
2319 textfield->text())); 2310 group->section, type, decorated->text()));
2320 2311
2321 // If the field transitioned from invalid to valid, re-validate the group, 2312 // If the field transitioned from invalid to valid, re-validate the group,
2322 // since inter-field checks become meaningful with valid fields. 2313 // since inter-field checks become meaningful with valid fields.
2323 if (!decorated->invalid()) 2314 if (!decorated->invalid())
2324 ValidateGroup(*group, VALIDATE_EDIT); 2315 ValidateGroup(*group, VALIDATE_EDIT);
2325 } 2316 }
2326 2317
2327 if (delegate_->FieldControlsIcons(type)) 2318 if (delegate_->FieldControlsIcons(type))
2328 SetIconsForSection(group->section); 2319 SetIconsForSection(group->section);
2329 2320
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 view->GetAncestorWithClassName(DecoratedTextfield::kViewClassName); 2367 view->GetAncestorWithClassName(DecoratedTextfield::kViewClassName);
2377 2368
2378 // Textfields need to check a second case, since they can be suggested 2369 // Textfields need to check a second case, since they can be suggested
2379 // inputs instead of directly editable inputs. Those are accessed via 2370 // inputs instead of directly editable inputs. Those are accessed via
2380 // |suggested_info|. 2371 // |suggested_info|.
2381 if (decorated && 2372 if (decorated &&
2382 decorated == group->suggested_info->decorated_textfield()) { 2373 decorated == group->suggested_info->decorated_textfield()) {
2383 return group; 2374 return group;
2384 } 2375 }
2385 } 2376 }
2377
2386 return NULL; 2378 return NULL;
2387 } 2379 }
2388 2380
2389 views::Textfield* AutofillDialogViews::TextfieldForType( 2381 void AutofillDialogViews::EraseInvalidViewsInGroup(const DetailsGroup* group) {
2382 std::map<views::View*, base::string16>::iterator it = validity_map_.begin();
2383 while (it != validity_map_.end()) {
2384 if (GroupForView(it->first) == group)
2385 validity_map_.erase(it++);
2386 else
2387 ++it;
2388 }
2389 }
2390
2391 DecoratedTextfield* AutofillDialogViews::TextfieldForType(
2390 ServerFieldType type) { 2392 ServerFieldType type) {
2393 if (type == CREDIT_CARD_VERIFICATION_CODE) {
2394 DetailsGroup* group = GroupForSection(GetCreditCardSection());
2395 if (!group->manual_input->visible())
2396 return group->suggested_info->decorated_textfield();
2397 }
2398
2391 for (DetailGroupMap::iterator iter = detail_groups_.begin(); 2399 for (DetailGroupMap::iterator iter = detail_groups_.begin();
2392 iter != detail_groups_.end(); ++iter) { 2400 iter != detail_groups_.end(); ++iter) {
2393 const DetailsGroup& group = iter->second; 2401 const DetailsGroup& group = iter->second;
2402 if (!delegate_->SectionIsActive(group.section))
2403 continue;
2404
2394 TextfieldMap::const_iterator text_mapping = group.textfields.find(type); 2405 TextfieldMap::const_iterator text_mapping = group.textfields.find(type);
2395 if (text_mapping != group.textfields.end()) 2406 if (text_mapping != group.textfields.end())
2396 return text_mapping->second; 2407 return text_mapping->second;
2397 } 2408 }
2398 2409
2399 return NULL; 2410 return NULL;
2400 } 2411 }
2401 2412
2413 ServerFieldType AutofillDialogViews::TypeForTextfield(
2414 const views::Textfield* textfield) {
2415 DetailsGroup* cc_group = GroupForSection(GetCreditCardSection());
2416 if (textfield == cc_group->suggested_info->decorated_textfield())
2417 return CREDIT_CARD_VERIFICATION_CODE;
2418
2419 for (DetailGroupMap::const_iterator it = detail_groups_.begin();
2420 it != detail_groups_.end(); ++it) {
2421 if (!delegate_->SectionIsActive(it->second.section))
2422 continue;
2423
2424 for (TextfieldMap::const_iterator text_it = it->second.textfields.begin();
2425 text_it != it->second.textfields.end(); ++text_it) {
2426 if (textfield == text_it->second)
2427 return text_it->first;
2428 }
2429 }
2430
2431 return UNKNOWN_TYPE;
2432 }
2433
2402 views::Combobox* AutofillDialogViews::ComboboxForType( 2434 views::Combobox* AutofillDialogViews::ComboboxForType(
2403 ServerFieldType type) { 2435 ServerFieldType type) {
2404 for (DetailGroupMap::iterator iter = detail_groups_.begin(); 2436 for (DetailGroupMap::iterator iter = detail_groups_.begin();
2405 iter != detail_groups_.end(); ++iter) { 2437 iter != detail_groups_.end(); ++iter) {
2406 const DetailsGroup& group = iter->second; 2438 const DetailsGroup& group = iter->second;
2439 if (!delegate_->SectionIsActive(group.section))
2440 continue;
2441
2407 ComboboxMap::const_iterator combo_mapping = group.comboboxes.find(type); 2442 ComboboxMap::const_iterator combo_mapping = group.comboboxes.find(type);
2408 if (combo_mapping != group.comboboxes.end()) 2443 if (combo_mapping != group.comboboxes.end())
2409 return combo_mapping->second; 2444 return combo_mapping->second;
2410 } 2445 }
2411 2446
2412 return NULL; 2447 return NULL;
2413 } 2448 }
2414 2449
2450 ServerFieldType AutofillDialogViews::TypeForCombobox(
2451 const views::Combobox* combobox) const {
2452 for (DetailGroupMap::const_iterator it = detail_groups_.begin();
2453 it != detail_groups_.end(); ++it) {
2454 const DetailsGroup& group = it->second;
2455 if (!delegate_->SectionIsActive(group.section))
2456 continue;
2457
2458 for (ComboboxMap::const_iterator combo_it = group.comboboxes.begin();
2459 combo_it != group.comboboxes.end(); ++combo_it) {
2460 if (combo_it->second == combobox)
2461 return combo_it->first;
2462 }
2463 }
2464
2465 return UNKNOWN_TYPE;
2466 }
2467
2415 void AutofillDialogViews::DetailsContainerBoundsChanged() { 2468 void AutofillDialogViews::DetailsContainerBoundsChanged() {
2416 if (error_bubble_) 2469 if (error_bubble_)
2417 error_bubble_->UpdatePosition(); 2470 error_bubble_->UpdatePosition();
2418 } 2471 }
2419 2472
2420 void AutofillDialogViews::SetIconsForSection(DialogSection section) { 2473 void AutofillDialogViews::SetIconsForSection(DialogSection section) {
2421 FieldValueMap user_input; 2474 FieldValueMap user_input;
2422 GetUserInput(section, &user_input); 2475 GetUserInput(section, &user_input);
2423 FieldIconMap field_icons = delegate_->IconsForFields(user_input); 2476 FieldIconMap field_icons = delegate_->IconsForFields(user_input);
2424 TextfieldMap* textfields = &GroupForSection(section)->textfields; 2477 TextfieldMap* textfields = &GroupForSection(section)->textfields;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2463 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) 2516 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section)
2464 : section(section), 2517 : section(section),
2465 container(NULL), 2518 container(NULL),
2466 manual_input(NULL), 2519 manual_input(NULL),
2467 suggested_info(NULL), 2520 suggested_info(NULL),
2468 suggested_button(NULL) {} 2521 suggested_button(NULL) {}
2469 2522
2470 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} 2523 AutofillDialogViews::DetailsGroup::~DetailsGroup() {}
2471 2524
2472 } // namespace autofill 2525 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/autofill/autofill_dialog_views.h ('k') | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698