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

Side by Side Diff: chrome/browser/ui/views/payments/profile_list_view_controller.cc

Issue 2855203002: [Payments] Display the shipping option error alongside the address (Closed)
Patch Set: addressed comments Created 3 years, 7 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
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/payments/profile_list_view_controller.h" 5 #include "chrome/browser/ui/views/payments/profile_list_view_controller.h"
6 6
7 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" 8 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h"
8 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" 9 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
9 #include "chrome/browser/ui/views/payments/payment_request_row_view.h" 10 #include "chrome/browser/ui/views/payments/payment_request_row_view.h"
10 #include "chrome/browser/ui/views/payments/payment_request_views_util.h" 11 #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
11 #include "chrome/grit/generated_resources.h" 12 #include "chrome/grit/generated_resources.h"
12 #include "components/payments/content/payment_request_spec.h" 13 #include "components/payments/content/payment_request_spec.h"
13 #include "components/payments/content/payment_request_state.h" 14 #include "components/payments/content/payment_request_state.h"
14 #include "components/payments/core/payments_profile_comparator.h" 15 #include "components/payments/core/payments_profile_comparator.h"
15 #include "components/payments/core/strings_util.h" 16 #include "components/payments/core/strings_util.h"
16 #include "components/strings/grit/components_strings.h" 17 #include "components/strings/grit/components_strings.h"
17 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/gfx/paint_vector_icon.h"
20 #include "ui/native_theme/native_theme.h"
21 #include "ui/vector_icons/vector_icons.h"
18 #include "ui/views/controls/button/label_button.h" 22 #include "ui/views/controls/button/label_button.h"
19 #include "ui/views/controls/button/md_text_button.h" 23 #include "ui/views/controls/button/md_text_button.h"
20 #include "ui/views/controls/image_view.h" 24 #include "ui/views/controls/image_view.h"
21 #include "ui/views/layout/box_layout.h" 25 #include "ui/views/layout/box_layout.h"
22 #include "ui/views/layout/fill_layout.h" 26 #include "ui/views/layout/fill_layout.h"
23 #include "ui/views/layout/grid_layout.h" 27 #include "ui/views/layout/grid_layout.h"
24 28
25 namespace payments { 29 namespace payments {
26 30
27 namespace { 31 namespace {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return parent_view_->GetLabel(profile_); 72 return parent_view_->GetLabel(profile_);
69 } 73 }
70 74
71 void SelectedStateChanged() override { 75 void SelectedStateChanged() override {
72 if (selected()) { 76 if (selected()) {
73 parent_view_->SelectProfile(profile_); 77 parent_view_->SelectProfile(profile_);
74 dialog_->GoBack(); 78 dialog_->GoBack();
75 } 79 }
76 } 80 }
77 81
78 bool CanBeSelected() const override { 82 bool IsEnabled() override { return parent_view_->IsEnabled(profile_); }
79 return parent_view_->IsValidProfile(*profile_); 83
84 bool CanBeSelected() override {
85 // In order to be selectable, a profile entry needs to be enabled, and the
86 // profile valid according to the controller. If either condition is false,
87 // PerformSelectionFallback() is called.
88 return IsEnabled() && parent_view_->IsValidProfile(*profile_);
80 } 89 }
81 90
82 void PerformSelectionFallback() override { 91 void PerformSelectionFallback() override {
83 parent_view_->ShowEditor(profile_); 92 // If not disabled, the editor is opened to complete the invalid profile.
anthonyvd 2017/05/04 14:11:34 nit: If enabled
Mathieu 2017/05/04 14:38:56 Done.
93 if (IsEnabled())
94 parent_view_->ShowEditor(profile_);
84 } 95 }
85 96
86 ProfileListViewController* parent_view_; 97 ProfileListViewController* parent_view_;
87 autofill::AutofillProfile* profile_; 98 autofill::AutofillProfile* profile_;
88 PaymentRequestDialogView* dialog_; 99 PaymentRequestDialogView* dialog_;
89 100
90 DISALLOW_COPY_AND_ASSIGN(ProfileItem); 101 DISALLOW_COPY_AND_ASSIGN(ProfileItem);
91 }; 102 };
92 103
93 // The ProfileListViewController subtype for the Shipping address list 104 // The ProfileListViewController subtype for the Shipping address list
94 // screen of the Payment Request flow. 105 // screen of the Payment Request flow.
95 class ShippingProfileViewController : public ProfileListViewController { 106 class ShippingProfileViewController : public ProfileListViewController {
96 public: 107 public:
97 ShippingProfileViewController(PaymentRequestSpec* spec, 108 ShippingProfileViewController(PaymentRequestSpec* spec,
98 PaymentRequestState* state, 109 PaymentRequestState* state,
99 PaymentRequestDialogView* dialog) 110 PaymentRequestDialogView* dialog)
100 : ProfileListViewController(spec, state, dialog) { 111 : ProfileListViewController(spec, state, dialog) {
101 PopulateList(); 112 PopulateList();
102 } 113 }
103 ~ShippingProfileViewController() override {} 114 ~ShippingProfileViewController() override {}
104 115
105 protected: 116 protected:
106 // ProfileListViewController: 117 // ProfileListViewController:
107 std::unique_ptr<views::View> GetLabel( 118 std::unique_ptr<views::View> GetLabel(
108 autofill::AutofillProfile* profile) override { 119 autofill::AutofillProfile* profile) override {
109 return GetShippingAddressLabel(AddressStyleType::DETAILED, 120 if (!IsEnabled(profile)) {
110 state()->GetApplicationLocale(), *profile, 121 // The error is not shown in the label itself on this screen, but the
111 *spec(), *(state()->profile_comparator())); 122 // entry is disabled.
123 return GetShippingAddressLabelWithError(
124 AddressStyleType::DETAILED, state()->GetApplicationLocale(), *profile,
125 /*error=*/base::string16(), /*disabled_state=*/true);
126 }
127 return GetShippingAddressLabelWithMissingInfo(
128 AddressStyleType::DETAILED, state()->GetApplicationLocale(), *profile,
129 *(state()->profile_comparator()));
112 } 130 }
113 131
114 void SelectProfile(autofill::AutofillProfile* profile) override { 132 void SelectProfile(autofill::AutofillProfile* profile) override {
115 state()->SetSelectedShippingProfile(profile); 133 state()->SetSelectedShippingProfile(profile);
116 } 134 }
117 135
118 void ShowEditor(autofill::AutofillProfile* profile) override { 136 void ShowEditor(autofill::AutofillProfile* profile) override {
119 dialog()->ShowShippingAddressEditor( 137 dialog()->ShowShippingAddressEditor(
120 /*on_edited=*/base::BindOnce( 138 /*on_edited=*/base::BindOnce(
121 &PaymentRequestState::SetSelectedShippingProfile, 139 &PaymentRequestState::SetSelectedShippingProfile,
122 base::Unretained(state()), profile), 140 base::Unretained(state()), profile),
123 /*on_added=*/ 141 /*on_added=*/
124 base::BindOnce(&PaymentRequestState::AddAutofillShippingProfile, 142 base::BindOnce(&PaymentRequestState::AddAutofillShippingProfile,
125 base::Unretained(state()), /*selected=*/true), 143 base::Unretained(state()), /*selected=*/true),
126 profile); 144 profile);
127 } 145 }
128 146
129 autofill::AutofillProfile* GetSelectedProfile() override { 147 autofill::AutofillProfile* GetSelectedProfile() override {
130 return state()->selected_shipping_profile(); 148 // If there are no errors with the currently selected profile, return it.
149 return spec()->selected_shipping_option_error().empty()
150 ? state()->selected_shipping_profile()
151 : nullptr;
131 } 152 }
132 153
133 bool IsValidProfile(const autofill::AutofillProfile& profile) override { 154 bool IsValidProfile(const autofill::AutofillProfile& profile) override {
134 return state()->profile_comparator()->IsShippingComplete(&profile); 155 return state()->profile_comparator()->IsShippingComplete(&profile);
135 } 156 }
136 157
137 std::vector<autofill::AutofillProfile*> GetProfiles() override { 158 std::vector<autofill::AutofillProfile*> GetProfiles() override {
138 return state()->shipping_profiles(); 159 return state()->shipping_profiles();
139 } 160 }
140 161
141 DialogViewID GetDialogViewId() override { 162 DialogViewID GetDialogViewId() override {
142 return DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW; 163 return DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW;
143 } 164 }
144 165
166 std::unique_ptr<views::View> CreateHeaderView() override {
167 if (spec()->selected_shipping_option_error().empty())
168 return nullptr;
169
170 std::unique_ptr<views::View> header_view = base::MakeUnique<views::View>();
171 // 8 pixels between the warning icon view and the text.
172 constexpr int kRowHorizontalSpacing = 8;
173 views::BoxLayout* layout = new views::BoxLayout(
174 views::BoxLayout::kHorizontal,
175 payments::kPaymentRequestRowHorizontalInsets, 0, kRowHorizontalSpacing);
176 layout->set_main_axis_alignment(
177 views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
178 layout->set_cross_axis_alignment(
179 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
180 header_view->SetLayoutManager(layout);
181
182 std::unique_ptr<views::ImageView> warning_icon =
183 base::MakeUnique<views::ImageView>();
184 warning_icon->set_can_process_events_within_subtree(false);
185 warning_icon->SetImage(gfx::CreateVectorIcon(
186 ui::kWarningIcon, 16,
187 warning_icon->GetNativeTheme()->GetSystemColor(
188 ui::NativeTheme::kColorId_AlertSeverityHigh)));
189 header_view->AddChildView(warning_icon.release());
190
191 std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>(
192 spec()->selected_shipping_option_error());
193 label->set_id(
194 static_cast<int>(DialogViewID::SHIPPING_ADDRESS_OPTION_ERROR));
195 label->SetEnabledColor(label->GetNativeTheme()->GetSystemColor(
196 ui::NativeTheme::kColorId_AlertSeverityHigh));
197 header_view->AddChildView(label.release());
198 return header_view;
199 }
200
145 base::string16 GetSheetTitle() override { 201 base::string16 GetSheetTitle() override {
146 return GetShippingAddressSectionString(spec()->shipping_type()); 202 return GetShippingAddressSectionString(spec()->shipping_type());
147 } 203 }
148 204
149 int GetSecondaryButtonTextId() override { 205 int GetSecondaryButtonTextId() override {
150 return IDS_AUTOFILL_ADD_ADDRESS_CAPTION; 206 return IDS_AUTOFILL_ADD_ADDRESS_CAPTION;
151 } 207 }
152 208
153 int GetSecondaryButtonTag() override { 209 int GetSecondaryButtonTag() override {
154 return static_cast<int>( 210 return static_cast<int>(
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 } 305 }
250 306
251 ProfileListViewController::ProfileListViewController( 307 ProfileListViewController::ProfileListViewController(
252 PaymentRequestSpec* spec, 308 PaymentRequestSpec* spec,
253 PaymentRequestState* state, 309 PaymentRequestState* state,
254 PaymentRequestDialogView* dialog) 310 PaymentRequestDialogView* dialog)
255 : PaymentRequestSheetController(spec, state, dialog) {} 311 : PaymentRequestSheetController(spec, state, dialog) {}
256 312
257 ProfileListViewController::~ProfileListViewController() {} 313 ProfileListViewController::~ProfileListViewController() {}
258 314
315 bool ProfileListViewController::IsEnabled(autofill::AutofillProfile* profile) {
316 // Entry is disabled if it's the selected entry and there exists a shipping
317 // option error. Otherwise, it's enabled.
318 return !(profile == state()->selected_shipping_profile() &&
anthonyvd 2017/05/04 14:11:34 nit: distribute the ! and expand the comment as pe
Mathieu 2017/05/04 14:38:56 Done.
319 !spec()->selected_shipping_option_error().empty());
320 }
321
322 std::unique_ptr<views::View> ProfileListViewController::CreateHeaderView() {
323 return nullptr;
324 }
325
259 void ProfileListViewController::PopulateList() { 326 void ProfileListViewController::PopulateList() {
260 autofill::AutofillProfile* selected_profile = GetSelectedProfile(); 327 autofill::AutofillProfile* selected_profile = GetSelectedProfile();
261 328
262 // This must be done at Create-time, rather than construct-time, because 329 // This must be done at Create-time, rather than construct-time, because
263 // the subclass method GetProfiles can't be called in the ctor. 330 // the subclass method GetProfiles can't be called in the ctor.
264 for (auto* profile : GetProfiles()) { 331 for (auto* profile : GetProfiles()) {
265 list_.AddItem(base::MakeUnique<ProfileItem>(profile, spec(), state(), 332 list_.AddItem(base::MakeUnique<ProfileItem>(profile, spec(), state(),
266 &list_, this, dialog(), 333 &list_, this, dialog(),
267 profile == selected_profile)); 334 profile == selected_profile));
268 } 335 }
269 } 336 }
270 337
271 void ProfileListViewController::FillContentView(views::View* content_view) { 338 void ProfileListViewController::FillContentView(views::View* content_view) {
272 content_view->SetLayoutManager(new views::FillLayout); 339 views::BoxLayout* layout =
340 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
341 layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
342 layout->set_cross_axis_alignment(
343 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
344 content_view->SetLayoutManager(layout);
345 std::unique_ptr<views::View> header_view = CreateHeaderView();
346 if (header_view)
347 content_view->AddChildView(header_view.release());
273 std::unique_ptr<views::View> list_view = list_.CreateListView(); 348 std::unique_ptr<views::View> list_view = list_.CreateListView();
274 list_view->set_id(static_cast<int>(GetDialogViewId())); 349 list_view->set_id(static_cast<int>(GetDialogViewId()));
275 content_view->AddChildView(list_view.release()); 350 content_view->AddChildView(list_view.release());
276 } 351 }
277 352
278 std::unique_ptr<views::View> 353 std::unique_ptr<views::View>
279 ProfileListViewController::CreateExtraFooterView() { 354 ProfileListViewController::CreateExtraFooterView() {
280 std::unique_ptr<views::View> extra_view = base::MakeUnique<views::View>(); 355 std::unique_ptr<views::View> extra_view = base::MakeUnique<views::View>();
281 356
282 extra_view->SetLayoutManager(new views::BoxLayout( 357 extra_view->SetLayoutManager(new views::BoxLayout(
(...skipping 10 matching lines...) Expand all
293 368
294 void ProfileListViewController::ButtonPressed(views::Button* sender, 369 void ProfileListViewController::ButtonPressed(views::Button* sender,
295 const ui::Event& event) { 370 const ui::Event& event) {
296 if (sender->tag() == GetSecondaryButtonTag()) 371 if (sender->tag() == GetSecondaryButtonTag())
297 ShowEditor(nullptr); 372 ShowEditor(nullptr);
298 else 373 else
299 PaymentRequestSheetController::ButtonPressed(sender, event); 374 PaymentRequestSheetController::ButtonPressed(sender, event);
300 } 375 }
301 376
302 } // namespace payments 377 } // namespace payments
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698