Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(804)

Unified Diff: chrome/browser/cocoa/search_engine_dialog_controller.mm

Issue 3223010: Add search engine selection dialog for Mac.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/cocoa/search_engine_dialog_controller.h ('k') | chrome/browser/first_run/first_run.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/cocoa/search_engine_dialog_controller.mm
===================================================================
--- chrome/browser/cocoa/search_engine_dialog_controller.mm (revision 0)
+++ chrome/browser/cocoa/search_engine_dialog_controller.mm (revision 0)
@@ -0,0 +1,279 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/search_engine_dialog_controller.h"
+
+#include <algorithm>
+
+#include "app/l10n_util_mac.h"
+#include "app/resource_bundle.h"
+#include "base/mac_util.h"
+#include "base/nsimage_cache_mac.h"
+#include "base/sys_string_conversions.h"
+#include "base/time.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_model.h"
+#include "chrome/browser/search_engines/template_url_model_observer.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+
+// Horizontal spacing between search engine choices.
+const int kSearchEngineSpacing = 20;
+
+// Vertical spacing between the search engine logo and the button underneath.
+const int kLogoButtonSpacing = 10;
+
+// Width of a label used in place of a logo.
+const int kLogoLabelWidth = 170;
+
+// Height of a label used in place of a logo.
+const int kLogoLabelHeight = 25;
+
+@interface SearchEngineDialogController (Private)
+- (void)onTemplateURLModelChanged;
+- (void)buildSearchEngineView;
+- (NSView*)viewForSearchEngine:(const TemplateURL*)engine
+ atIndex:(size_t)index;
+- (IBAction)searchEngineSelected:(id)sender;
+@end
+
+class SearchEngineDialogControllerBridge : public TemplateURLModelObserver {
+ public:
+ SearchEngineDialogControllerBridge(SearchEngineDialogController* controller);
+
+ // TemplateURLModelObserver
+ virtual void OnTemplateURLModelChanged();
+
+ private:
+ SearchEngineDialogController* controller_;
+};
+
+SearchEngineDialogControllerBridge::SearchEngineDialogControllerBridge(
+ SearchEngineDialogController* controller) : controller_(controller) {
+}
+
+void SearchEngineDialogControllerBridge::OnTemplateURLModelChanged() {
+ [controller_ onTemplateURLModelChanged];
+ MessageLoop::current()->QuitNow();
+}
+
+@implementation SearchEngineDialogController
+
+@synthesize profile = profile_;
+@synthesize randomize = randomize_;
+
+- (id)init {
+ NSString* nibpath =
+ [mac_util::MainAppBundle() pathForResource:@"SearchEngineDialog"
+ ofType:@"nib"];
+ self = [super initWithWindowNibPath:nibpath owner:self];
+ if (self != nil) {
+ bridge_.reset(new SearchEngineDialogControllerBridge(self));
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+- (IBAction)showWindow:(id)sender {
+ searchEnginesModel_ = profile_->GetTemplateURLModel();
+ searchEnginesModel_->AddObserver(bridge_.get());
+
+ if (searchEnginesModel_->loaded()) {
+ [self onTemplateURLModelChanged];
+ } else {
+ searchEnginesModel_->Load();
+ MessageLoop::current()->Run();
+ }
+}
+
+- (void)onTemplateURLModelChanged {
+ searchEnginesModel_->RemoveObserver(bridge_.get());
+
+ // Add the search engines in the search_engines_model_ to the buttons list.
+ // The first three will always be from prepopulated data.
+ std::vector<const TemplateURL*> templateUrls =
+ searchEnginesModel_->GetTemplateURLs();
+
+ // If we have fewer than two search engines, end the search engine dialog
+ // immediately, leaving the imported default search engine setting intact.
+ if (templateUrls.size() < 2) {
+ return;
+ }
+
+ NSWindow* win = [self window];
+
+ [win setBackgroundColor:[NSColor whiteColor]];
+
+ NSImage* headerImage = ResourceBundle::GetSharedInstance().
+ GetNSImageNamed(IDR_SEARCH_ENGINE_DIALOG_TOP);
+ [headerImageView_ setImage:headerImage];
+
+ // Is the user's default search engine included in the first three
+ // prepopulated set? If not, we need to expand the dialog to include a fourth
+ // engine.
+ const TemplateURL* defaultSearchEngine =
+ searchEnginesModel_->GetDefaultSearchProvider();
+
+ std::vector<const TemplateURL*>::iterator engineIter =
+ templateUrls.begin();
+ for (int i = 0; engineIter != templateUrls.end(); ++i, ++engineIter) {
+ if (i < 3) {
+ choices_.push_back(*engineIter);
+ } else {
+ if (*engineIter == defaultSearchEngine)
+ choices_.push_back(*engineIter);
+ }
+ }
+
+ // Randomize the order of the logos if the option has been set.
+ if (randomize_) {
+ int seed = static_cast<int>(base::Time::Now().ToInternalValue());
+ srand(seed);
+ std::random_shuffle(choices_.begin(), choices_.end());
+ }
+
+ [self buildSearchEngineView];
+
+ // Display the dialog.
+ NSInteger choice = [NSApp runModalForWindow:win];
+ searchEnginesModel_->SetDefaultSearchProvider(choices_.at(choice));
+}
+
+- (void)buildSearchEngineView {
+ scoped_nsobject<NSMutableArray> searchEngineViews
+ ([[NSMutableArray alloc] init]);
+
+ for (size_t i = 0; i < choices_.size(); ++i)
+ [searchEngineViews addObject:[self viewForSearchEngine:choices_.at(i)
+ atIndex:i]];
+
+ NSSize newOverallSize = NSZeroSize;
+ for (NSView* view in searchEngineViews.get()) {
+ NSRect engineFrame = [view frame];
+ engineFrame.origin = NSMakePoint(newOverallSize.width, 0);
+ [searchEngineView_ addSubview:view];
+ [view setFrame:engineFrame];
+ newOverallSize = NSMakeSize(
+ newOverallSize.width + NSWidth(engineFrame) + kSearchEngineSpacing,
+ std::max(newOverallSize.height, NSHeight(engineFrame)));
+ }
+ newOverallSize.width -= kSearchEngineSpacing;
+
+ // Resize the window to fit (and because it's bound on all sides it will
+ // resize the search engine view).
+ NSSize currentOverallSize = [searchEngineView_ bounds].size;
+ NSSize deltaSize = NSMakeSize(
+ newOverallSize.width - currentOverallSize.width,
+ newOverallSize.height - currentOverallSize.height);
+ NSSize windowDeltaSize = [searchEngineView_ convertSize:deltaSize toView:nil];
+ NSRect windowFrame = [[self window] frame];
+ windowFrame.size.width += windowDeltaSize.width;
+ windowFrame.size.height += windowDeltaSize.height;
+ [[self window] setFrame:windowFrame display:NO];
+}
+
+- (NSView*)viewForSearchEngine:(const TemplateURL*)engine
+ atIndex:(size_t)index {
+ bool useImages = false;
+#if defined(GOOGLE_CHROME_BUILD)
+ useImages = true;
+#endif
+
+ // Make the engine identifier.
+ NSView* engineIdentifier = nil; // either the logo or the text label
+
+ int logoId = engine->logo_id();
+ if (useImages && logoId > 0) {
+ NSImage* logoImage =
+ ResourceBundle::GetSharedInstance().GetNSImageNamed(logoId);
+ NSRect logoBounds = NSZeroRect;
+ logoBounds.size = [logoImage size];
+ NSImageView* logoView =
+ [[[NSImageView alloc] initWithFrame:logoBounds] autorelease];
+ [logoView setImage:logoImage];
+ [logoView setEditable:NO];
+
+ // Tooltip text provides accessibility.
+ [logoView setToolTip:base::SysWideToNSString(engine->short_name())];
+ engineIdentifier = logoView;
+ } else {
+ // No logo -- we must show a text label.
+ NSRect labelBounds = NSMakeRect(0, 0, kLogoLabelWidth, kLogoLabelHeight);
+ NSTextField* labelField =
+ [[[NSTextField alloc] initWithFrame:labelBounds] autorelease];
+ [labelField setBezeled:NO];
+ [labelField setEditable:NO];
+ [labelField setSelectable:NO];
+
+ scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
+ [[NSMutableParagraphStyle alloc] init]);
+ [paragraphStyle setAlignment:NSCenterTextAlignment];
+ NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSFont boldSystemFontOfSize:13], NSFontAttributeName,
+ paragraphStyle.get(), NSParagraphStyleAttributeName,
+ nil];
+
+ NSString* value = base::SysWideToNSString(engine->short_name());
+ scoped_nsobject<NSAttributedString> attrValue(
+ [[NSAttributedString alloc] initWithString:value
+ attributes:attrs]);
+
+ [labelField setAttributedStringValue:attrValue.get()];
+
+ engineIdentifier = labelField;
+ }
+
+ // Make the "Choose" button.
+ scoped_nsobject<NSButton> chooseButton(
+ [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 34)]);
+ [chooseButton setBezelStyle:NSRoundedBezelStyle];
+ [[chooseButton cell] setFont:[NSFont systemFontOfSize:
+ [NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
+ [chooseButton setTitle:l10n_util::GetNSStringWithFixup(IDS_FR_SEARCH_CHOOSE)];
+ [GTMUILocalizerAndLayoutTweaker sizeToFitView:chooseButton.get()];
+ [chooseButton setTag:index];
+ [chooseButton setTarget:self];
+ [chooseButton setAction:@selector(searchEngineSelected:)];
+
+ // Put 'em together.
+ NSRect engineIdentifierFrame = [engineIdentifier frame];
+ NSRect chooseButtonFrame = [chooseButton frame];
+
+ NSRect containingViewFrame = NSZeroRect;
+ containingViewFrame.size.width += engineIdentifierFrame.size.width;
+ containingViewFrame.size.height += engineIdentifierFrame.size.height;
+ containingViewFrame.size.height += kLogoButtonSpacing;
+ containingViewFrame.size.height += chooseButtonFrame.size.height;
+
+ NSView* containingView =
+ [[[NSView alloc] initWithFrame:containingViewFrame] autorelease];
+
+ [containingView addSubview:engineIdentifier];
+ engineIdentifierFrame.origin.y =
+ chooseButtonFrame.size.height + kLogoButtonSpacing;
+ [engineIdentifier setFrame:engineIdentifierFrame];
+
+ [containingView addSubview:chooseButton];
+ chooseButtonFrame.origin.x =
+ int((containingViewFrame.size.width - chooseButtonFrame.size.width) / 2);
+ [chooseButton setFrame:chooseButtonFrame];
+
+ return containingView;
+}
+
+- (NSFont*)mainLabelFont {
+ return [NSFont boldSystemFontOfSize:13];
+}
+
+- (IBAction)searchEngineSelected:(id)sender {
+ [[self window] close];
+ [NSApp stopModalWithCode:[sender tag]];
+}
+
+@end
Property changes on: chrome/browser/cocoa/search_engine_dialog_controller.mm
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « chrome/browser/cocoa/search_engine_dialog_controller.h ('k') | chrome/browser/first_run/first_run.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698