| 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 |