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

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

Issue 63053003: Ask libaddressinput for address components to use in requestAutocomplete(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tests Created 7 years 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 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 1527
1528 // The rest (the |scrollable_area_|) takes up whatever's left. 1528 // The rest (the |scrollable_area_|) takes up whatever's left.
1529 if (scrollable_area_->visible()) { 1529 if (scrollable_area_->visible()) {
1530 int scroll_y = y; 1530 int scroll_y = y;
1531 if (notification_height > notification_area_->GetInsets().height()) 1531 if (notification_height > notification_area_->GetInsets().height())
1532 scroll_y += notification_height + views::kRelatedControlVerticalSpacing; 1532 scroll_y += notification_height + views::kRelatedControlVerticalSpacing;
1533 1533
1534 int scroll_bottom = content_bounds.bottom(); 1534 int scroll_bottom = content_bounds.bottom();
1535 DCHECK_EQ(scrollable_area_->contents(), details_container_); 1535 DCHECK_EQ(scrollable_area_->contents(), details_container_);
1536 details_container_->SizeToPreferredSize(); 1536 details_container_->SizeToPreferredSize();
1537 details_container_->Layout();
1537 // TODO(estade): remove this hack. See crbug.com/285996 1538 // TODO(estade): remove this hack. See crbug.com/285996
1538 details_container_->set_ignore_layouts(true); 1539 details_container_->set_ignore_layouts(true);
1539 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y); 1540 scrollable_area_->SetBounds(x, scroll_y, width, scroll_bottom - scroll_y);
1540 details_container_->set_ignore_layouts(false); 1541 details_container_->set_ignore_layouts(false);
1541 } 1542 }
1542 1543
1543 if (error_bubble_) 1544 if (error_bubble_)
1544 error_bubble_->UpdatePosition(); 1545 error_bubble_->UpdatePosition();
1545 } 1546 }
1546 1547
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 } 1735 }
1735 1736
1736 // Show an error bubble when the user focuses the input. 1737 // Show an error bubble when the user focuses the input.
1737 if (focused_now) { 1738 if (focused_now) {
1738 focused_now->ScrollRectToVisible(focused_now->GetLocalBounds()); 1739 focused_now->ScrollRectToVisible(focused_now->GetLocalBounds());
1739 ShowErrorBubbleForViewIfNecessary(focused_now); 1740 ShowErrorBubbleForViewIfNecessary(focused_now);
1740 } 1741 }
1741 } 1742 }
1742 1743
1743 void AutofillDialogViews::OnSelectedIndexChanged(views::Combobox* combobox) { 1744 void AutofillDialogViews::OnSelectedIndexChanged(views::Combobox* combobox) {
1744 DetailsGroup* group = GroupForView(combobox); 1745 DialogSection section = GroupForView(combobox)->section;
1745 ValidateGroup(*group, VALIDATE_EDIT); 1746
1746 SetEditabilityForSection(group->section); 1747 int index = combobox->selected_index();
1748 delegate_->ComboboxItemSelected(TypeForCombobox(combobox), index);
1749 // NOTE: |combobox| may have been deleted.
1750
1751 ValidateGroup(*GroupForSection(section), VALIDATE_EDIT);
1752 SetEditabilityForSection(section);
1747 } 1753 }
1748 1754
1749 void AutofillDialogViews::StyledLabelLinkClicked(const gfx::Range& range, 1755 void AutofillDialogViews::StyledLabelLinkClicked(const gfx::Range& range,
1750 int event_flags) { 1756 int event_flags) {
1751 delegate_->LegalDocumentLinkClicked(range); 1757 delegate_->LegalDocumentLinkClicked(range);
1752 } 1758 }
1753 1759
1754 void AutofillDialogViews::OnMenuButtonClicked(views::View* source, 1760 void AutofillDialogViews::OnMenuButtonClicked(views::View* source,
1755 const gfx::Point& point) { 1761 const gfx::Point& point) {
1756 DCHECK_EQ(kSuggestedButtonClassName, source->GetClassName()); 1762 DCHECK_EQ(kSuggestedButtonClassName, source->GetClassName());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 AddChildView(sign_in_web_view_); 1900 AddChildView(sign_in_web_view_);
1895 1901
1896 overlay_view_ = new OverlayView(delegate_); 1902 overlay_view_ = new OverlayView(delegate_);
1897 overlay_view_->SetVisible(false); 1903 overlay_view_->SetVisible(false);
1898 } 1904 }
1899 1905
1900 views::View* AutofillDialogViews::CreateDetailsContainer() { 1906 views::View* AutofillDialogViews::CreateDetailsContainer() {
1901 details_container_ = new DetailsContainerView( 1907 details_container_ = new DetailsContainerView(
1902 base::Bind(&AutofillDialogViews::DetailsContainerBoundsChanged, 1908 base::Bind(&AutofillDialogViews::DetailsContainerBoundsChanged,
1903 base::Unretained(this))); 1909 base::Unretained(this)));
1910
1904 // A box layout is used because it respects widget visibility. 1911 // A box layout is used because it respects widget visibility.
1905 details_container_->SetLayoutManager( 1912 details_container_->SetLayoutManager(
1906 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 1913 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
1907 for (DetailGroupMap::iterator iter = detail_groups_.begin(); 1914 for (DetailGroupMap::iterator iter = detail_groups_.begin();
1908 iter != detail_groups_.end(); ++iter) { 1915 iter != detail_groups_.end(); ++iter) {
1909 CreateDetailsSection(iter->second.section); 1916 CreateDetailsSection(iter->second.section);
1910 details_container_->AddChildView(iter->second.container); 1917 details_container_->AddChildView(iter->second.container);
1911 } 1918 }
1912 1919
1913 return details_container_; 1920 return details_container_;
1914 } 1921 }
1915 1922
1916 void AutofillDialogViews::CreateDetailsSection(DialogSection section) { 1923 void AutofillDialogViews::CreateDetailsSection(DialogSection section) {
1917 // Inputs container (manual inputs + combobox).
1918 views::View* inputs_container = CreateInputsContainer(section);
1919
1920 DetailsGroup* group = GroupForSection(section); 1924 DetailsGroup* group = GroupForSection(section);
1921 // Container (holds label + inputs). 1925 // Container (holds label + inputs).
1922 group->container = new SectionContainer( 1926 group->container = new SectionContainer(delegate_->LabelForSection(section),
1923 delegate_->LabelForSection(section), 1927 CreateInputsContainer(section),
1924 inputs_container, 1928 group->suggested_button);
1925 group->suggested_button);
1926 DCHECK(group->suggested_button->parent()); 1929 DCHECK(group->suggested_button->parent());
1927 UpdateDetailsGroupState(*group); 1930 UpdateDetailsGroupState(*group);
1928 } 1931 }
1929 1932
1930 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) { 1933 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) {
1931 // The |info_view| holds |manual_inputs| and |suggested_info|, allowing the 1934 // The |info_view| holds |manual_inputs| and |suggested_info|, allowing the
1932 // dialog to toggle which is shown. 1935 // dialog to toggle which is shown.
1933 views::View* info_view = new views::View(); 1936 views::View* info_view = new views::View();
1934 info_view->SetLayoutManager( 1937 info_view->SetLayoutManager(
1935 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 1938 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
1936 1939
1937 views::View* manual_inputs = InitInputsView(section); 1940 DetailsGroup* group = GroupForSection(section);
1938 info_view->AddChildView(manual_inputs); 1941 group->manual_input = new views::View();
1939 SuggestionView* suggested_info = new SuggestionView(this); 1942 InitInputsView(section);
1940 info_view->AddChildView(suggested_info); 1943 info_view->AddChildView(group->manual_input);
1941 1944
1942 DetailsGroup* group = GroupForSection(section); 1945 group->suggested_info = new SuggestionView(this);
1946 info_view->AddChildView(group->suggested_info);
1947
1943 // TODO(estade): It might be slightly more OO if this button were created 1948 // TODO(estade): It might be slightly more OO if this button were created
1944 // and listened to by the section container. 1949 // and listened to by the section container.
1945 group->suggested_button = new SuggestedButton(this); 1950 group->suggested_button = new SuggestedButton(this);
1946 group->manual_input = manual_inputs;
1947 group->suggested_info = suggested_info;
1948 1951
1949 return info_view; 1952 return info_view;
1950 } 1953 }
1951 1954
1952 // TODO(estade): we should be using Chrome-style constrained window padding 1955 // TODO(estade): we should be using Chrome-style constrained window padding
1953 // values. 1956 // values.
1954 views::View* AutofillDialogViews::InitInputsView(DialogSection section) { 1957 void AutofillDialogViews::InitInputsView(DialogSection section) {
1955 const DetailInputs& inputs = delegate_->RequestedFieldsForSection(section); 1958 DetailsGroup* group = GroupForSection(section);
1956 TextfieldMap* textfields = &GroupForSection(section)->textfields; 1959 TextfieldMap* textfields = &group->textfields;
1957 ComboboxMap* comboboxes = &GroupForSection(section)->comboboxes; 1960 textfields->clear();
1958 1961
1959 views::View* view = new views::View(); 1962 ComboboxMap* comboboxes = &group->comboboxes;
1963 comboboxes->clear();
1964
1965 views::View* view = group->manual_input;
1966 view->RemoveAllChildViews(true);
1967
1960 views::GridLayout* layout = new views::GridLayout(view); 1968 views::GridLayout* layout = new views::GridLayout(view);
1961 view->SetLayoutManager(layout); 1969 view->SetLayoutManager(layout);
1962 1970
1963 int column_set_id = 0; 1971 int column_set_id = 0;
1972 const DetailInputs& inputs = delegate_->RequestedFieldsForSection(section);
1964 for (DetailInputs::const_iterator it = inputs.begin(); 1973 for (DetailInputs::const_iterator it = inputs.begin();
1965 it != inputs.end(); ++it) { 1974 it != inputs.end(); ++it) {
1966 const DetailInput& input = *it; 1975 const DetailInput& input = *it;
1976
1967 ui::ComboboxModel* input_model = 1977 ui::ComboboxModel* input_model =
1968 delegate_->ComboboxModelForAutofillType(input.type); 1978 delegate_->ComboboxModelForAutofillType(input.type);
1969 scoped_ptr<views::View> view_to_add; 1979 scoped_ptr<views::View> view_to_add;
1970 if (input_model) { 1980 if (input_model) {
1971 views::Combobox* combobox = new views::Combobox(input_model); 1981 views::Combobox* combobox = new views::Combobox(input_model);
1972 combobox->set_listener(this); 1982 combobox->set_listener(this);
1973 comboboxes->insert(std::make_pair(input.type, combobox)); 1983 comboboxes->insert(std::make_pair(input.type, combobox));
1974 SelectComboboxValueOrSetToDefault(combobox, input.initial_value); 1984 SelectComboboxValueOrSetToDefault(combobox, input.initial_value);
1975 view_to_add.reset(combobox); 1985 view_to_add.reset(combobox);
1976 } else { 1986 } else {
1977 DecoratedTextfield* field = new DecoratedTextfield( 1987 DecoratedTextfield* field = new DecoratedTextfield(input.initial_value,
1978 input.initial_value, 1988 input.placeholder_text,
1979 l10n_util::GetStringUTF16(input.placeholder_text_rid), 1989 this);
1980 this);
1981
1982 textfields->insert(std::make_pair(input.type, field)); 1990 textfields->insert(std::make_pair(input.type, field));
1983 view_to_add.reset(field); 1991 view_to_add.reset(field);
1984 } 1992 }
1985 1993
1986 if (input.length == DetailInput::NONE) { 1994 if (input.length == DetailInput::NONE) {
1987 other_owned_views_.push_back(view_to_add.release()); 1995 other_owned_views_.push_back(view_to_add.release());
1988 continue; 1996 continue;
1989 } 1997 }
1990 1998
1991 if (input.length == DetailInput::LONG) 1999 if (input.length == DetailInput::LONG)
(...skipping 22 matching lines...) Expand all
2014 0, 2022 0,
2015 0); 2023 0);
2016 2024
2017 // This is the same as AddView(view_to_add), except that 1 is used for the 2025 // This is the same as AddView(view_to_add), except that 1 is used for the
2018 // view's preferred width. Thus the width of the column completely depends 2026 // view's preferred width. Thus the width of the column completely depends
2019 // on |expand|. 2027 // on |expand|.
2020 layout->AddView(view_to_add.release(), 1, 1, 2028 layout->AddView(view_to_add.release(), 1, 1,
2021 views::GridLayout::FILL, views::GridLayout::FILL, 2029 views::GridLayout::FILL, views::GridLayout::FILL,
2022 1, 0); 2030 1, 0);
2023 2031
2024 if (input.length == DetailInput::LONG) 2032 if (input.length == DetailInput::LONG ||
2033 input.length == DetailInput::SHORT_EOL) {
Evan Stade 2013/12/05 03:09:18 would be nice to test this stuff works. Maybe a TO
2025 ++column_set_id; 2034 ++column_set_id;
2035 }
2026 } 2036 }
2027 2037
2028 SetIconsForSection(section); 2038 SetIconsForSection(section);
2029
2030 return view;
2031 } 2039 }
2032 2040
2033 void AutofillDialogViews::ShowDialogInMode(DialogMode dialog_mode) { 2041 void AutofillDialogViews::ShowDialogInMode(DialogMode dialog_mode) {
2034 loading_shield_->SetVisible(dialog_mode == LOADING); 2042 loading_shield_->SetVisible(dialog_mode == LOADING);
2035 sign_in_web_view_->SetVisible(dialog_mode == SIGN_IN); 2043 sign_in_web_view_->SetVisible(dialog_mode == SIGN_IN);
2036 notification_area_->SetVisible(dialog_mode == DETAIL_INPUT); 2044 notification_area_->SetVisible(dialog_mode == DETAIL_INPUT);
2037 scrollable_area_->SetVisible(dialog_mode == DETAIL_INPUT); 2045 scrollable_area_->SetVisible(dialog_mode == DETAIL_INPUT);
2038 FocusInitialView(); 2046 FocusInitialView();
2039 } 2047 }
2040 2048
2041 void AutofillDialogViews::UpdateSectionImpl( 2049 void AutofillDialogViews::UpdateSectionImpl(
2042 DialogSection section, 2050 DialogSection section,
2043 bool clobber_inputs) { 2051 bool clobber_inputs) {
2044 // Reset all validity marks for this section. 2052 DetailsGroup* group = GroupForSection(section);
2053
2045 if (clobber_inputs) 2054 if (clobber_inputs)
2046 MarkInputsInvalid(section, ValidityMessages(), true); 2055 InitInputsView(section);
2047 2056
2048 const DetailInputs& updated_inputs = 2057 const DetailInputs& updated_inputs =
2049 delegate_->RequestedFieldsForSection(section); 2058 delegate_->RequestedFieldsForSection(section);
2050 DetailsGroup* group = GroupForSection(section);
2051 2059
2052 for (DetailInputs::const_iterator iter = updated_inputs.begin(); 2060 for (DetailInputs::const_iterator iter = updated_inputs.begin();
2053 iter != updated_inputs.end(); ++iter) { 2061 iter != updated_inputs.end(); ++iter) {
2054 const DetailInput& input = *iter; 2062 const DetailInput& input = *iter;
2063
2055 TextfieldMap::iterator text_mapping = group->textfields.find(input.type); 2064 TextfieldMap::iterator text_mapping = group->textfields.find(input.type);
2056
2057 if (text_mapping != group->textfields.end()) { 2065 if (text_mapping != group->textfields.end()) {
2058 DecoratedTextfield* decorated = text_mapping->second; 2066 DecoratedTextfield* decorated = text_mapping->second;
2059 if (decorated->text().empty() || clobber_inputs) 2067 if (decorated->text().empty() || clobber_inputs)
2060 decorated->SetText(input.initial_value); 2068 decorated->SetText(input.initial_value);
2061 } 2069 }
2062 2070
2063 ComboboxMap::iterator combo_mapping = group->comboboxes.find(input.type); 2071 ComboboxMap::iterator combo_mapping = group->comboboxes.find(input.type);
2064 if (combo_mapping != group->comboboxes.end()) { 2072 if (combo_mapping != group->comboboxes.end()) {
2065 views::Combobox* combobox = combo_mapping->second; 2073 views::Combobox* combobox = combo_mapping->second;
2066 if (combobox->selected_index() == combobox->model()->GetDefaultIndex() || 2074 if (combobox->selected_index() == combobox->model()->GetDefaultIndex() ||
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2181 iter != group->comboboxes.end(); ++iter) { 2189 iter != group->comboboxes.end(); ++iter) {
2182 const ValidityMessage& message = 2190 const ValidityMessage& message =
2183 messages.GetMessageOrDefault(iter->first); 2191 messages.GetMessageOrDefault(iter->first);
2184 if (overwrite_unsure || message.sure) 2192 if (overwrite_unsure || message.sure)
2185 SetValidityForInput(iter->second, message.text); 2193 SetValidityForInput(iter->second, message.text);
2186 } 2194 }
2187 } else { 2195 } else {
2188 // Purge invisible views from |validity_map_|. 2196 // Purge invisible views from |validity_map_|.
2189 std::map<views::View*, base::string16>::iterator it; 2197 std::map<views::View*, base::string16>::iterator it;
2190 for (it = validity_map_.begin(); it != validity_map_.end();) { 2198 for (it = validity_map_.begin(); it != validity_map_.end();) {
2191 DCHECK(GroupForView(it->first));
2192 if (GroupForView(it->first) == group) 2199 if (GroupForView(it->first) == group)
2193 validity_map_.erase(it++); 2200 validity_map_.erase(it++);
2194 else 2201 else
2195 ++it; 2202 ++it;
2196 } 2203 }
2197 2204
2198 if (section == GetCreditCardSection()) { 2205 if (section == GetCreditCardSection()) {
2199 // Special case CVC as it's not part of |group->manual_input|. 2206 // Special case CVC as it's not part of |group->manual_input|.
2200 const ValidityMessage& message = 2207 const ValidityMessage& message =
2201 messages.GetMessageOrDefault(CREDIT_CARD_VERIFICATION_CODE); 2208 messages.GetMessageOrDefault(CREDIT_CARD_VERIFICATION_CODE);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2396 const DetailsGroup& group = iter->second; 2403 const DetailsGroup& group = iter->second;
2397 ComboboxMap::const_iterator combo_mapping = 2404 ComboboxMap::const_iterator combo_mapping =
2398 group.comboboxes.find(input.type); 2405 group.comboboxes.find(input.type);
2399 if (combo_mapping != group.comboboxes.end()) 2406 if (combo_mapping != group.comboboxes.end())
2400 return combo_mapping->second; 2407 return combo_mapping->second;
2401 } 2408 }
2402 2409
2403 return NULL; 2410 return NULL;
2404 } 2411 }
2405 2412
2413 ServerFieldType AutofillDialogViews::TypeForCombobox(
2414 const views::Combobox* combobox) const {
2415 for (DetailGroupMap::const_iterator it = detail_groups_.begin();
2416 it != detail_groups_.end(); ++it) {
2417 const DetailsGroup& group = it->second;
2418 for (ComboboxMap::const_iterator combo_it = group.comboboxes.begin();
2419 combo_it != group.comboboxes.end(); ++combo_it) {
2420 if (combo_it->second == combobox)
2421 return combo_it->first;
2422 }
2423 }
2424 NOTREACHED();
2425 return UNKNOWN_TYPE;
2426 }
2427
2406 void AutofillDialogViews::DetailsContainerBoundsChanged() { 2428 void AutofillDialogViews::DetailsContainerBoundsChanged() {
2407 if (error_bubble_) 2429 if (error_bubble_)
2408 error_bubble_->UpdatePosition(); 2430 error_bubble_->UpdatePosition();
2409 } 2431 }
2410 2432
2411 void AutofillDialogViews::SetIconsForSection(DialogSection section) { 2433 void AutofillDialogViews::SetIconsForSection(DialogSection section) {
2412 FieldValueMap user_input; 2434 FieldValueMap user_input;
2413 GetUserInput(section, &user_input); 2435 GetUserInput(section, &user_input);
2414 FieldIconMap field_icons = delegate_->IconsForFields(user_input); 2436 FieldIconMap field_icons = delegate_->IconsForFields(user_input);
2415 TextfieldMap* textfields = &GroupForSection(section)->textfields; 2437 TextfieldMap* textfields = &GroupForSection(section)->textfields;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2454 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) 2476 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section)
2455 : section(section), 2477 : section(section),
2456 container(NULL), 2478 container(NULL),
2457 manual_input(NULL), 2479 manual_input(NULL),
2458 suggested_info(NULL), 2480 suggested_info(NULL),
2459 suggested_button(NULL) {} 2481 suggested_button(NULL) {}
2460 2482
2461 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} 2483 AutofillDialogViews::DetailsGroup::~DetailsGroup() {}
2462 2484
2463 } // namespace autofill 2485 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698