- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / infobars / confirm_infobar_controller.mm
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.
4
5 #include "chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.h"
6
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/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
13 #import "ui/base/cocoa/cocoa_event_utils.h"
14 #include "ui/base/window_open_disposition.h"
15
16 @implementation ConfirmInfoBarController
17
18 // Called when someone clicks on the "OK" button.
19 - (IBAction)ok:(id)sender {
20   if (![self isOwned])
21     return;
22   if ([self delegate]->AsConfirmInfoBarDelegate()->Accept())
23     [self removeSelf];
24 }
25
26 // Called when someone clicks on the "Cancel" button.
27 - (IBAction)cancel:(id)sender {
28   if (![self isOwned])
29     return;
30   if ([self delegate]->AsConfirmInfoBarDelegate()->Cancel())
31     [self removeSelf];
32 }
33
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();
40   DCHECK(delegate);
41   int visibleButtons = delegate->GetButtons();
42
43   NSRect okButtonFrame = [okButton_ frame];
44   NSRect cancelButtonFrame = [cancelButton_ frame];
45
46   DCHECK(NSMaxX(cancelButtonFrame) < NSMinX(okButtonFrame))
47       << "Ok button expected to be on the right of the Cancel button in nib";
48
49   CGFloat rightEdge = NSMaxX(okButtonFrame);
50   CGFloat spaceBetweenButtons =
51       NSMinX(okButtonFrame) - NSMaxX(cancelButtonFrame);
52   CGFloat spaceBeforeButtons =
53       NSMinX(cancelButtonFrame) - NSMaxX([label_.get() frame]);
54
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];
61
62     // Position the ok button to the left of the Close button.
63     okButtonFrame.origin.x = rightEdge - okButtonFrame.size.width;
64     [okButton_ setFrame:okButtonFrame];
65
66     // Update the rightEdge
67     rightEdge = NSMinX(okButtonFrame);
68   } else {
69     [okButton_ removeFromSuperview];
70     okButton_ = nil;
71   }
72
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];
79
80     // If we had a Ok button, leave space between the buttons.
81     if (visibleButtons & ConfirmInfoBarDelegate::BUTTON_OK) {
82       rightEdge -= spaceBetweenButtons;
83     }
84
85     // Position the Cancel button on our current right edge.
86     cancelButtonFrame.origin.x = rightEdge - cancelButtonFrame.size.width;
87     [cancelButton_ setFrame:cancelButtonFrame];
88
89     // Update the rightEdge.
90     rightEdge = NSMinX(cancelButtonFrame);
91   } else {
92     [cancelButton_ removeFromSuperview];
93     cancelButton_ = nil;
94   }
95
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;
100   }
101
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];
107
108   // Set the text and link.
109   NSString* message = base::SysUTF16ToNSString(delegate->GetMessageText());
110   string16 link = delegate->GetLinkText();
111   if (!link.empty()) {
112     // Add spacing between the label and the link.
113     message = [message stringByAppendingString:@"   "];
114   }
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]
121                      font:font
122              messageColor:[NSColor blackColor]
123                 linkColor:[NSColor blueColor]];
124 }
125
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 {
130   if (![self isOwned])
131     return;
132   WindowOpenDisposition disposition =
133       ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
134   if ([self delegate]->AsConfirmInfoBarDelegate()->LinkClicked(disposition))
135     [self removeSelf];
136 }
137
138 @end
139
140 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
141   scoped_ptr<InfoBarCocoa> infobar(new InfoBarCocoa(owner, this));
142   base::scoped_nsobject<ConfirmInfoBarController> controller(
143       [[ConfirmInfoBarController alloc] initWithInfoBar:infobar.get()]);
144   infobar->set_controller(controller);
145   return infobar.release();
146 }