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

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