- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / browser / edit_search_engine_cocoa_controller.mm
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/browser/edit_search_engine_cocoa_controller.h"
6
7 #include "base/logging.h"
8 #include "base/mac/bundle_locations.h"
9 #import "base/mac/mac_util.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "chrome/browser/search_engines/template_url.h"
13 #include "grit/generated_resources.h"
14 #include "grit/theme_resources.h"
15 #include "grit/ui_resources.h"
16 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
17 #include "ui/base/l10n/l10n_util_mac.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/image/image.h"
20
21 namespace {
22
23 void ShiftOriginY(NSView* view, CGFloat amount) {
24   NSPoint origin = [view frame].origin;
25   origin.y += amount;
26   [view setFrameOrigin:origin];
27 }
28
29 }  // namespace
30
31 @implementation EditSearchEngineCocoaController
32
33 - (id)initWithProfile:(Profile*)profile
34              delegate:(EditSearchEngineControllerDelegate*)delegate
35           templateURL:(TemplateURL*)url {
36   DCHECK(profile);
37   NSString* nibpath = [base::mac::FrameworkBundle()
38                         pathForResource:@"EditSearchEngine"
39                                  ofType:@"nib"];
40   if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
41     profile_ = profile;
42     templateURL_ = url;
43     controller_.reset(
44         new EditSearchEngineController(templateURL_, delegate, profile_));
45   }
46   return self;
47 }
48
49 - (void)awakeFromNib {
50   DCHECK([self window]);
51   DCHECK_EQ(self, [[self window] delegate]);
52
53   // Make sure the url description field fits the text in it.
54   CGFloat descriptionShift = [GTMUILocalizerAndLayoutTweaker
55       sizeToFitFixedWidthTextField:urlDescriptionField_];
56
57   // Move the label container above the url description.
58   ShiftOriginY(labelContainer_, descriptionShift);
59   // There was no way via view containment to use a helper view to move all
60   // the textfields and images at once, most move them all on their own so
61   // they stay above the url description.
62   ShiftOriginY(nameField_, descriptionShift);
63   ShiftOriginY(keywordField_, descriptionShift);
64   ShiftOriginY(urlField_, descriptionShift);
65   ShiftOriginY(nameImage_, descriptionShift);
66   ShiftOriginY(keywordImage_, descriptionShift);
67   ShiftOriginY(urlImage_, descriptionShift);
68
69   // Resize the containing box for the name/keyword/url fields/images since it
70   // also contains the url description (which just grew).
71   [[fieldAndImageContainer_ contentView] setAutoresizesSubviews:NO];
72   NSRect rect = [fieldAndImageContainer_ frame];
73   rect.size.height += descriptionShift;
74   [fieldAndImageContainer_ setFrame:rect];
75   [[fieldAndImageContainer_ contentView] setAutoresizesSubviews:YES];
76
77   // Resize the window.
78   NSWindow* window = [self window];
79   NSSize windowDelta = NSMakeSize(0, descriptionShift);
80   [GTMUILocalizerAndLayoutTweaker
81       resizeWindowWithoutAutoResizingSubViews:window
82                                         delta:windowDelta];
83
84   if (templateURL_) {
85     // Defaults to |..._NEW_WINDOW_TITLE|.
86     [window setTitle:l10n_util::GetNSString(
87       IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE)];
88     [nameField_ setStringValue:
89         base::SysUTF16ToNSString(templateURL_->short_name())];
90     [keywordField_ setStringValue:
91         base::SysUTF16ToNSString(templateURL_->keyword())];
92     [urlField_ setStringValue:
93         base::SysUTF16ToNSString(templateURL_->url_ref().DisplayURL())];
94     [urlField_ setEnabled:(templateURL_->prepopulate_id() == 0)];
95   }
96   // When creating a new keyword, this will mark the fields as "invalid" and
97   // will not let the user save. If this is an edit, then this will set all
98   // the images to the "valid" state.
99   [self validateFields];
100 }
101
102 // When the window closes, clean ourselves up.
103 - (void)windowWillClose:(NSNotification*)notif {
104   [self autorelease];
105 }
106
107 // Performs the logic of closing the window. If we are a sheet, then it ends the
108 // modal session; otherwise, it closes the window.
109 - (void)doClose {
110   if ([[self window] isSheet]) {
111     [NSApp endSheet:[self window]];
112   } else {
113     [[self window] close];
114   }
115 }
116
117 - (IBAction)cancel:(id)sender {
118   [self doClose];
119 }
120
121 - (IBAction)save:(id)sender {
122   DCHECK([self validateFields]);
123   string16 title = base::SysNSStringToUTF16([nameField_ stringValue]);
124   string16 keyword = base::SysNSStringToUTF16([keywordField_ stringValue]);
125   std::string url = base::SysNSStringToUTF8([urlField_ stringValue]);
126   controller_->AcceptAddOrEdit(title, keyword, url);
127   [self doClose];
128 }
129
130 // Delegate method for the text fields.
131
132 - (void)controlTextDidChange:(NSNotification*)notif {
133   [self validateFields];
134 }
135
136 - (void)controlTextDidEndEditing:(NSNotification*)notif {
137   [self validateFields];
138 }
139
140 // Private /////////////////////////////////////////////////////////////////////
141
142 // Sets the appropriate image and tooltip based on a boolean |valid|.
143 - (void)setIsValid:(BOOL)valid
144            toolTip:(int)messageID
145       forImageView:(NSImageView*)imageView
146          textField:(NSTextField*)textField {
147   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
148   NSImage* image = valid ? rb.GetNativeImageNamed(IDR_INPUT_GOOD).ToNSImage()
149                          : rb.GetNativeImageNamed(IDR_INPUT_ALERT).ToNSImage();
150   [imageView setImage:image];
151
152   NSString* toolTip = nil;
153   if (!valid)
154     toolTip = l10n_util::GetNSString(messageID);
155   [textField setToolTip:toolTip];
156   [imageView setToolTip:toolTip];
157 }
158
159 // This sets the image state for all the controls and enables or disables the
160 // done button. Returns YES if all the fields are valid.
161 - (BOOL)validateFields {
162   string16 title = base::SysNSStringToUTF16([nameField_ stringValue]);
163   BOOL titleValid = controller_->IsTitleValid(title);
164   [self setIsValid:titleValid
165            toolTip:IDS_SEARCH_ENGINES_INVALID_TITLE_TT
166       forImageView:nameImage_
167          textField:nameField_];
168
169   string16 keyword = base::SysNSStringToUTF16([keywordField_ stringValue]);
170   BOOL keywordValid = controller_->IsKeywordValid(keyword);
171   [self setIsValid:keywordValid
172            toolTip:IDS_SEARCH_ENGINES_INVALID_KEYWORD_TT
173       forImageView:keywordImage_
174          textField:keywordField_];
175
176   std::string url = base::SysNSStringToUTF8([urlField_ stringValue]);
177   BOOL urlValid = controller_->IsURLValid(url);
178   [self setIsValid:urlValid
179            toolTip:IDS_SEARCH_ENGINES_INVALID_URL_TT
180       forImageView:urlImage_
181          textField:urlField_];
182
183   BOOL isValid = (titleValid && keywordValid && urlValid);
184   [doneButton_ setEnabled:isValid];
185   return isValid;
186 }
187
188 @end