Home | History | Annotate | Download | only in sync
      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 
     37 namespace chrome {
     38 // Declared in browser_dialogs.h
     39 void 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 
     52 ProfileSigninConfirmationDialogViews::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 
     63 ProfileSigninConfirmationDialogViews::~ProfileSigninConfirmationDialogViews() {}
     64 
     65 // static
     66 void 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 
     92 void 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 
     98 base::string16 ProfileSigninConfirmationDialogViews::GetWindowTitle() const {
     99   return l10n_util::GetStringUTF16(
    100       IDS_ENTERPRISE_SIGNIN_TITLE_NEW_STYLE);
    101 }
    102 
    103 base::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 
    116 int ProfileSigninConfirmationDialogViews::GetDefaultDialogButton() const {
    117   return ui::DIALOG_BUTTON_NONE;
    118 }
    119 
    120 views::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 
    132 bool 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 
    143 bool ProfileSigninConfirmationDialogViews::Cancel() {
    144   if (delegate_) {
    145     delegate_->OnCancelSignin();
    146     delegate_ = NULL;
    147   }
    148   return true;
    149 }
    150 
    151 void ProfileSigninConfirmationDialogViews::OnClosed() {
    152   Cancel();
    153 }
    154 
    155 ui::ModalType ProfileSigninConfirmationDialogViews::GetModalType() const {
    156   return ui::MODAL_TYPE_CHILD;
    157 }
    158 
    159 void 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 
    249 void 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 
    261 void 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