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 "ios/chrome/browser/infobars/confirm_infobar_controller.h"
7 #include "base/mac/foundation_util.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/sys_string_conversions.h"
10 #include "components/infobars/core/confirm_infobar_delegate.h"
11 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
12 #import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
13 #import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/base/window_open_disposition.h"
16 #include "ui/gfx/image/image.h"
20 // UI Tags for the infobar elements.
21 enum ConfirmInfoBarUITags { OK = 1, CANCEL, CLOSE, TITLE_LINK };
23 // Converts a UI button tag to the corresponding InfoBarButton.
24 ConfirmInfoBarDelegate::InfoBarButton UITagToButton(NSUInteger tag) {
26 case ConfirmInfoBarUITags::OK:
27 return ConfirmInfoBarDelegate::BUTTON_OK;
28 case ConfirmInfoBarUITags::CANCEL:
29 case ConfirmInfoBarUITags::CLOSE:
30 return ConfirmInfoBarDelegate::BUTTON_CANCEL;
33 return ConfirmInfoBarDelegate::BUTTON_CANCEL;
39 #pragma mark - ConfirmInfoBarController
41 @interface ConfirmInfoBarController ()
43 // Action for any of the user defined buttons.
44 - (void)infoBarButtonDidPress:(id)sender;
45 // Action for any of the user defined links.
46 - (void)infobarLinkDidPress:(NSNumber*)tag;
47 - (void)updateInfobarLabel:(UIView<InfoBarViewProtocol>*)view;
50 @implementation ConfirmInfoBarController {
51 __weak ConfirmInfoBarDelegate* confirmInfobarDelegate_;
55 #pragma mark InfoBarController
57 - (base::scoped_nsobject<UIView<InfoBarViewProtocol>>)
58 viewForDelegate:(infobars::InfoBarDelegate*)delegate
60 base::scoped_nsobject<UIView<InfoBarViewProtocol>> infoBarView;
61 confirmInfobarDelegate_ = delegate->AsConfirmInfoBarDelegate();
63 ios::GetChromeBrowserProvider()->CreateInfoBarView(frame, self.delegate));
65 gfx::Image modelIcon = confirmInfobarDelegate_->GetIcon();
66 int buttons = confirmInfobarDelegate_->GetButtons();
67 NSString* buttonOK = nil;
68 if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) {
69 buttonOK = base::SysUTF16ToNSString(confirmInfobarDelegate_->GetButtonLabel(
70 ConfirmInfoBarDelegate::BUTTON_OK));
72 NSString* buttonCancel = nil;
73 if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
75 base::SysUTF16ToNSString(confirmInfobarDelegate_->GetButtonLabel(
76 ConfirmInfoBarDelegate::BUTTON_CANCEL));
79 [infoBarView addCloseButtonWithTag:ConfirmInfoBarUITags::CLOSE
81 action:@selector(infoBarButtonDidPress:)];
83 // Optional left icon.
84 if (!modelIcon.IsEmpty())
85 [infoBarView addLeftIcon:modelIcon.ToUIImage()];
88 [self updateInfobarLabel:infoBarView];
90 if (buttonOK && buttonCancel) {
91 [infoBarView addButton1:buttonOK
92 tag1:ConfirmInfoBarUITags::OK
94 tag2:ConfirmInfoBarUITags::CANCEL
96 action:@selector(infoBarButtonDidPress:)];
97 } else if (buttonOK) {
98 [infoBarView addButton:buttonOK
99 tag:ConfirmInfoBarUITags::OK
101 action:@selector(infoBarButtonDidPress:)];
103 // No buttons, only message.
104 DCHECK(!confirmInfobarDelegate_->GetMessageText().empty() && !buttonCancel);
109 - (void)updateInfobarLabel:(UIView<InfoBarViewProtocol>*)view {
110 if (!confirmInfobarDelegate_->GetMessageText().length())
112 if (confirmInfobarDelegate_->GetLinkText().length()) {
113 base::string16 msgLink = base::SysNSStringToUTF16(
114 [[view class] stringAsLink:base::SysUTF16ToNSString(
115 confirmInfobarDelegate_->GetLinkText())
116 tag:ConfirmInfoBarUITags::TITLE_LINK]);
117 base::string16 messageText = confirmInfobarDelegate_->GetMessageText();
118 base::ReplaceFirstSubstringAfterOffset(
119 &messageText, 0, confirmInfobarDelegate_->GetLinkText(), msgLink);
121 [view addLabel:base::SysUTF16ToNSString(messageText)
123 action:@selector(infobarLinkDidPress:)];
126 base::SysUTF16ToNSString(confirmInfobarDelegate_->GetMessageText());
127 [view addLabel:label];
131 #pragma mark - Handling of User Events
133 - (void)infoBarButtonDidPress:(id)sender {
134 // This press might have occurred after the user has already pressed a button,
135 // in which case the view has been detached from the delegate and this press
136 // should be ignored.
137 if (!self.delegate) {
140 if ([sender isKindOfClass:[UIButton class]]) {
141 NSUInteger tag = static_cast<UIButton*>(sender).tag;
142 if (tag == ConfirmInfoBarUITags::CLOSE)
143 self.delegate->InfoBarDidCancel();
145 self.delegate->InfoBarButtonDidPress(UITagToButton(tag));
149 // Title link was clicked.
150 - (void)infobarLinkDidPress:(NSNumber*)tag {
151 DCHECK([tag isKindOfClass:[NSNumber class]]);
152 if (!self.delegate) {
155 if ([tag unsignedIntegerValue] == ConfirmInfoBarUITags::TITLE_LINK) {
156 confirmInfobarDelegate_->LinkClicked(NEW_FOREGROUND_TAB);