• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4
5#import "chrome/browser/ui/cocoa/infobars/infobar_controller.h"
6
7#include "base/logging.h"
8#include "base/mac/bundle_locations.h"
9#include "base/mac/mac_util.h"
10#include "chrome/browser/infobars/infobar_service.h"
11#import "chrome/browser/ui/cocoa/animatable_view.h"
12#import "chrome/browser/ui/cocoa/browser_window_controller.h"
13#import "chrome/browser/ui/cocoa/image_button_cell.h"
14#include "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h"
15#import "chrome/browser/ui/cocoa/infobars/infobar_container_cocoa.h"
16#import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
17#import "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h"
18#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
19#include "grit/theme_resources.h"
20#import "ui/base/cocoa/controls/hyperlink_text_view.h"
21#include "ui/gfx/image/image.h"
22#include "ui/resources/grit/ui_resources.h"
23
24@interface InfoBarController ()
25// Sets |label_| based on |labelPlaceholder_|, sets |labelPlaceholder_| to nil.
26- (void)initializeLabel;
27@end
28
29@implementation InfoBarController
30
31@synthesize containerController = containerController_;
32
33- (id)initWithInfoBar:(InfoBarCocoa*)infobar {
34  if ((self = [super initWithNibName:@"InfoBar"
35                              bundle:base::mac::FrameworkBundle()])) {
36    DCHECK(infobar);
37    infobar_ = infobar->GetWeakPtr();
38  }
39  return self;
40}
41
42// All infobars have an icon, so we set up the icon in the base class
43// awakeFromNib.
44- (void)awakeFromNib {
45  [[closeButton_ cell] setImageID:IDR_CLOSE_1
46                   forButtonState:image_button_cell::kDefaultState];
47  [[closeButton_ cell] setImageID:IDR_CLOSE_1_H
48                   forButtonState:image_button_cell::kHoverState];
49  [[closeButton_ cell] setImageID:IDR_CLOSE_1_P
50                   forButtonState:image_button_cell::kPressedState];
51  [[closeButton_ cell] setImageID:IDR_CLOSE_1
52                   forButtonState:image_button_cell::kDisabledState];
53
54  if (![self delegate]->GetIcon().IsEmpty()) {
55    [image_ setImage:[self delegate]->GetIcon().ToNSImage()];
56  } else {
57    // No icon, remove it from the view and grow the textfield to include the
58    // space.
59    NSRect imageFrame = [image_ frame];
60    NSRect labelFrame = [labelPlaceholder_ frame];
61    labelFrame.size.width += NSMinX(imageFrame) - NSMinX(labelFrame);
62    labelFrame.origin.x = imageFrame.origin.x;
63    [image_ removeFromSuperview];
64    image_ = nil;
65    [labelPlaceholder_ setFrame:labelFrame];
66  }
67  [self initializeLabel];
68
69  [self addAdditionalControls];
70
71  [infoBarView_ setInfobarType:[self delegate]->GetInfoBarType()];
72  [infoBarView_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
73}
74
75- (void)dealloc {
76  [okButton_ setTarget:nil];
77  [cancelButton_ setTarget:nil];
78  [closeButton_ setTarget:nil];
79  [super dealloc];
80}
81
82- (InfoBarCocoa*)infobar {
83  return infobar_.get();
84}
85
86// Called when someone clicks on the embedded link.
87- (BOOL)textView:(NSTextView*)textView
88   clickedOnLink:(id)link
89         atIndex:(NSUInteger)charIndex {
90  if ([self respondsToSelector:@selector(linkClicked)])
91    [self performSelector:@selector(linkClicked)];
92  return YES;
93}
94
95- (BOOL)isOwned {
96  return infobar_ && infobar_->OwnerCocoa() != NULL;
97}
98
99// Called when someone clicks on the ok button.
100- (void)ok:(id)sender {
101  // Subclasses must override this method if they do not hide the ok button.
102  NOTREACHED();
103}
104
105// Called when someone clicks on the cancel button.
106- (void)cancel:(id)sender {
107  // Subclasses must override this method if they do not hide the cancel button.
108  NOTREACHED();
109}
110
111// Called when someone clicks on the close button.
112- (void)dismiss:(id)sender {
113  if (![self isOwned])
114    return;
115  [self delegate]->InfoBarDismissed();
116  [self removeSelf];
117}
118
119- (void)removeSelf {
120  infobar_->RemoveSelf();
121}
122
123- (void)addAdditionalControls {
124  // Default implementation does nothing.
125}
126
127- (void)infobarWillHide {
128}
129
130- (void)infobarWillClose {
131}
132
133- (void)removeButtons {
134  // Extend the label all the way across.
135  NSRect labelFrame = [label_.get() frame];
136  labelFrame.size.width = NSMaxX([cancelButton_ frame]) - NSMinX(labelFrame);
137  [okButton_ removeFromSuperview];
138  okButton_ = nil;
139  [cancelButton_ removeFromSuperview];
140  cancelButton_ = nil;
141  [label_.get() setFrame:labelFrame];
142}
143
144- (void)layoutArrow {
145  [infoBarView_ setArrowHeight:infobar_->arrow_height()];
146  [infoBarView_ setArrowHalfWidth:infobar_->arrow_half_width()];
147  [infoBarView_ setHasTip:![containerController_ shouldSuppressTopInfoBarTip]];
148
149  // Convert from window to view coordinates.
150  NSPoint point = NSMakePoint([containerController_ infobarArrowX], 0);
151  point = [infoBarView_ convertPoint:point fromView:nil];
152  [infoBarView_ setArrowX:point.x];
153}
154
155- (void)disablePopUpMenu:(NSMenu*)menu {
156  // If the menu is re-opened, prevent queries to update items.
157  [menu setDelegate:nil];
158
159  // Prevent target/action messages to the controller.
160  for (NSMenuItem* item in [menu itemArray]) {
161    [item setEnabled:NO];
162    [item setTarget:nil];
163  }
164}
165
166- (infobars::InfoBarDelegate*)delegate {
167  return infobar_->delegate();
168}
169
170- (void)initializeLabel {
171  // Replace the label placeholder NSTextField with the real label NSTextView.
172  // The former doesn't show links in a nice way, but the latter can't be added
173  // in IB without a containing scroll view, so create the NSTextView
174  // programmatically.
175  base::scoped_nsobject<HyperlinkTextView> newLabel(
176    [[HyperlinkTextView alloc] initWithFrame:[labelPlaceholder_ frame]]);
177  [newLabel setDrawsBackgroundUsingSuperview:YES];
178  [newLabel setAutoresizingMask:[labelPlaceholder_ autoresizingMask]];
179  [[labelPlaceholder_ superview]
180      replaceSubview:labelPlaceholder_ with:newLabel];
181  labelPlaceholder_ = nil;  // Now released.
182  [newLabel setDelegate:self];
183
184  label_.reset(newLabel.release());
185}
186
187@end
188