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