profile_signin_confirmation_dialog_views.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2013 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/profile_signin_confirmation_dialog_views.h"
6
7#include <algorithm>
8
9#include "base/strings/utf_string_conversions.h"
10#include "chrome/browser/ui/browser.h"
11#include "chrome/browser/ui/browser_dialogs.h"
12#include "chrome/browser/ui/browser_navigator.h"
13#include "chrome/browser/ui/browser_window.h"
14#include "chrome/browser/ui/host_desktop.h"
15#include "chrome/browser/ui/views/constrained_window_views.h"
16#include "chrome/browser/ui/views/profiles/profile_chooser_view.h"
17#include "chrome/grit/chromium_strings.h"
18#include "chrome/grit/generated_resources.h"
19#include "components/signin/core/common/profile_management_switches.h"
20#include "content/public/browser/web_contents.h"
21#include "google_apis/gaia/gaia_auth_util.h"
22#include "third_party/skia/include/core/SkColor.h"
23#include "ui/base/l10n/l10n_util.h"
24#include "ui/gfx/font.h"
25#include "ui/gfx/native_widget_types.h"
26#include "ui/gfx/range/range.h"
27#include "ui/views/background.h"
28#include "ui/views/border.h"
29#include "ui/views/controls/label.h"
30#include "ui/views/controls/styled_label.h"
31#include "ui/views/layout/box_layout.h"
32#include "ui/views/layout/grid_layout.h"
33#include "ui/views/layout/layout_constants.h"
34#include "ui/views/widget/widget.h"
35#include "ui/views/window/dialog_client_view.h"
36
37namespace chrome {
38// Declared in browser_dialogs.h
39void ShowProfileSigninConfirmationDialog(
40    Browser* browser,
41    content::WebContents* web_contents,
42    Profile* profile,
43    const std::string& username,
44    ui::ProfileSigninConfirmationDelegate* delegate) {
45  ProfileSigninConfirmationDialogViews::ShowDialog(browser,
46                                                   profile,
47                                                   username,
48                                                   delegate);
49}
50}  // namespace chrome
51
52ProfileSigninConfirmationDialogViews::ProfileSigninConfirmationDialogViews(
53    Browser* browser,
54    const std::string& username,
55    ui::ProfileSigninConfirmationDelegate* delegate)
56    : browser_(browser),
57      username_(username),
58      delegate_(delegate),
59      prompt_for_new_profile_(true),
60      continue_signin_button_(NULL) {
61}
62
63ProfileSigninConfirmationDialogViews::~ProfileSigninConfirmationDialogViews() {}
64
65// static
66void ProfileSigninConfirmationDialogViews::ShowDialog(
67    Browser* browser,
68    Profile* profile,
69    const std::string& username,
70    ui::ProfileSigninConfirmationDelegate* delegate) {
71  // Hides the new avatar bubble if it is currently shown. The new avatar bubble
72  // should be automatically closed when it loses focus. However on windows the
73  // profile signin confirmation dialog is not modal yet thus it does not take
74  // away focus, thus as a temporary workaround we need to manually close the
75  // bubble.
76  // TODO(guohui): removes the workaround once the profile confirmation dialog
77  // is fixed.
78  if (switches::IsNewAvatarMenu() && ProfileChooserView::IsShowing())
79    ProfileChooserView::Hide();
80
81  ProfileSigninConfirmationDialogViews* dialog =
82      new ProfileSigninConfirmationDialogViews(
83          browser, username, delegate);
84  ui::CheckShouldPromptForNewProfile(
85      profile,
86      // This callback is guaranteed to be invoked, and once it is, the dialog
87      // owns itself.
88      base::Bind(&ProfileSigninConfirmationDialogViews::Show,
89                 base::Unretained(dialog)));
90}
91
92void ProfileSigninConfirmationDialogViews::Show(bool prompt_for_new_profile) {
93  prompt_for_new_profile_ = prompt_for_new_profile;
94  CreateBrowserModalDialogViews(
95      this, browser_->window()->GetNativeWindow())->Show();
96}
97
98base::string16 ProfileSigninConfirmationDialogViews::GetWindowTitle() const {
99  return l10n_util::GetStringUTF16(
100      IDS_ENTERPRISE_SIGNIN_TITLE_NEW_STYLE);
101}
102
103base::string16 ProfileSigninConfirmationDialogViews::GetDialogButtonLabel(
104    ui::DialogButton button) const {
105  if (button == ui::DIALOG_BUTTON_OK) {
106    // If we're giving the option to create a new profile, then OK is
107    // "Create new profile".  Otherwise it is "Continue signin".
108    return l10n_util::GetStringUTF16(
109        prompt_for_new_profile_ ?
110            IDS_ENTERPRISE_SIGNIN_CREATE_NEW_PROFILE_NEW_STYLE :
111            IDS_ENTERPRISE_SIGNIN_CONTINUE_NEW_STYLE);
112  }
113  return l10n_util::GetStringUTF16(IDS_ENTERPRISE_SIGNIN_CANCEL);
114}
115
116int ProfileSigninConfirmationDialogViews::GetDefaultDialogButton() const {
117  return ui::DIALOG_BUTTON_NONE;
118}
119
120views::View* ProfileSigninConfirmationDialogViews::CreateExtraView() {
121  if (prompt_for_new_profile_) {
122    const base::string16 continue_signin_text =
123        l10n_util::GetStringUTF16(IDS_ENTERPRISE_SIGNIN_CONTINUE_NEW_STYLE);
124    continue_signin_button_ =
125        new views::LabelButton(this, continue_signin_text);
126    continue_signin_button_->SetStyle(views::Button::STYLE_BUTTON);
127    continue_signin_button_->SetFocusable(true);
128  }
129  return continue_signin_button_;
130}
131
132bool ProfileSigninConfirmationDialogViews::Accept() {
133  if (delegate_) {
134    if (prompt_for_new_profile_)
135      delegate_->OnSigninWithNewProfile();
136    else
137      delegate_->OnContinueSignin();
138    delegate_ = NULL;
139  }
140  return true;
141}
142
143bool ProfileSigninConfirmationDialogViews::Cancel() {
144  if (delegate_) {
145    delegate_->OnCancelSignin();
146    delegate_ = NULL;
147  }
148  return true;
149}
150
151void ProfileSigninConfirmationDialogViews::OnClosed() {
152  Cancel();
153}
154
155ui::ModalType ProfileSigninConfirmationDialogViews::GetModalType() const {
156  return ui::MODAL_TYPE_CHILD;
157}
158
159void ProfileSigninConfirmationDialogViews::ViewHierarchyChanged(
160    const ViewHierarchyChangedDetails& details) {
161  if (!details.is_add || details.child != this)
162    return;
163
164  const SkColor kPromptBarBackgroundColor =
165      ui::GetSigninConfirmationPromptBarColor(
166          ui::kSigninConfirmationPromptBarBackgroundAlpha);
167
168  // Create the prompt label.
169  size_t offset;
170  const base::string16 domain =
171      base::ASCIIToUTF16(gaia::ExtractDomainName(username_));
172  const base::string16 username = base::ASCIIToUTF16(username_);
173  const base::string16 prompt_text =
174      l10n_util::GetStringFUTF16(
175          IDS_ENTERPRISE_SIGNIN_ALERT_NEW_STYLE,
176          domain, &offset);
177  views::StyledLabel* prompt_label = new views::StyledLabel(prompt_text, this);
178  prompt_label->SetDisplayedOnBackgroundColor(kPromptBarBackgroundColor);
179
180  views::StyledLabel::RangeStyleInfo bold_style;
181  bold_style.font_style = gfx::Font::BOLD;
182  prompt_label->AddStyleRange(
183      gfx::Range(offset, offset + domain.size()), bold_style);
184
185  // Create the prompt bar.
186  views::View* prompt_bar = new views::View;
187  prompt_bar->SetBorder(views::Border::CreateSolidSidedBorder(
188      1,
189      0,
190      1,
191      0,
192      ui::GetSigninConfirmationPromptBarColor(
193          ui::kSigninConfirmationPromptBarBorderAlpha)));
194  prompt_bar->set_background(views::Background::CreateSolidBackground(
195      kPromptBarBackgroundColor));
196
197  // Create the explanation label.
198  std::vector<size_t> offsets;
199  const base::string16 learn_more_text =
200      l10n_util::GetStringUTF16(
201          IDS_ENTERPRISE_SIGNIN_PROFILE_LINK_LEARN_MORE);
202  const base::string16 signin_explanation_text =
203      l10n_util::GetStringFUTF16(prompt_for_new_profile_ ?
204          IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITH_PROFILE_CREATION_NEW_STYLE :
205          IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITHOUT_PROFILE_CREATION_NEW_STYLE,
206          username, learn_more_text, &offsets);
207  explanation_label_ = new views::StyledLabel(signin_explanation_text, this);
208  explanation_label_->AddStyleRange(
209      gfx::Range(offsets[1], offsets[1] + learn_more_text.size()),
210      views::StyledLabel::RangeStyleInfo::CreateForLink());
211
212  // Layout the components.
213  views::GridLayout* dialog_layout = new views::GridLayout(this);
214  SetLayoutManager(dialog_layout);
215
216  // Use GridLayout inside the prompt bar because StyledLabel requires it.
217  views::GridLayout* prompt_layout = views::GridLayout::CreatePanel(prompt_bar);
218  prompt_bar->SetLayoutManager(prompt_layout);
219  prompt_layout->AddColumnSet(0)->AddColumn(
220      views::GridLayout::FILL, views::GridLayout::CENTER, 100,
221      views::GridLayout::USE_PREF, 0, 0);
222  prompt_layout->StartRow(0, 0);
223  prompt_layout->AddView(prompt_label);
224  // Use a column set with no padding.
225  dialog_layout->AddColumnSet(0)->AddColumn(
226      views::GridLayout::FILL, views::GridLayout::FILL, 100,
227      views::GridLayout::USE_PREF, 0, 0);
228  dialog_layout->StartRow(0, 0);
229  dialog_layout->AddView(
230      prompt_bar, 1, 1,
231      views::GridLayout::FILL, views::GridLayout::FILL, 0, 0);
232
233  // Use a new column set for the explanation label so we can add padding.
234  dialog_layout->AddPaddingRow(0.0, views::kPanelVertMargin);
235  views::ColumnSet* explanation_columns = dialog_layout->AddColumnSet(1);
236  explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew);
237  explanation_columns->AddColumn(
238      views::GridLayout::FILL, views::GridLayout::FILL, 100,
239      views::GridLayout::USE_PREF, 0, 0);
240  explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew);
241  dialog_layout->StartRow(0, 1);
242  const int kPreferredWidth = 440;
243  dialog_layout->AddView(
244      explanation_label_, 1, 1,
245      views::GridLayout::FILL, views::GridLayout::FILL,
246      kPreferredWidth, explanation_label_->GetHeightForWidth(kPreferredWidth));
247}
248
249void ProfileSigninConfirmationDialogViews::StyledLabelLinkClicked(
250    const gfx::Range& range,
251    int event_flags) {
252  chrome::NavigateParams params(
253      browser_,
254      GURL("http://support.google.com/chromeos/bin/answer.py?answer=1331549"),
255      ui::PAGE_TRANSITION_LINK);
256  params.disposition = NEW_POPUP;
257  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
258  chrome::Navigate(&params);
259}
260
261void ProfileSigninConfirmationDialogViews::ButtonPressed(
262    views::Button* sender,
263    const ui::Event& event) {
264  DCHECK(prompt_for_new_profile_);
265  DCHECK_EQ(continue_signin_button_, sender);
266  if (delegate_) {
267    delegate_->OnContinueSignin();
268    delegate_ = NULL;
269  }
270  GetWidget()->Close();
271}
272