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

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

Issue 2955963002: Update Chrome Upstream flow to reflect new UI mocks (Closed)
Patch Set: Update comments Created 3 years, 5 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/save_card_bubble_views.h" 5 #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 SaveCardBubbleController* controller) 56 SaveCardBubbleController* controller)
57 : LocationBarBubbleDelegateView(anchor_view, web_contents), 57 : LocationBarBubbleDelegateView(anchor_view, web_contents),
58 controller_(controller) { 58 controller_(controller) {
59 DCHECK(controller); 59 DCHECK(controller);
60 views::BubbleDialogDelegateView::CreateBubble(this); 60 views::BubbleDialogDelegateView::CreateBubble(this);
61 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD); 61 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD);
62 } 62 }
63 63
64 SaveCardBubbleViews::~SaveCardBubbleViews() {} 64 SaveCardBubbleViews::~SaveCardBubbleViews() {}
65 65
66 SaveCardBubbleViews::CurrentFlowStep SaveCardBubbleViews::GetCurrentFlowStep()
67 const {
68 // No legal messages means this is not upload save.
69 if (controller_->GetLegalMessageLines().empty())
70 return LOCAL_SAVE_ONLY_STEP;
71 // If we're not requesting CVC, this is the only step on the upload path.
72 if (!controller_->ShouldRequestCvcFromUser())
73 return UPLOAD_SAVE_ONLY_STEP;
74 // Must be on the CVC fix flow on the upload path.
75 if (view_stack_->size() == 1)
76 return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1;
77 if (view_stack_->size() == 2)
78 return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2;
79 // CVC fix flow should never have more than 3 views on the stack.
80 NOTREACHED();
81 return UNKNOWN_STEP;
82 }
83
66 void SaveCardBubbleViews::Show(DisplayReason reason) { 84 void SaveCardBubbleViews::Show(DisplayReason reason) {
67 ShowForReason(reason); 85 ShowForReason(reason);
68 } 86 }
69 87
70 void SaveCardBubbleViews::Hide() { 88 void SaveCardBubbleViews::Hide() {
71 controller_ = nullptr; 89 controller_ = nullptr;
72 CloseBubble(); 90 CloseBubble();
73 } 91 }
74 92
75 views::View* SaveCardBubbleViews::CreateExtraView() { 93 views::View* SaveCardBubbleViews::CreateExtraView() {
76 DCHECK(!learn_more_link_); 94 if (GetCurrentFlowStep() == LOCAL_SAVE_ONLY_STEP) {
Shanfeng 2017/06/27 04:00:31 if (GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP)
Jared Saul 2017/06/27 16:38:02 Done.
77 learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); 95 // Learn More link is only shown on local save bubble.
78 learn_more_link_->SetUnderline(false); 96 DCHECK(!learn_more_link_);
79 learn_more_link_->set_listener(this); 97 learn_more_link_ =
80 return learn_more_link_; 98 new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
99 learn_more_link_->SetUnderline(false);
100 learn_more_link_->set_listener(this);
101 return learn_more_link_;
102 }
103 return nullptr;
104 }
105
106 int SaveCardBubbleViews::GetDialogButtons() const {
107 if (GetCurrentFlowStep() == LOCAL_SAVE_ONLY_STEP)
108 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
109 // For upload save, don't show the "No thanks" cancel option; use the
110 // top-right [X] close button for that.
111 return ui::DIALOG_BUTTON_OK;
81 } 112 }
82 113
83 views::View* SaveCardBubbleViews::CreateFootnoteView() { 114 views::View* SaveCardBubbleViews::CreateFootnoteView() {
84 if (controller_->GetLegalMessageLines().empty()) 115 if (controller_->GetLegalMessageLines().empty())
85 return nullptr; 116 return nullptr;
86 117
87 // Use BoxLayout to provide insets around the label. 118 // Use BoxLayout to provide insets around the label.
88 View* view = new View(); 119 footnote_view_ = new View();
89 view->SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); 120 footnote_view_->SetLayoutManager(
121 new views::BoxLayout(views::BoxLayout::kVertical));
90 122
91 // Add a StyledLabel for each line of the legal message. 123 // Add a StyledLabel for each line of the legal message.
92 for (const LegalMessageLine& line : controller_->GetLegalMessageLines()) 124 for (const LegalMessageLine& line : controller_->GetLegalMessageLines())
93 view->AddChildView(CreateLegalMessageLineLabel(line, this).release()); 125 footnote_view_->AddChildView(
126 CreateLegalMessageLineLabel(line, this).release());
94 127
95 return view; 128 // If on the first step of the 2-step upload flow, hide the footer area until
129 // it's time to actually accept the dialog and ToS.
130 if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1)
131 footnote_view_->SetVisible(false);
132
133 return footnote_view_;
96 } 134 }
97 135
98 bool SaveCardBubbleViews::Accept() { 136 bool SaveCardBubbleViews::Accept() {
99 // The main content ViewStack for local save and happy-path upload save should 137 // The main content ViewStack for local save and happy-path upload save should
100 // only ever have 1 View on it. Upload save can have a second View if CVC 138 // only ever have 1 View on it. Upload save can have a second View if CVC
101 // needs to be requested. Assert that the ViewStack has no more than 2 Views 139 // needs to be requested. Assert that the ViewStack has no more than 2 Views
102 // and that if it *does* have 2, it's because CVC is being requested. 140 // and that if it *does* have 2, it's because CVC is being requested.
103 DCHECK_LE(view_stack_->size(), 2U); 141 DCHECK_LE(view_stack_->size(), 2U);
104 DCHECK(view_stack_->size() == 1 || controller_->ShouldRequestCvcFromUser()); 142 DCHECK(view_stack_->size() == 1 || controller_->ShouldRequestCvcFromUser());
105 if (controller_->ShouldRequestCvcFromUser() && view_stack_->size() == 1) { 143 if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1) {
106 // If user accepted upload but more info is needed, push the next view onto 144 // If user accepted upload but more info is needed, push the next view onto
107 // the stack. 145 // the stack and update the bubble.
146 if (controller_)
Shanfeng 2017/06/27 04:00:31 DCHECK(controller_) ? Can controller be null at th
Jared Saul 2017/06/27 16:38:02 Done.
147 controller_->setShowUploadConfirmTitle(true);
148 GetWidget()->UpdateWindowTitle();
108 view_stack_->Push(CreateRequestCvcView(), /*animate=*/true); 149 view_stack_->Push(CreateRequestCvcView(), /*animate=*/true);
109 // Disable the Save button until a valid CVC is entered: 150 // Disable the Save button until a valid CVC is entered:
110 GetDialogClientView()->UpdateDialogButtons(); 151 GetDialogClientView()->UpdateDialogButtons();
152 // Make the legal messaging footer appear:
153 DCHECK(footnote_view_);
154 footnote_view_->SetVisible(true);
111 // Resize the bubble if it's grown larger: 155 // Resize the bubble if it's grown larger:
112 SizeToContents(); 156 SizeToContents();
113 return false; 157 return false;
114 } 158 }
115 // Otherwise, close the bubble as normal. 159 // Otherwise, close the bubble as normal.
116 if (controller_) 160 if (controller_)
117 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text() 161 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text()
118 : base::string16()); 162 : base::string16());
119 return true; 163 return true;
120 } 164 }
121 165
122 bool SaveCardBubbleViews::Cancel() { 166 bool SaveCardBubbleViews::Cancel() {
123 if (controller_) 167 if (controller_)
124 controller_->OnCancelButton(); 168 controller_->OnCancelButton();
125 return true; 169 return true;
126 } 170 }
127 171
128 bool SaveCardBubbleViews::Close() { 172 bool SaveCardBubbleViews::Close() {
129 // Cancel is logged as a different user action than closing, so override 173 // Cancel is logged as a different user action than closing, so override
130 // Close() to prevent the superclass' implementation from calling Cancel(). 174 // Close() to prevent the superclass' implementation from calling Cancel().
131 // Return true to indicate that the bubble can be closed. 175 // Return true to indicate that the bubble can be closed.
132 return true; 176 return true;
133 } 177 }
134 178
135 base::string16 SaveCardBubbleViews::GetDialogButtonLabel( 179 base::string16 SaveCardBubbleViews::GetDialogButtonLabel(
136 ui::DialogButton button) const { 180 ui::DialogButton button) const {
137 return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK 181 // Local save has two buttons:
138 ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT 182 if (GetCurrentFlowStep() == LOCAL_SAVE_ONLY_STEP)
139 : IDS_NO_THANKS); 183 return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK
184 ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT
185 : IDS_NO_THANKS);
186 // Upload save has one button but it can say three different things:
187 DCHECK(button == ui::DIALOG_BUTTON_OK);
188 if (GetCurrentFlowStep() == UPLOAD_SAVE_ONLY_STEP)
189 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT);
Shanfeng 2017/06/27 04:00:31 Nit: use switch instead.
Jared Saul 2017/06/27 16:38:02 Done.
190 else if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1)
191 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_NEXT);
192 else /*if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2)*/
193 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_CONFIRM);
140 } 194 }
141 195
142 gfx::Size SaveCardBubbleViews::CalculatePreferredSize() const { 196 gfx::Size SaveCardBubbleViews::CalculatePreferredSize() const {
143 return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth)); 197 return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth));
144 } 198 }
145 199
200 bool SaveCardBubbleViews::ShouldShowCloseButton() const {
201 // Local save should have a [No thanks] button, but Upload save should surface
202 // the top-right [X] close button instead.
203 return GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP;
204 }
205
146 base::string16 SaveCardBubbleViews::GetWindowTitle() const { 206 base::string16 SaveCardBubbleViews::GetWindowTitle() const {
147 return controller_ ? controller_->GetWindowTitle() : base::string16(); 207 return controller_ ? controller_->GetWindowTitle() : base::string16();
148 } 208 }
149 209
150 void SaveCardBubbleViews::WindowClosing() { 210 void SaveCardBubbleViews::WindowClosing() {
151 if (controller_) 211 if (controller_)
152 controller_->OnBubbleClosed(); 212 controller_->OnBubbleClosed();
153 } 213 }
154 214
155 void SaveCardBubbleViews::LinkClicked(views::Link* source, int event_flags) { 215 void SaveCardBubbleViews::LinkClicked(views::Link* source, int event_flags) {
(...skipping 30 matching lines...) Expand all
186 246
187 // Create view containing everything except for the footnote. 247 // Create view containing everything except for the footnote.
188 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() { 248 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() {
189 auto view = base::MakeUnique<views::View>(); 249 auto view = base::MakeUnique<views::View>();
190 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); 250 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
191 251
192 view->SetLayoutManager(new views::BoxLayout( 252 view->SetLayoutManager(new views::BoxLayout(
193 views::BoxLayout::kVertical, gfx::Insets(), 253 views::BoxLayout::kVertical, gfx::Insets(),
194 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); 254 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)));
195 255
256 // If applicable, add the upload explanation label.
257 base::string16 explanation = controller_->GetExplanatoryMessage();
258 if (!explanation.empty()) {
259 views::Label* explanation_label = new views::Label(explanation);
260 explanation_label->SetMultiLine(true);
261 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
262 view->AddChildView(explanation_label);
263 }
264
196 // Add the card type icon, last four digits and expiration date. 265 // Add the card type icon, last four digits and expiration date.
197 views::View* description_view = new views::View(); 266 views::View* description_view = new views::View();
198 description_view->SetLayoutManager(new views::BoxLayout( 267 description_view->SetLayoutManager(new views::BoxLayout(
199 views::BoxLayout::kHorizontal, gfx::Insets(), 268 views::BoxLayout::kHorizontal, gfx::Insets(),
200 provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); 269 provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
201 view->AddChildView(description_view); 270 view->AddChildView(description_view);
202 271
203 const CreditCard& card = controller_->GetCard(); 272 const CreditCard& card = controller_->GetCard();
204 views::ImageView* card_type_icon = new views::ImageView(); 273 views::ImageView* card_type_icon = new views::ImageView();
205 card_type_icon->SetImage( 274 card_type_icon->SetImage(
206 ResourceBundle::GetSharedInstance() 275 ResourceBundle::GetSharedInstance()
207 .GetImageNamed(CreditCard::IconResourceId(card.network())) 276 .GetImageNamed(CreditCard::IconResourceId(card.network()))
208 .AsImageSkia()); 277 .AsImageSkia());
209 card_type_icon->SetTooltipText(card.NetworkForDisplay()); 278 card_type_icon->SetTooltipText(card.NetworkForDisplay());
210 card_type_icon->SetBorder( 279 card_type_icon->SetBorder(
211 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10))); 280 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10)));
212 description_view->AddChildView(card_type_icon); 281 description_view->AddChildView(card_type_icon);
213 282
214 description_view->AddChildView(new views::Label( 283 description_view->AddChildView(new views::Label(
215 base::string16(kMidlineEllipsis) + card.LastFourDigits())); 284 base::string16(kMidlineEllipsis) + card.LastFourDigits()));
216 description_view->AddChildView( 285 description_view->AddChildView(
217 new views::Label(card.AbbreviatedExpirationDateForDisplay())); 286 new views::Label(card.AbbreviatedExpirationDateForDisplay()));
218 287
219 // Optionally add label that will contain an explanation for upload.
220 base::string16 explanation = controller_->GetExplanatoryMessage();
221 if (!explanation.empty()) {
222 views::Label* explanation_label = new views::Label(explanation);
223 explanation_label->SetMultiLine(true);
224 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
225 view->AddChildView(explanation_label);
226 }
227
228 return view; 288 return view;
229 } 289 }
230 290
231 std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() { 291 std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() {
232 auto request_cvc_view = base::MakeUnique<views::View>(); 292 auto request_cvc_view = base::MakeUnique<views::View>();
293 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
294
295 request_cvc_view->SetLayoutManager(new views::BoxLayout(
296 views::BoxLayout::kVertical, gfx::Insets(),
297 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)));
233 request_cvc_view->SetBackground(views::CreateThemedSolidBackground( 298 request_cvc_view->SetBackground(views::CreateThemedSolidBackground(
234 request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground)); 299 request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground));
300
301 views::Label* explanation_label = new views::Label(l10n_util::GetStringUTF16(
302 IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC_EXPLANATION));
303 explanation_label->SetMultiLine(true);
304 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
305 request_cvc_view->AddChildView(explanation_label);
306
307 views::View* cvc_entry_view = new views::View();
235 views::BoxLayout* layout = 308 views::BoxLayout* layout =
236 new views::BoxLayout(views::BoxLayout::kHorizontal, gfx::Insets(), 309 new views::BoxLayout(views::BoxLayout::kHorizontal, gfx::Insets(),
237 ChromeLayoutProvider::Get()->GetDistanceMetric( 310 ChromeLayoutProvider::Get()->GetDistanceMetric(
238 views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); 311 views::DISTANCE_RELATED_BUTTON_HORIZONTAL));
239 layout->set_cross_axis_alignment( 312 layout->set_cross_axis_alignment(
240 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); 313 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
241 request_cvc_view->SetLayoutManager(layout); 314 cvc_entry_view->SetLayoutManager(layout);
242 315
243 DCHECK(!cvc_textfield_); 316 DCHECK(!cvc_textfield_);
244 cvc_textfield_ = CreateCvcTextfield(); 317 cvc_textfield_ = CreateCvcTextfield();
245 cvc_textfield_->set_controller(this); 318 cvc_textfield_->set_controller(this);
246 request_cvc_view->AddChildView(cvc_textfield_); 319 cvc_entry_view->AddChildView(cvc_textfield_);
247 320
248 views::ImageView* cvc_image = new views::ImageView(); 321 views::ImageView* cvc_image = new views::ImageView();
249 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 322 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
250 cvc_image->SetImage( 323 cvc_image->SetImage(
251 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId())); 324 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId()));
252 request_cvc_view->AddChildView(cvc_image); 325 cvc_entry_view->AddChildView(cvc_image);
253 326
254 request_cvc_view->AddChildView(new views::Label( 327 request_cvc_view->AddChildView(cvc_entry_view);
255 l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC)));
256
257 return request_cvc_view; 328 return request_cvc_view;
258 } 329 }
259 330
260 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const { 331 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const {
261 if (button == ui::DIALOG_BUTTON_CANCEL) 332 if (button == ui::DIALOG_BUTTON_CANCEL)
262 return true; 333 return true;
263 334
264 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); 335 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button);
265 return !cvc_textfield_ || 336 return !cvc_textfield_ ||
266 controller_->InputCvcIsValid(cvc_textfield_->text()); 337 controller_->InputCvcIsValid(cvc_textfield_->text());
267 } 338 }
268 339
269 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender, 340 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender,
270 const base::string16& new_contents) { 341 const base::string16& new_contents) {
271 DCHECK_EQ(cvc_textfield_, sender); 342 DCHECK_EQ(cvc_textfield_, sender);
272 GetDialogClientView()->UpdateDialogButtons(); 343 GetDialogClientView()->UpdateDialogButtons();
273 } 344 }
274 345
275 void SaveCardBubbleViews::Init() { 346 void SaveCardBubbleViews::Init() {
276 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); 347 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical));
277 view_stack_ = new ViewStack(); 348 view_stack_ = new ViewStack();
278 view_stack_->SetBackground(views::CreateThemedSolidBackground( 349 view_stack_->SetBackground(views::CreateThemedSolidBackground(
279 view_stack_, ui::NativeTheme::kColorId_BubbleBackground)); 350 view_stack_, ui::NativeTheme::kColorId_BubbleBackground));
280 view_stack_->Push(CreateMainContentView(), /*animate=*/false); 351 view_stack_->Push(CreateMainContentView(), /*animate=*/false);
281 AddChildView(view_stack_); 352 AddChildView(view_stack_);
282 } 353 }
283 354
284 } // namespace autofill 355 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698