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

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

Powered by Google App Engine
This is Rietveld 408576698