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

Side by Side Diff: chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm

Issue 10810062: Moving common code into OmniboxView from OmniboxView* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: public destructor Created 8 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h" 5 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
6 6
7 #include <Carbon/Carbon.h> // kVK_Return 7 #include <Carbon/Carbon.h> // kVK_Return
8 8
9 #include "base/property_bag.h" 9 #include "base/property_bag.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 11 matching lines...) Expand all
22 #include "grit/generated_resources.h" 22 #include "grit/generated_resources.h"
23 #include "grit/theme_resources.h" 23 #include "grit/theme_resources.h"
24 #import "third_party/mozilla/NSPasteboard+Utils.h" 24 #import "third_party/mozilla/NSPasteboard+Utils.h"
25 #include "ui/base/clipboard/clipboard.h" 25 #include "ui/base/clipboard/clipboard.h"
26 #include "ui/base/resource/resource_bundle.h" 26 #include "ui/base/resource/resource_bundle.h"
27 #include "ui/gfx/mac/nsimage_cache.h" 27 #include "ui/gfx/mac/nsimage_cache.h"
28 #include "ui/gfx/rect.h" 28 #include "ui/gfx/rect.h"
29 29
30 using content::WebContents; 30 using content::WebContents;
31 31
32 // Focus-handling between |field_| and |model_| is a bit subtle. 32 // Focus-handling between |field_| and |model()| is a bit subtle.
Peter Kasting 2012/07/26 23:03:24 Nit: Now that it's model() and not model_, the ||
dominich 2012/07/27 20:33:54 Done.
33 // Other platforms detect change of focus, which is inconvenient 33 // Other platforms detect change of focus, which is inconvenient
34 // without subclassing NSTextField (even with a subclass, the use of a 34 // without subclassing NSTextField (even with a subclass, the use of a
35 // field editor may complicate things). 35 // field editor may complicate things).
36 // 36 //
37 // |model_| doesn't actually do anything when it gains focus, it just 37 // |model()| doesn't actually do anything when it gains focus, it just
38 // initializes. Visible activity happens only after the user edits. 38 // initializes. Visible activity happens only after the user edits.
39 // NSTextField delegate receives messages around starting and ending 39 // NSTextField delegate receives messages around starting and ending
40 // edits, so that suffices to catch focus changes. Since all calls 40 // edits, so that suffices to catch focus changes. Since all calls
41 // into |model_| start from OmniboxViewMac, in the worst case 41 // into |model()| start from OmniboxViewMac, in the worst case
42 // we can add code to sync up the sense of focus as needed. 42 // we can add code to sync up the sense of focus as needed.
43 // 43 //
44 // I've added DCHECK(IsFirstResponder()) in the places which I believe 44 // I've added DCHECK(IsFirstResponder()) in the places which I believe
45 // should only be reachable when |field_| is being edited. If these 45 // should only be reachable when |field_| is being edited. If these
46 // fire, it probably means someone unexpected is calling into 46 // fire, it probably means someone unexpected is calling into
47 // |model_|. 47 // |model()|.
48 // 48 //
49 // Other platforms don't appear to have the sense of "key window" that 49 // Other platforms don't appear to have the sense of "key window" that
50 // Mac does (I believe their fields lose focus when the window loses 50 // Mac does (I believe their fields lose focus when the window loses
51 // focus). Rather than modifying focus outside the control's edit 51 // focus). Rather than modifying focus outside the control's edit
52 // scope, when the window resigns key the autocomplete popup is 52 // scope, when the window resigns key the autocomplete popup is
53 // closed. |model_| still believes it has focus, and the popup will 53 // closed. |model()| still believes it has focus, and the popup will
54 // be regenerated on the user's next edit. That seems to match how 54 // be regenerated on the user's next edit. That seems to match how
55 // things work on other platforms. 55 // things work on other platforms.
56 56
57 namespace { 57 namespace {
58 58
59 // TODO(shess): This is ugly, find a better way. Using it right now 59 // TODO(shess): This is ugly, find a better way. Using it right now
60 // so that I can crib from gtk and still be able to see that I'm using 60 // so that I can crib from gtk and still be able to see that I'm using
61 // the same values easily. 61 // the same values easily.
62 NSColor* ColorWithRGBBytes(int rr, int gg, int bb) { 62 NSColor* ColorWithRGBBytes(int rr, int gg, int bb) {
63 DCHECK_LE(rr, 255); 63 DCHECK_LE(rr, 255);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 NSImage* OmniboxViewMac::ImageForResource(int resource_id) { 132 NSImage* OmniboxViewMac::ImageForResource(int resource_id) {
133 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 133 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
134 return rb.GetNativeImageNamed(resource_id); 134 return rb.GetNativeImageNamed(resource_id);
135 } 135 }
136 136
137 OmniboxViewMac::OmniboxViewMac(OmniboxEditController* controller, 137 OmniboxViewMac::OmniboxViewMac(OmniboxEditController* controller,
138 ToolbarModel* toolbar_model, 138 ToolbarModel* toolbar_model,
139 Profile* profile, 139 Profile* profile,
140 CommandUpdater* command_updater, 140 CommandUpdater* command_updater,
141 AutocompleteTextField* field) 141 AutocompleteTextField* field)
142 : model_(new OmniboxEditModel(this, controller, profile)), 142 : OmniboxView(profile, controller, toolbar_model, command_updater),
143 popup_view_(new OmniboxPopupViewMac(this, model_.get(), field)), 143 popup_view_(new OmniboxPopupViewMac(this, model(), field)),
144 controller_(controller),
145 toolbar_model_(toolbar_model),
146 command_updater_(command_updater),
147 field_(field), 144 field_(field),
148 suggest_text_length_(0), 145 suggest_text_length_(0),
149 delete_was_pressed_(false), 146 delete_was_pressed_(false),
150 delete_at_end_pressed_(false), 147 delete_at_end_pressed_(false),
151 line_height_(0) { 148 line_height_(0) {
152 DCHECK(controller); 149 DCHECK(controller);
153 DCHECK(toolbar_model); 150 DCHECK(toolbar_model);
154 DCHECK(profile); 151 DCHECK(profile);
155 DCHECK(command_updater); 152 DCHECK(command_updater);
156 DCHECK(field); 153 DCHECK(field);
157 [field_ setObserver:this]; 154 [field_ setObserver:this];
158 155
159 // Needed so that editing doesn't lose the styling. 156 // Needed so that editing doesn't lose the styling.
160 [field_ setAllowsEditingTextAttributes:YES]; 157 [field_ setAllowsEditingTextAttributes:YES];
161 158
162 // Get the appropriate line height for the font that we use. 159 // Get the appropriate line height for the font that we use.
163 scoped_nsobject<NSLayoutManager> 160 scoped_nsobject<NSLayoutManager>
164 layoutManager([[NSLayoutManager alloc] init]); 161 layoutManager([[NSLayoutManager alloc] init]);
165 [layoutManager setUsesScreenFonts:YES]; 162 [layoutManager setUsesScreenFonts:YES];
166 line_height_ = [layoutManager defaultLineHeightForFont:GetFieldFont()]; 163 line_height_ = [layoutManager defaultLineHeightForFont:GetFieldFont()];
167 DCHECK_GT(line_height_, 0); 164 DCHECK_GT(line_height_, 0);
168 } 165 }
169 166
170 OmniboxViewMac::~OmniboxViewMac() { 167 OmniboxViewMac::~OmniboxViewMac() {
171 // Destroy popup view before this object in case it tries to call us 168 // Destroy popup view before this object in case it tries to call us
172 // back in the destructor. Likewise for destroying the model before 169 // back in the destructor. Likewise for destroying the model before
173 // this object. 170 // this object.
174 popup_view_.reset(); 171 popup_view_.reset();
175 model_.reset();
176 172
177 // Disconnect from |field_|, it outlives this object. 173 // Disconnect from |field_|, it outlives this object.
178 [field_ setObserver:NULL]; 174 [field_ setObserver:NULL];
179 } 175 }
180 176
181 OmniboxEditModel* OmniboxViewMac::model() {
182 return model_.get();
183 }
184
185 const OmniboxEditModel* OmniboxViewMac::model() const {
186 return model_.get();
187 }
188
189 void OmniboxViewMac::SaveStateToTab(WebContents* tab) { 177 void OmniboxViewMac::SaveStateToTab(WebContents* tab) {
190 DCHECK(tab); 178 DCHECK(tab);
191 179
192 const bool hasFocus = [field_ currentEditor] ? true : false; 180 const bool hasFocus = [field_ currentEditor] ? true : false;
193 181
194 NSRange range; 182 NSRange range;
195 if (hasFocus) { 183 if (hasFocus) {
196 range = GetSelectedRange(); 184 range = GetSelectedRange();
197 } else { 185 } else {
198 // If we are not focussed, there is no selection. Manufacture 186 // If we are not focussed, there is no selection. Manufacture
199 // something reasonable in case it starts to matter in the future. 187 // something reasonable in case it starts to matter in the future.
200 range = NSMakeRange(0, GetTextLength()); 188 range = NSMakeRange(0, GetTextLength());
201 } 189 }
202 190
203 OmniboxViewMacState state(model_->GetStateForTabSwitch(), hasFocus, range); 191 OmniboxViewMacState state(model()->GetStateForTabSwitch(), hasFocus, range);
204 StoreStateToTab(tab, state); 192 StoreStateToTab(tab, state);
205 } 193 }
206 194
207 void OmniboxViewMac::Update(const WebContents* tab_for_state_restoring) { 195 void OmniboxViewMac::Update(const WebContents* tab_for_state_restoring) {
208 // TODO(shess): It seems like if the tab is non-NULL, then this code 196 // TODO(shess): It seems like if the tab is non-NULL, then this code
209 // shouldn't need to be called at all. When coded that way, I find 197 // shouldn't need to be called at all. When coded that way, I find
210 // that the field isn't always updated correctly. Figure out why 198 // that the field isn't always updated correctly. Figure out why
211 // this is. Maybe this method should be refactored into more 199 // this is. Maybe this method should be refactored into more
212 // specific cases. 200 // specific cases.
213 bool user_visible = model_->UpdatePermanentText(toolbar_model_->GetText()); 201 bool user_visible = model()->UpdatePermanentText(toolbar_model()->GetText());
214 202
215 if (tab_for_state_restoring) { 203 if (tab_for_state_restoring) {
216 RevertAll(); 204 RevertAll();
217 205
218 const OmniboxViewMacState* state = GetStateFromTab(tab_for_state_restoring); 206 const OmniboxViewMacState* state = GetStateFromTab(tab_for_state_restoring);
219 if (state) { 207 if (state) {
220 // Should restore the user's text via SetUserText(). 208 // Should restore the user's text via SetUserText().
221 model_->RestoreState(state->model_state); 209 model()->RestoreState(state->model_state);
222 210
223 // Restore focus and selection if they were present when the tab 211 // Restore focus and selection if they were present when the tab
224 // was switched away. 212 // was switched away.
225 if (state->has_focus) { 213 if (state->has_focus) {
226 // TODO(shess): Unfortunately, there is no safe way to update 214 // TODO(shess): Unfortunately, there is no safe way to update
227 // this because TabStripController -selectTabWithContents:* is 215 // this because TabStripController -selectTabWithContents:* is
228 // also messing with focus. Both parties need to agree to 216 // also messing with focus. Both parties need to agree to
229 // store existing state before anyone tries to setup the new 217 // store existing state before anyone tries to setup the new
230 // state. Anyhow, it would look something like this. 218 // state. Anyhow, it would look something like this.
231 #if 0 219 #if 0
232 [[field_ window] makeFirstResponder:field_]; 220 [[field_ window] makeFirstResponder:field_];
233 [[field_ currentEditor] setSelectedRange:state->selection]; 221 [[field_ currentEditor] setSelectedRange:state->selection];
234 #endif 222 #endif
235 } 223 }
236 } 224 }
237 } else if (user_visible) { 225 } else if (user_visible) {
238 // Restore everything to the baseline look. 226 // Restore everything to the baseline look.
239 RevertAll(); 227 RevertAll();
240 // TODO(shess): Figure out how this case is used, to make sure 228 // TODO(shess): Figure out how this case is used, to make sure
241 // we're getting the selection and popup right. 229 // we're getting the selection and popup right.
242 230
243 } else { 231 } else {
244 // TODO(shess): This corresponds to _win and _gtk, except those 232 // TODO(shess): This corresponds to _win and _gtk, except those
245 // guard it with a test for whether the security level changed. 233 // guard it with a test for whether the security level changed.
246 // But AFAICT, that can only change if the text changed, and that 234 // But AFAICT, that can only change if the text changed, and that
247 // code compares the toolbar_model_ security level with the local 235 // code compares the toolbar_model() security level with the local
248 // security level. Dig in and figure out why this isn't a no-op 236 // security level. Dig in and figure out why this isn't a no-op
249 // that should go away. 237 // that should go away.
250 EmphasizeURLComponents(); 238 EmphasizeURLComponents();
251 } 239 }
252 } 240 }
253 241
254 void OmniboxViewMac::OpenMatch(const AutocompleteMatch& match,
255 WindowOpenDisposition disposition,
256 const GURL& alternate_nav_url,
257 size_t selected_line) {
258 // TODO(shess): Why is the caller passing an invalid url in the
259 // first place? Make sure that case isn't being dropped on the
260 // floor.
261 if (!match.destination_url.is_valid()) {
262 return;
263 }
264
265 model_->OpenMatch(match, disposition, alternate_nav_url, selected_line);
266 }
267
268 string16 OmniboxViewMac::GetText() const { 242 string16 OmniboxViewMac::GetText() const {
269 return base::SysNSStringToUTF16(GetNonSuggestTextSubstring()); 243 return base::SysNSStringToUTF16(GetNonSuggestTextSubstring());
270 } 244 }
271 245
272 bool OmniboxViewMac::IsEditingOrEmpty() const {
273 return model_->user_input_in_progress() || !GetTextLength();
274 }
275
276 int OmniboxViewMac::GetIcon() const {
277 return IsEditingOrEmpty() ?
278 AutocompleteMatch::TypeToIcon(model_->CurrentTextType()) :
279 toolbar_model_->GetIcon();
280 }
281
282 void OmniboxViewMac::SetUserText(const string16& text) {
283 SetUserText(text, text, true);
284 }
285
286 void OmniboxViewMac::SetUserText(const string16& text,
287 const string16& display_text,
288 bool update_popup) {
289 model_->SetUserText(text);
290 // TODO(shess): TODO below from gtk.
291 // TODO(deanm): something about selection / focus change here.
292 SetWindowTextAndCaretPos(display_text, display_text.length(), update_popup,
293 true);
294 }
295
296 NSRange OmniboxViewMac::GetSelectedRange() const { 246 NSRange OmniboxViewMac::GetSelectedRange() const {
297 return [[field_ currentEditor] selectedRange]; 247 return [[field_ currentEditor] selectedRange];
298 } 248 }
299 249
300 NSRange OmniboxViewMac::GetMarkedRange() const { 250 NSRange OmniboxViewMac::GetMarkedRange() const {
301 DCHECK([field_ currentEditor]); 251 DCHECK([field_ currentEditor]);
302 return [(NSTextView*)[field_ currentEditor] markedRange]; 252 return [(NSTextView*)[field_ currentEditor] markedRange];
303 } 253 }
304 254
305 void OmniboxViewMac::SetSelectedRange(const NSRange range) { 255 void OmniboxViewMac::SetSelectedRange(const NSRange range) {
306 // This can be called when we don't have focus. For instance, when 256 // This can be called when we don't have focus. For instance, when
307 // the user clicks the "Go" button. 257 // the user clicks the "Go" button.
308 if (model_->has_focus()) { 258 if (model()->has_focus()) {
309 // TODO(shess): If |model_| thinks we have focus, this should not 259 // TODO(shess): If |model()| thinks we have focus, this should not
310 // be necessary. Try to convert to DCHECK(IsFirstResponder()). 260 // be necessary. Try to convert to DCHECK(IsFirstResponder()).
311 if (![field_ currentEditor]) { 261 if (![field_ currentEditor]) {
312 [[field_ window] makeFirstResponder:field_]; 262 [[field_ window] makeFirstResponder:field_];
313 } 263 }
314 264
315 // TODO(shess): What if it didn't get first responder, and there is 265 // TODO(shess): What if it didn't get first responder, and there is
316 // no field editor? This will do nothing. Well, at least it won't 266 // no field editor? This will do nothing. Well, at least it won't
317 // crash. Think of something more productive to do, or prove that 267 // crash. Think of something more productive to do, or prove that
318 // it cannot occur and DCHECK appropriately. 268 // it cannot occur and DCHECK appropriately.
319 [[field_ currentEditor] setSelectedRange:range]; 269 [[field_ currentEditor] setSelectedRange:range];
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 // TODO(shess): Figure out what |reversed| implies. The gtk version 325 // TODO(shess): Figure out what |reversed| implies. The gtk version
376 // has it imply inverting the selection front to back, but I don't 326 // has it imply inverting the selection front to back, but I don't
377 // even know if that makes sense for Mac. 327 // even know if that makes sense for Mac.
378 328
379 // TODO(shess): Verify that we should be stealing focus at this 329 // TODO(shess): Verify that we should be stealing focus at this
380 // point. 330 // point.
381 SetSelectedRange(NSMakeRange(0, GetTextLength())); 331 SetSelectedRange(NSMakeRange(0, GetTextLength()));
382 } 332 }
383 333
384 void OmniboxViewMac::RevertAll() { 334 void OmniboxViewMac::RevertAll() {
385 ClosePopup(); 335 OmniboxView::RevertAll();
386 model_->Revert();
387 model_->OnChanged();
388 [field_ clearUndoChain]; 336 [field_ clearUndoChain];
389 } 337 }
390 338
391 void OmniboxViewMac::UpdatePopup() { 339 void OmniboxViewMac::UpdatePopup() {
392 model_->SetInputInProgress(true); 340 model()->SetInputInProgress(true);
393 if (!model_->has_focus()) 341 if (!model()->has_focus())
394 return; 342 return;
395 343
396 // Comment copied from OmniboxViewWin::UpdatePopup(): 344 // Comment copied from OmniboxViewWin::UpdatePopup():
397 // Don't inline autocomplete when: 345 // Don't inline autocomplete when:
398 // * The user is deleting text 346 // * The user is deleting text
399 // * The caret/selection isn't at the end of the text 347 // * The caret/selection isn't at the end of the text
400 // * The user has just pasted in something that replaced all the text 348 // * The user has just pasted in something that replaced all the text
401 // * The user is trying to compose something in an IME 349 // * The user is trying to compose something in an IME
402 bool prevent_inline_autocomplete = IsImeComposing(); 350 bool prevent_inline_autocomplete = IsImeComposing();
403 NSTextView* editor = (NSTextView*)[field_ currentEditor]; 351 NSTextView* editor = (NSTextView*)[field_ currentEditor];
404 if (editor) { 352 if (editor) {
405 if (NSMaxRange([editor selectedRange]) < 353 if (NSMaxRange([editor selectedRange]) <
406 [[editor textStorage] length] - suggest_text_length_) 354 [[editor textStorage] length] - suggest_text_length_)
407 prevent_inline_autocomplete = true; 355 prevent_inline_autocomplete = true;
408 } 356 }
409 357
410 model_->StartAutocomplete([editor selectedRange].length != 0, 358 model()->StartAutocomplete([editor selectedRange].length != 0,
411 prevent_inline_autocomplete); 359 prevent_inline_autocomplete);
412 } 360 }
413 361
414 void OmniboxViewMac::ClosePopup() {
415 model_->StopAutocomplete();
416 }
417
418 void OmniboxViewMac::SetFocus() { 362 void OmniboxViewMac::SetFocus() {
419 } 363 }
420 364
421 void OmniboxViewMac::SetText(const string16& display_text) { 365 void OmniboxViewMac::SetText(const string16& display_text) {
422 // If we are setting the text directly, there cannot be any suggest text. 366 // If we are setting the text directly, there cannot be any suggest text.
423 suggest_text_length_ = 0; 367 suggest_text_length_ = 0;
424 SetTextInternal(display_text); 368 SetTextInternal(display_text);
425 } 369 }
426 370
427 void OmniboxViewMac::SetTextInternal(const string16& display_text) { 371 void OmniboxViewMac::SetTextInternal(const string16& display_text) {
428 NSString* ss = base::SysUTF16ToNSString(display_text); 372 NSString* ss = base::SysUTF16ToNSString(display_text);
429 NSMutableAttributedString* as = 373 NSMutableAttributedString* as =
430 [[[NSMutableAttributedString alloc] initWithString:ss] autorelease]; 374 [[[NSMutableAttributedString alloc] initWithString:ss] autorelease];
431 375
432 ApplyTextAttributes(display_text, as); 376 ApplyTextAttributes(display_text, as);
433 377
434 [field_ setAttributedStringValue:as]; 378 [field_ setAttributedStringValue:as];
435 379
436 // TODO(shess): This may be an appropriate place to call: 380 // TODO(shess): This may be an appropriate place to call:
437 // model_->OnChanged(); 381 // model()->OnChanged();
438 // In the current implementation, this tells LocationBarViewMac to 382 // In the current implementation, this tells LocationBarViewMac to
439 // mess around with |model_| and update |field_|. Unfortunately, 383 // mess around with |model()| and update |field_|. Unfortunately,
440 // when I look at our peer implementations, it's not entirely clear 384 // when I look at our peer implementations, it's not entirely clear
441 // to me if this is safe. SetTextInternal() is sort of an utility method, 385 // to me if this is safe. SetTextInternal() is sort of an utility method,
442 // and different callers sometimes have different needs. Research 386 // and different callers sometimes have different needs. Research
443 // this issue so that it can be added safely. 387 // this issue so that it can be added safely.
444 388
445 // TODO(shess): Also, consider whether this code couldn't just 389 // TODO(shess): Also, consider whether this code couldn't just
446 // manage things directly. Windows uses a series of overlaid view 390 // manage things directly. Windows uses a series of overlaid view
447 // objects to accomplish the hinting stuff that OnChanged() does, so 391 // objects to accomplish the hinting stuff that OnChanged() does, so
448 // it makes sense to have it in the controller that lays those 392 // it makes sense to have it in the controller that lays those
449 // things out. Mac instead pushes the support into a custom 393 // things out. Mac instead pushes the support into a custom
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 [storage setAttributes:[NSDictionary dictionary] 434 [storage setAttributes:[NSDictionary dictionary]
491 range:NSMakeRange(0, [storage length])]; 435 range:NSMakeRange(0, [storage length])];
492 ApplyTextAttributes(GetText(), storage); 436 ApplyTextAttributes(GetText(), storage);
493 437
494 [storage endEditing]; 438 [storage endEditing];
495 } else { 439 } else {
496 SetText(GetText()); 440 SetText(GetText());
497 } 441 }
498 } 442 }
499 443
500 void OmniboxViewMac::TextChanged() {
501 EmphasizeURLComponents();
502 model_->OnChanged();
503 }
504
505 void OmniboxViewMac::ApplyTextAttributes(const string16& display_text, 444 void OmniboxViewMac::ApplyTextAttributes(const string16& display_text,
506 NSMutableAttributedString* as) { 445 NSMutableAttributedString* as) {
507 NSUInteger as_length = [as length]; 446 NSUInteger as_length = [as length];
508 NSRange as_entire_string = NSMakeRange(0, as_length); 447 NSRange as_entire_string = NSMakeRange(0, as_length);
509 448
510 [as addAttribute:NSFontAttributeName value:GetFieldFont() 449 [as addAttribute:NSFontAttributeName value:GetFieldFont()
511 range:as_entire_string]; 450 range:as_entire_string];
512 451
513 // A kinda hacky way to add breaking at periods. This is what Safari does. 452 // A kinda hacky way to add breaking at periods. This is what Safari does.
514 // This works for IDNs too, despite the "en_US". 453 // This works for IDNs too, despite the "en_US".
515 [as addAttribute:@"NSLanguage" value:@"en_US_POSIX" 454 [as addAttribute:@"NSLanguage" value:@"en_US_POSIX"
516 range:as_entire_string]; 455 range:as_entire_string];
517 456
518 // Make a paragraph style locking in the standard line height as the maximum, 457 // Make a paragraph style locking in the standard line height as the maximum,
519 // otherwise the baseline may shift "downwards". 458 // otherwise the baseline may shift "downwards".
520 scoped_nsobject<NSMutableParagraphStyle> 459 scoped_nsobject<NSMutableParagraphStyle>
521 paragraph_style([[NSMutableParagraphStyle alloc] init]); 460 paragraph_style([[NSMutableParagraphStyle alloc] init]);
522 [paragraph_style setMaximumLineHeight:line_height_]; 461 [paragraph_style setMaximumLineHeight:line_height_];
523 [as addAttribute:NSParagraphStyleAttributeName value:paragraph_style 462 [as addAttribute:NSParagraphStyleAttributeName value:paragraph_style
524 range:as_entire_string]; 463 range:as_entire_string];
525 464
526 // Grey out the suggest text. 465 // Grey out the suggest text.
527 [as addAttribute:NSForegroundColorAttributeName value:SuggestTextColor() 466 [as addAttribute:NSForegroundColorAttributeName value:SuggestTextColor()
528 range:NSMakeRange(as_length - suggest_text_length_, 467 range:NSMakeRange(as_length - suggest_text_length_,
529 suggest_text_length_)]; 468 suggest_text_length_)];
530 469
531 url_parse::Component scheme, host; 470 url_parse::Component scheme, host;
532 AutocompleteInput::ParseForEmphasizeComponents( 471 AutocompleteInput::ParseForEmphasizeComponents(
533 display_text, model_->GetDesiredTLD(), &scheme, &host); 472 display_text, model()->GetDesiredTLD(), &scheme, &host);
534 const bool emphasize = model_->CurrentTextIsURL() && (host.len > 0); 473 const bool emphasize = model()->CurrentTextIsURL() && (host.len > 0);
535 if (emphasize) { 474 if (emphasize) {
536 [as addAttribute:NSForegroundColorAttributeName value:BaseTextColor() 475 [as addAttribute:NSForegroundColorAttributeName value:BaseTextColor()
537 range:as_entire_string]; 476 range:as_entire_string];
538 477
539 [as addAttribute:NSForegroundColorAttributeName value:HostTextColor() 478 [as addAttribute:NSForegroundColorAttributeName value:HostTextColor()
540 range:ComponentToNSRange(host)]; 479 range:ComponentToNSRange(host)];
541 } 480 }
542 481
543 // TODO(shess): GTK has this as a member var, figure out why. 482 // TODO(shess): GTK has this as a member var, figure out why.
544 // [Could it be to not change if no change? If so, I'm guessing 483 // [Could it be to not change if no change? If so, I'm guessing
545 // AppKit may already handle that.] 484 // AppKit may already handle that.]
546 const ToolbarModel::SecurityLevel security_level = 485 const ToolbarModel::SecurityLevel security_level =
547 toolbar_model_->GetSecurityLevel(); 486 toolbar_model()->GetSecurityLevel();
548 487
549 // Emphasize the scheme for security UI display purposes (if necessary). 488 // Emphasize the scheme for security UI display purposes (if necessary).
550 if (!model_->user_input_in_progress() && scheme.is_nonempty() && 489 if (!model()->user_input_in_progress() && scheme.is_nonempty() &&
551 (security_level != ToolbarModel::NONE)) { 490 (security_level != ToolbarModel::NONE)) {
552 NSColor* color; 491 NSColor* color;
553 if (security_level == ToolbarModel::EV_SECURE || 492 if (security_level == ToolbarModel::EV_SECURE ||
554 security_level == ToolbarModel::SECURE) { 493 security_level == ToolbarModel::SECURE) {
555 color = SecureSchemeColor(); 494 color = SecureSchemeColor();
556 } else if (security_level == ToolbarModel::SECURITY_ERROR) { 495 } else if (security_level == ToolbarModel::SECURITY_ERROR) {
557 color = SecurityErrorSchemeColor(); 496 color = SecurityErrorSchemeColor();
558 // Add a strikethrough through the scheme. 497 // Add a strikethrough through the scheme.
559 [as addAttribute:NSStrikethroughStyleAttributeName 498 [as addAttribute:NSStrikethroughStyleAttributeName
560 value:[NSNumber numberWithInt:NSUnderlineStyleSingle] 499 value:[NSNumber numberWithInt:NSUnderlineStyleSingle]
561 range:ComponentToNSRange(scheme)]; 500 range:ComponentToNSRange(scheme)];
562 } else if (security_level == ToolbarModel::SECURITY_WARNING) { 501 } else if (security_level == ToolbarModel::SECURITY_WARNING) {
563 color = BaseTextColor(); 502 color = BaseTextColor();
564 } else { 503 } else {
565 NOTREACHED(); 504 NOTREACHED();
566 color = BaseTextColor(); 505 color = BaseTextColor();
567 } 506 }
568 [as addAttribute:NSForegroundColorAttributeName value:color 507 [as addAttribute:NSForegroundColorAttributeName value:color
569 range:ComponentToNSRange(scheme)]; 508 range:ComponentToNSRange(scheme)];
570 } 509 }
571 } 510 }
572 511
573 void OmniboxViewMac::OnTemporaryTextMaybeChanged(const string16& display_text, 512 void OmniboxViewMac::OnTemporaryTextMaybeChanged(const string16& display_text,
574 bool save_original_selection) { 513 bool save_original_selection) {
575 if (save_original_selection) 514 if (save_original_selection)
576 saved_temporary_selection_ = GetSelectedRange(); 515 saved_temporary_selection_ = GetSelectedRange();
577 516
578 suggest_text_length_ = 0; 517 suggest_text_length_ = 0;
579 SetWindowTextAndCaretPos(display_text, display_text.size(), false, false); 518 SetWindowTextAndCaretPos(display_text, display_text.size(), false, false);
580 model_->OnChanged(); 519 model()->OnChanged();
581 [field_ clearUndoChain]; 520 [field_ clearUndoChain];
582 } 521 }
583 522
584 void OmniboxViewMac::OnStartingIME() { 523 void OmniboxViewMac::OnStartingIME() {
585 // Reset the suggest text just before starting an IME composition session, 524 // Reset the suggest text just before starting an IME composition session,
586 // otherwise the IME composition may be interrupted when the suggest text 525 // otherwise the IME composition may be interrupted when the suggest text
587 // gets reset by the IME composition change. 526 // gets reset by the IME composition change.
588 SetInstantSuggestion(string16(), false); 527 SetInstantSuggestion(string16(), false);
589 } 528 }
590 529
591 bool OmniboxViewMac::OnInlineAutocompleteTextMaybeChanged( 530 bool OmniboxViewMac::OnInlineAutocompleteTextMaybeChanged(
592 const string16& display_text, 531 const string16& display_text,
593 size_t user_text_length) { 532 size_t user_text_length) {
594 // TODO(shess): Make sure that this actually works. The round trip 533 // TODO(shess): Make sure that this actually works. The round trip
595 // to native form and back may mean that it's the same but not the 534 // to native form and back may mean that it's the same but not the
596 // same. 535 // same.
597 if (display_text == GetText()) 536 if (display_text == GetText())
598 return false; 537 return false;
599 538
600 DCHECK_LE(user_text_length, display_text.size()); 539 DCHECK_LE(user_text_length, display_text.size());
601 const NSRange range = 540 const NSRange range =
602 NSMakeRange(user_text_length, display_text.size() - user_text_length); 541 NSMakeRange(user_text_length, display_text.size() - user_text_length);
603 SetTextAndSelectedRange(display_text, range); 542 SetTextAndSelectedRange(display_text, range);
604 model_->OnChanged(); 543 model()->OnChanged();
605 [field_ clearUndoChain]; 544 [field_ clearUndoChain];
606 545
607 return true; 546 return true;
608 } 547 }
609 548
610 void OmniboxViewMac::OnRevertTemporaryText() { 549 void OmniboxViewMac::OnRevertTemporaryText() {
611 SetSelectedRange(saved_temporary_selection_); 550 SetSelectedRange(saved_temporary_selection_);
612 } 551 }
613 552
614 bool OmniboxViewMac::IsFirstResponder() const { 553 bool OmniboxViewMac::IsFirstResponder() const {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 // TODO(shess): In our implementation, we can catch -deleteBackward: 587 // TODO(shess): In our implementation, we can catch -deleteBackward:
649 // and other methods to provide positive knowledge that a delete 588 // and other methods to provide positive knowledge that a delete
650 // occured, rather than intuiting it from context. Consider whether 589 // occured, rather than intuiting it from context. Consider whether
651 // that would be a stronger approach. 590 // that would be a stronger approach.
652 const bool just_deleted_text = 591 const bool just_deleted_text =
653 (length < text_before_change_.length() && 592 (length < text_before_change_.length() &&
654 new_selection.location <= selection_before_change_.location); 593 new_selection.location <= selection_before_change_.location);
655 594
656 delete_at_end_pressed_ = false; 595 delete_at_end_pressed_ = false;
657 596
658 const bool something_changed = model_->OnAfterPossibleChange( 597 const bool something_changed = model()->OnAfterPossibleChange(
659 text_before_change_, new_text, new_selection.location, 598 text_before_change_, new_text, new_selection.location,
660 NSMaxRange(new_selection), selection_differs, text_differs, 599 NSMaxRange(new_selection), selection_differs, text_differs,
661 just_deleted_text, !IsImeComposing()); 600 just_deleted_text, !IsImeComposing());
662 601
663 if (delete_was_pressed_ && at_end_of_edit) 602 if (delete_was_pressed_ && at_end_of_edit)
664 delete_at_end_pressed_ = true; 603 delete_at_end_pressed_ = true;
665 604
666 // Restyle in case the user changed something. 605 // Restyle in case the user changed something.
667 // TODO(shess): I believe there are multiple-redraw cases, here. 606 // TODO(shess): I believe there are multiple-redraw cases, here.
668 // Linux watches for something_changed && text_differs, but that 607 // Linux watches for something_changed && text_differs, but that
669 // fails for us in case you copy the URL and paste the identical URL 608 // fails for us in case you copy the URL and paste the identical URL
670 // back (we'll lose the styling). 609 // back (we'll lose the styling).
671 TextChanged(); 610 TextChanged();
672 611
673 delete_was_pressed_ = false; 612 delete_was_pressed_ = false;
674 613
675 return something_changed; 614 return something_changed;
676 } 615 }
677 616
678 gfx::NativeView OmniboxViewMac::GetNativeView() const { 617 gfx::NativeView OmniboxViewMac::GetNativeView() const {
679 return field_; 618 return field_;
680 } 619 }
681 620
682 gfx::NativeView OmniboxViewMac::GetRelativeWindowForPopup() const { 621 gfx::NativeView OmniboxViewMac::GetRelativeWindowForPopup() const {
683 // Not used on mac. 622 // Not used on mac.
684 NOTREACHED(); 623 NOTREACHED();
685 return NULL; 624 return NULL;
686 } 625 }
687 626
688 CommandUpdater* OmniboxViewMac::GetCommandUpdater() {
689 return command_updater_;
690 }
691
692 void OmniboxViewMac::SetInstantSuggestion(const string16& suggest_text, 627 void OmniboxViewMac::SetInstantSuggestion(const string16& suggest_text,
693 bool animate_to_complete) { 628 bool animate_to_complete) {
694 NSString* text = GetNonSuggestTextSubstring(); 629 NSString* text = GetNonSuggestTextSubstring();
695 bool needs_update = (suggest_text_length_ > 0); 630 bool needs_update = (suggest_text_length_ > 0);
696 631
697 // Append the new suggest text. 632 // Append the new suggest text.
698 suggest_text_length_ = suggest_text.length(); 633 suggest_text_length_ = suggest_text.length();
699 if (suggest_text_length_ > 0) { 634 if (suggest_text_length_ > 0) {
700 text = [text stringByAppendingString:base::SysUTF16ToNSString( 635 text = [text stringByAppendingString:base::SysUTF16ToNSString(
701 suggest_text)]; 636 suggest_text)];
(...skipping 29 matching lines...) Expand all
731 // We should only arrive here when the field is focussed. 666 // We should only arrive here when the field is focussed.
732 DCHECK([field_ currentEditor]); 667 DCHECK([field_ currentEditor]);
733 } 668 }
734 669
735 void OmniboxViewMac::OnBeforeChange() { 670 void OmniboxViewMac::OnBeforeChange() {
736 // Capture the current state. 671 // Capture the current state.
737 OnBeforePossibleChange(); 672 OnBeforePossibleChange();
738 } 673 }
739 674
740 void OmniboxViewMac::OnDidChange() { 675 void OmniboxViewMac::OnDidChange() {
741 // Figure out what changed and notify the model_. 676 // Figure out what changed and notify the model().
Peter Kasting 2012/07/26 23:03:24 Nit: This should probably not have parens.
dominich 2012/07/27 20:33:54 Done.
742 OnAfterPossibleChange(); 677 OnAfterPossibleChange();
743 } 678 }
744 679
745 void OmniboxViewMac::OnDidEndEditing() { 680 void OmniboxViewMac::OnDidEndEditing() {
746 ClosePopup(); 681 ClosePopup();
747 } 682 }
748 683
749 bool OmniboxViewMac::OnDoCommandBySelector(SEL cmd) { 684 bool OmniboxViewMac::OnDoCommandBySelector(SEL cmd) {
750 // We should only arrive here when the field is focussed. 685 // We should only arrive here when the field is focussed.
751 DCHECK(IsFirstResponder()); 686 DCHECK(IsFirstResponder());
752 687
753 if (cmd != @selector(moveRight:) && 688 if (cmd != @selector(moveRight:) &&
754 cmd != @selector(insertTab:) && 689 cmd != @selector(insertTab:) &&
755 cmd != @selector(insertTabIgnoringFieldEditor:)) { 690 cmd != @selector(insertTabIgnoringFieldEditor:)) {
756 // Reset the suggest text for any change other than key right or tab. 691 // Reset the suggest text for any change other than key right or tab.
757 // TODO(rohitrao): This is here to prevent complications when editing text. 692 // TODO(rohitrao): This is here to prevent complications when editing text.
758 // See if this can be removed. 693 // See if this can be removed.
759 SetInstantSuggestion(string16(), false); 694 SetInstantSuggestion(string16(), false);
760 } 695 }
761 696
762 if (cmd == @selector(deleteForward:)) 697 if (cmd == @selector(deleteForward:))
763 delete_was_pressed_ = true; 698 delete_was_pressed_ = true;
764 699
765 // Don't intercept up/down-arrow or backtab if the popup isn't open. 700 // Don't intercept up/down-arrow or backtab if the popup isn't open.
766 if (popup_view_->IsOpen()) { 701 if (popup_view_->IsOpen()) {
767 if (cmd == @selector(moveDown:)) { 702 if (cmd == @selector(moveDown:)) {
768 model_->OnUpOrDownKeyPressed(1); 703 model()->OnUpOrDownKeyPressed(1);
769 return true; 704 return true;
770 } 705 }
771 706
772 if (cmd == @selector(moveUp:)) { 707 if (cmd == @selector(moveUp:)) {
773 model_->OnUpOrDownKeyPressed(-1); 708 model()->OnUpOrDownKeyPressed(-1);
774 return true; 709 return true;
775 } 710 }
776 711
777 if (cmd == @selector(insertBacktab:) && 712 if (cmd == @selector(insertBacktab:) &&
778 model_->popup_model()->selected_line_state() == 713 model()->popup_model()->selected_line_state() ==
779 OmniboxPopupModel::KEYWORD) { 714 OmniboxPopupModel::KEYWORD) {
780 model_->ClearKeyword(GetText()); 715 model()->ClearKeyword(GetText());
781 return true; 716 return true;
782 } 717 }
783 } 718 }
784 719
785 if (cmd == @selector(moveRight:)) { 720 if (cmd == @selector(moveRight:)) {
786 // Only commit suggested text if the cursor is all the way to the right and 721 // Only commit suggested text if the cursor is all the way to the right and
787 // there is no selection. 722 // there is no selection.
788 if (suggest_text_length_ > 0 && IsCaretAtEnd()) { 723 if (suggest_text_length_ > 0 && IsCaretAtEnd()) {
789 model_->CommitSuggestedText(true); 724 model()->CommitSuggestedText(true);
790 return true; 725 return true;
791 } 726 }
792 } 727 }
793 728
794 if (cmd == @selector(scrollPageDown:)) { 729 if (cmd == @selector(scrollPageDown:)) {
795 model_->OnUpOrDownKeyPressed(model_->result().size()); 730 model()->OnUpOrDownKeyPressed(model()->result().size());
796 return true; 731 return true;
797 } 732 }
798 733
799 if (cmd == @selector(scrollPageUp:)) { 734 if (cmd == @selector(scrollPageUp:)) {
800 model_->OnUpOrDownKeyPressed(-model_->result().size()); 735 model()->OnUpOrDownKeyPressed(-model()->result().size());
801 return true; 736 return true;
802 } 737 }
803 738
804 if (cmd == @selector(cancelOperation:)) { 739 if (cmd == @selector(cancelOperation:)) {
805 return model_->OnEscapeKeyPressed(); 740 return model()->OnEscapeKeyPressed();
806 } 741 }
807 742
808 if ((cmd == @selector(insertTab:) || 743 if ((cmd == @selector(insertTab:) ||
809 cmd == @selector(insertTabIgnoringFieldEditor:)) && 744 cmd == @selector(insertTabIgnoringFieldEditor:)) &&
810 model_->is_keyword_hint()) { 745 model()->is_keyword_hint()) {
811 return model_->AcceptKeyword(); 746 return model()->AcceptKeyword();
812 } 747 }
813 748
814 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op 749 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op
815 // behavior with the proper WindowOpenDisposition. 750 // behavior with the proper WindowOpenDisposition.
816 NSEvent* event = [NSApp currentEvent]; 751 NSEvent* event = [NSApp currentEvent];
817 if (cmd == @selector(insertNewline:) || 752 if (cmd == @selector(insertNewline:) ||
818 (cmd == @selector(noop:) && 753 (cmd == @selector(noop:) &&
819 ([event type] == NSKeyDown || [event type] == NSKeyUp) && 754 ([event type] == NSKeyDown || [event type] == NSKeyUp) &&
820 [event keyCode] == kVK_Return)) { 755 [event keyCode] == kVK_Return)) {
821 WindowOpenDisposition disposition = 756 WindowOpenDisposition disposition =
822 event_utils::WindowOpenDispositionFromNSEvent(event); 757 event_utils::WindowOpenDispositionFromNSEvent(event);
823 model_->AcceptInput(disposition, false); 758 model()->AcceptInput(disposition, false);
824 // Opening a URL in a background tab should also revert the omnibox contents 759 // Opening a URL in a background tab should also revert the omnibox contents
825 // to their original state. We cannot do a blanket revert in OpenURL() 760 // to their original state. We cannot do a blanket revert in OpenURL()
826 // because middle-clicks also open in a new background tab, but those should 761 // because middle-clicks also open in a new background tab, but those should
827 // not revert the omnibox text. 762 // not revert the omnibox text.
828 RevertAll(); 763 RevertAll();
829 return true; 764 return true;
830 } 765 }
831 766
832 // Option-Return 767 // Option-Return
833 if (cmd == @selector(insertNewlineIgnoringFieldEditor:)) { 768 if (cmd == @selector(insertNewlineIgnoringFieldEditor:)) {
834 model_->AcceptInput(NEW_FOREGROUND_TAB, false); 769 model()->AcceptInput(NEW_FOREGROUND_TAB, false);
835 return true; 770 return true;
836 } 771 }
837 772
838 // When the user does Control-Enter, the existing content has "www." 773 // When the user does Control-Enter, the existing content has "www."
839 // prepended and ".com" appended. |model_| should already have 774 // prepended and ".com" appended. |model()| should already have
840 // received notification when the Control key was depressed, but it 775 // received notification when the Control key was depressed, but it
841 // is safe to tell it twice. 776 // is safe to tell it twice.
842 if (cmd == @selector(insertLineBreak:)) { 777 if (cmd == @selector(insertLineBreak:)) {
843 OnControlKeyChanged(true); 778 OnControlKeyChanged(true);
844 WindowOpenDisposition disposition = 779 WindowOpenDisposition disposition =
845 event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); 780 event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
846 model_->AcceptInput(disposition, false); 781 model()->AcceptInput(disposition, false);
847 return true; 782 return true;
848 } 783 }
849 784
850 if (cmd == @selector(deleteBackward:)) { 785 if (cmd == @selector(deleteBackward:)) {
851 if (OnBackspacePressed()) { 786 if (OnBackspacePressed()) {
852 return true; 787 return true;
853 } 788 }
854 } 789 }
855 790
856 if (cmd == @selector(deleteForward:)) { 791 if (cmd == @selector(deleteForward:)) {
857 const NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; 792 const NSUInteger modifiers = [[NSApp currentEvent] modifierFlags];
858 if ((modifiers & NSShiftKeyMask) != 0) { 793 if ((modifiers & NSShiftKeyMask) != 0) {
859 if (model_->popup_model()->IsOpen()) { 794 if (model()->popup_model()->IsOpen()) {
860 model_->popup_model()->TryDeletingCurrentItem(); 795 model()->popup_model()->TryDeletingCurrentItem();
861 return true; 796 return true;
862 } 797 }
863 } 798 }
864 } 799 }
865 800
866 return false; 801 return false;
867 } 802 }
868 803
869 void OmniboxViewMac::OnSetFocus(bool control_down) { 804 void OmniboxViewMac::OnSetFocus(bool control_down) {
870 model_->OnSetFocus(control_down); 805 model()->OnSetFocus(control_down);
871 controller_->OnSetFocus(); 806 controller()->OnSetFocus();
872 } 807 }
873 808
874 void OmniboxViewMac::OnKillFocus() { 809 void OmniboxViewMac::OnKillFocus() {
875 // Tell the model to reset itself. 810 // Tell the model to reset itself.
876 model_->OnWillKillFocus(NULL); 811 model()->OnWillKillFocus(NULL);
877 model_->OnKillFocus(); 812 model()->OnKillFocus();
878 controller_->OnKillFocus(); 813 controller()->OnKillFocus();
879 } 814 }
880 815
881 bool OmniboxViewMac::CanCopy() { 816 bool OmniboxViewMac::CanCopy() {
882 const NSRange selection = GetSelectedRange(); 817 const NSRange selection = GetSelectedRange();
883 return selection.length > 0; 818 return selection.length > 0;
884 } 819 }
885 820
886 void OmniboxViewMac::CopyToPasteboard(NSPasteboard* pb) { 821 void OmniboxViewMac::CopyToPasteboard(NSPasteboard* pb) {
887 DCHECK(CanCopy()); 822 DCHECK(CanCopy());
888 823
889 const NSRange selection = GetSelectedRange(); 824 const NSRange selection = GetSelectedRange();
890 string16 text = base::SysNSStringToUTF16( 825 string16 text = base::SysNSStringToUTF16(
891 [[field_ stringValue] substringWithRange:selection]); 826 [[field_ stringValue] substringWithRange:selection]);
892 827
893 GURL url; 828 GURL url;
894 bool write_url = false; 829 bool write_url = false;
895 model_->AdjustTextForCopy(selection.location, IsSelectAll(), &text, &url, 830 model()->AdjustTextForCopy(selection.location, IsSelectAll(), &text, &url,
896 &write_url); 831 &write_url);
897 832
898 NSString* nstext = base::SysUTF16ToNSString(text); 833 NSString* nstext = base::SysUTF16ToNSString(text);
899 [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; 834 [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
900 [pb setString:nstext forType:NSStringPboardType]; 835 [pb setString:nstext forType:NSStringPboardType];
901 836
902 if (write_url) { 837 if (write_url) {
903 [pb declareURLPasteboardWithAdditionalTypes:[NSArray array] owner:nil]; 838 [pb declareURLPasteboardWithAdditionalTypes:[NSArray array] owner:nil];
904 [pb setDataForURL:base::SysUTF8ToNSString(url.spec()) title:nstext]; 839 [pb setDataForURL:base::SysUTF8ToNSString(url.spec()) title:nstext];
905 } 840 }
(...skipping 12 matching lines...) Expand all
918 // -shouldChangeTextInRange:* and -didChangeText are documented in 853 // -shouldChangeTextInRange:* and -didChangeText are documented in
919 // NSTextView as things you need to do if you write additional 854 // NSTextView as things you need to do if you write additional
920 // user-initiated editing functions. They cause the appropriate 855 // user-initiated editing functions. They cause the appropriate
921 // delegate methods to be called. 856 // delegate methods to be called.
922 // TODO(shess): It would be nice to separate the Cocoa-specific code 857 // TODO(shess): It would be nice to separate the Cocoa-specific code
923 // from the Chrome-specific code. 858 // from the Chrome-specific code.
924 NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]); 859 NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]);
925 const NSRange selectedRange = GetSelectedRange(); 860 const NSRange selectedRange = GetSelectedRange();
926 if ([editor shouldChangeTextInRange:selectedRange replacementString:s]) { 861 if ([editor shouldChangeTextInRange:selectedRange replacementString:s]) {
927 // Record this paste, so we can do different behavior. 862 // Record this paste, so we can do different behavior.
928 model_->on_paste(); 863 model()->on_paste();
929 864
930 // Force a Paste operation to trigger the text_changed code in 865 // Force a Paste operation to trigger the text_changed code in
931 // OnAfterPossibleChange(), even if identical contents are pasted 866 // OnAfterPossibleChange(), even if identical contents are pasted
932 // into the text box. 867 // into the text box.
933 text_before_change_.clear(); 868 text_before_change_.clear();
934 869
935 [editor replaceCharactersInRange:selectedRange withString:s]; 870 [editor replaceCharactersInRange:selectedRange withString:s];
936 [editor didChangeText]; 871 [editor didChangeText];
937 } 872 }
938 } 873 }
939 874
940 bool OmniboxViewMac::CanPasteAndGo() { 875 bool OmniboxViewMac::CanPasteAndGo() {
941 return model_->CanPasteAndGo(GetClipboardText()); 876 return model()->CanPasteAndGo(GetClipboardText());
942 } 877 }
943 878
944 int OmniboxViewMac::GetPasteActionStringId() { 879 int OmniboxViewMac::GetPasteActionStringId() {
945 string16 text(GetClipboardText()); 880 string16 text(GetClipboardText());
946 DCHECK(model_->CanPasteAndGo(text)); 881 DCHECK(model()->CanPasteAndGo(text));
947 return model_->IsPasteAndSearch(GetClipboardText()) ? 882 return model()->IsPasteAndSearch(GetClipboardText()) ?
948 IDS_PASTE_AND_SEARCH : IDS_PASTE_AND_GO; 883 IDS_PASTE_AND_SEARCH : IDS_PASTE_AND_GO;
949 } 884 }
950 885
951 void OmniboxViewMac::OnPasteAndGo() { 886 void OmniboxViewMac::OnPasteAndGo() {
952 string16 text(GetClipboardText()); 887 string16 text(GetClipboardText());
953 if (model_->CanPasteAndGo(text)) 888 if (model()->CanPasteAndGo(text))
954 model_->PasteAndGo(text); 889 model()->PasteAndGo(text);
955 } 890 }
956 891
957 void OmniboxViewMac::OnFrameChanged() { 892 void OmniboxViewMac::OnFrameChanged() {
958 // TODO(shess): UpdatePopupAppearance() is called frequently, so it 893 // TODO(shess): UpdatePopupAppearance() is called frequently, so it
959 // should be really cheap, but in this case we could probably make 894 // should be really cheap, but in this case we could probably make
960 // things even cheaper by refactoring between the popup-placement 895 // things even cheaper by refactoring between the popup-placement
961 // code and the matrix-population code. 896 // code and the matrix-population code.
962 popup_view_->UpdatePopupAppearance(); 897 popup_view_->UpdatePopupAppearance();
963 model_->PopupBoundsChangedTo(popup_view_->GetTargetBounds()); 898 model()->PopupBoundsChangedTo(popup_view_->GetTargetBounds());
964 899
965 // Give controller a chance to rearrange decorations. 900 // Give controller a chance to rearrange decorations.
966 model_->OnChanged(); 901 model()->OnChanged();
902 }
903
904 void OmniboxViewMac::ClosePopup() {
905 OmniboxView::ClosePopup();
967 } 906 }
968 907
969 bool OmniboxViewMac::OnBackspacePressed() { 908 bool OmniboxViewMac::OnBackspacePressed() {
970 // Don't intercept if not in keyword search mode. 909 // Don't intercept if not in keyword search mode.
971 if (model_->is_keyword_hint() || model_->keyword().empty()) { 910 if (model()->is_keyword_hint() || model()->keyword().empty()) {
972 return false; 911 return false;
973 } 912 }
974 913
975 // Don't intercept if there is a selection, or the cursor isn't at 914 // Don't intercept if there is a selection, or the cursor isn't at
976 // the leftmost position. 915 // the leftmost position.
977 const NSRange selection = GetSelectedRange(); 916 const NSRange selection = GetSelectedRange();
978 if (selection.length > 0 || selection.location > 0) { 917 if (selection.length > 0 || selection.location > 0) {
979 return false; 918 return false;
980 } 919 }
981 920
982 // We're showing a keyword and the user pressed backspace at the 921 // We're showing a keyword and the user pressed backspace at the
983 // beginning of the text. Delete the selected keyword. 922 // beginning of the text. Delete the selected keyword.
984 model_->ClearKeyword(GetText()); 923 model()->ClearKeyword(GetText());
985 return true; 924 return true;
986 } 925 }
987 926
988 NSRange OmniboxViewMac::SelectionRangeForProposedRange(NSRange proposed_range) { 927 NSRange OmniboxViewMac::SelectionRangeForProposedRange(NSRange proposed_range) {
989 // Should never call this function unless editing is in progress. 928 // Should never call this function unless editing is in progress.
990 DCHECK([field_ currentEditor]); 929 DCHECK([field_ currentEditor]);
991 930
992 if (![field_ currentEditor]) 931 if (![field_ currentEditor])
993 return proposed_range; 932 return proposed_range;
994 933
(...skipping 11 matching lines...) Expand all
1006 if (start > max) 945 if (start > max)
1007 start = max; 946 start = max;
1008 947
1009 if (end > max) 948 if (end > max)
1010 end = max; 949 end = max;
1011 950
1012 return NSMakeRange(start, end - start); 951 return NSMakeRange(start, end - start);
1013 } 952 }
1014 953
1015 void OmniboxViewMac::OnControlKeyChanged(bool pressed) { 954 void OmniboxViewMac::OnControlKeyChanged(bool pressed) {
1016 model_->OnControlKeyChanged(pressed); 955 model()->OnControlKeyChanged(pressed);
1017 } 956 }
1018 957
1019 void OmniboxViewMac::FocusLocation(bool select_all) { 958 void OmniboxViewMac::FocusLocation(bool select_all) {
1020 if ([field_ isEditable]) { 959 if ([field_ isEditable]) {
1021 // If the text field has a field editor, it's the first responder, meaning 960 // If the text field has a field editor, it's the first responder, meaning
1022 // that it's already focused. makeFirstResponder: will select all, so only 961 // that it's already focused. makeFirstResponder: will select all, so only
1023 // call it if this behavior is desired. 962 // call it if this behavior is desired.
1024 if (select_all || ![field_ currentEditor]) 963 if (select_all || ![field_ currentEditor])
1025 [[field_ window] makeFirstResponder:field_]; 964 [[field_ window] makeFirstResponder:field_];
1026 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]); 965 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]);
1027 } 966 }
1028 } 967 }
1029 968
1030 // static 969 // static
1031 NSFont* OmniboxViewMac::GetFieldFont() { 970 NSFont* OmniboxViewMac::GetFieldFont() {
1032 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 971 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1033 return rb.GetFont(ResourceBundle::BaseFont).GetNativeFont(); 972 return rb.GetFont(ResourceBundle::BaseFont).GetNativeFont();
1034 } 973 }
1035 974
975 int OmniboxViewMac::GetOmniboxTextLength() const {
976 return static_cast<int>(GetTextLength());
977 }
978
1036 NSUInteger OmniboxViewMac::GetTextLength() const { 979 NSUInteger OmniboxViewMac::GetTextLength() const {
1037 return ([field_ currentEditor] ? 980 return ([field_ currentEditor] ?
1038 [[[field_ currentEditor] string] length] : 981 [[[field_ currentEditor] string] length] :
1039 [[field_ stringValue] length]) - suggest_text_length_; 982 [[field_ stringValue] length]) - suggest_text_length_;
1040 } 983 }
1041 984
1042 void OmniboxViewMac::PlaceCaretAt(NSUInteger pos) {
1043 DCHECK(pos <= GetTextLength());
1044 SetSelectedRange(NSMakeRange(pos, pos));
1045 }
1046
1047 bool OmniboxViewMac::IsCaretAtEnd() const { 985 bool OmniboxViewMac::IsCaretAtEnd() const {
1048 const NSRange selection = GetSelectedRange(); 986 const NSRange selection = GetSelectedRange();
1049 return selection.length == 0 && selection.location == GetTextLength(); 987 return selection.length == 0 &&
988 selection.location == GetTextLength();
Peter Kasting 2012/07/26 23:03:24 Nit: This change unnecessary
dominich 2012/07/27 20:33:54 Done.
1050 } 989 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698