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 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |