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 "components/web_modal/web_contents_modal_dialog_manager.h" 17 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" 18 #include "content/public/browser/web_contents.h" 19 #include "content/public/browser/web_contents_view.h" 20 #include "google_apis/gaia/gaia_auth_util.h" 21 #include "grit/chromium_strings.h" 22 #include "grit/generated_resources.h" 23 #include "third_party/skia/include/core/SkColor.h" 24 #include "ui/base/l10n/l10n_util.h" 25 #include "ui/base/range/range.h" 26 #include "ui/gfx/font.h" 27 #include "ui/gfx/native_widget_types.h" 28 #include "ui/views/background.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 Profile* profile, 55 const std::string& username, 56 ui::ProfileSigninConfirmationDelegate* delegate) 57 : browser_(browser), 58 profile_(profile), 59 username_(username), 60 delegate_(delegate), 61 prompt_for_new_profile_(true), 62 continue_signin_button_(NULL) { 63 } 64 65 ProfileSigninConfirmationDialogViews::~ProfileSigninConfirmationDialogViews() {} 66 67 // static 68 void ProfileSigninConfirmationDialogViews::ShowDialog( 69 Browser* browser, 70 Profile* profile, 71 const std::string& username, 72 ui::ProfileSigninConfirmationDelegate* delegate) { 73 ProfileSigninConfirmationDialogViews* dialog = 74 new ProfileSigninConfirmationDialogViews( 75 browser, profile, username, delegate); 76 ui::CheckShouldPromptForNewProfile( 77 profile, 78 // This callback is guaranteed to be invoked, and once it is, the dialog 79 // owns itself. 80 base::Bind(&ProfileSigninConfirmationDialogViews::Show, 81 base::Unretained(dialog))); 82 } 83 84 void ProfileSigninConfirmationDialogViews::Show(bool prompt_for_new_profile) { 85 prompt_for_new_profile_ = prompt_for_new_profile; 86 CreateBrowserModalDialogViews( 87 this, browser_->window()->GetNativeWindow())->Show(); 88 } 89 90 string16 ProfileSigninConfirmationDialogViews::GetWindowTitle() const { 91 return l10n_util::GetStringUTF16( 92 IDS_ENTERPRISE_SIGNIN_TITLE_NEW_STYLE); 93 } 94 95 string16 ProfileSigninConfirmationDialogViews::GetDialogButtonLabel( 96 ui::DialogButton button) const { 97 if (button == ui::DIALOG_BUTTON_OK) { 98 // If we're giving the option to create a new profile, then OK is 99 // "Create new profile". Otherwise it is "Continue signin". 100 return l10n_util::GetStringUTF16( 101 prompt_for_new_profile_ ? 102 IDS_ENTERPRISE_SIGNIN_CREATE_NEW_PROFILE_NEW_STYLE : 103 IDS_ENTERPRISE_SIGNIN_CONTINUE_NEW_STYLE); 104 } 105 return l10n_util::GetStringUTF16(IDS_ENTERPRISE_SIGNIN_CANCEL); 106 } 107 108 int ProfileSigninConfirmationDialogViews::GetDefaultDialogButton() const { 109 return ui::DIALOG_BUTTON_NONE; 110 } 111 112 views::View* ProfileSigninConfirmationDialogViews::CreateExtraView() { 113 if (prompt_for_new_profile_) { 114 const string16 continue_signin_text = 115 l10n_util::GetStringUTF16(IDS_ENTERPRISE_SIGNIN_CONTINUE_NEW_STYLE); 116 continue_signin_button_ = 117 new views::LabelButton(this, continue_signin_text); 118 continue_signin_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); 119 continue_signin_button_->set_focusable(true); 120 } 121 return continue_signin_button_; 122 } 123 124 bool ProfileSigninConfirmationDialogViews::Accept() { 125 if (delegate_) { 126 if (prompt_for_new_profile_) 127 delegate_->OnSigninWithNewProfile(); 128 else 129 delegate_->OnContinueSignin(); 130 delegate_ = NULL; 131 } 132 return true; 133 } 134 135 bool ProfileSigninConfirmationDialogViews::Cancel() { 136 if (delegate_) { 137 delegate_->OnCancelSignin(); 138 delegate_ = NULL; 139 } 140 return true; 141 } 142 143 void ProfileSigninConfirmationDialogViews::OnClosed() { 144 Cancel(); 145 } 146 147 ui::ModalType ProfileSigninConfirmationDialogViews::GetModalType() const { 148 return ui::MODAL_TYPE_WINDOW; 149 } 150 151 void ProfileSigninConfirmationDialogViews::ViewHierarchyChanged( 152 const ViewHierarchyChangedDetails& details) { 153 if (!details.is_add || details.child != this) 154 return; 155 156 const SkColor kPromptBarBackgroundColor = 157 ui::GetSigninConfirmationPromptBarColor( 158 ui::kSigninConfirmationPromptBarBackgroundAlpha); 159 160 // Create the prompt label. 161 size_t offset; 162 const string16 domain = ASCIIToUTF16(gaia::ExtractDomainName(username_)); 163 const string16 username = ASCIIToUTF16(username_); 164 const string16 prompt_text = 165 l10n_util::GetStringFUTF16( 166 IDS_ENTERPRISE_SIGNIN_ALERT_NEW_STYLE, 167 domain, &offset); 168 views::StyledLabel* prompt_label = new views::StyledLabel(prompt_text, this); 169 prompt_label->SetDisplayedOnBackgroundColor(kPromptBarBackgroundColor); 170 171 views::StyledLabel::RangeStyleInfo bold_style; 172 bold_style.font_style = gfx::Font::BOLD; 173 prompt_label->AddStyleRange( 174 ui::Range(offset, offset + domain.size()), bold_style); 175 176 // Create the prompt bar. 177 views::View* prompt_bar = new views::View; 178 prompt_bar->set_border( 179 views::Border::CreateSolidSidedBorder( 180 1, 0, 1, 0, 181 ui::GetSigninConfirmationPromptBarColor( 182 ui::kSigninConfirmationPromptBarBorderAlpha))); 183 prompt_bar->set_background(views::Background::CreateSolidBackground( 184 kPromptBarBackgroundColor)); 185 186 // Create the explanation label. 187 std::vector<size_t> offsets; 188 const string16 learn_more_text = 189 l10n_util::GetStringUTF16( 190 IDS_ENTERPRISE_SIGNIN_PROFILE_LINK_LEARN_MORE); 191 const string16 signin_explanation_text = 192 l10n_util::GetStringFUTF16(prompt_for_new_profile_ ? 193 IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITH_PROFILE_CREATION_NEW_STYLE : 194 IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITHOUT_PROFILE_CREATION_NEW_STYLE, 195 username, learn_more_text, &offsets); 196 explanation_label_ = new views::StyledLabel(signin_explanation_text, this); 197 explanation_label_->AddStyleRange( 198 ui::Range(offsets[1], offsets[1] + learn_more_text.size()), 199 views::StyledLabel::RangeStyleInfo::CreateForLink()); 200 201 // Layout the components. 202 views::GridLayout* dialog_layout = new views::GridLayout(this); 203 SetLayoutManager(dialog_layout); 204 205 // Use GridLayout inside the prompt bar because StyledLabel requires it. 206 views::GridLayout* prompt_layout = views::GridLayout::CreatePanel(prompt_bar); 207 prompt_bar->SetLayoutManager(prompt_layout); 208 prompt_layout->AddColumnSet(0)->AddColumn( 209 views::GridLayout::FILL, views::GridLayout::CENTER, 100, 210 views::GridLayout::USE_PREF, 0, 0); 211 prompt_layout->StartRow(0, 0); 212 prompt_layout->AddView(prompt_label); 213 // Use a column set with no padding. 214 dialog_layout->AddColumnSet(0)->AddColumn( 215 views::GridLayout::FILL, views::GridLayout::FILL, 100, 216 views::GridLayout::USE_PREF, 0, 0); 217 dialog_layout->StartRow(0, 0); 218 dialog_layout->AddView( 219 prompt_bar, 1, 1, 220 views::GridLayout::FILL, views::GridLayout::FILL, 0, 0); 221 222 // Use a new column set for the explanation label so we can add padding. 223 dialog_layout->AddPaddingRow(0.0, views::kPanelVertMargin); 224 views::ColumnSet* explanation_columns = dialog_layout->AddColumnSet(1); 225 explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew); 226 explanation_columns->AddColumn( 227 views::GridLayout::FILL, views::GridLayout::FILL, 100, 228 views::GridLayout::USE_PREF, 0, 0); 229 explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew); 230 dialog_layout->StartRow(0, 1); 231 const int kPreferredWidth = 440; 232 dialog_layout->AddView( 233 explanation_label_, 1, 1, 234 views::GridLayout::FILL, views::GridLayout::FILL, 235 kPreferredWidth, explanation_label_->GetHeightForWidth(kPreferredWidth)); 236 } 237 238 void ProfileSigninConfirmationDialogViews::StyledLabelLinkClicked( 239 const ui::Range& range, 240 int event_flags) { 241 chrome::NavigateParams params( 242 browser_, 243 GURL("http://support.google.com/chromeos/bin/answer.py?answer=1331549"), 244 content::PAGE_TRANSITION_LINK); 245 params.disposition = NEW_POPUP; 246 params.window_action = chrome::NavigateParams::SHOW_WINDOW; 247 chrome::Navigate(¶ms); 248 } 249 250 void ProfileSigninConfirmationDialogViews::ButtonPressed( 251 views::Button* sender, 252 const ui::Event& event) { 253 DCHECK(prompt_for_new_profile_); 254 DCHECK_EQ(continue_signin_button_, sender); 255 if (delegate_) { 256 delegate_->OnContinueSignin(); 257 delegate_ = NULL; 258 } 259 GetWidget()->Close(); 260 } 261