1 // Copyright (c) 2012 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.
4 
5 #include "chrome/browser/ui/views/sync/one_click_signin_dialog_view.h"
6 
7 #include <utility>
8 
9 #include "base/callback_helpers.h"
10 #include "base/logging.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_dialogs.h"
13 #include "chrome/browser/ui/views/chrome_layout_provider.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/grit/chromium_strings.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "components/constrained_window/constrained_window_views.h"
18 #include "components/google/core/common/google_util.h"
19 #include "components/strings/grit/components_strings.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/events/keycodes/keyboard_codes.h"
23 #include "ui/views/controls/button/image_button.h"
24 #include "ui/views/controls/button/label_button.h"
25 #include "ui/views/controls/image_view.h"
26 #include "ui/views/controls/label.h"
27 #include "ui/views/controls/link.h"
28 #include "ui/views/layout/grid_layout.h"
29 #include "ui/views/widget/widget.h"
30 
31 // static
32 OneClickSigninDialogView* OneClickSigninDialogView::dialog_view_ = nullptr;
33 
34 // static
ShowDialog(const base::string16 & email,std::unique_ptr<OneClickSigninLinksDelegate> delegate,gfx::NativeWindow window,base::OnceCallback<void (bool)> confirmed_callback)35 void OneClickSigninDialogView::ShowDialog(
36     const base::string16& email,
37     std::unique_ptr<OneClickSigninLinksDelegate> delegate,
38     gfx::NativeWindow window,
39     base::OnceCallback<void(bool)> confirmed_callback) {
40   if (IsShowing())
41     return;
42 
43   dialog_view_ = new OneClickSigninDialogView(email, std::move(delegate),
44                                               std::move(confirmed_callback));
45   constrained_window::CreateBrowserModalDialogViews(dialog_view_, window)
46       ->Show();
47 }
48 
49 // static
IsShowing()50 bool OneClickSigninDialogView::IsShowing() {
51   return dialog_view_ != nullptr;
52 }
53 
54 // static
Hide()55 void OneClickSigninDialogView::Hide() {
56   if (IsShowing())
57     dialog_view_->GetWidget()->Close();
58 }
59 
GetModalType() const60 ui::ModalType OneClickSigninDialogView::GetModalType() const {
61   return ui::MODAL_TYPE_WINDOW;
62 }
63 
WindowClosing()64 void OneClickSigninDialogView::WindowClosing() {
65   // We have to reset |dialog_view_| here, not in our destructor, because
66   // we'll be destroyed asynchronously and the shown state will be checked
67   // before then.
68   DCHECK_EQ(dialog_view_, this);
69   dialog_view_ = nullptr;
70 }
71 
Accept()72 bool OneClickSigninDialogView::Accept() {
73   std::move(confirmed_callback_).Run(true);
74   return true;
75 }
76 
OneClickSigninDialogView(const base::string16 & email,std::unique_ptr<OneClickSigninLinksDelegate> delegate,base::OnceCallback<void (bool)> confirmed_callback)77 OneClickSigninDialogView::OneClickSigninDialogView(
78     const base::string16& email,
79     std::unique_ptr<OneClickSigninLinksDelegate> delegate,
80     base::OnceCallback<void(bool)> confirmed_callback)
81     : email_(email), confirmed_callback_(std::move(confirmed_callback)) {
82   DCHECK(!confirmed_callback_.is_null());
83 
84   views::GridLayout* layout =
85       SetLayoutManager(std::make_unique<views::GridLayout>());
86 
87   // Column set for descriptive text and link.
88   views::ColumnSet* cs = layout->AddColumnSet(0);
89   cs->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 1.0,
90                 views::GridLayout::ColumnSize::kUsePreferred, 0, 0);
91 
92   layout->StartRow(views::GridLayout::kFixedSize, 0);
93 
94   auto label = std::make_unique<views::Label>(l10n_util::GetStringFUTF16(
95       IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE_NEW, email_));
96   label->SetMultiLine(true);
97   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
98   // Minimum width for the multi-line label.
99   constexpr int kMinimumDialogLabelWidth = 400;
100   label->SizeToFit(kMinimumDialogLabelWidth);
101   layout->AddView(std::move(label));
102 
103   layout->StartRow(views::GridLayout::kFixedSize, 0);
104 
105   auto learn_more_link =
106       std::make_unique<views::Link>(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
107   learn_more_link->SetCallback(
108       base::BindRepeating(&OneClickSigninLinksDelegate::OnLearnMoreLinkClicked,
109                           std::move(delegate), true));
110   learn_more_link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
111   layout->AddView(std::move(learn_more_link), 1, 1, views::GridLayout::TRAILING,
112                   views::GridLayout::CENTER);
113 
114   auto advanced_link = std::make_unique<views::Link>(
115       l10n_util::GetStringUTF16(IDS_ONE_CLICK_SIGNIN_DIALOG_ADVANCED));
116   advanced_link->SetCallback(base::BindRepeating(
117       [](OneClickSigninDialogView* view) {
118         if (view->Accept())
119           Hide();
120       },
121       base::Unretained(this)));
122   advanced_link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
123   SetExtraView(std::move(advanced_link));
124 
125   SetButtonLabel(
126       ui::DIALOG_BUTTON_OK,
127       l10n_util::GetStringUTF16(IDS_ONE_CLICK_SIGNIN_DIALOG_OK_BUTTON));
128   SetButtonLabel(
129       ui::DIALOG_BUTTON_CANCEL,
130       l10n_util::GetStringUTF16(IDS_ONE_CLICK_SIGNIN_DIALOG_UNDO_BUTTON));
131   SetTitle(IDS_ONE_CLICK_SIGNIN_DIALOG_TITLE_NEW);
132 
133   set_margins(ChromeLayoutProvider::Get()->GetDialogInsetsForContentType(
134       views::TEXT, views::TEXT));
135   chrome::RecordDialogCreation(chrome::DialogIdentifier::ONE_CLICK_SIGNIN);
136 }
137 
~OneClickSigninDialogView()138 OneClickSigninDialogView::~OneClickSigninDialogView() {
139   if (!confirmed_callback_.is_null())
140     std::move(confirmed_callback_).Run(false);
141 }
142