1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h"
8 #include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
9 #include "chrome/grit/generated_resources.h"
10 #include "components/constrained_window/constrained_window_views.h"
11 #include "grit/theme_resources.h"
12 #include "ui/base/l10n/l10n_util.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/views/controls/image_view.h"
15 #include "ui/views/controls/label.h"
16 #include "ui/views/controls/textfield/textfield.h"
17 #include "ui/views/controls/textfield/textfield_controller.h"
18 #include "ui/views/layout/box_layout.h"
19 #include "ui/views/widget/widget.h"
20 #include "ui/views/window/dialog_client_view.h"
21 #include "ui/views/window/dialog_delegate.h"
27 class CardUnmaskPromptViews
: public CardUnmaskPromptView
,
28 views::DialogDelegateView
,
29 views::TextfieldController
{
31 explicit CardUnmaskPromptViews(CardUnmaskPromptController
* controller
)
32 : controller_(controller
), cvc_input_(nullptr), message_label_(nullptr) {}
34 ~CardUnmaskPromptViews() override
{
36 controller_
->OnUnmaskDialogClosed();
40 constrained_window::ShowWebModalDialogViews(this,
41 controller_
->GetWebContents());
44 // CardUnmaskPromptView
45 void ControllerGone() override
{
46 controller_
= nullptr;
50 void DisableAndWaitForVerification() override
{
51 cvc_input_
->SetEnabled(false);
52 message_label_
->SetText(base::ASCIIToUTF16("Verifying..."));
53 message_label_
->SetVisible(true);
54 GetDialogClientView()->UpdateDialogButtons();
58 void GotVerificationResult(bool success
) override
{
60 message_label_
->SetText(base::ASCIIToUTF16("Success!"));
61 base::MessageLoop::current()->PostDelayedTask(
62 FROM_HERE
, base::Bind(&CardUnmaskPromptViews::ClosePrompt
,
63 base::Unretained(this)),
64 base::TimeDelta::FromSeconds(1));
66 cvc_input_
->SetEnabled(true);
67 message_label_
->SetText(base::ASCIIToUTF16("Verification error."));
68 GetDialogClientView()->UpdateDialogButtons();
73 // views::DialogDelegateView
74 View
* GetContentsView() override
{
80 gfx::Size
GetPreferredSize() const override
{
81 // Must hardcode a width so the label knows where to wrap. TODO(estade):
82 // This can lead to a weird looking dialog if we end up getting allocated
83 // more width than we ask for, e.g. if the title is super long.
84 const int kWidth
= 250;
85 return gfx::Size(kWidth
, GetHeightForWidth(kWidth
));
88 ui::ModalType
GetModalType() const override
{ return ui::MODAL_TYPE_CHILD
; }
90 base::string16
GetWindowTitle() const override
{
91 return controller_
->GetWindowTitle();
94 void DeleteDelegate() override
{ delete this; }
96 int GetDialogButtons() const override
{
97 return ui::DIALOG_BUTTON_OK
| ui::DIALOG_BUTTON_CANCEL
;
100 base::string16
GetDialogButtonLabel(ui::DialogButton button
) const override
{
101 // TODO(estade): fix this.
102 if (button
== ui::DIALOG_BUTTON_OK
)
103 return base::ASCIIToUTF16("Verify");
105 return DialogDelegateView::GetDialogButtonLabel(button
);
108 bool ShouldDefaultButtonBeBlue() const override
{ return true; }
110 bool IsDialogButtonEnabled(ui::DialogButton button
) const override
{
111 if (button
== ui::DIALOG_BUTTON_CANCEL
)
114 DCHECK_EQ(ui::DIALOG_BUTTON_OK
, button
);
116 return cvc_input_
->enabled() &&
117 controller_
->InputTextIsValid(cvc_input_
->text());
120 views::View
* GetInitiallyFocusedView() override
{ return cvc_input_
; }
122 bool Cancel() override
{
126 bool Accept() override
{
130 controller_
->OnUnmaskResponse(cvc_input_
->text());
134 // views::TextfieldController
135 void ContentsChanged(views::Textfield
* sender
,
136 const base::string16
& new_contents
) override
{
137 GetDialogClientView()->UpdateDialogButtons();
141 void InitIfNecessary() {
146 new views::BoxLayout(views::BoxLayout::kVertical
, 19, 0, 5));
147 views::Label
* instructions
=
148 new views::Label(controller_
->GetInstructionsMessage());
150 instructions
->SetMultiLine(true);
151 instructions
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
152 AddChildView(instructions
);
154 views::View
* cvc_container
= new views::View();
155 cvc_container
->SetLayoutManager(
156 new views::BoxLayout(views::BoxLayout::kHorizontal
, 0, 0, 5));
157 AddChildView(cvc_container
);
159 cvc_input_
= new views::Textfield();
160 cvc_input_
->set_controller(this);
161 cvc_input_
->set_placeholder_text(
162 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC
));
163 cvc_input_
->set_default_width_in_chars(10);
164 cvc_container
->AddChildView(cvc_input_
);
166 views::ImageView
* cvc_image
= new views::ImageView();
167 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
169 cvc_image
->SetImage(rb
.GetImageSkiaNamed(controller_
->GetCvcImageRid()));
171 cvc_container
->AddChildView(cvc_image
);
173 message_label_
= new views::Label();
174 cvc_container
->AddChildView(message_label_
);
175 message_label_
->SetVisible(false);
178 void ClosePrompt() { GetWidget()->Close(); }
180 CardUnmaskPromptController
* controller_
;
182 views::Textfield
* cvc_input_
;
184 // TODO(estade): this is a temporary standin in place of some spinner UI
185 // as well as a better error message.
186 views::Label
* message_label_
;
188 DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews
);
194 CardUnmaskPromptView
* CardUnmaskPromptView::CreateAndShow(
195 CardUnmaskPromptController
* controller
) {
196 CardUnmaskPromptViews
* view
= new CardUnmaskPromptViews(controller
);
201 } // namespace autofill