OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(©); | 1723 content::NativeWebKeyboardEvent event(©); |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |