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/first_run_bubble_controller.h"
6
7#include "base/logging.h"
8#include "base/strings/utf_string_conversions.h"
9#include "chrome/browser/first_run/first_run.h"
10#include "chrome/browser/search_engines/template_url_service_factory.h"
11#include "chrome/browser/ui/chrome_pages.h"
12#import "chrome/browser/ui/cocoa/info_bubble_view.h"
13#import "chrome/browser/ui/cocoa/l10n_util.h"
14#include "components/search_engines/util.h"
15#include "ui/base/l10n/l10n_util.h"
16
17@interface FirstRunBubbleController(Private)
18- (id)initRelativeToView:(NSView*)view
19                  offset:(NSPoint)offset
20                 browser:(Browser*)browser
21                 profile:(Profile*)profile;
22- (void)closeIfNotKey;
23@end
24
25@implementation FirstRunBubbleController
26
27+ (FirstRunBubbleController*) showForView:(NSView*)view
28                                   offset:(NSPoint)offset
29                                  browser:(Browser*)browser
30                                  profile:(Profile*)profile {
31  // Autoreleases itself on bubble close.
32  return [[FirstRunBubbleController alloc] initRelativeToView:view
33                                                       offset:offset
34                                                      browser:browser
35                                                      profile:profile];
36}
37
38- (id)initRelativeToView:(NSView*)view
39                  offset:(NSPoint)offset
40                 browser:(Browser*)browser
41                 profile:(Profile*)profile {
42  if ((self = [super initWithWindowNibPath:@"FirstRunBubble"
43                            relativeToView:view
44                                    offset:offset])) {
45    browser_ = browser;
46    profile_ = profile;
47    [self showWindow:nil];
48
49    // On 10.5, the first run bubble sometimes does not disappear when clicking
50    // the omnibox. This happens if the bubble never became key, due to it
51    // showing up so early in the startup sequence. As a workaround, close it
52    // automatically after a few seconds if it doesn't become key.
53    // http://crbug.com/52726
54    [self performSelector:@selector(closeIfNotKey) withObject:nil afterDelay:3];
55  }
56  return self;
57}
58
59- (void)awakeFromNib {
60  first_run::LogFirstRunMetric(first_run::FIRST_RUN_BUBBLE_SHOWN);
61
62  TemplateURLService* service =
63      TemplateURLServiceFactory::GetForProfile(profile_);
64  DCHECK(header_);
65  [header_ setStringValue:cocoa_l10n_util::ReplaceNSStringPlaceholders(
66      [header_ stringValue], GetDefaultSearchEngineName(service), NULL)];
67
68  // Adapt window size to contents. Do this before all other layouting.
69  CGFloat dy = cocoa_l10n_util::VerticallyReflowGroup([[self bubble] subviews]);
70  NSSize ds = NSMakeSize(0, dy);
71  ds = [[self bubble] convertSize:ds toView:nil];
72
73  NSRect frame = [[self window] frame];
74  frame.origin.y -= ds.height;
75  frame.size.height += ds.height;
76  [[self window] setFrame:frame display:YES];
77}
78
79- (void)close {
80  // If the window is closed before the timer is fired, cancel the timer, since
81  // it retains the controller.
82  [NSObject cancelPreviousPerformRequestsWithTarget:self
83                                           selector:@selector(closeIfNotKey)
84                                             object:nil];
85  [super close];
86}
87
88- (void)closeIfNotKey {
89  if (![[self window] isKeyWindow])
90    [self close];
91}
92
93- (IBAction)onChange:(id)sender {
94  first_run::LogFirstRunMetric(first_run::FIRST_RUN_BUBBLE_CHANGE_INVOKED);
95
96  Browser* browser = browser_;
97  [self close];
98  if (browser)
99    chrome::ShowSearchEngineSettings(browser);
100}
101
102@end  // FirstRunBubbleController
103