Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm

Issue 303463010: [Mac] Show a warning in the new avatar button/menu if there's an auth error (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 #import <Cocoa/Cocoa.h> 5 #import <Cocoa/Cocoa.h>
6 6
7 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h" 7 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h"
8 8
9 #include "base/mac/bundle_locations.h" 9 #include "base/mac/bundle_locations.h"
10 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 223
224 [container addSubview:button]; 224 [container addSubview:button];
225 [container addSubview:title_label]; 225 [container addSubview:title_label];
226 CGFloat height = std::max(NSMaxY([title_label frame]), 226 CGFloat height = std::max(NSMaxY([title_label frame]),
227 NSMaxY([button frame])) + kSmallVerticalSpacing; 227 NSMaxY([button frame])) + kSmallVerticalSpacing;
228 [container setFrameSize:NSMakeSize(NSWidth([container frame]), height)]; 228 [container setFrameSize:NSMakeSize(NSWidth([container frame]), height)];
229 229
230 return container.autorelease(); 230 return container.autorelease();
231 } 231 }
232 232
233 bool HasAuthError(Profile* profile) {
msw 2014/06/03 04:15:31 nit: this is used twice, is a helper necessary?
noms (inactive) 2014/06/06 20:33:44 I thought it looked a little nicer, because the th
234 const SigninErrorController* error =
235 profiles::GetSigninErrorController(profile);
236 return error && error->HasError();
237 }
238
239 std::string GetAuthErrorAccountId(Profile* profile) {
msw 2014/06/03 04:15:31 nit: this is used once, please inline it.
noms (inactive) 2014/06/06 20:33:44 Done.
240 SigninErrorController* error =
241 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
242 signin_error_controller();
243 if (!error)
msw 2014/06/03 04:15:31 nit: return error ? error->error_account_id() : st
noms (inactive) 2014/06/06 20:33:44 Done.
244 return std::string();
245
246 return error->error_account_id();
247 }
248
249 std::string GetAuthErrorUsername(Profile* profile) {
msw 2014/06/03 04:15:31 nit: this is used once, please inline it.
noms (inactive) 2014/06/06 20:33:43 Done.
250 const SigninErrorController* error =
251 profiles::GetSigninErrorController(profile);
252 if (!error)
msw 2014/06/03 04:15:31 nit: return error ? error->error_username() : std:
noms (inactive) 2014/06/06 20:33:44 Done.
253 return std::string();
254
255 return error->error_username();
256 }
257
233 } // namespace 258 } // namespace
234 259
235 // Class that listens to changes to the OAuth2Tokens for the active profile, 260 // Class that listens to changes to the OAuth2Tokens for the active profile,
236 // changes to the avatar menu model or browser close notifications. 261 // changes to the avatar menu model or browser close notifications.
237 class ActiveProfileObserverBridge : public AvatarMenuObserver, 262 class ActiveProfileObserverBridge : public AvatarMenuObserver,
238 public content::NotificationObserver, 263 public content::NotificationObserver,
239 public OAuth2TokenService::Observer { 264 public OAuth2TokenService::Observer {
240 public: 265 public:
241 ActiveProfileObserverBridge(ProfileChooserController* controller, 266 ActiveProfileObserverBridge(ProfileChooserController* controller,
242 Browser* browser) 267 Browser* browser)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 299 }
275 300
276 // OAuth2TokenService::Observer: 301 // OAuth2TokenService::Observer:
277 virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE { 302 virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE {
278 // Tokens can only be added by adding an account through the inline flow, 303 // Tokens can only be added by adding an account through the inline flow,
279 // which is started from the account management view. Refresh it to show the 304 // which is started from the account management view. Refresh it to show the
280 // update. 305 // update.
281 profiles::BubbleViewMode viewMode = [controller_ viewMode]; 306 profiles::BubbleViewMode viewMode = [controller_ viewMode];
282 if (viewMode == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT || 307 if (viewMode == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT ||
283 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN || 308 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN ||
284 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT) { 309 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT ||
310 viewMode == profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH) {
285 [controller_ initMenuContentsWithView: 311 [controller_ initMenuContentsWithView:
286 profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; 312 profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
287 } 313 }
288 } 314 }
289 315
290 virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE { 316 virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE {
291 // Tokens can only be removed from the account management view. Refresh it 317 // Tokens can only be removed from the account management view. Refresh it
292 // to show the update. 318 // to show the update.
293 if ([controller_ viewMode] == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) 319 if ([controller_ viewMode] == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT)
294 [controller_ initMenuContentsWithView: 320 [controller_ initMenuContentsWithView:
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 imageResourceId:(int)imageResourceId 755 imageResourceId:(int)imageResourceId
730 alternateImageResourceId:(int)alternateImageResourceId 756 alternateImageResourceId:(int)alternateImageResourceId
731 action:(SEL)action; 757 action:(SEL)action;
732 758
733 // Creates a generic link button with |title| and an |action| positioned at 759 // Creates a generic link button with |title| and an |action| positioned at
734 // |frameOrigin|. 760 // |frameOrigin|.
735 - (NSButton*)linkButtonWithTitle:(NSString*)title 761 - (NSButton*)linkButtonWithTitle:(NSString*)title
736 frameOrigin:(NSPoint)frameOrigin 762 frameOrigin:(NSPoint)frameOrigin
737 action:(SEL)action; 763 action:(SEL)action;
738 764
739 // Creates an email account button with |title| and a remove icon. |tag| 765 // Creates an email account button with |title| and a remove icon. If
766 // |reauthRequired| is true, the button also displays a warning icon. |tag|
740 // indicates which account the button refers to. 767 // indicates which account the button refers to.
741 - (NSButton*)accountButtonWithRect:(NSRect)rect 768 - (NSButton*)accountButtonWithRect:(NSRect)rect
742 title:(const std::string&)title 769 title:(const std::string&)title
743 tag:(int)tag; 770 tag:(int)tag
771 reauthRequired:(BOOL)reauthRequired;
744 772
745 @end 773 @end
746 774
747 @implementation ProfileChooserController 775 @implementation ProfileChooserController
748 - (profiles::BubbleViewMode) viewMode { 776 - (profiles::BubbleViewMode) viewMode {
749 return viewMode_; 777 return viewMode_;
750 } 778 }
751 779
752 - (IBAction)switchToProfile:(id)sender { 780 - (IBAction)switchToProfile:(id)sender {
753 // Check the event flags to see if a new window should be created. 781 // Check the event flags to see if a new window should be created.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 accountIdToRemove_ = SigninManagerFactory::GetForProfile( 837 accountIdToRemove_ = SigninManagerFactory::GetForProfile(
810 browser_->profile())->GetAuthenticatedUsername(); 838 browser_->profile())->GetAuthenticatedUsername();
811 } else { 839 } else {
812 DCHECK(ContainsKey(currentProfileAccounts_, tag)); 840 DCHECK(ContainsKey(currentProfileAccounts_, tag));
813 accountIdToRemove_ = currentProfileAccounts_[tag]; 841 accountIdToRemove_ = currentProfileAccounts_[tag];
814 } 842 }
815 843
816 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL]; 844 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL];
817 } 845 }
818 846
847 - (IBAction)showAccountReauthView:(id)sender {
848 DCHECK(!isGuestSession_);
849 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH];
850 }
851
819 - (IBAction)removeAccount:(id)sender { 852 - (IBAction)removeAccount:(id)sender {
820 DCHECK(!accountIdToRemove_.empty()); 853 DCHECK(!accountIdToRemove_.empty());
821 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile( 854 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(
822 browser_->profile())->RevokeCredentials(accountIdToRemove_); 855 browser_->profile())->RevokeCredentials(accountIdToRemove_);
823 accountIdToRemove_.clear(); 856 accountIdToRemove_.clear();
824 857
825 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT]; 858 [self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
826 } 859 }
827 860
828 - (IBAction)openTutorialLearnMoreURL:(id)sender { 861 - (IBAction)openTutorialLearnMoreURL:(id)sender {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 929
897 avatarMenu_.reset(new AvatarMenu( 930 avatarMenu_.reset(new AvatarMenu(
898 &g_browser_process->profile_manager()->GetProfileInfoCache(), 931 &g_browser_process->profile_manager()->GetProfileInfoCache(),
899 observer_.get(), 932 observer_.get(),
900 browser_)); 933 browser_));
901 avatarMenu_->RebuildMenu(); 934 avatarMenu_->RebuildMenu();
902 935
903 // Guest profiles do not have a token service. 936 // Guest profiles do not have a token service.
904 isGuestSession_ = browser_->profile()->IsGuestSession(); 937 isGuestSession_ = browser_->profile()->IsGuestSession();
905 938
939 // If view mode is PROFILE_CHOOSER but there is an auth error, force
940 // ACCOUNT_MANAGEMENT mode.
941 if (viewMode_ == profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER &&
942 HasAuthError(browser_->profile())) {
943 viewMode_ = profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT;
944 }
945
906 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; 946 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge];
907 [[self bubble] setArrowLocation:info_bubble::kNoArrow]; 947 [[self bubble] setArrowLocation:info_bubble::kNoArrow];
908 [[self bubble] setBackgroundColor:GetDialogBackgroundColor()]; 948 [[self bubble] setBackgroundColor:GetDialogBackgroundColor()];
909 [self initMenuContentsWithView:viewMode_]; 949 [self initMenuContentsWithView:viewMode_];
910 } 950 }
911 951
912 return self; 952 return self;
913 } 953 }
914 954
915 - (void)initMenuContentsWithView:(profiles::BubbleViewMode)viewToDisplay { 955 - (void)initMenuContentsWithView:(profiles::BubbleViewMode)viewToDisplay {
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]); 1514 base::scoped_nsobject<NSView> container([[NSView alloc] initWithFrame:rect]);
1475 currentProfileAccounts_.clear(); 1515 currentProfileAccounts_.clear();
1476 1516
1477 Profile* profile = browser_->profile(); 1517 Profile* profile = browser_->profile();
1478 std::string primaryAccount = 1518 std::string primaryAccount =
1479 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername(); 1519 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedUsername();
1480 DCHECK(!primaryAccount.empty()); 1520 DCHECK(!primaryAccount.empty());
1481 std::vector<std::string>accounts = 1521 std::vector<std::string>accounts =
1482 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount); 1522 profiles::GetSecondaryAccountsForProfile(profile, primaryAccount);
1483 1523
1524 // Get state of authentication error, if any.
msw 2014/06/03 04:15:31 nit: this comment should be made more helpful or r
noms (inactive) 2014/06/06 20:33:43 Done.
1525 std::string errorAccountId = GetAuthErrorAccountId(profile);
1526
1484 rect.origin.y = 0; 1527 rect.origin.y = 0;
1485 for (size_t i = 0; i < accounts.size(); ++i) { 1528 for (size_t i = 0; i < accounts.size(); ++i) {
1486 // Save the original email address, as the button text could be elided. 1529 // Save the original email address, as the button text could be elided.
1487 currentProfileAccounts_[i] = accounts[i]; 1530 currentProfileAccounts_[i] = accounts[i];
1488 NSButton* accountButton = [self accountButtonWithRect:rect 1531 NSButton* accountButton =
1489 title:accounts[i] 1532 [self accountButtonWithRect:rect
1490 tag:i]; 1533 title:accounts[i]
1534 tag:i
1535 reauthRequired:errorAccountId == accounts[i]];
msw 2014/06/03 04:15:31 Couldn't multiple accounts have auth errors at the
noms (inactive) 2014/06/06 20:33:44 They could, but the way it works right now is that
msw 2014/06/09 19:02:38 It's also unclear to me how this retains the autho
noms (inactive) 2014/06/10 15:02:47 A little background: this error controller used to
1491 [container addSubview:accountButton]; 1536 [container addSubview:accountButton];
1492 rect.origin.y = NSMaxY([accountButton frame]); 1537 rect.origin.y = NSMaxY([accountButton frame]);
1493 } 1538 }
1494 1539
1495 // The primary account should always be listed first. 1540 // The primary account should always be listed first.
1496 NSButton* accountButton = [self accountButtonWithRect:rect 1541 NSButton* accountButton =
1497 title:primaryAccount 1542 [self accountButtonWithRect:rect
1498 tag:kPrimaryProfileTag]; 1543 title:primaryAccount
1544 tag:kPrimaryProfileTag
1545 reauthRequired:errorAccountId == primaryAccount];
1499 [container addSubview:accountButton]; 1546 [container addSubview:accountButton];
1500 [container setFrameSize:NSMakeSize(NSWidth([container frame]), 1547 [container setFrameSize:NSMakeSize(NSWidth([container frame]),
1501 NSMaxY([accountButton frame]))]; 1548 NSMaxY([accountButton frame]))];
1502 return container.autorelease(); 1549 return container.autorelease();
1503 } 1550 }
1504 1551
1505 - (NSView*)buildGaiaEmbeddedView { 1552 - (NSView*)buildGaiaEmbeddedView {
1506 base::scoped_nsobject<NSView> container( 1553 base::scoped_nsobject<NSView> container(
1507 [[NSView alloc] initWithFrame:NSZeroRect]); 1554 [[NSView alloc] initWithFrame:NSZeroRect]);
1508 CGFloat yOffset = 0; 1555 CGFloat yOffset = 0;
1509 1556
1510 bool addSecondaryAccount = 1557 GURL url;
1511 viewMode_ == profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT; 1558 int messageId;
msw 2014/06/03 04:15:31 nit: initialize this value
noms (inactive) 2014/06/06 20:33:44 Done.
1512 signin::Source source = addSecondaryAccount ? 1559 switch (viewMode_) {
1513 signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT : 1560 case profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN:
1514 signin::SOURCE_AVATAR_BUBBLE_SIGN_IN; 1561 url = signin::GetPromoURL(signin::SOURCE_AVATAR_BUBBLE_SIGN_IN,
1562 false /* auto_close */,
1563 true /* is_constrained */);
1564 messageId = IDS_PROFILES_GAIA_SIGNIN_TITLE;
1565 break;
1566 case profiles::BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT:
1567 url = signin::GetPromoURL(signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT,
1568 false /* auto_close */,
1569 true /* is_constrained */);
1570 messageId = IDS_PROFILES_GAIA_ADD_ACCOUNT_TITLE;
1571 break;
1572 case profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH: {
msw 2014/06/03 04:15:31 nit: you shouldn't need these curly braces.
noms (inactive) 2014/06/06 20:33:44 Without the curly braces, the compiler is unhappy
1573 DCHECK(HasAuthError(browser_->profile()));
1574 url = signin::GetReauthURL(browser_->profile(),
1575 GetAuthErrorUsername(browser_->profile()));
1576 messageId = IDS_PROFILES_GAIA_REAUTH_TITLE;
1577 break;
1578 }
1579 default:
1580 NOTREACHED() << "Called with invalid mode=" << viewMode_;
1581 return NULL;
1582 }
1515 1583
1516 webContents_.reset(content::WebContents::Create( 1584 webContents_.reset(content::WebContents::Create(
1517 content::WebContents::CreateParams(browser_->profile()))); 1585 content::WebContents::CreateParams(browser_->profile())));
1518 webContents_->GetController().LoadURL( 1586 webContents_->GetController().LoadURL(url,
1519 signin::GetPromoURL( 1587 content::Referrer(),
1520 source, false /* auto_close */, true /* is_constrained */), 1588 content::PAGE_TRANSITION_AUTO_TOPLEVEL,
1521 content::Referrer(), 1589 std::string());
1522 content::PAGE_TRANSITION_AUTO_TOPLEVEL,
1523 std::string());
1524 NSView* webview = webContents_->GetNativeView(); 1590 NSView* webview = webContents_->GetNativeView();
1525 [webview setFrameSize:NSMakeSize(kFixedGaiaViewWidth, kFixedGaiaViewHeight)]; 1591 [webview setFrameSize:NSMakeSize(kFixedGaiaViewWidth, kFixedGaiaViewHeight)];
1526 [container addSubview:webview]; 1592 [container addSubview:webview];
1527 yOffset = NSMaxY([webview frame]); 1593 yOffset = NSMaxY([webview frame]);
1528 1594
1529 // Adds the title card. 1595 // Adds the title card.
1530 NSBox* separator = [self separatorWithFrame: 1596 NSBox* separator = [self separatorWithFrame:
1531 NSMakeRect(0, yOffset, kFixedGaiaViewWidth, 0)]; 1597 NSMakeRect(0, yOffset, kFixedGaiaViewWidth, 0)];
1532 [container addSubview:separator]; 1598 [container addSubview:separator];
1533 yOffset = NSMaxY([separator frame]) + kSmallVerticalSpacing; 1599 yOffset = NSMaxY([separator frame]) + kSmallVerticalSpacing;
1534 1600
1535 NSView* titleView = BuildTitleCard( 1601 NSView* titleView = BuildTitleCard(
1536 NSMakeRect(0, yOffset, kFixedGaiaViewWidth,0), 1602 NSMakeRect(0, yOffset, kFixedGaiaViewWidth, 0),
1537 addSecondaryAccount ? IDS_PROFILES_GAIA_ADD_ACCOUNT_TITLE : 1603 messageId,
1538 IDS_PROFILES_GAIA_SIGNIN_TITLE,
1539 self /* backButtonTarget*/, 1604 self /* backButtonTarget*/,
1540 @selector(navigateBackFromSigninPage:) /* backButtonAction */); 1605 @selector(navigateBackFromSigninPage:) /* backButtonAction */);
1541 [container addSubview:titleView]; 1606 [container addSubview:titleView];
1542 yOffset = NSMaxY([titleView frame]); 1607 yOffset = NSMaxY([titleView frame]);
1543 1608
1544 [container setFrameSize:NSMakeSize(kFixedGaiaViewWidth, yOffset)]; 1609 [container setFrameSize:NSMakeSize(kFixedGaiaViewWidth, yOffset)];
1545 return container.autorelease(); 1610 return container.autorelease();
1546 } 1611 }
1547 1612
1548 - (NSView*)buildAccountRemovalView { 1613 - (NSView*)buildAccountRemovalView {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1717 [link setTarget:self]; 1782 [link setTarget:self];
1718 [link setAction:action]; 1783 [link setAction:action];
1719 [link setFrameOrigin:frameOrigin]; 1784 [link setFrameOrigin:frameOrigin];
1720 [link sizeToFit]; 1785 [link sizeToFit];
1721 1786
1722 return link.autorelease(); 1787 return link.autorelease();
1723 } 1788 }
1724 1789
1725 - (NSButton*)accountButtonWithRect:(NSRect)rect 1790 - (NSButton*)accountButtonWithRect:(NSRect)rect
1726 title:(const std::string&)title 1791 title:(const std::string&)title
1727 tag:(int)tag { 1792 tag:(int)tag
1793 reauthRequired:(BOOL)reauthRequired {
1794 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
1795 NSImage* deleteImage = rb->GetNativeImageNamed(IDR_CLOSE_1).AsNSImage();
1796 CGFloat deleteImageWidth = [deleteImage size].width;
1797
1798 NSImage* reauthImage = nil;
1799 CGFloat reauthImageWidth = 0;
1800 if (reauthRequired) {
1801 reauthImage = rb->GetNativeImageNamed(
1802 IDR_ICON_PROFILES_ACCOUNT_BUTTON_ERROR).AsNSImage();
1803 reauthImageWidth = [reauthImage size].width;
msw 2014/06/03 04:15:31 Do you need to add some padding, like kHorizontalS
noms (inactive) 2014/06/06 20:33:44 Done.
1804 }
1805
1806 CGFloat availableTextWidth = rect.size.width - kHorizontalSpacing -
1807 deleteImageWidth - reauthImageWidth;
1808
1728 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor( 1809 NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor(
1729 profiles::kAvatarBubbleAccountsBackgroundColor); 1810 profiles::kAvatarBubbleAccountsBackgroundColor);
1730 base::scoped_nsobject<BackgroundColorHoverButton> button( 1811 base::scoped_nsobject<BackgroundColorHoverButton> button(
1731 [[BackgroundColorHoverButton alloc] initWithFrame:rect 1812 [[BackgroundColorHoverButton alloc] initWithFrame:rect
1732 imageTitleSpacing:0 1813 imageTitleSpacing:0
1733 backgroundColor:backgroundColor]); 1814 backgroundColor:backgroundColor]);
1734 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 1815 [button setTitle:ElideEmail(title, availableTextWidth)];
1735 NSImage* defaultImage = rb->GetNativeImageNamed(IDR_CLOSE_1).AsNSImage();
1736 CGFloat kDeleteButtonWidth = [defaultImage size].width;
1737 CGFloat availableWidth = rect.size.width -
1738 kDeleteButtonWidth - kHorizontalSpacing;
1739 [button setTitle:ElideEmail(title, availableWidth)];
1740 [button setAlignment:NSLeftTextAlignment]; 1816 [button setAlignment:NSLeftTextAlignment];
1741 [button setBordered:NO]; 1817 [button setBordered:NO];
1818 if (reauthRequired) {
1819 [button setTarget:self];
1820 [button setAction:@selector(showAccountReauthView:)];
1821 [button setTag:tag];
1822 }
1742 1823
1743 // Delete button. 1824 // Delete button.
1744 rect.origin = NSMakePoint(availableWidth, 0); 1825 rect.origin = NSMakePoint(availableTextWidth + reauthImageWidth, 0);
1745 rect.size.width = kDeleteButtonWidth; 1826 rect.size.width = deleteImageWidth;
1746 base::scoped_nsobject<HoverImageButton> deleteButton( 1827 base::scoped_nsobject<HoverImageButton> deleteButton(
1747 [[HoverImageButton alloc] initWithFrame:rect]); 1828 [[HoverImageButton alloc] initWithFrame:rect]);
1748 [deleteButton setBordered:NO]; 1829 [deleteButton setBordered:NO];
1749 [deleteButton setDefaultImage:defaultImage]; 1830 [deleteButton setDefaultImage:deleteImage];
1750 [deleteButton setHoverImage:rb->GetNativeImageNamed( 1831 [deleteButton setHoverImage:rb->GetNativeImageNamed(
1751 IDR_CLOSE_1_H).ToNSImage()]; 1832 IDR_CLOSE_1_H).ToNSImage()];
1752 [deleteButton setPressedImage:rb->GetNativeImageNamed( 1833 [deleteButton setPressedImage:rb->GetNativeImageNamed(
1753 IDR_CLOSE_1_P).ToNSImage()]; 1834 IDR_CLOSE_1_P).ToNSImage()];
1754 [deleteButton setTarget:self]; 1835 [deleteButton setTarget:self];
1755 [deleteButton setAction:@selector(showAccountRemovalView:)]; 1836 [deleteButton setAction:@selector(showAccountRemovalView:)];
1756 [deleteButton setTag:tag]; 1837 [deleteButton setTag:tag];
1757 1838
1758 [button addSubview:deleteButton]; 1839 [button addSubview:deleteButton];
1840
1841 // Warning icon.
1842 if (reauthRequired) {
1843 base::scoped_nsobject<NSImageView> reauthIcon(
1844 [[NSImageView alloc] initWithFrame:NSMakeRect(
1845 availableTextWidth, 0, reauthImageWidth, rect.size.height)]);
1846 [reauthIcon setImage:reauthImage];
1847 [button addSubview:reauthIcon];
1848 }
1849
1759 return button.autorelease(); 1850 return button.autorelease();
1760 } 1851 }
1761 1852
1762 @end 1853 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698