OLD | NEW |
---|---|
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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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_.get(), 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); |
(...skipping 14 matching lines...) Expand all Loading... | |
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(); | 172 model_.reset(); |
176 | 173 |
177 // Disconnect from |field_|, it outlives this object. | 174 // Disconnect from |field_|, it outlives this object. |
178 [field_ setObserver:NULL]; | 175 [field_ setObserver:NULL]; |
179 } | 176 } |
180 | 177 |
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) { | 178 void OmniboxViewMac::SaveStateToTab(WebContents* tab) { |
190 DCHECK(tab); | 179 DCHECK(tab); |
191 | 180 |
192 const bool hasFocus = [field_ currentEditor] ? true : false; | 181 const bool hasFocus = [field_ currentEditor] ? true : false; |
193 | 182 |
194 NSRange range; | 183 NSRange range; |
195 if (hasFocus) { | 184 if (hasFocus) { |
196 range = GetSelectedRange(); | 185 range = GetSelectedRange(); |
197 } else { | 186 } else { |
198 // If we are not focussed, there is no selection. Manufacture | 187 // If we are not focussed, there is no selection. Manufacture |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 // TODO(shess): This corresponds to _win and _gtk, except those | 233 // TODO(shess): This corresponds to _win and _gtk, except those |
245 // guard it with a test for whether the security level changed. | 234 // guard it with a test for whether the security level changed. |
246 // But AFAICT, that can only change if the text changed, and that | 235 // But AFAICT, that can only change if the text changed, and that |
247 // code compares the toolbar_model_ security level with the local | 236 // 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 | 237 // security level. Dig in and figure out why this isn't a no-op |
249 // that should go away. | 238 // that should go away. |
250 EmphasizeURLComponents(); | 239 EmphasizeURLComponents(); |
251 } | 240 } |
252 } | 241 } |
253 | 242 |
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 { | 243 string16 OmniboxViewMac::GetText() const { |
269 return base::SysNSStringToUTF16(GetNonSuggestTextSubstring()); | 244 return base::SysNSStringToUTF16(GetNonSuggestTextSubstring()); |
270 } | 245 } |
271 | 246 |
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 { | 247 NSRange OmniboxViewMac::GetSelectedRange() const { |
297 return [[field_ currentEditor] selectedRange]; | 248 return [[field_ currentEditor] selectedRange]; |
298 } | 249 } |
299 | 250 |
300 NSRange OmniboxViewMac::GetMarkedRange() const { | 251 NSRange OmniboxViewMac::GetMarkedRange() const { |
301 DCHECK([field_ currentEditor]); | 252 DCHECK([field_ currentEditor]); |
302 return [(NSTextView*)[field_ currentEditor] markedRange]; | 253 return [(NSTextView*)[field_ currentEditor] markedRange]; |
303 } | 254 } |
304 | 255 |
305 void OmniboxViewMac::SetSelectedRange(const NSRange range) { | 256 void OmniboxViewMac::SetSelectedRange(const NSRange range) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 // TODO(shess): Figure out what |reversed| implies. The gtk version | 326 // TODO(shess): Figure out what |reversed| implies. The gtk version |
376 // has it imply inverting the selection front to back, but I don't | 327 // has it imply inverting the selection front to back, but I don't |
377 // even know if that makes sense for Mac. | 328 // even know if that makes sense for Mac. |
378 | 329 |
379 // TODO(shess): Verify that we should be stealing focus at this | 330 // TODO(shess): Verify that we should be stealing focus at this |
380 // point. | 331 // point. |
381 SetSelectedRange(NSMakeRange(0, GetTextLength())); | 332 SetSelectedRange(NSMakeRange(0, GetTextLength())); |
382 } | 333 } |
383 | 334 |
384 void OmniboxViewMac::RevertAll() { | 335 void OmniboxViewMac::RevertAll() { |
385 ClosePopup(); | 336 OmniboxView::RevertAll(); |
386 model_->Revert(); | |
387 model_->OnChanged(); | |
388 [field_ clearUndoChain]; | 337 [field_ clearUndoChain]; |
389 } | 338 } |
390 | 339 |
391 void OmniboxViewMac::UpdatePopup() { | 340 void OmniboxViewMac::UpdatePopup() { |
392 model_->SetInputInProgress(true); | 341 model_->SetInputInProgress(true); |
393 if (!model_->has_focus()) | 342 if (!model_->has_focus()) |
394 return; | 343 return; |
395 | 344 |
396 // Comment copied from OmniboxViewWin::UpdatePopup(): | 345 // Comment copied from OmniboxViewWin::UpdatePopup(): |
397 // Don't inline autocomplete when: | 346 // Don't inline autocomplete when: |
398 // * The user is deleting text | 347 // * The user is deleting text |
399 // * The caret/selection isn't at the end of the text | 348 // * The caret/selection isn't at the end of the text |
400 // * The user has just pasted in something that replaced all the text | 349 // * The user has just pasted in something that replaced all the text |
401 // * The user is trying to compose something in an IME | 350 // * The user is trying to compose something in an IME |
402 bool prevent_inline_autocomplete = IsImeComposing(); | 351 bool prevent_inline_autocomplete = IsImeComposing(); |
403 NSTextView* editor = (NSTextView*)[field_ currentEditor]; | 352 NSTextView* editor = (NSTextView*)[field_ currentEditor]; |
404 if (editor) { | 353 if (editor) { |
405 if (NSMaxRange([editor selectedRange]) < | 354 if (NSMaxRange([editor selectedRange]) < |
406 [[editor textStorage] length] - suggest_text_length_) | 355 [[editor textStorage] length] - suggest_text_length_) |
407 prevent_inline_autocomplete = true; | 356 prevent_inline_autocomplete = true; |
408 } | 357 } |
409 | 358 |
410 model_->StartAutocomplete([editor selectedRange].length != 0, | 359 model_->StartAutocomplete([editor selectedRange].length != 0, |
411 prevent_inline_autocomplete); | 360 prevent_inline_autocomplete); |
412 } | 361 } |
413 | 362 |
414 void OmniboxViewMac::ClosePopup() { | |
415 model_->StopAutocomplete(); | |
416 } | |
417 | |
418 void OmniboxViewMac::SetFocus() { | 363 void OmniboxViewMac::SetFocus() { |
419 } | 364 } |
420 | 365 |
421 void OmniboxViewMac::SetText(const string16& display_text) { | 366 void OmniboxViewMac::SetText(const string16& display_text) { |
422 // If we are setting the text directly, there cannot be any suggest text. | 367 // If we are setting the text directly, there cannot be any suggest text. |
423 suggest_text_length_ = 0; | 368 suggest_text_length_ = 0; |
424 SetTextInternal(display_text); | 369 SetTextInternal(display_text); |
425 } | 370 } |
426 | 371 |
427 void OmniboxViewMac::SetTextInternal(const string16& display_text) { | 372 void OmniboxViewMac::SetTextInternal(const string16& display_text) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 [storage setAttributes:[NSDictionary dictionary] | 435 [storage setAttributes:[NSDictionary dictionary] |
491 range:NSMakeRange(0, [storage length])]; | 436 range:NSMakeRange(0, [storage length])]; |
492 ApplyTextAttributes(GetText(), storage); | 437 ApplyTextAttributes(GetText(), storage); |
493 | 438 |
494 [storage endEditing]; | 439 [storage endEditing]; |
495 } else { | 440 } else { |
496 SetText(GetText()); | 441 SetText(GetText()); |
497 } | 442 } |
498 } | 443 } |
499 | 444 |
500 void OmniboxViewMac::TextChanged() { | |
501 EmphasizeURLComponents(); | |
502 model_->OnChanged(); | |
503 } | |
504 | |
505 void OmniboxViewMac::ApplyTextAttributes(const string16& display_text, | 445 void OmniboxViewMac::ApplyTextAttributes(const string16& display_text, |
506 NSMutableAttributedString* as) { | 446 NSMutableAttributedString* as) { |
507 NSUInteger as_length = [as length]; | 447 NSUInteger as_length = [as length]; |
508 NSRange as_entire_string = NSMakeRange(0, as_length); | 448 NSRange as_entire_string = NSMakeRange(0, as_length); |
509 | 449 |
510 [as addAttribute:NSFontAttributeName value:GetFieldFont() | 450 [as addAttribute:NSFontAttributeName value:GetFieldFont() |
511 range:as_entire_string]; | 451 range:as_entire_string]; |
512 | 452 |
513 // A kinda hacky way to add breaking at periods. This is what Safari does. | 453 // A kinda hacky way to add breaking at periods. This is what Safari does. |
514 // This works for IDNs too, despite the "en_US". | 454 // This works for IDNs too, despite the "en_US". |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
678 gfx::NativeView OmniboxViewMac::GetNativeView() const { | 618 gfx::NativeView OmniboxViewMac::GetNativeView() const { |
679 return field_; | 619 return field_; |
680 } | 620 } |
681 | 621 |
682 gfx::NativeView OmniboxViewMac::GetRelativeWindowForPopup() const { | 622 gfx::NativeView OmniboxViewMac::GetRelativeWindowForPopup() const { |
683 // Not used on mac. | 623 // Not used on mac. |
684 NOTREACHED(); | 624 NOTREACHED(); |
685 return NULL; | 625 return NULL; |
686 } | 626 } |
687 | 627 |
688 CommandUpdater* OmniboxViewMac::GetCommandUpdater() { | |
689 return command_updater_; | |
690 } | |
691 | |
692 void OmniboxViewMac::SetInstantSuggestion(const string16& suggest_text, | 628 void OmniboxViewMac::SetInstantSuggestion(const string16& suggest_text, |
693 bool animate_to_complete) { | 629 bool animate_to_complete) { |
694 NSString* text = GetNonSuggestTextSubstring(); | 630 NSString* text = GetNonSuggestTextSubstring(); |
695 bool needs_update = (suggest_text_length_ > 0); | 631 bool needs_update = (suggest_text_length_ > 0); |
696 | 632 |
697 // Append the new suggest text. | 633 // Append the new suggest text. |
698 suggest_text_length_ = suggest_text.length(); | 634 suggest_text_length_ = suggest_text.length(); |
699 if (suggest_text_length_ > 0) { | 635 if (suggest_text_length_ > 0) { |
700 text = [text stringByAppendingString:base::SysUTF16ToNSString( | 636 text = [text stringByAppendingString:base::SysUTF16ToNSString( |
701 suggest_text)]; | 637 suggest_text)]; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
959 // should be really cheap, but in this case we could probably make | 895 // should be really cheap, but in this case we could probably make |
960 // things even cheaper by refactoring between the popup-placement | 896 // things even cheaper by refactoring between the popup-placement |
961 // code and the matrix-population code. | 897 // code and the matrix-population code. |
962 popup_view_->UpdatePopupAppearance(); | 898 popup_view_->UpdatePopupAppearance(); |
963 model_->PopupBoundsChangedTo(popup_view_->GetTargetBounds()); | 899 model_->PopupBoundsChangedTo(popup_view_->GetTargetBounds()); |
964 | 900 |
965 // Give controller a chance to rearrange decorations. | 901 // Give controller a chance to rearrange decorations. |
966 model_->OnChanged(); | 902 model_->OnChanged(); |
967 } | 903 } |
968 | 904 |
905 void OmniboxViewMac::ClosePopup() { | |
906 OmniboxView::ClosePopup(); | |
907 } | |
908 | |
969 bool OmniboxViewMac::OnBackspacePressed() { | 909 bool OmniboxViewMac::OnBackspacePressed() { |
970 // Don't intercept if not in keyword search mode. | 910 // Don't intercept if not in keyword search mode. |
971 if (model_->is_keyword_hint() || model_->keyword().empty()) { | 911 if (model_->is_keyword_hint() || model_->keyword().empty()) { |
972 return false; | 912 return false; |
973 } | 913 } |
974 | 914 |
975 // Don't intercept if there is a selection, or the cursor isn't at | 915 // Don't intercept if there is a selection, or the cursor isn't at |
976 // the leftmost position. | 916 // the leftmost position. |
977 const NSRange selection = GetSelectedRange(); | 917 const NSRange selection = GetSelectedRange(); |
978 if (selection.length > 0 || selection.location > 0) { | 918 if (selection.length > 0 || selection.location > 0) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1026 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]); | 966 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]); |
1027 } | 967 } |
1028 } | 968 } |
1029 | 969 |
1030 // static | 970 // static |
1031 NSFont* OmniboxViewMac::GetFieldFont() { | 971 NSFont* OmniboxViewMac::GetFieldFont() { |
1032 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 972 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
1033 return rb.GetFont(ResourceBundle::BaseFont).GetNativeFont(); | 973 return rb.GetFont(ResourceBundle::BaseFont).GetNativeFont(); |
1034 } | 974 } |
1035 | 975 |
976 int OmniboxViewMac::GetOmniboxTextLength() const { | |
977 return static_cast<int>(GetTextLength()); | |
Peter Kasting
2012/07/26 03:59:17
Nit: For all these derived classes, I kind of feel
dominich
2012/07/26 22:33:24
I originally built this however there are some pro
Peter Kasting
2012/07/26 23:03:24
My hope was that for most of those cases, if we we
| |
978 } | |
979 | |
1036 NSUInteger OmniboxViewMac::GetTextLength() const { | 980 NSUInteger OmniboxViewMac::GetTextLength() const { |
1037 return ([field_ currentEditor] ? | 981 return ([field_ currentEditor] ? |
1038 [[[field_ currentEditor] string] length] : | 982 [[[field_ currentEditor] string] length] : |
1039 [[field_ stringValue] length]) - suggest_text_length_; | 983 [[field_ stringValue] length]) - suggest_text_length_; |
1040 } | 984 } |
1041 | 985 |
1042 void OmniboxViewMac::PlaceCaretAt(NSUInteger pos) { | |
1043 DCHECK(pos <= GetTextLength()); | |
1044 SetSelectedRange(NSMakeRange(pos, pos)); | |
1045 } | |
1046 | |
1047 bool OmniboxViewMac::IsCaretAtEnd() const { | 986 bool OmniboxViewMac::IsCaretAtEnd() const { |
1048 const NSRange selection = GetSelectedRange(); | 987 const NSRange selection = GetSelectedRange(); |
1049 return selection.length == 0 && selection.location == GetTextLength(); | 988 return selection.length == 0 && |
989 selection.location == GetTextLength(); | |
1050 } | 990 } |
OLD | NEW |