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(¶ms); 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