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 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 } | 1310 } |
1311 | 1311 |
1312 void AutofillDialogViews::UpdateErrorBubble() { | 1312 void AutofillDialogViews::UpdateErrorBubble() { |
1313 if (!delegate_->ShouldShowErrorBubble()) | 1313 if (!delegate_->ShouldShowErrorBubble()) |
1314 HideErrorBubble(); | 1314 HideErrorBubble(); |
1315 } | 1315 } |
1316 | 1316 |
1317 void AutofillDialogViews::FillSection(DialogSection section, | 1317 void AutofillDialogViews::FillSection(DialogSection section, |
1318 ServerFieldType originating_type) { | 1318 ServerFieldType originating_type) { |
1319 DetailsGroup* group = GroupForSection(section); | 1319 DetailsGroup* group = GroupForSection(section); |
1320 // Make sure to overwrite the originating input. | 1320 // Make sure to overwrite the originating input if it exists. |
1321 TextfieldMap::iterator text_mapping = | 1321 TextfieldMap::iterator text_mapping = |
1322 group->textfields.find(originating_type); | 1322 group->textfields.find(originating_type); |
1323 if (text_mapping != group->textfields.end()) | 1323 if (text_mapping != group->textfields.end()) |
1324 text_mapping->second->SetText(base::string16()); | 1324 text_mapping->second->SetText(base::string16()); |
1325 | 1325 |
1326 // If the Autofill data comes from a credit card, make sure to overwrite the | 1326 // If the Autofill data comes from a credit card, make sure to overwrite the |
1327 // CC comboboxes (even if they already have something in them). If the | 1327 // CC comboboxes (even if they already have something in them). If the |
1328 // Autofill data comes from an AutofillProfile, leave the comboboxes alone. | 1328 // Autofill data comes from an AutofillProfile, leave the comboboxes alone. |
1329 if (section == GetCreditCardSection() && | 1329 if (section == GetCreditCardSection() && |
1330 AutofillType(originating_type).group() == CREDIT_CARD) { | 1330 AutofillType(originating_type).group() == CREDIT_CARD) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 ServerFieldType type, | 1460 ServerFieldType type, |
1461 const base::string16& contents) { | 1461 const base::string16& contents) { |
1462 views::Textfield* textfield = TextfieldForType(type); | 1462 views::Textfield* textfield = TextfieldForType(type); |
1463 if (textfield) { | 1463 if (textfield) { |
1464 textfield->SetText(contents); | 1464 textfield->SetText(contents); |
1465 return; | 1465 return; |
1466 } | 1466 } |
1467 | 1467 |
1468 views::Combobox* combobox = ComboboxForType(type); | 1468 views::Combobox* combobox = ComboboxForType(type); |
1469 if (combobox) { | 1469 if (combobox) { |
| 1470 int selected_index = combobox->selected_index(); |
1470 SelectComboboxValueOrSetToDefault(combobox, contents); | 1471 SelectComboboxValueOrSetToDefault(combobox, contents); |
| 1472 if (selected_index != combobox->selected_index()) |
| 1473 OnSelectedIndexChanged(combobox); |
1471 return; | 1474 return; |
1472 } | 1475 } |
1473 | 1476 |
1474 NOTREACHED(); | 1477 NOTREACHED(); |
1475 } | 1478 } |
1476 | 1479 |
1477 void AutofillDialogViews::SetTextContentsOfSuggestionInput( | 1480 void AutofillDialogViews::SetTextContentsOfSuggestionInput( |
1478 DialogSection section, | 1481 DialogSection section, |
1479 const base::string16& text) { | 1482 const base::string16& text) { |
1480 GroupForSection(section)->suggested_info->decorated_textfield()-> | 1483 GroupForSection(section)->suggested_info->decorated_textfield()-> |
1481 SetText(text); | 1484 SetText(text); |
1482 } | 1485 } |
1483 | 1486 |
1484 void AutofillDialogViews::ActivateInput(ServerFieldType type) { | 1487 void AutofillDialogViews::ActivateInput(ServerFieldType type) { |
1485 TextfieldEditedOrActivated(TextfieldForType(type), false); | 1488 InputEditedOrActivated(type, gfx::Rect(), false); |
1486 } | 1489 } |
1487 | 1490 |
1488 gfx::Size AutofillDialogViews::GetSize() const { | 1491 gfx::Size AutofillDialogViews::GetSize() const { |
1489 return GetWidget() ? GetWidget()->GetRootView()->size() : gfx::Size(); | 1492 return GetWidget() ? GetWidget()->GetRootView()->size() : gfx::Size(); |
1490 } | 1493 } |
1491 | 1494 |
1492 content::WebContents* AutofillDialogViews::GetSignInWebContents() { | 1495 content::WebContents* AutofillDialogViews::GetSignInWebContents() { |
1493 return sign_in_web_view_->web_contents(); | 1496 return sign_in_web_view_->web_contents(); |
1494 } | 1497 } |
1495 | 1498 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1529 | 1532 |
1530 // The rest (the |scrollable_area_|) takes up whatever's left. | 1533 // The rest (the |scrollable_area_|) takes up whatever's left. |
1531 if (scrollable_area_->visible()) { | 1534 if (scrollable_area_->visible()) { |
1532 int scroll_y = y; | 1535 int scroll_y = y; |
1533 if (notification_height > notification_area_->GetInsets().height()) | 1536 if (notification_height > notification_area_->GetInsets().height()) |
1534 scroll_y += notification_height + views::kRelatedControlVerticalSpacing; | 1537 scroll_y += notification_height + views::kRelatedControlVerticalSpacing; |
1535 | 1538 |
1536 int scroll_bottom = content_bounds.bottom(); | 1539 int scroll_bottom = content_bounds.bottom(); |
1537 DCHECK_EQ(scrollable_area_->contents(), details_container_); | 1540 DCHECK_EQ(scrollable_area_->contents(), details_container_); |
1538 details_container_->SizeToPreferredSize(); | 1541 details_container_->SizeToPreferredSize(); |
| 1542 details_container_->Layout(); |
1539 // TODO(estade): remove this hack. See crbug.com/285996 | 1543 // TODO(estade): remove this hack. See crbug.com/285996 |
1540 details_container_->set_ignore_layouts(true); | 1544 details_container_->set_ignore_layouts(true); |
1541 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y); | 1545 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y); |
1542 details_container_->set_ignore_layouts(false); | 1546 details_container_->set_ignore_layouts(false); |
1543 } | 1547 } |
1544 | 1548 |
1545 if (error_bubble_) | 1549 if (error_bubble_) |
1546 error_bubble_->UpdatePosition(); | 1550 error_bubble_->UpdatePosition(); |
1547 } | 1551 } |
1548 | 1552 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 // on all dialogs. | 1689 // on all dialogs. |
1686 views::NonClientFrameView* AutofillDialogViews::CreateNonClientFrameView( | 1690 views::NonClientFrameView* AutofillDialogViews::CreateNonClientFrameView( |
1687 views::Widget* widget) { | 1691 views::Widget* widget) { |
1688 return CreateConstrainedStyleNonClientFrameView( | 1692 return CreateConstrainedStyleNonClientFrameView( |
1689 widget, | 1693 widget, |
1690 delegate_->GetWebContents()->GetBrowserContext()); | 1694 delegate_->GetWebContents()->GetBrowserContext()); |
1691 } | 1695 } |
1692 | 1696 |
1693 void AutofillDialogViews::ContentsChanged(views::Textfield* sender, | 1697 void AutofillDialogViews::ContentsChanged(views::Textfield* sender, |
1694 const base::string16& new_contents) { | 1698 const base::string16& new_contents) { |
1695 TextfieldEditedOrActivated(sender, true); | 1699 InputEditedOrActivated(TypeForTextfield(sender), |
| 1700 sender->GetBoundsInScreen(), |
| 1701 true); |
1696 } | 1702 } |
1697 | 1703 |
1698 bool AutofillDialogViews::HandleKeyEvent(views::Textfield* sender, | 1704 bool AutofillDialogViews::HandleKeyEvent(views::Textfield* sender, |
1699 const ui::KeyEvent& key_event) { | 1705 const ui::KeyEvent& key_event) { |
1700 ui::KeyEvent copy(key_event); | 1706 ui::KeyEvent copy(key_event); |
1701 #if defined(OS_WIN) && !defined(USE_AURA) | 1707 #if defined(OS_WIN) && !defined(USE_AURA) |
1702 content::NativeWebKeyboardEvent event(copy.native_event()); | 1708 content::NativeWebKeyboardEvent event(copy.native_event()); |
1703 #else | 1709 #else |
1704 content::NativeWebKeyboardEvent event(©); | 1710 content::NativeWebKeyboardEvent event(©); |
1705 #endif | 1711 #endif |
1706 return delegate_->HandleKeyPressEventInInput(event); | 1712 return delegate_->HandleKeyPressEventInInput(event); |
1707 } | 1713 } |
1708 | 1714 |
1709 bool AutofillDialogViews::HandleMouseEvent(views::Textfield* sender, | 1715 bool AutofillDialogViews::HandleMouseEvent(views::Textfield* sender, |
1710 const ui::MouseEvent& mouse_event) { | 1716 const ui::MouseEvent& mouse_event) { |
1711 if (mouse_event.IsLeftMouseButton() && sender->HasFocus()) { | 1717 if (mouse_event.IsLeftMouseButton() && sender->HasFocus()) { |
1712 TextfieldEditedOrActivated(sender, false); | 1718 InputEditedOrActivated(TypeForTextfield(sender), |
| 1719 sender->GetBoundsInScreen(), |
| 1720 false); |
1713 // Show an error bubble if a user clicks on an input that's already focused | 1721 // Show an error bubble if a user clicks on an input that's already focused |
1714 // (and invalid). | 1722 // (and invalid). |
1715 ShowErrorBubbleForViewIfNecessary(sender); | 1723 ShowErrorBubbleForViewIfNecessary(sender); |
1716 } | 1724 } |
1717 | 1725 |
1718 return false; | 1726 return false; |
1719 } | 1727 } |
1720 | 1728 |
1721 void AutofillDialogViews::OnWillChangeFocus( | 1729 void AutofillDialogViews::OnWillChangeFocus( |
1722 views::View* focused_before, | 1730 views::View* focused_before, |
(...skipping 13 matching lines...) Expand all Loading... |
1736 } | 1744 } |
1737 | 1745 |
1738 // Show an error bubble when the user focuses the input. | 1746 // Show an error bubble when the user focuses the input. |
1739 if (focused_now) { | 1747 if (focused_now) { |
1740 focused_now->ScrollRectToVisible(focused_now->GetLocalBounds()); | 1748 focused_now->ScrollRectToVisible(focused_now->GetLocalBounds()); |
1741 ShowErrorBubbleForViewIfNecessary(focused_now); | 1749 ShowErrorBubbleForViewIfNecessary(focused_now); |
1742 } | 1750 } |
1743 } | 1751 } |
1744 | 1752 |
1745 void AutofillDialogViews::OnSelectedIndexChanged(views::Combobox* combobox) { | 1753 void AutofillDialogViews::OnSelectedIndexChanged(views::Combobox* combobox) { |
1746 DetailsGroup* group = GroupForView(combobox); | 1754 DialogSection section = GroupForView(combobox)->section; |
1747 ValidateGroup(*group, VALIDATE_EDIT); | 1755 InputEditedOrActivated(TypeForCombobox(combobox), gfx::Rect(), true); |
1748 SetEditabilityForSection(group->section); | 1756 // NOTE: |combobox| may have been deleted. |
| 1757 ValidateGroup(*GroupForSection(section), VALIDATE_EDIT); |
| 1758 SetEditabilityForSection(section); |
1749 } | 1759 } |
1750 | 1760 |
1751 void AutofillDialogViews::StyledLabelLinkClicked(const gfx::Range& range, | 1761 void AutofillDialogViews::StyledLabelLinkClicked(const gfx::Range& range, |
1752 int event_flags) { | 1762 int event_flags) { |
1753 delegate_->LegalDocumentLinkClicked(range); | 1763 delegate_->LegalDocumentLinkClicked(range); |
1754 } | 1764 } |
1755 | 1765 |
1756 void AutofillDialogViews::OnMenuButtonClicked(views::View* source, | 1766 void AutofillDialogViews::OnMenuButtonClicked(views::View* source, |
1757 const gfx::Point& point) { | 1767 const gfx::Point& point) { |
1758 DCHECK_EQ(kSuggestedButtonClassName, source->GetClassName()); | 1768 DCHECK_EQ(kSuggestedButtonClassName, source->GetClassName()); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 AddChildView(sign_in_web_view_); | 1906 AddChildView(sign_in_web_view_); |
1897 | 1907 |
1898 overlay_view_ = new OverlayView(delegate_); | 1908 overlay_view_ = new OverlayView(delegate_); |
1899 overlay_view_->SetVisible(false); | 1909 overlay_view_->SetVisible(false); |
1900 } | 1910 } |
1901 | 1911 |
1902 views::View* AutofillDialogViews::CreateDetailsContainer() { | 1912 views::View* AutofillDialogViews::CreateDetailsContainer() { |
1903 details_container_ = new DetailsContainerView( | 1913 details_container_ = new DetailsContainerView( |
1904 base::Bind(&AutofillDialogViews::DetailsContainerBoundsChanged, | 1914 base::Bind(&AutofillDialogViews::DetailsContainerBoundsChanged, |
1905 base::Unretained(this))); | 1915 base::Unretained(this))); |
| 1916 |
1906 // A box layout is used because it respects widget visibility. | 1917 // A box layout is used because it respects widget visibility. |
1907 details_container_->SetLayoutManager( | 1918 details_container_->SetLayoutManager( |
1908 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 1919 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); |
1909 for (DetailGroupMap::iterator iter = detail_groups_.begin(); | 1920 for (DetailGroupMap::iterator iter = detail_groups_.begin(); |
1910 iter != detail_groups_.end(); ++iter) { | 1921 iter != detail_groups_.end(); ++iter) { |
1911 CreateDetailsSection(iter->second.section); | 1922 CreateDetailsSection(iter->second.section); |
1912 details_container_->AddChildView(iter->second.container); | 1923 details_container_->AddChildView(iter->second.container); |
1913 } | 1924 } |
1914 | 1925 |
1915 return details_container_; | 1926 return details_container_; |
(...skipping 12 matching lines...) Expand all Loading... |
1928 UpdateDetailsGroupState(*group); | 1939 UpdateDetailsGroupState(*group); |
1929 } | 1940 } |
1930 | 1941 |
1931 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) { | 1942 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) { |
1932 // The |info_view| holds |manual_inputs| and |suggested_info|, allowing the | 1943 // The |info_view| holds |manual_inputs| and |suggested_info|, allowing the |
1933 // dialog to toggle which is shown. | 1944 // dialog to toggle which is shown. |
1934 views::View* info_view = new views::View(); | 1945 views::View* info_view = new views::View(); |
1935 info_view->SetLayoutManager( | 1946 info_view->SetLayoutManager( |
1936 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 1947 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); |
1937 | 1948 |
1938 views::View* manual_inputs = InitInputsView(section); | 1949 DetailsGroup* group = GroupForSection(section); |
1939 info_view->AddChildView(manual_inputs); | 1950 group->manual_input = new views::View(); |
1940 SuggestionView* suggested_info = new SuggestionView(this); | 1951 InitInputsView(section); |
1941 info_view->AddChildView(suggested_info); | 1952 info_view->AddChildView(group->manual_input); |
1942 | 1953 |
1943 DetailsGroup* group = GroupForSection(section); | 1954 group->suggested_info = new SuggestionView(this); |
| 1955 info_view->AddChildView(group->suggested_info); |
| 1956 |
1944 // TODO(estade): It might be slightly more OO if this button were created | 1957 // TODO(estade): It might be slightly more OO if this button were created |
1945 // and listened to by the section container. | 1958 // and listened to by the section container. |
1946 group->suggested_button = new SuggestedButton(this); | 1959 group->suggested_button = new SuggestedButton(this); |
1947 group->manual_input = manual_inputs; | |
1948 group->suggested_info = suggested_info; | |
1949 | 1960 |
1950 return info_view; | 1961 return info_view; |
1951 } | 1962 } |
1952 | 1963 |
1953 // TODO(estade): we should be using Chrome-style constrained window padding | 1964 // TODO(estade): we should be using Chrome-style constrained window padding |
1954 // values. | 1965 // values. |
1955 views::View* AutofillDialogViews::InitInputsView(DialogSection section) { | 1966 void AutofillDialogViews::InitInputsView(DialogSection section) { |
1956 const DetailInputs& inputs = delegate_->RequestedFieldsForSection(section); | 1967 DetailsGroup* group = GroupForSection(section); |
1957 TextfieldMap* textfields = &GroupForSection(section)->textfields; | 1968 EraseInvalidViewsInGroup(group); |
1958 ComboboxMap* comboboxes = &GroupForSection(section)->comboboxes; | |
1959 | 1969 |
1960 views::View* view = new views::View(); | 1970 TextfieldMap* textfields = &group->textfields; |
| 1971 textfields->clear(); |
| 1972 |
| 1973 ComboboxMap* comboboxes = &group->comboboxes; |
| 1974 comboboxes->clear(); |
| 1975 |
| 1976 views::View* view = group->manual_input; |
| 1977 view->RemoveAllChildViews(true); |
| 1978 |
1961 views::GridLayout* layout = new views::GridLayout(view); | 1979 views::GridLayout* layout = new views::GridLayout(view); |
1962 view->SetLayoutManager(layout); | 1980 view->SetLayoutManager(layout); |
1963 | 1981 |
1964 int column_set_id = 0; | 1982 int column_set_id = 0; |
| 1983 const DetailInputs& inputs = delegate_->RequestedFieldsForSection(section); |
1965 for (DetailInputs::const_iterator it = inputs.begin(); | 1984 for (DetailInputs::const_iterator it = inputs.begin(); |
1966 it != inputs.end(); ++it) { | 1985 it != inputs.end(); ++it) { |
1967 const DetailInput& input = *it; | 1986 const DetailInput& input = *it; |
| 1987 |
1968 ui::ComboboxModel* input_model = | 1988 ui::ComboboxModel* input_model = |
1969 delegate_->ComboboxModelForAutofillType(input.type); | 1989 delegate_->ComboboxModelForAutofillType(input.type); |
1970 scoped_ptr<views::View> view_to_add; | 1990 scoped_ptr<views::View> view_to_add; |
1971 if (input_model) { | 1991 if (input_model) { |
1972 views::Combobox* combobox = new views::Combobox(input_model); | 1992 views::Combobox* combobox = new views::Combobox(input_model); |
1973 combobox->set_listener(this); | 1993 combobox->set_listener(this); |
1974 comboboxes->insert(std::make_pair(input.type, combobox)); | 1994 comboboxes->insert(std::make_pair(input.type, combobox)); |
1975 SelectComboboxValueOrSetToDefault(combobox, input.initial_value); | 1995 SelectComboboxValueOrSetToDefault(combobox, input.initial_value); |
1976 view_to_add.reset(combobox); | 1996 view_to_add.reset(combobox); |
1977 } else { | 1997 } else { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2020 views::GridLayout::FILL, views::GridLayout::FILL, | 2040 views::GridLayout::FILL, views::GridLayout::FILL, |
2021 1, 0); | 2041 1, 0); |
2022 | 2042 |
2023 if (input.length == DetailInput::LONG || | 2043 if (input.length == DetailInput::LONG || |
2024 input.length == DetailInput::SHORT_EOL) { | 2044 input.length == DetailInput::SHORT_EOL) { |
2025 ++column_set_id; | 2045 ++column_set_id; |
2026 } | 2046 } |
2027 } | 2047 } |
2028 | 2048 |
2029 SetIconsForSection(section); | 2049 SetIconsForSection(section); |
2030 | |
2031 return view; | |
2032 } | 2050 } |
2033 | 2051 |
2034 void AutofillDialogViews::ShowDialogInMode(DialogMode dialog_mode) { | 2052 void AutofillDialogViews::ShowDialogInMode(DialogMode dialog_mode) { |
2035 loading_shield_->SetVisible(dialog_mode == LOADING); | 2053 loading_shield_->SetVisible(dialog_mode == LOADING); |
2036 sign_in_web_view_->SetVisible(dialog_mode == SIGN_IN); | 2054 sign_in_web_view_->SetVisible(dialog_mode == SIGN_IN); |
2037 notification_area_->SetVisible(dialog_mode == DETAIL_INPUT); | 2055 notification_area_->SetVisible(dialog_mode == DETAIL_INPUT); |
2038 scrollable_area_->SetVisible(dialog_mode == DETAIL_INPUT); | 2056 scrollable_area_->SetVisible(dialog_mode == DETAIL_INPUT); |
2039 FocusInitialView(); | 2057 FocusInitialView(); |
2040 } | 2058 } |
2041 | 2059 |
2042 void AutofillDialogViews::UpdateSectionImpl( | 2060 void AutofillDialogViews::UpdateSectionImpl( |
2043 DialogSection section, | 2061 DialogSection section, |
2044 bool clobber_inputs) { | 2062 bool clobber_inputs) { |
2045 // Reset all validity marks for this section. | |
2046 if (clobber_inputs) | |
2047 MarkInputsInvalid(section, ValidityMessages(), true); | |
2048 | |
2049 const DetailInputs& updated_inputs = | |
2050 delegate_->RequestedFieldsForSection(section); | |
2051 DetailsGroup* group = GroupForSection(section); | 2063 DetailsGroup* group = GroupForSection(section); |
2052 | 2064 |
2053 for (DetailInputs::const_iterator iter = updated_inputs.begin(); | 2065 if (clobber_inputs) { |
2054 iter != updated_inputs.end(); ++iter) { | 2066 InitInputsView(section); |
2055 const DetailInput& input = *iter; | 2067 } else { |
2056 TextfieldMap::iterator text_mapping = group->textfields.find(input.type); | 2068 const DetailInputs& updated_inputs = |
| 2069 delegate_->RequestedFieldsForSection(section); |
2057 | 2070 |
2058 if (text_mapping != group->textfields.end()) { | 2071 for (DetailInputs::const_iterator iter = updated_inputs.begin(); |
2059 DecoratedTextfield* decorated = text_mapping->second; | 2072 iter != updated_inputs.end(); ++iter) { |
2060 if (decorated->text().empty() || clobber_inputs) | 2073 const DetailInput& input = *iter; |
2061 decorated->SetText(input.initial_value); | 2074 |
| 2075 TextfieldMap::iterator text_mapping = group->textfields.find(input.type); |
| 2076 if (text_mapping != group->textfields.end()) { |
| 2077 DecoratedTextfield* decorated = text_mapping->second; |
| 2078 if (decorated->text().empty()) |
| 2079 decorated->SetText(input.initial_value); |
| 2080 } |
| 2081 |
| 2082 ComboboxMap::iterator combo_mapping = group->comboboxes.find(input.type); |
| 2083 if (combo_mapping != group->comboboxes.end()) { |
| 2084 views::Combobox* combobox = combo_mapping->second; |
| 2085 if (combobox->selected_index() == combobox->model()->GetDefaultIndex()) |
| 2086 SelectComboboxValueOrSetToDefault(combobox, input.initial_value); |
| 2087 } |
2062 } | 2088 } |
2063 | 2089 |
2064 ComboboxMap::iterator combo_mapping = group->comboboxes.find(input.type); | 2090 SetIconsForSection(section); |
2065 if (combo_mapping != group->comboboxes.end()) { | |
2066 views::Combobox* combobox = combo_mapping->second; | |
2067 if (combobox->selected_index() == combobox->model()->GetDefaultIndex() || | |
2068 clobber_inputs) { | |
2069 SelectComboboxValueOrSetToDefault(combobox, input.initial_value); | |
2070 } | |
2071 } | |
2072 } | 2091 } |
2073 | 2092 |
2074 SetIconsForSection(section); | |
2075 SetEditabilityForSection(section); | 2093 SetEditabilityForSection(section); |
2076 UpdateDetailsGroupState(*group); | 2094 UpdateDetailsGroupState(*group); |
2077 } | 2095 } |
2078 | 2096 |
2079 void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) { | 2097 void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) { |
2080 const SuggestionState& suggestion_state = | 2098 const SuggestionState& suggestion_state = |
2081 delegate_->SuggestionStateForSection(group.section); | 2099 delegate_->SuggestionStateForSection(group.section); |
2082 group.suggested_info->SetState(suggestion_state); | 2100 group.suggested_info->SetState(suggestion_state); |
2083 group.manual_input->SetVisible(!suggestion_state.visible); | 2101 group.manual_input->SetVisible(!suggestion_state.visible); |
2084 | 2102 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2174 SetValidityForInput(iter->second, message.text); | 2192 SetValidityForInput(iter->second, message.text); |
2175 } | 2193 } |
2176 for (ComboboxMap::const_iterator iter = group->comboboxes.begin(); | 2194 for (ComboboxMap::const_iterator iter = group->comboboxes.begin(); |
2177 iter != group->comboboxes.end(); ++iter) { | 2195 iter != group->comboboxes.end(); ++iter) { |
2178 const ValidityMessage& message = | 2196 const ValidityMessage& message = |
2179 messages.GetMessageOrDefault(iter->first); | 2197 messages.GetMessageOrDefault(iter->first); |
2180 if (overwrite_unsure || message.sure) | 2198 if (overwrite_unsure || message.sure) |
2181 SetValidityForInput(iter->second, message.text); | 2199 SetValidityForInput(iter->second, message.text); |
2182 } | 2200 } |
2183 } else { | 2201 } else { |
2184 // Purge invisible views from |validity_map_|. | 2202 EraseInvalidViewsInGroup(group); |
2185 std::map<views::View*, base::string16>::iterator it; | |
2186 for (it = validity_map_.begin(); it != validity_map_.end();) { | |
2187 DCHECK(GroupForView(it->first)); | |
2188 if (GroupForView(it->first) == group) | |
2189 validity_map_.erase(it++); | |
2190 else | |
2191 ++it; | |
2192 } | |
2193 | 2203 |
2194 if (section == GetCreditCardSection()) { | 2204 if (section == GetCreditCardSection()) { |
2195 // Special case CVC as it's not part of |group->manual_input|. | 2205 // Special case CVC as it's not part of |group->manual_input|. |
2196 const ValidityMessage& message = | 2206 const ValidityMessage& message = |
2197 messages.GetMessageOrDefault(CREDIT_CARD_VERIFICATION_CODE); | 2207 messages.GetMessageOrDefault(CREDIT_CARD_VERIFICATION_CODE); |
2198 if (overwrite_unsure || message.sure) { | 2208 if (overwrite_unsure || message.sure) { |
2199 SetValidityForInput(group->suggested_info->decorated_textfield(), | 2209 SetValidityForInput(group->suggested_info->decorated_textfield(), |
2200 message.text); | 2210 message.text); |
2201 } | 2211 } |
2202 } | 2212 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 if (!group.container->visible()) | 2262 if (!group.container->visible()) |
2253 continue; | 2263 continue; |
2254 | 2264 |
2255 if (!ValidateGroup(group, VALIDATE_FINAL)) | 2265 if (!ValidateGroup(group, VALIDATE_FINAL)) |
2256 all_valid = false; | 2266 all_valid = false; |
2257 } | 2267 } |
2258 | 2268 |
2259 return all_valid; | 2269 return all_valid; |
2260 } | 2270 } |
2261 | 2271 |
2262 void AutofillDialogViews::TextfieldEditedOrActivated( | 2272 void AutofillDialogViews::InputEditedOrActivated(ServerFieldType type, |
2263 views::Textfield* textfield, | 2273 const gfx::Rect& bounds, |
2264 bool was_edit) { | 2274 bool was_edit) { |
2265 DetailsGroup* group = GroupForView(textfield); | 2275 DCHECK_NE(UNKNOWN_TYPE, type); |
| 2276 |
| 2277 DecoratedTextfield* decorated = TextfieldForType(type); |
| 2278 DetailsGroup* group = decorated ? |
| 2279 GroupForView(decorated) : GroupForView(ComboboxForType(type)); |
2266 DCHECK(group); | 2280 DCHECK(group); |
2267 | 2281 |
2268 // Figure out the ServerFieldType this textfield represents. | 2282 delegate_->UserEditedOrActivatedInput(group->section, |
2269 ServerFieldType type = UNKNOWN_TYPE; | 2283 type, |
2270 DecoratedTextfield* decorated = NULL; | 2284 GetWidget()->GetNativeView(), |
| 2285 bounds, |
| 2286 GetTextContentsOfInput(type), |
| 2287 was_edit); |
2271 | 2288 |
2272 // Look for the input in the manual inputs. | 2289 // If the field is a textfield and is invalid, check if the text is now valid. |
2273 for (TextfieldMap::const_iterator iter = group->textfields.begin(); | |
2274 iter != group->textfields.end(); | |
2275 ++iter) { | |
2276 decorated = iter->second; | |
2277 if (decorated == textfield) { | |
2278 delegate_->UserEditedOrActivatedInput(group->section, | |
2279 iter->first, | |
2280 GetWidget()->GetNativeView(), | |
2281 textfield->GetBoundsInScreen(), | |
2282 textfield->text(), | |
2283 was_edit); | |
2284 type = iter->first; | |
2285 break; | |
2286 } | |
2287 } | |
2288 | |
2289 if (textfield == group->suggested_info->decorated_textfield()) { | |
2290 decorated = group->suggested_info->decorated_textfield(); | |
2291 type = CREDIT_CARD_VERIFICATION_CODE; | |
2292 } | |
2293 DCHECK_NE(UNKNOWN_TYPE, type); | |
2294 | |
2295 // If the field is marked as invalid, check if the text is now valid. | |
2296 // Many fields (i.e. CC#) are invalid for most of the duration of editing, | 2290 // Many fields (i.e. CC#) are invalid for most of the duration of editing, |
2297 // so flagging them as invalid prematurely is not helpful. However, | 2291 // so flagging them as invalid prematurely is not helpful. However, |
2298 // correcting a minor mistake (i.e. a wrong CC digit) should immediately | 2292 // correcting a minor mistake (i.e. a wrong CC digit) should immediately |
2299 // result in validation - positive user feedback. | 2293 // result in validation - positive user feedback. |
2300 if (decorated->invalid() && was_edit) { | 2294 if (decorated && decorated->invalid() && was_edit) { |
2301 SetValidityForInput( | 2295 SetValidityForInput( |
2302 decorated, | 2296 decorated, |
2303 delegate_->InputValidityMessage(group->section, type, | 2297 delegate_->InputValidityMessage( |
2304 textfield->text())); | 2298 group->section, type, decorated->text())); |
2305 | 2299 |
2306 // If the field transitioned from invalid to valid, re-validate the group, | 2300 // If the field transitioned from invalid to valid, re-validate the group, |
2307 // since inter-field checks become meaningful with valid fields. | 2301 // since inter-field checks become meaningful with valid fields. |
2308 if (!decorated->invalid()) | 2302 if (!decorated->invalid()) |
2309 ValidateGroup(*group, VALIDATE_EDIT); | 2303 ValidateGroup(*group, VALIDATE_EDIT); |
2310 } | 2304 } |
2311 | 2305 |
2312 if (delegate_->FieldControlsIcons(type)) | 2306 if (delegate_->FieldControlsIcons(type)) |
2313 SetIconsForSection(group->section); | 2307 SetIconsForSection(group->section); |
2314 | 2308 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2361 view->GetAncestorWithClassName(DecoratedTextfield::kViewClassName); | 2355 view->GetAncestorWithClassName(DecoratedTextfield::kViewClassName); |
2362 | 2356 |
2363 // Textfields need to check a second case, since they can be suggested | 2357 // Textfields need to check a second case, since they can be suggested |
2364 // inputs instead of directly editable inputs. Those are accessed via | 2358 // inputs instead of directly editable inputs. Those are accessed via |
2365 // |suggested_info|. | 2359 // |suggested_info|. |
2366 if (decorated && | 2360 if (decorated && |
2367 decorated == group->suggested_info->decorated_textfield()) { | 2361 decorated == group->suggested_info->decorated_textfield()) { |
2368 return group; | 2362 return group; |
2369 } | 2363 } |
2370 } | 2364 } |
| 2365 |
2371 return NULL; | 2366 return NULL; |
2372 } | 2367 } |
2373 | 2368 |
2374 views::Textfield* AutofillDialogViews::TextfieldForType( | 2369 void AutofillDialogViews::EraseInvalidViewsInGroup(const DetailsGroup* group) { |
| 2370 std::map<views::View*, base::string16>::iterator it = validity_map_.begin(); |
| 2371 while (it != validity_map_.end()) { |
| 2372 if (GroupForView(it->first) == group) |
| 2373 validity_map_.erase(it++); |
| 2374 else |
| 2375 ++it; |
| 2376 } |
| 2377 } |
| 2378 |
| 2379 DecoratedTextfield* AutofillDialogViews::TextfieldForType( |
2375 ServerFieldType type) { | 2380 ServerFieldType type) { |
| 2381 if (type == CREDIT_CARD_VERIFICATION_CODE) { |
| 2382 DetailsGroup* group = GroupForSection(GetCreditCardSection()); |
| 2383 if (!group->manual_input->visible()) |
| 2384 return group->suggested_info->decorated_textfield(); |
| 2385 } |
| 2386 |
2376 for (DetailGroupMap::iterator iter = detail_groups_.begin(); | 2387 for (DetailGroupMap::iterator iter = detail_groups_.begin(); |
2377 iter != detail_groups_.end(); ++iter) { | 2388 iter != detail_groups_.end(); ++iter) { |
2378 const DetailsGroup& group = iter->second; | 2389 const DetailsGroup& group = iter->second; |
| 2390 if (!delegate_->SectionIsActive(group.section)) |
| 2391 continue; |
2379 TextfieldMap::const_iterator text_mapping = group.textfields.find(type); | 2392 TextfieldMap::const_iterator text_mapping = group.textfields.find(type); |
2380 if (text_mapping != group.textfields.end()) | 2393 if (text_mapping != group.textfields.end()) |
2381 return text_mapping->second; | 2394 return text_mapping->second; |
2382 } | 2395 } |
2383 | 2396 |
2384 return NULL; | 2397 return NULL; |
2385 } | 2398 } |
2386 | 2399 |
| 2400 ServerFieldType AutofillDialogViews::TypeForTextfield( |
| 2401 const views::Textfield* textfield) { |
| 2402 DetailsGroup* cc_group = GroupForSection(GetCreditCardSection()); |
| 2403 if (textfield == cc_group->suggested_info->decorated_textfield()) |
| 2404 return CREDIT_CARD_VERIFICATION_CODE; |
| 2405 |
| 2406 for (DetailGroupMap::const_iterator it = detail_groups_.begin(); |
| 2407 it != detail_groups_.end(); ++it) { |
| 2408 if (!delegate_->SectionIsActive(it->second.section)) |
| 2409 continue; |
| 2410 for (TextfieldMap::const_iterator text_it = it->second.textfields.begin(); |
| 2411 text_it != it->second.textfields.end(); ++text_it) { |
| 2412 if (textfield == text_it->second) |
| 2413 return text_it->first; |
| 2414 } |
| 2415 } |
| 2416 |
| 2417 return UNKNOWN_TYPE; |
| 2418 } |
| 2419 |
2387 views::Combobox* AutofillDialogViews::ComboboxForType( | 2420 views::Combobox* AutofillDialogViews::ComboboxForType( |
2388 ServerFieldType type) { | 2421 ServerFieldType type) { |
2389 for (DetailGroupMap::iterator iter = detail_groups_.begin(); | 2422 for (DetailGroupMap::iterator iter = detail_groups_.begin(); |
2390 iter != detail_groups_.end(); ++iter) { | 2423 iter != detail_groups_.end(); ++iter) { |
2391 const DetailsGroup& group = iter->second; | 2424 const DetailsGroup& group = iter->second; |
| 2425 if (!delegate_->SectionIsActive(group.section)) |
| 2426 continue; |
2392 ComboboxMap::const_iterator combo_mapping = group.comboboxes.find(type); | 2427 ComboboxMap::const_iterator combo_mapping = group.comboboxes.find(type); |
2393 if (combo_mapping != group.comboboxes.end()) | 2428 if (combo_mapping != group.comboboxes.end()) |
2394 return combo_mapping->second; | 2429 return combo_mapping->second; |
2395 } | 2430 } |
2396 | 2431 |
2397 return NULL; | 2432 return NULL; |
2398 } | 2433 } |
2399 | 2434 |
| 2435 ServerFieldType AutofillDialogViews::TypeForCombobox( |
| 2436 const views::Combobox* combobox) const { |
| 2437 for (DetailGroupMap::const_iterator it = detail_groups_.begin(); |
| 2438 it != detail_groups_.end(); ++it) { |
| 2439 const DetailsGroup& group = it->second; |
| 2440 if (!delegate_->SectionIsActive(group.section)) |
| 2441 continue; |
| 2442 for (ComboboxMap::const_iterator combo_it = group.comboboxes.begin(); |
| 2443 combo_it != group.comboboxes.end(); ++combo_it) { |
| 2444 if (combo_it->second == combobox) |
| 2445 return combo_it->first; |
| 2446 } |
| 2447 } |
| 2448 |
| 2449 return UNKNOWN_TYPE; |
| 2450 } |
| 2451 |
2400 void AutofillDialogViews::DetailsContainerBoundsChanged() { | 2452 void AutofillDialogViews::DetailsContainerBoundsChanged() { |
2401 if (error_bubble_) | 2453 if (error_bubble_) |
2402 error_bubble_->UpdatePosition(); | 2454 error_bubble_->UpdatePosition(); |
2403 } | 2455 } |
2404 | 2456 |
2405 void AutofillDialogViews::SetIconsForSection(DialogSection section) { | 2457 void AutofillDialogViews::SetIconsForSection(DialogSection section) { |
2406 FieldValueMap user_input; | 2458 FieldValueMap user_input; |
2407 GetUserInput(section, &user_input); | 2459 GetUserInput(section, &user_input); |
2408 FieldIconMap field_icons = delegate_->IconsForFields(user_input); | 2460 FieldIconMap field_icons = delegate_->IconsForFields(user_input); |
2409 TextfieldMap* textfields = &GroupForSection(section)->textfields; | 2461 TextfieldMap* textfields = &GroupForSection(section)->textfields; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2448 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) | 2500 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) |
2449 : section(section), | 2501 : section(section), |
2450 container(NULL), | 2502 container(NULL), |
2451 manual_input(NULL), | 2503 manual_input(NULL), |
2452 suggested_info(NULL), | 2504 suggested_info(NULL), |
2453 suggested_button(NULL) {} | 2505 suggested_button(NULL) {} |
2454 | 2506 |
2455 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} | 2507 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} |
2456 | 2508 |
2457 } // namespace autofill | 2509 } // namespace autofill |
OLD | NEW |