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

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

Powered by Google App Engine
This is Rietveld 408576698