1 // Copyright 2014 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 "ash/system/user/accounts_detailed_view.h" 6 7 #include <vector> 8 9 #include "ash/multi_profile_uma.h" 10 #include "ash/shell.h" 11 #include "ash/system/tray/fixed_sized_scroll_view.h" 12 #include "ash/system/tray/hover_highlight_view.h" 13 #include "ash/system/tray/system_tray.h" 14 #include "ash/system/tray/system_tray_delegate.h" 15 #include "ash/system/tray/tray_constants.h" 16 #include "ash/system/tray/tray_popup_header_button.h" 17 #include "ash/system/user/config.h" 18 #include "ash/system/user/tray_user.h" 19 #include "base/strings/utf_string_conversions.h" 20 #include "components/user_manager/user_info.h" 21 #include "grit/ash_resources.h" 22 #include "grit/ash_strings.h" 23 #include "ui/base/l10n/l10n_util.h" 24 #include "ui/base/resource/resource_bundle.h" 25 #include "ui/views/border.h" 26 #include "ui/views/layout/box_layout.h" 27 #include "ui/views/layout/grid_layout.h" 28 29 namespace ash { 30 namespace tray { 31 32 namespace { 33 34 const int kAccountsViewVerticalPadding = 12; 35 const int kPrimaryAccountColumnSetID = 0; 36 const int kSecondaryAccountColumnSetID = 1; 37 const int kPaddingBetweenAccounts = 20; 38 39 } // namespace 40 41 AccountsDetailedView::AccountsDetailedView(TrayUser* owner, 42 user::LoginStatus login_status) 43 : TrayDetailsView(owner), 44 delegate_(NULL), 45 account_list_(NULL), 46 add_account_button_(NULL), 47 add_user_button_(NULL) { 48 std::string user_id = Shell::GetInstance() 49 ->session_state_delegate() 50 ->GetUserInfo(0) 51 ->GetUserID(); 52 delegate_ = 53 Shell::GetInstance()->system_tray_delegate()->GetUserAccountsDelegate( 54 user_id); 55 delegate_->AddObserver(this); 56 AddHeader(login_status); 57 CreateScrollableList(); 58 AddAccountList(); 59 AddAddAccountButton(); 60 AddFooter(); 61 } 62 63 AccountsDetailedView::~AccountsDetailedView() { 64 delegate_->RemoveObserver(this); 65 } 66 67 void AccountsDetailedView::OnViewClicked(views::View* sender) { 68 if (sender == footer()->content()) 69 TransitionToDefaultView(); 70 else if (sender == add_account_button_) 71 delegate_->LaunchAddAccountDialog(); 72 else 73 NOTREACHED(); 74 } 75 76 void AccountsDetailedView::ButtonPressed(views::Button* sender, 77 const ui::Event& event) { 78 std::map<views::View*, std::string>::iterator it = 79 delete_button_to_account_id_.find(sender); 80 if (it != delete_button_to_account_id_.end()) { 81 delegate_->DeleteAccount(it->second); 82 } else if (add_user_button_ && add_user_button_ == sender) { 83 MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY); 84 Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); 85 owner()->system_tray()->CloseSystemBubble(); 86 } else { 87 NOTREACHED(); 88 } 89 } 90 91 void AccountsDetailedView::AccountListChanged() { UpdateAccountList(); } 92 93 void AccountsDetailedView::AddHeader(user::LoginStatus login_status) { 94 views::View* user_view_container = new views::View; 95 user_view_container->SetLayoutManager( 96 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 97 user_view_container->SetBorder( 98 views::Border::CreateSolidSidedBorder(0, 0, 1, 0, kBorderLightColor)); 99 user_view_container->AddChildView( 100 new tray::UserView(owner(), login_status, 0, true)); 101 AddChildView(user_view_container); 102 } 103 104 void AccountsDetailedView::AddAccountList() { 105 scroll_content()->SetBorder( 106 views::Border::CreateEmptyBorder(kAccountsViewVerticalPadding, 107 kTrayPopupPaddingHorizontal, 108 kAccountsViewVerticalPadding, 109 kTrayPopupPaddingHorizontal)); 110 views::Label* account_list_title = new views::Label( 111 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCOUNT_LIST_TITLE)); 112 account_list_title->SetEnabledColor(SkColorSetARGB(0x7f, 0, 0, 0)); 113 account_list_title->SetHorizontalAlignment(gfx::ALIGN_LEFT); 114 scroll_content()->AddChildView(account_list_title); 115 account_list_ = new views::View(); 116 UpdateAccountList(); 117 scroll_content()->AddChildView(account_list_); 118 } 119 120 void AccountsDetailedView::AddAddAccountButton() { 121 SessionStateDelegate* session_state_delegate = 122 Shell::GetInstance()->session_state_delegate(); 123 HoverHighlightView* add_account_button = new HoverHighlightView(this); 124 const user_manager::UserInfo* user_info = 125 session_state_delegate->GetUserInfo(0); 126 base::string16 user_name = user_info->GetGivenName(); 127 if (user_name.empty()) 128 user_name = user_info->GetDisplayName(); 129 if (user_name.empty()) 130 user_name = base::ASCIIToUTF16(user_info->GetEmail()); 131 add_account_button->AddLabel( 132 l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_ADD_ACCOUNT_LABEL, 133 user_name), 134 gfx::ALIGN_CENTER, 135 gfx::Font::NORMAL); 136 AddChildView(add_account_button); 137 add_account_button_ = add_account_button; 138 } 139 140 void AccountsDetailedView::AddFooter() { 141 CreateSpecialRow(IDS_ASH_STATUS_TRAY_ACCOUNTS_TITLE, this); 142 if (!IsMultiProfileSupportedAndUserActive()) 143 return; 144 TrayPopupHeaderButton* add_user_button = 145 new TrayPopupHeaderButton(this, 146 IDR_AURA_UBER_TRAY_ADD_PROFILE, 147 IDR_AURA_UBER_TRAY_ADD_PROFILE, 148 IDR_AURA_UBER_TRAY_ADD_PROFILE_HOVER, 149 IDR_AURA_UBER_TRAY_ADD_PROFILE_HOVER, 150 IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT); 151 add_user_button->SetTooltipText( 152 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); 153 footer()->AddButton(add_user_button); 154 add_user_button_ = add_user_button; 155 } 156 157 void AccountsDetailedView::UpdateAccountList() { 158 // Clear existing view. 159 delete_button_to_account_id_.clear(); 160 account_list_->RemoveAllChildViews(true); 161 162 // Configuring layout manager. 163 views::GridLayout* layout = new views::GridLayout(account_list_); 164 account_list_->SetLayoutManager(layout); 165 views::ColumnSet* primary_account_row = 166 layout->AddColumnSet(kPrimaryAccountColumnSetID); 167 primary_account_row->AddColumn(views::GridLayout::LEADING, 168 views::GridLayout::CENTER, 169 1.0, 170 views::GridLayout::USE_PREF, 171 0, 172 0); 173 views::ColumnSet* secondary_account_row = 174 layout->AddColumnSet(kSecondaryAccountColumnSetID); 175 secondary_account_row->AddColumn(views::GridLayout::FILL, 176 views::GridLayout::CENTER, 177 1.0, 178 views::GridLayout::USE_PREF, 179 0, 180 0); 181 secondary_account_row->AddPaddingColumn(0.0, kTrayPopupPaddingBetweenItems); 182 secondary_account_row->AddColumn(views::GridLayout::FILL, 183 views::GridLayout::CENTER, 184 0.0, 185 views::GridLayout::USE_PREF, 186 0, 187 0); 188 189 // Adding primary account. 190 layout->AddPaddingRow(0.0, kPaddingBetweenAccounts); 191 layout->StartRow(0.0, kPrimaryAccountColumnSetID); 192 const std::string& primary_account = delegate_->GetPrimaryAccountId(); 193 views::Label* primary_account_label = 194 new views::Label(l10n_util::GetStringFUTF16( 195 IDS_ASH_STATUS_TRAY_PRIMARY_ACCOUNT_LABEL, 196 base::ASCIIToUTF16( 197 delegate_->GetAccountDisplayName(primary_account)))); 198 layout->AddView(primary_account_label); 199 200 // Adding secondary accounts. 201 const std::vector<std::string>& secondary_accounts = 202 delegate_->GetSecondaryAccountIds(); 203 for (size_t i = 0; i < secondary_accounts.size(); ++i) { 204 layout->AddPaddingRow(0.0, kPaddingBetweenAccounts); 205 layout->StartRow(0.0, kSecondaryAccountColumnSetID); 206 const std::string& account_id = secondary_accounts[i]; 207 views::Label* account_label = new views::Label( 208 base::ASCIIToUTF16(delegate_->GetAccountDisplayName(account_id))); 209 account_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 210 layout->AddView(account_label); 211 views::View* delete_button = CreateDeleteButton(); 212 delete_button_to_account_id_[delete_button] = account_id; 213 layout->AddView(delete_button); 214 } 215 216 scroll_content()->SizeToPreferredSize(); 217 scroller()->Layout(); 218 } 219 220 views::View* AccountsDetailedView::CreateDeleteButton() { 221 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 222 views::ImageButton* delete_button = new views::ImageButton(this); 223 delete_button->SetImage( 224 views::Button::STATE_NORMAL, 225 rb.GetImageNamed(IDR_AURA_UBER_TRAY_REMOVE_ACCOUNT).ToImageSkia()); 226 delete_button->SetImage( 227 views::Button::STATE_HOVERED, 228 rb.GetImageNamed(IDR_AURA_UBER_TRAY_REMOVE_ACCOUNT_HOVER).ToImageSkia()); 229 delete_button->SetImage( 230 views::Button::STATE_PRESSED, 231 rb.GetImageNamed(IDR_AURA_UBER_TRAY_REMOVE_ACCOUNT_HOVER).ToImageSkia()); 232 return delete_button; 233 } 234 235 } // namespace tray 236 } // namespace ash 237