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