Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / one_click_signin_view_controller.mm
blob5e4d9677656be4c8629a1f96ae0a26f03caf024c
1 // Copyright (c) 2012 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.
5 #import "chrome/browser/ui/cocoa/one_click_signin_view_controller.h"
7 #include "base/callback_helpers.h"
8 #include "base/logging.h"
9 #include "base/mac/bundle_locations.h"
10 #import "chrome/browser/ui/chrome_style.h"
11 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
12 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
13 #include "chrome/browser/ui/sync/one_click_signin_histogram.h"
14 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/web_contents.h"
16 #include "grit/chromium_strings.h"
17 #include "grit/generated_resources.h"
18 #include "skia/ext/skia_utils_mac.h"
19 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
20 #include "ui/base/l10n/l10n_util_mac.h"
22 namespace {
24 // Shift the origin of |view|'s frame by the given amount in the
25 // positive y direction (up).
26 void ShiftOriginY(NSView* view, CGFloat amount) {
27   NSPoint origin = [view frame].origin;
28   origin.y += amount;
29   [view setFrameOrigin:origin];
32 }  // namespace
34 @interface OneClickSigninViewController ()
35 - (CGFloat)initializeInformativeTextView;
36 - (void)close;
37 @end
39 @implementation OneClickSigninViewController
42 - (id)initWithNibName:(NSString*)nibName
43           webContents:(content::WebContents*)webContents
44          syncCallback:(const BrowserWindow::StartSyncCallback&)syncCallback
45         closeCallback:(const base::Closure&)closeCallback
46          isSyncDialog:(BOOL)isSyncDialog
47                 email:(const base::string16&)email
48          errorMessage:(NSString*)errorMessage {
49   if ((self = [super initWithNibName:nibName
50                               bundle:base::mac::FrameworkBundle()])) {
51     webContents_ = webContents;
52     startSyncCallback_ = syncCallback;
53     closeCallback_ = closeCallback;
54     isSyncDialog_ = isSyncDialog;
55     clickedLearnMore_ = NO;
56     email_ = email;
57     errorMessage_.reset([errorMessage retain]);
58     if (isSyncDialog_)
59       DCHECK(!startSyncCallback_.is_null());
60   }
61   return self;
64 - (void)viewWillClose {
65   // This is usually called after a click handler has initiated sync
66   // and has reset the callback. However, in the case that we are closing
67   // the window and nothing else has initiated the sync, we must do so here
68   if (isSyncDialog_ && !startSyncCallback_.is_null()) {
69     base::ResetAndReturn(&startSyncCallback_).Run(
70         OneClickSigninSyncStarter::UNDO_SYNC);
71   }
74 - (IBAction)ok:(id)sender {
75   if (isSyncDialog_) {
76     OneClickSigninHelper::LogConfirmHistogramValue(
77         clickedLearnMore_ ?
78             one_click_signin::HISTOGRAM_CONFIRM_LEARN_MORE_OK :
79             one_click_signin::HISTOGRAM_CONFIRM_OK);
81     base::ResetAndReturn(&startSyncCallback_).Run(
82       OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
83   }
84   [self close];
87 - (IBAction)onClickUndo:(id)sender {
88   if (isSyncDialog_) {
89     OneClickSigninHelper::LogConfirmHistogramValue(
90         clickedLearnMore_ ?
91             one_click_signin::HISTOGRAM_CONFIRM_LEARN_MORE_UNDO :
92             one_click_signin::HISTOGRAM_CONFIRM_UNDO);
94     base::ResetAndReturn(&startSyncCallback_).Run(
95       OneClickSigninSyncStarter::UNDO_SYNC);
96   }
97   [self close];
100 - (IBAction)onClickAdvancedLink:(id)sender {
101   if (isSyncDialog_) {
102     OneClickSigninHelper::LogConfirmHistogramValue(
103         clickedLearnMore_ ?
104             one_click_signin::HISTOGRAM_CONFIRM_LEARN_MORE_ADVANCED :
105             one_click_signin::HISTOGRAM_CONFIRM_ADVANCED);
107     base::ResetAndReturn(&startSyncCallback_).Run(
108         OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST);
109   }
110   else {
111     content::OpenURLParams params(GURL(chrome::kChromeUISettingsURL),
112                                   content::Referrer(), CURRENT_TAB,
113                                   content::PAGE_TRANSITION_LINK, false);
114     webContents_->OpenURL(params);
115   }
116   [self close];
119 - (IBAction)onClickClose:(id)sender {
120   if (isSyncDialog_) {
121     OneClickSigninHelper::LogConfirmHistogramValue(
122         clickedLearnMore_ ?
123             one_click_signin::HISTOGRAM_CONFIRM_LEARN_MORE_CLOSE :
124             one_click_signin::HISTOGRAM_CONFIRM_CLOSE);
126     base::ResetAndReturn(&startSyncCallback_).Run(
127         OneClickSigninSyncStarter::UNDO_SYNC);
128   }
129   [self close];
132 - (void)awakeFromNib {
133   // Lay out the text controls from the bottom up.
134   CGFloat totalYOffset = 0.0;
136   if ([errorMessage_ length] == 0) {
137     totalYOffset +=
138         [GTMUILocalizerAndLayoutTweaker sizeToFitView:advancedLink_].height;
139     [[advancedLink_ cell] setTextColor:
140         gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor())];
141   } else {
142     // Don't display the advanced link for the error bubble.
143     // To align the Learn More link with the OK button, we need to offset by
144     // the height of the Advanced link, plus the padding between it and the
145     // Learn More link above.
146     float advancedLinkHeightPlusPadding =
147         [informativePlaceholderTextField_ frame].origin.y -
148         [advancedLink_ frame].origin.y;
150     totalYOffset -= advancedLinkHeightPlusPadding;
151     [advancedLink_ removeFromSuperview];
152   }
154   if (informativePlaceholderTextField_) {
155     ShiftOriginY(informativePlaceholderTextField_, totalYOffset);
156     totalYOffset += [self initializeInformativeTextView];
157   }
159   ShiftOriginY(messageTextField_, totalYOffset);
160   totalYOffset +=
161       [GTMUILocalizerAndLayoutTweaker
162           sizeToFitFixedWidthTextField:messageTextField_];
164   ShiftOriginY(titleTextField_, totalYOffset);
165   totalYOffset +=
166       [GTMUILocalizerAndLayoutTweaker
167           sizeToFitFixedWidthTextField:titleTextField_];
169   if (closeButton_)
170     ShiftOriginY(closeButton_, totalYOffset);
172   NSSize delta = NSMakeSize(0.0, totalYOffset);
174   if (isSyncDialog_) {
175     [messageTextField_ setStringValue:l10n_util::GetNSStringWithFixup(
176         IDS_ONE_CLICK_SIGNIN_DIALOG_TITLE_NEW)];
177   } else if ([errorMessage_ length] != 0) {
178     [messageTextField_ setStringValue:errorMessage_];
179   }
181   // Resize bubble and window to hold the controls.
182   [GTMUILocalizerAndLayoutTweaker
183       resizeViewWithoutAutoResizingSubViews:[self view]
184                                       delta:delta];
186   if (isSyncDialog_) {
187     OneClickSigninHelper::LogConfirmHistogramValue(
188         one_click_signin::HISTOGRAM_CONFIRM_SHOWN);
189   }
192 - (CGFloat)initializeInformativeTextView {
193   NSRect oldFrame = [informativePlaceholderTextField_ frame];
195   // Replace the placeholder NSTextField with the real label NSTextView. The
196   // former doesn't show links in a nice way, but the latter can't be added in
197   // a xib without a containing scroll view, so create the NSTextView
198   // programmatically.
199   informativeTextView_.reset(
200       [[HyperlinkTextView alloc] initWithFrame:oldFrame]);
201   [informativeTextView_.get() setAutoresizingMask:
202       [informativePlaceholderTextField_ autoresizingMask]];
203   [informativeTextView_.get() setDelegate:self];
205   // Set the text.
206   NSString* learnMoreText = l10n_util::GetNSStringWithFixup(IDS_LEARN_MORE);
207   NSString* messageText;
209   ui::ResourceBundle::FontStyle fontStyle = isSyncDialog_ ?
210       chrome_style::kTextFontStyle : ui::ResourceBundle::SmallFont;
211   NSFont* font = ui::ResourceBundle::GetSharedInstance().GetFont(
212       fontStyle).GetNativeFont();
214   // The non-modal bubble already has a text content and only needs the
215   // Learn More link (in a smaller font).
216   if (isSyncDialog_) {
217     messageText = l10n_util::GetNSStringFWithFixup(
218         IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE_NEW, email_);
219     messageText = [messageText stringByAppendingString:@" "];
220   } else {
221     messageText = @"";
222   }
224   NSColor* linkColor =
225       gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor());
226   [informativeTextView_ setMessageAndLink:messageText
227                                  withLink:learnMoreText
228                                  atOffset:[messageText length]
229                                      font:font
230                              messageColor:[NSColor blackColor]
231                                 linkColor:linkColor];
234   // Make the "Advanced" link font as large as the "Learn More" link.
235   [[advancedLink_ cell] setFont:font];
236   [advancedLink_ sizeToFit];
238   // Size to fit.
239   [[informativePlaceholderTextField_ cell] setAttributedStringValue:
240       [informativeTextView_ attributedString]];
241   [GTMUILocalizerAndLayoutTweaker
242         sizeToFitFixedWidthTextField:informativePlaceholderTextField_];
243   NSRect newFrame = [informativePlaceholderTextField_ frame];
244   [informativeTextView_ setFrame:newFrame];
246   // Swap placeholder.
247   [[informativePlaceholderTextField_ superview]
248      replaceSubview:informativePlaceholderTextField_
249                with:informativeTextView_.get()];
250   informativePlaceholderTextField_ = nil;  // Now released.
252   return NSHeight(newFrame) - NSHeight(oldFrame);
255 - (BOOL)textView:(NSTextView*)textView
256    clickedOnLink:(id)link
257          atIndex:(NSUInteger)charIndex {
258   if (isSyncDialog_ && !clickedLearnMore_) {
259     clickedLearnMore_ = YES;
261     OneClickSigninHelper::LogConfirmHistogramValue(
262         one_click_signin::HISTOGRAM_CONFIRM_LEARN_MORE);
263   }
264   WindowOpenDisposition location = isSyncDialog_ ?
265                                    NEW_WINDOW : NEW_FOREGROUND_TAB;
266   content::OpenURLParams params(GURL(chrome::kChromeSyncLearnMoreURL),
267                                 content::Referrer(), location,
268                                 content::PAGE_TRANSITION_LINK, false);
269   webContents_->OpenURL(params);
270   return YES;
273 - (void)close {
274   base::ResetAndReturn(&closeCallback_).Run();
277 @end