Chromium Code Reviews| Index: chrome/browser/ui/views/autofill/save_card_bubble_views.cc |
| diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc |
| index c418d39aa566a940f29fa50eefe25ec10b9027ed..325edcc12ce185c347dc3a4f1c61c2d2846944c4 100644 |
| --- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc |
| +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc |
| @@ -63,6 +63,24 @@ SaveCardBubbleViews::SaveCardBubbleViews(views::View* anchor_view, |
| SaveCardBubbleViews::~SaveCardBubbleViews() {} |
| +SaveCardBubbleViews::CurrentFlowStep SaveCardBubbleViews::GetCurrentFlowStep() |
| + const { |
| + // No legal messages means this is not upload save. |
| + if (controller_->GetLegalMessageLines().empty()) |
| + return LOCAL_SAVE_ONLY_STEP; |
| + // If we're not requesting CVC, this is the only step on the upload path. |
| + if (!controller_->ShouldRequestCvcFromUser()) |
| + return UPLOAD_SAVE_ONLY_STEP; |
| + // Must be on the CVC fix flow on the upload path. |
| + if (view_stack_->size() == 1) |
| + return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD; |
| + if (view_stack_->size() == 2) |
| + return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2_REQUEST_CVC; |
| + // CVC fix flow should never have more than 3 views on the stack. |
| + NOTREACHED(); |
| + return UNKNOWN_STEP; |
| +} |
| + |
| void SaveCardBubbleViews::Show(DisplayReason reason) { |
| ShowForReason(reason); |
| } |
| @@ -73,6 +91,9 @@ void SaveCardBubbleViews::Hide() { |
| } |
| views::View* SaveCardBubbleViews::CreateExtraView() { |
| + if (GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP) |
| + return nullptr; |
| + // Learn More link is only shown on local save bubble. |
| DCHECK(!learn_more_link_); |
| learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); |
| learn_more_link_->SetUnderline(false); |
| @@ -80,19 +101,34 @@ views::View* SaveCardBubbleViews::CreateExtraView() { |
| return learn_more_link_; |
| } |
| +int SaveCardBubbleViews::GetDialogButtons() const { |
| + if (GetCurrentFlowStep() == LOCAL_SAVE_ONLY_STEP) |
| + return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; |
| + // For upload save, don't show the "No thanks" cancel option; use the |
| + // top-right [X] close button for that. |
| + return ui::DIALOG_BUTTON_OK; |
| +} |
| + |
| views::View* SaveCardBubbleViews::CreateFootnoteView() { |
| if (controller_->GetLegalMessageLines().empty()) |
| return nullptr; |
| // Use BoxLayout to provide insets around the label. |
| - View* view = new View(); |
| - view->SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); |
| + footnote_view_ = new View(); |
| + footnote_view_->SetLayoutManager( |
| + new views::BoxLayout(views::BoxLayout::kVertical)); |
| // Add a StyledLabel for each line of the legal message. |
| for (const LegalMessageLine& line : controller_->GetLegalMessageLines()) |
| - view->AddChildView(CreateLegalMessageLineLabel(line, this).release()); |
| + footnote_view_->AddChildView( |
| + CreateLegalMessageLineLabel(line, this).release()); |
| - return view; |
| + // If on the first step of the 2-step upload flow, hide the footer area until |
| + // it's time to actually accept the dialog and ToS. |
| + if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD) |
| + footnote_view_->SetVisible(false); |
| + |
| + return footnote_view_; |
| } |
| bool SaveCardBubbleViews::Accept() { |
| @@ -102,12 +138,18 @@ bool SaveCardBubbleViews::Accept() { |
| // and that if it *does* have 2, it's because CVC is being requested. |
| DCHECK_LE(view_stack_->size(), 2U); |
| DCHECK(view_stack_->size() == 1 || controller_->ShouldRequestCvcFromUser()); |
| - if (controller_->ShouldRequestCvcFromUser() && view_stack_->size() == 1) { |
| + if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD) { |
| // If user accepted upload but more info is needed, push the next view onto |
| - // the stack. |
| + // the stack and update the bubble. |
| + DCHECK(controller_); |
| + controller_->SetShowUploadConfirmTitle(true); |
| + GetWidget()->UpdateWindowTitle(); |
| view_stack_->Push(CreateRequestCvcView(), /*animate=*/true); |
| // Disable the Save button until a valid CVC is entered: |
| GetDialogClientView()->UpdateDialogButtons(); |
| + // Make the legal messaging footer appear: |
| + DCHECK(footnote_view_); |
| + footnote_view_->SetVisible(true); |
| // Resize the bubble if it's grown larger: |
| SizeToContents(); |
| return false; |
| @@ -134,15 +176,38 @@ bool SaveCardBubbleViews::Close() { |
| base::string16 SaveCardBubbleViews::GetDialogButtonLabel( |
| ui::DialogButton button) const { |
| - return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK |
| - ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT |
| - : IDS_NO_THANKS); |
| + switch (GetCurrentFlowStep()) { |
| + // Local save has two buttons: |
| + case LOCAL_SAVE_ONLY_STEP: |
| + return l10n_util::GetStringUTF16( |
| + button == ui::DIALOG_BUTTON_OK ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT |
| + : IDS_NO_THANKS); |
| + // Upload save has one button but it can say three different things: |
| + case UPLOAD_SAVE_ONLY_STEP: |
| + DCHECK(button == ui::DIALOG_BUTTON_OK); |
| + return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT); |
| + case UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD: |
| + DCHECK(button == ui::DIALOG_BUTTON_OK); |
| + return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_NEXT); |
| + case UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2_REQUEST_CVC: |
| + DCHECK(button == ui::DIALOG_BUTTON_OK); |
| + return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_CONFIRM); |
| + default: |
| + NOTREACHED(); |
| + return base::string16(); |
| + } |
| } |
| gfx::Size SaveCardBubbleViews::CalculatePreferredSize() const { |
| return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth)); |
| } |
| +bool SaveCardBubbleViews::ShouldShowCloseButton() const { |
| + // Local save should have a [No thanks] button, but Upload save should surface |
| + // the top-right [X] close button instead. |
| + return GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP; |
| +} |
| + |
| base::string16 SaveCardBubbleViews::GetWindowTitle() const { |
| return controller_ ? controller_->GetWindowTitle() : base::string16(); |
| } |
| @@ -193,6 +258,15 @@ std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() { |
| views::BoxLayout::kVertical, gfx::Insets(), |
| provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); |
| + // If applicable, add the upload explanation label. |
| + base::string16 explanation = controller_->GetExplanatoryMessage(); |
| + if (!explanation.empty()) { |
| + views::Label* explanation_label = new views::Label(explanation); |
| + explanation_label->SetMultiLine(true); |
| + explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| + view->AddChildView(explanation_label); |
| + } |
| + |
| // Add the card type icon, last four digits and expiration date. |
| views::View* description_view = new views::View(); |
| description_view->SetLayoutManager(new views::BoxLayout( |
| @@ -216,44 +290,46 @@ std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() { |
| description_view->AddChildView( |
| new views::Label(card.AbbreviatedExpirationDateForDisplay())); |
| - // Optionally add label that will contain an explanation for upload. |
| - base::string16 explanation = controller_->GetExplanatoryMessage(); |
| - if (!explanation.empty()) { |
| - views::Label* explanation_label = new views::Label(explanation); |
| - explanation_label->SetMultiLine(true); |
| - explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| - view->AddChildView(explanation_label); |
| - } |
| - |
| return view; |
| } |
| std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() { |
| auto request_cvc_view = base::MakeUnique<views::View>(); |
| + ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); |
| + |
| + request_cvc_view->SetLayoutManager(new views::BoxLayout( |
| + views::BoxLayout::kVertical, gfx::Insets(), |
| + provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); |
| request_cvc_view->SetBackground(views::CreateThemedSolidBackground( |
| request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground)); |
| + |
| + views::Label* explanation_label = new views::Label(l10n_util::GetStringUTF16( |
| + IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC_EXPLANATION)); |
| + explanation_label->SetMultiLine(true); |
| + explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| + request_cvc_view->AddChildView(explanation_label); |
| + |
| + views::View* cvc_entry_view = new views::View(); |
| views::BoxLayout* layout = |
| new views::BoxLayout(views::BoxLayout::kHorizontal, gfx::Insets(), |
| ChromeLayoutProvider::Get()->GetDistanceMetric( |
|
Mathieu
2017/06/27 21:12:06
use |provider| here?
Jared Saul
2017/06/27 21:45:55
Good catch; done.
|
| views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); |
| layout->set_cross_axis_alignment( |
| views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); |
| - request_cvc_view->SetLayoutManager(layout); |
| + cvc_entry_view->SetLayoutManager(layout); |
| DCHECK(!cvc_textfield_); |
| cvc_textfield_ = CreateCvcTextfield(); |
| cvc_textfield_->set_controller(this); |
| - request_cvc_view->AddChildView(cvc_textfield_); |
| + cvc_entry_view->AddChildView(cvc_textfield_); |
| views::ImageView* cvc_image = new views::ImageView(); |
| ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| cvc_image->SetImage( |
| rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId())); |
| - request_cvc_view->AddChildView(cvc_image); |
| - |
| - request_cvc_view->AddChildView(new views::Label( |
| - l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC))); |
| + cvc_entry_view->AddChildView(cvc_image); |
| + request_cvc_view->AddChildView(cvc_entry_view); |
| return request_cvc_view; |
| } |