Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/profile_chooser_view.h" | 5 #include "chrome/browser/ui/views/profile_chooser_view.h" |
| 6 | 6 |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "chrome/browser/browser_process.h" | 8 #include "chrome/browser/browser_process.h" |
| 9 #include "chrome/browser/profiles/profile_info_util.h" | 9 #include "chrome/browser/profiles/profile_info_util.h" |
| 10 #include "chrome/browser/profiles/profile_manager.h" | 10 #include "chrome/browser/profiles/profile_manager.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 #include "ui/views/widget/widget.h" | 42 #include "ui/views/widget/widget.h" |
| 43 | 43 |
| 44 #if defined(USE_AURA) | 44 #if defined(USE_AURA) |
| 45 #include "ui/native_theme/native_theme_aura.h" | 45 #include "ui/native_theme/native_theme_aura.h" |
| 46 #endif | 46 #endif |
| 47 | 47 |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 // Helpers -------------------------------------------------------------------- | 50 // Helpers -------------------------------------------------------------------- |
| 51 | 51 |
| 52 const int kMinMenuWidth = 250; | 52 const int kFixedMenuWidth = 250; |
| 53 const int kButtonHeight = 29; | 53 const int kButtonHeight = 29; |
| 54 const int kLargeImageSide = 64; | |
| 54 | 55 |
| 55 // Creates a GridLayout with a single column. This ensures that all the child | 56 // Creates a GridLayout with a single column. This ensures that all the child |
| 56 // views added get auto-expanded to fill the full width of the bubble. | 57 // views added get auto-expanded to fill the full width of the bubble. |
| 57 views::GridLayout* CreateSingleColumnLayout(views::View* view) { | 58 views::GridLayout* CreateSingleColumnLayout(views::View* view) { |
| 58 views::GridLayout* layout = new views::GridLayout(view); | 59 views::GridLayout* layout = new views::GridLayout(view); |
| 59 view->SetLayoutManager(layout); | 60 view->SetLayoutManager(layout); |
| 60 | 61 |
| 61 views::ColumnSet* columns = layout->AddColumnSet(0); | 62 views::ColumnSet* columns = layout->AddColumnSet(0); |
| 62 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, | 63 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, |
| 63 views::GridLayout::USE_PREF, 0, 0); | 64 views::GridLayout::FIXED, kFixedMenuWidth, 0); |
| 64 return layout; | 65 return layout; |
| 65 } | 66 } |
| 66 | 67 |
| 67 // Creates a GridLayout with two columns. | 68 // Creates a GridLayout with two columns. |
| 68 views::GridLayout* CreateDoubleColumnLayout(views::View* view) { | 69 views::GridLayout* CreateDoubleColumnLayout(views::View* view) { |
| 69 views::GridLayout* layout = new views::GridLayout(view); | 70 views::GridLayout* layout = new views::GridLayout(view); |
| 70 view->SetLayoutManager(layout); | 71 view->SetLayoutManager(layout); |
| 71 | 72 |
| 72 views::ColumnSet* columns = layout->AddColumnSet(0); | 73 views::ColumnSet* columns = layout->AddColumnSet(0); |
| 73 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, | 74 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, |
| 74 views::GridLayout::USE_PREF, 0, 0); | 75 views::GridLayout::USE_PREF, 0, 0); |
| 75 columns->AddPaddingColumn(0, views::kUnrelatedControlLargeHorizontalSpacing); | 76 columns->AddPaddingColumn(0, views::kUnrelatedControlLargeHorizontalSpacing); |
| 76 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, | 77 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, |
| 77 views::GridLayout::USE_PREF, 0, 0); | 78 views::GridLayout::USE_PREF, 0, 0); |
| 78 return layout; | 79 return layout; |
| 79 } | 80 } |
| 80 | 81 |
| 81 views::Link* CreateLink(const base::string16& link_text, | 82 views::Link* CreateLink(const base::string16& link_text, |
| 82 views::LinkListener* listener) { | 83 views::LinkListener* listener) { |
| 83 views::Link* link_button = new views::Link(link_text); | 84 views::Link* link_button = new views::Link(link_text); |
| 84 link_button->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 85 link_button->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 85 link_button->SetUnderline(false); | 86 link_button->SetUnderline(false); |
| 86 link_button->set_listener(listener); | 87 link_button->set_listener(listener); |
| 87 return link_button; | 88 return link_button; |
| 88 } | 89 } |
| 89 | 90 |
| 91 base::string16 ElideText(const base::string16& text, | |
| 92 float width, | |
| 93 ui::ResourceBundle::FontStyle font_style) { | |
| 94 return gfx::ElideText( | |
| 95 text, | |
| 96 ui::ResourceBundle::GetSharedInstance().GetFontList(font_style), | |
| 97 width, | |
| 98 gfx::ELIDE_AT_END); | |
| 99 } | |
| 100 | |
| 90 | 101 |
| 91 // BackgroundColorHoverButton ------------------------------------------------- | 102 // BackgroundColorHoverButton ------------------------------------------------- |
| 92 | 103 |
| 93 // A custom button that allows for setting a background color when hovered over. | 104 // A custom button that allows for setting a background color when hovered over. |
| 94 class BackgroundColorHoverButton : public views::TextButton { | 105 class BackgroundColorHoverButton : public views::TextButton { |
| 95 public: | 106 public: |
| 96 BackgroundColorHoverButton(views::ButtonListener* listener, | 107 BackgroundColorHoverButton(views::ButtonListener* listener, |
| 97 const base::string16& text, | 108 const base::string16& text, |
| 98 const gfx::ImageSkia& normal_icon, | 109 const gfx::ImageSkia& normal_icon, |
| 99 const gfx::ImageSkia& hover_icon); | 110 const gfx::ImageSkia& hover_icon); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 // EditableProfilePhoto ------------------------------------------------- | 170 // EditableProfilePhoto ------------------------------------------------- |
| 160 | 171 |
| 161 // A custom Image control that shows a "change" button when moused over. | 172 // A custom Image control that shows a "change" button when moused over. |
| 162 class EditableProfilePhoto : public views::ImageView { | 173 class EditableProfilePhoto : public views::ImageView { |
| 163 public: | 174 public: |
| 164 EditableProfilePhoto(views::ButtonListener* listener, | 175 EditableProfilePhoto(views::ButtonListener* listener, |
| 165 const gfx::Image& icon, | 176 const gfx::Image& icon, |
| 166 bool is_editing_allowed) | 177 bool is_editing_allowed) |
| 167 : views::ImageView(), | 178 : views::ImageView(), |
| 168 change_photo_button_(NULL) { | 179 change_photo_button_(NULL) { |
| 169 const int kLargeImageSide = 64; | |
| 170 const SkColor kBackgroundColor = SkColorSetARGB(125, 0, 0, 0); | 180 const SkColor kBackgroundColor = SkColorSetARGB(125, 0, 0, 0); |
| 171 const int kOverlayHeight = 20; | 181 const int kOverlayHeight = 20; |
| 172 | 182 |
| 173 gfx::Image image = profiles::GetSizedAvatarIconWithBorder( | 183 gfx::Image image = profiles::GetSizedAvatarIconWithBorder( |
| 174 icon, true, | 184 icon, true, |
| 175 kLargeImageSide + profiles::kAvatarIconPadding, | 185 kLargeImageSide + profiles::kAvatarIconPadding, |
| 176 kLargeImageSide + profiles::kAvatarIconPadding); | 186 kLargeImageSide + profiles::kAvatarIconPadding); |
| 177 SetImage(image.ToImageSkia()); | 187 SetImage(image.ToImageSkia()); |
| 178 | 188 |
| 179 if (!is_editing_allowed) | 189 if (!is_editing_allowed) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 | 237 |
| 228 // EditableProfileName ------------------------------------------------- | 238 // EditableProfileName ------------------------------------------------- |
| 229 | 239 |
| 230 // A custom text control that turns into a textfield for editing when clicked. | 240 // A custom text control that turns into a textfield for editing when clicked. |
| 231 class EditableProfileName : public views::TextButton, | 241 class EditableProfileName : public views::TextButton, |
| 232 public views::ButtonListener { | 242 public views::ButtonListener { |
| 233 public: | 243 public: |
| 234 EditableProfileName(views::TextfieldController* controller, | 244 EditableProfileName(views::TextfieldController* controller, |
| 235 const base::string16& text, | 245 const base::string16& text, |
| 236 bool is_editing_allowed) | 246 bool is_editing_allowed) |
| 237 : views::TextButton(this, text), | 247 : views::TextButton(this, base::string16()), |
| 248 full_profile_name_(text), | |
| 238 profile_name_textfield_(NULL) { | 249 profile_name_textfield_(NULL) { |
| 250 | |
| 251 // The button has a fixed width, so we need to calculate the exact width | |
| 252 // available for the profile name column, so that the text can be | |
| 253 // elided correctly if needed. | |
| 254 float available_button_width = | |
| 255 kFixedMenuWidth - // Entire width of the bubble. | |
| 256 2 * views::kButtonHEdgeMarginNew - // Bubble insets. | |
| 257 kLargeImageSide - // Width of the profile photo. | |
| 258 views::kUnrelatedControlLargeHorizontalSpacing; | |
| 259 | |
| 239 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | 260 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
| 261 const gfx::ImageSkia& icon = *rb->GetImageSkiaNamed(IDR_INFOBAR_AUTOFILL); | |
| 262 float icon_width = is_editing_allowed? icon.width() : 0; | |
| 263 base::string16 elided_name = ElideText(text, | |
|
sky
2014/01/23 01:00:52
You shouldn't need to elide the text yourself. You
| |
| 264 available_button_width - icon_width, | |
| 265 ui::ResourceBundle::MediumFont); | |
| 240 const gfx::FontList& medium_font_list = | 266 const gfx::FontList& medium_font_list = |
| 241 rb->GetFontList(ui::ResourceBundle::MediumFont); | 267 rb->GetFontList(ui::ResourceBundle::MediumFont); |
| 242 SetFontList(medium_font_list); | 268 SetFontList(medium_font_list); |
| 269 SetText(elided_name); | |
| 243 set_border(NULL); | 270 set_border(NULL); |
| 244 | 271 |
| 245 if (!is_editing_allowed) | 272 if (!is_editing_allowed) |
| 246 return; | 273 return; |
| 247 | 274 |
| 248 SetIcon(*rb->GetImageSkiaNamed(IDR_INFOBAR_AUTOFILL)); | 275 SetIcon(*rb->GetImageSkiaNamed(IDR_INFOBAR_AUTOFILL)); |
| 249 set_icon_placement(views::TextButton::ICON_ON_RIGHT); | 276 set_icon_placement(views::TextButton::ICON_ON_RIGHT); |
| 250 | 277 |
| 251 // Textfield that overlaps the button. | 278 // Textfield that overlaps the button. |
| 252 profile_name_textfield_ = new views::Textfield(); | 279 profile_name_textfield_ = new views::Textfield(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 266 if (profile_name_textfield_) | 293 if (profile_name_textfield_) |
| 267 profile_name_textfield_->SetVisible(false); | 294 profile_name_textfield_->SetVisible(false); |
| 268 } | 295 } |
| 269 | 296 |
| 270 private: | 297 private: |
| 271 // views::ButtonListener: | 298 // views::ButtonListener: |
| 272 virtual void ButtonPressed(views::Button* sender, | 299 virtual void ButtonPressed(views::Button* sender, |
| 273 const ui::Event& event) OVERRIDE { | 300 const ui::Event& event) OVERRIDE { |
| 274 if (profile_name_textfield_) { | 301 if (profile_name_textfield_) { |
| 275 profile_name_textfield_->SetVisible(true); | 302 profile_name_textfield_->SetVisible(true); |
| 276 profile_name_textfield_->SetText(text()); | 303 profile_name_textfield_->SetText(full_profile_name_); |
| 277 profile_name_textfield_->SelectAll(false); | 304 profile_name_textfield_->SelectAll(false); |
| 278 profile_name_textfield_->RequestFocus(); | 305 profile_name_textfield_->RequestFocus(); |
| 279 } | 306 } |
| 280 } | 307 } |
| 281 | 308 |
| 282 // views::CustomButton: | 309 // views::CustomButton: |
| 283 virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE { | 310 virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE { |
| 284 // Override CustomButton's implementation, which presses the button when | 311 // Override CustomButton's implementation, which presses the button when |
| 285 // you press space and clicks it when you release space, as the space can be | 312 // you press space and clicks it when you release space, as the space can be |
| 286 // part of the new profile name typed in the textfield. | 313 // part of the new profile name typed in the textfield. |
| 287 return false; | 314 return false; |
| 288 } | 315 } |
| 289 | 316 |
| 290 // views::View: | 317 // views::View: |
| 291 virtual void Layout() OVERRIDE { | 318 virtual void Layout() OVERRIDE { |
| 292 if (profile_name_textfield_) | 319 if (profile_name_textfield_) |
| 293 profile_name_textfield_->SetBounds(0, 0, width(), height()); | 320 profile_name_textfield_->SetBounds(0, 0, width(), height()); |
| 294 views::View::Layout(); | 321 views::View::Layout(); |
| 295 } | 322 } |
| 296 | 323 |
| 324 // The complete profile name. Because the control has a fixed width, we will | |
| 325 // have to elide the profile name when displaying it. However, in edit mode, | |
| 326 // we should show the entire name. | |
| 327 base::string16 full_profile_name_; | |
| 328 | |
| 297 // Button that is shown when hovering over the image view. Can be NULL if | 329 // Button that is shown when hovering over the image view. Can be NULL if |
| 298 // the profile name isn't allowed to be edited (e.g. for guest profiles). | 330 // the profile name isn't allowed to be edited (e.g. for guest profiles). |
| 299 views::Textfield* profile_name_textfield_; | 331 views::Textfield* profile_name_textfield_; |
| 300 | 332 |
| 301 DISALLOW_COPY_AND_ASSIGN(EditableProfileName); | 333 DISALLOW_COPY_AND_ASSIGN(EditableProfileName); |
| 302 }; | 334 }; |
| 303 | 335 |
| 304 | 336 |
| 305 // ProfileChooserView --------------------------------------------------------- | 337 // ProfileChooserView --------------------------------------------------------- |
| 306 | 338 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 const AvatarMenu::Item& active_item = avatar_menu->GetItemAt( | 455 const AvatarMenu::Item& active_item = avatar_menu->GetItemAt( |
| 424 avatar_menu->GetActiveProfileIndex()); | 456 avatar_menu->GetActiveProfileIndex()); |
| 425 DCHECK(active_item.signed_in); | 457 DCHECK(active_item.signed_in); |
| 426 } | 458 } |
| 427 | 459 |
| 428 ResetView(); | 460 ResetView(); |
| 429 RemoveAllChildViews(true); | 461 RemoveAllChildViews(true); |
| 430 view_mode_ = view_to_display; | 462 view_mode_ = view_to_display; |
| 431 | 463 |
| 432 views::GridLayout* layout = CreateSingleColumnLayout(this); | 464 views::GridLayout* layout = CreateSingleColumnLayout(this); |
| 433 layout->set_minimum_size(gfx::Size(kMinMenuWidth, 0)); | 465 layout->set_minimum_size(gfx::Size(kFixedMenuWidth, 0)); |
| 434 | 466 |
| 435 if (view_to_display == GAIA_SIGNIN_VIEW || | 467 if (view_to_display == GAIA_SIGNIN_VIEW || |
| 436 view_to_display == GAIA_ADD_ACCOUNT_VIEW) { | 468 view_to_display == GAIA_ADD_ACCOUNT_VIEW) { |
| 437 // Minimum size for embedded sign in pages as defined in Gaia. | 469 // Minimum size for embedded sign in pages as defined in Gaia. |
| 438 const int kMinGaiaViewWidth = 320; | 470 const int kMinGaiaViewWidth = 320; |
| 439 const int kMinGaiaViewHeight = 440; | 471 const int kMinGaiaViewHeight = 440; |
| 440 Profile* profile = browser_->profile(); | 472 Profile* profile = browser_->profile(); |
| 441 views::WebView* web_view = new views::WebView(profile); | 473 views::WebView* web_view = new views::WebView(profile); |
| 442 signin::Source source = (view_to_display == GAIA_SIGNIN_VIEW) ? | 474 signin::Source source = (view_to_display == GAIA_SIGNIN_VIEW) ? |
| 443 signin::SOURCE_AVATAR_BUBBLE_SIGN_IN : | 475 signin::SOURCE_AVATAR_BUBBLE_SIGN_IN : |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 707 for (int i = 0; i < num_avatars_to_show; ++i) { | 739 for (int i = 0; i < num_avatars_to_show; ++i) { |
| 708 const size_t index = avatars_to_show[i]; | 740 const size_t index = avatars_to_show[i]; |
| 709 const AvatarMenu::Item& item = avatar_menu_->GetItemAt(index); | 741 const AvatarMenu::Item& item = avatar_menu_->GetItemAt(index); |
| 710 const int kSmallImageSide = 32; | 742 const int kSmallImageSide = 32; |
| 711 | 743 |
| 712 gfx::Image image = profiles::GetSizedAvatarIconWithBorder( | 744 gfx::Image image = profiles::GetSizedAvatarIconWithBorder( |
| 713 item.icon, true, | 745 item.icon, true, |
| 714 kSmallImageSide + profiles::kAvatarIconPadding, | 746 kSmallImageSide + profiles::kAvatarIconPadding, |
| 715 kSmallImageSide + profiles::kAvatarIconPadding); | 747 kSmallImageSide + profiles::kAvatarIconPadding); |
| 716 | 748 |
| 717 views::TextButton* button = new views::TextButton(this, item.name); | 749 // Since the bubble has a fixed width, we need to calculate the exact |
| 750 // width available for the profile name, and elide it if needed. | |
| 751 float available_text_width = | |
| 752 kFixedMenuWidth - // Entire width of the bubble. | |
| 753 2 * views::kButtonHEdgeMarginNew - // Insets. | |
| 754 kSmallImageSide - // Width of the button icon. | |
| 755 views::kItemLabelSpacing; // Space between text and icon. | |
| 756 views::TextButton* button = new views::TextButton( | |
| 757 this, | |
| 758 ElideText(item.name, | |
| 759 available_text_width, | |
| 760 ui::ResourceBundle::MediumFont)); | |
| 718 open_other_profile_indexes_map_[button] = index; | 761 open_other_profile_indexes_map_[button] = index; |
| 719 button->SetIcon(*image.ToImageSkia()); | 762 button->SetIcon(*image.ToImageSkia()); |
| 720 button->set_icon_text_spacing(views::kItemLabelSpacing); | 763 button->set_icon_text_spacing(views::kItemLabelSpacing); |
| 721 button->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( | 764 button->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( |
| 722 ui::ResourceBundle::MediumFont)); | 765 ui::ResourceBundle::MediumFont)); |
| 723 button->set_border(NULL); | 766 button->set_border(NULL); |
| 724 | 767 |
| 725 layout->StartRow(1, 0); | 768 layout->StartRow(1, 0); |
| 726 layout->AddView(button); | 769 layout->AddView(button); |
| 727 | 770 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 799 // The primary account should always be listed first. | 842 // The primary account should always be listed first. |
| 800 // TODO(rogerta): we still need to further differentiate the primary account | 843 // TODO(rogerta): we still need to further differentiate the primary account |
| 801 // from the others in the UI, so more work is likely required here: | 844 // from the others in the UI, so more work is likely required here: |
| 802 // crbug.com/311124. | 845 // crbug.com/311124. |
| 803 CreateAccountButton(layout, primary_account, true); | 846 CreateAccountButton(layout, primary_account, true); |
| 804 for (size_t i = 0; i < accounts.size(); ++i) | 847 for (size_t i = 0; i < accounts.size(); ++i) |
| 805 CreateAccountButton(layout, accounts[i], false); | 848 CreateAccountButton(layout, accounts[i], false); |
| 806 | 849 |
| 807 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 850 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 808 | 851 |
| 809 add_account_button_ = new views::BlueButton( | 852 // Elide the button text so that the contents fit inside the bubble. |
| 810 this, | 853 base::string16 elided_button_text = |
| 811 l10n_util::GetStringFUTF16(IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, | 854 ElideText(l10n_util::GetStringFUTF16( |
| 812 avatar_item.name)); | 855 IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, avatar_item.name), |
| 856 kFixedMenuWidth - 2 * views::kButtonHEdgeMarginNew, // Width - insets. | |
| 857 ui::ResourceBundle::MediumFont); | |
| 858 | |
| 859 add_account_button_ = new views::BlueButton(this, elided_button_text); | |
| 813 layout->StartRow(1, 0); | 860 layout->StartRow(1, 0); |
| 814 layout->AddView(add_account_button_); | 861 layout->AddView(add_account_button_); |
| 815 return view; | 862 return view; |
| 816 } | 863 } |
| 817 | 864 |
| 818 void ProfileChooserView::CreateAccountButton(views::GridLayout* layout, | 865 void ProfileChooserView::CreateAccountButton(views::GridLayout* layout, |
| 819 const std::string& account, | 866 const std::string& account, |
| 820 bool is_primary_account) { | 867 bool is_primary_account) { |
| 821 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | 868 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
| 822 // Use a MenuButtonListener and not a regular ButtonListener to be | 869 // Use a MenuButtonListener and not a regular ButtonListener to be |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 834 email_button->set_menu_marker( | 881 email_button->set_menu_marker( |
| 835 rb->GetImageNamed(IDR_CLOSE_1).ToImageSkia()); | 882 rb->GetImageNamed(IDR_CLOSE_1).ToImageSkia()); |
| 836 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 883 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 837 } | 884 } |
| 838 layout->StartRow(1, 0); | 885 layout->StartRow(1, 0); |
| 839 layout->AddView(email_button); | 886 layout->AddView(email_button); |
| 840 | 887 |
| 841 // Save the original email address, as the button text could be elided. | 888 // Save the original email address, as the button text could be elided. |
| 842 current_profile_accounts_map_[email_button] = account; | 889 current_profile_accounts_map_[email_button] = account; |
| 843 } | 890 } |
| OLD | NEW |