Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: chrome/browser/ui/views/autofill/autofill_dialog_views.cc

Issue 124533003: Add country combobox to change country and rebuild address inputs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: test Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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(&copy); 1710 content::NativeWebKeyboardEvent event(&copy);
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698