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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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(©); | 1729 content::NativeWebKeyboardEvent event(©); |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |