1 // Copyright 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 #include "chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.h"
7 #include "base/logging.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
10 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
11 #include "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h"
12 #include "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
13 #import "ui/base/cocoa/cocoa_base_utils.h"
14 #include "ui/base/window_open_disposition.h"
16 @implementation ConfirmInfoBarController
18 // Called when someone clicks on the "OK" button.
19 - (IBAction)ok:(id)sender {
22 if ([self delegate]->AsConfirmInfoBarDelegate()->Accept())
26 // Called when someone clicks on the "Cancel" button.
27 - (IBAction)cancel:(id)sender {
30 if ([self delegate]->AsConfirmInfoBarDelegate()->Cancel())
34 // Confirm infobars can have OK and/or cancel buttons, depending on
35 // the return value of GetButtons(). We create each button if
36 // required and position them to the left of the close button.
37 - (void)addAdditionalControls {
38 ConfirmInfoBarDelegate* delegate =
39 [self delegate]->AsConfirmInfoBarDelegate();
41 int visibleButtons = delegate->GetButtons();
43 NSRect okButtonFrame = [okButton_ frame];
44 NSRect cancelButtonFrame = [cancelButton_ frame];
46 DCHECK(NSMaxX(cancelButtonFrame) < NSMinX(okButtonFrame))
47 << "Ok button expected to be on the right of the Cancel button in nib";
49 CGFloat rightEdge = NSMaxX(okButtonFrame);
50 CGFloat spaceBetweenButtons =
51 NSMinX(okButtonFrame) - NSMaxX(cancelButtonFrame);
52 CGFloat spaceBeforeButtons =
53 NSMinX(cancelButtonFrame) - NSMaxX([label_.get() frame]);
55 // Update and position the OK button if needed. Otherwise, hide it.
56 if (visibleButtons & ConfirmInfoBarDelegate::BUTTON_OK) {
57 [okButton_ setTitle:base::SysUTF16ToNSString(
58 delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK))];
59 [GTMUILocalizerAndLayoutTweaker sizeToFitView:okButton_];
60 okButtonFrame = [okButton_ frame];
62 // Position the ok button to the left of the Close button.
63 okButtonFrame.origin.x = rightEdge - okButtonFrame.size.width;
64 [okButton_ setFrame:okButtonFrame];
66 // Update the rightEdge
67 rightEdge = NSMinX(okButtonFrame);
69 [okButton_ removeFromSuperview];
73 // Update and position the Cancel button if needed. Otherwise, hide it.
74 if (visibleButtons & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
75 [cancelButton_ setTitle:base::SysUTF16ToNSString(
76 delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL))];
77 [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_];
78 cancelButtonFrame = [cancelButton_ frame];
80 // If we had a Ok button, leave space between the buttons.
81 if (visibleButtons & ConfirmInfoBarDelegate::BUTTON_OK) {
82 rightEdge -= spaceBetweenButtons;
85 // Position the Cancel button on our current right edge.
86 cancelButtonFrame.origin.x = rightEdge - cancelButtonFrame.size.width;
87 [cancelButton_ setFrame:cancelButtonFrame];
89 // Update the rightEdge.
90 rightEdge = NSMinX(cancelButtonFrame);
92 [cancelButton_ removeFromSuperview];
96 // If we had either button, leave space before the edge of the textfield.
97 if ((visibleButtons & ConfirmInfoBarDelegate::BUTTON_CANCEL) ||
98 (visibleButtons & ConfirmInfoBarDelegate::BUTTON_OK)) {
99 rightEdge -= spaceBeforeButtons;
102 NSRect frame = [label_.get() frame];
103 DCHECK(rightEdge > NSMinX(frame))
104 << "Need to make the xib larger to handle buttons with text this long";
105 frame.size.width = rightEdge - NSMinX(frame);
106 [label_.get() setFrame:frame];
108 // Set the text and link.
109 NSString* message = base::SysUTF16ToNSString(delegate->GetMessageText());
110 base::string16 link = delegate->GetLinkText();
112 // Add spacing between the label and the link.
113 message = [message stringByAppendingString:@" "];
115 NSFont* font = [NSFont labelFontOfSize:
116 [NSFont systemFontSizeForControlSize:NSRegularControlSize]];
117 HyperlinkTextView* view = (HyperlinkTextView*)label_.get();
118 [view setMessageAndLink:message
119 withLink:base::SysUTF16ToNSString(link)
120 atOffset:[message length]
122 messageColor:[NSColor blackColor]
123 linkColor:[NSColor blueColor]];
126 // Called when someone clicks on the link in the infobar. This method
127 // is called by the InfobarTextField on its delegate (the
128 // AlternateNavInfoBarController).
129 - (void)linkClicked {
132 WindowOpenDisposition disposition =
133 ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
134 if ([self delegate]->AsConfirmInfoBarDelegate()->LinkClicked(disposition))
141 scoped_ptr<infobars::InfoBar> ConfirmInfoBarDelegate::CreateInfoBar(
142 scoped_ptr<ConfirmInfoBarDelegate> delegate) {
143 scoped_ptr<InfoBarCocoa> infobar(
144 new InfoBarCocoa(delegate.PassAs<infobars::InfoBarDelegate>()));
145 base::scoped_nsobject<ConfirmInfoBarController> controller(
146 [[ConfirmInfoBarController alloc] initWithInfoBar:infobar.get()]);
147 infobar->set_controller(controller);
148 return infobar.PassAs<infobars::InfoBar>();