OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 void OmniboxViewMac::SetUserText(const string16& text) { | 322 void OmniboxViewMac::SetUserText(const string16& text) { |
323 SetUserText(text, text, true); | 323 SetUserText(text, text, true); |
324 } | 324 } |
325 | 325 |
326 void OmniboxViewMac::SetUserText(const string16& text, | 326 void OmniboxViewMac::SetUserText(const string16& text, |
327 const string16& display_text, | 327 const string16& display_text, |
328 bool update_popup) { | 328 bool update_popup) { |
329 model_->SetUserText(text); | 329 model_->SetUserText(text); |
330 // TODO(shess): TODO below from gtk. | 330 // TODO(shess): TODO below from gtk. |
331 // TODO(deanm): something about selection / focus change here. | 331 // TODO(deanm): something about selection / focus change here. |
332 SetWindowTextAndCaretPos(display_text, display_text.length(), update_popup, | 332 SetText(display_text); |
333 true); | 333 if (update_popup) { |
| 334 UpdatePopup(); |
| 335 } |
| 336 model_->OnChanged(); |
334 } | 337 } |
335 | 338 |
336 NSRange OmniboxViewMac::GetSelectedRange() const { | 339 NSRange OmniboxViewMac::GetSelectedRange() const { |
337 return [[field_ currentEditor] selectedRange]; | 340 return [[field_ currentEditor] selectedRange]; |
338 } | 341 } |
339 | 342 |
340 NSRange OmniboxViewMac::GetMarkedRange() const { | 343 NSRange OmniboxViewMac::GetMarkedRange() const { |
341 DCHECK([field_ currentEditor]); | 344 DCHECK([field_ currentEditor]); |
342 return [(NSTextView*)[field_ currentEditor] markedRange]; | 345 return [(NSTextView*)[field_ currentEditor] markedRange]; |
343 } | 346 } |
(...skipping 10 matching lines...) Expand all Loading... |
354 | 357 |
355 // TODO(shess): What if it didn't get first responder, and there is | 358 // TODO(shess): What if it didn't get first responder, and there is |
356 // no field editor? This will do nothing. Well, at least it won't | 359 // no field editor? This will do nothing. Well, at least it won't |
357 // crash. Think of something more productive to do, or prove that | 360 // crash. Think of something more productive to do, or prove that |
358 // it cannot occur and DCHECK appropriately. | 361 // it cannot occur and DCHECK appropriately. |
359 [[field_ currentEditor] setSelectedRange:range]; | 362 [[field_ currentEditor] setSelectedRange:range]; |
360 } | 363 } |
361 } | 364 } |
362 | 365 |
363 void OmniboxViewMac::SetWindowTextAndCaretPos(const string16& text, | 366 void OmniboxViewMac::SetWindowTextAndCaretPos(const string16& text, |
364 size_t caret_pos, | 367 size_t caret_pos) { |
365 bool update_popup, | |
366 bool notify_text_changed) { | |
367 DCHECK_LE(caret_pos, text.size()); | 368 DCHECK_LE(caret_pos, text.size()); |
368 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, caret_pos)); | 369 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, caret_pos)); |
369 | |
370 if (update_popup) | |
371 UpdatePopup(); | |
372 | |
373 if (notify_text_changed) | |
374 TextChanged(); | |
375 } | 370 } |
376 | 371 |
377 void OmniboxViewMac::SetForcedQuery() { | 372 void OmniboxViewMac::SetForcedQuery() { |
378 // We need to do this first, else |SetSelectedRange()| won't work. | 373 // We need to do this first, else |SetSelectedRange()| won't work. |
379 FocusLocation(true); | 374 FocusLocation(true); |
380 | 375 |
381 const string16 current_text(GetText()); | 376 const string16 current_text(GetText()); |
382 const size_t start = current_text.find_first_not_of(kWhitespaceUTF16); | 377 const size_t start = current_text.find_first_not_of(kWhitespaceUTF16); |
383 if (start == string16::npos || (current_text[start] != '?')) { | 378 if (start == string16::npos || (current_text[start] != '?')) { |
384 SetUserText(ASCIIToUTF16("?")); | 379 SetUserText(ASCIIToUTF16("?")); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 [storage setAttributes:[NSDictionary dictionary] | 525 [storage setAttributes:[NSDictionary dictionary] |
531 range:NSMakeRange(0, [storage length])]; | 526 range:NSMakeRange(0, [storage length])]; |
532 ApplyTextAttributes(GetText(), storage); | 527 ApplyTextAttributes(GetText(), storage); |
533 | 528 |
534 [storage endEditing]; | 529 [storage endEditing]; |
535 } else { | 530 } else { |
536 SetText(GetText()); | 531 SetText(GetText()); |
537 } | 532 } |
538 } | 533 } |
539 | 534 |
540 void OmniboxViewMac::TextChanged() { | |
541 EmphasizeURLComponents(); | |
542 model_->OnChanged(); | |
543 } | |
544 | |
545 void OmniboxViewMac::ApplyTextAttributes(const string16& display_text, | 535 void OmniboxViewMac::ApplyTextAttributes(const string16& display_text, |
546 NSMutableAttributedString* as) { | 536 NSMutableAttributedString* as) { |
547 NSUInteger as_length = [as length]; | 537 NSUInteger as_length = [as length]; |
548 NSRange as_entire_string = NSMakeRange(0, as_length); | 538 NSRange as_entire_string = NSMakeRange(0, as_length); |
549 | 539 |
550 [as addAttribute:NSFontAttributeName value:GetFieldFont() | 540 [as addAttribute:NSFontAttributeName value:GetFieldFont() |
551 range:as_entire_string]; | 541 range:as_entire_string]; |
552 | 542 |
553 // A kinda hacky way to add breaking at periods. This is what Safari does. | 543 // A kinda hacky way to add breaking at periods. This is what Safari does. |
554 // This works for IDNs too, despite the "en_US". | 544 // This works for IDNs too, despite the "en_US". |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 range:ComponentToNSRange(scheme)]; | 599 range:ComponentToNSRange(scheme)]; |
610 } | 600 } |
611 } | 601 } |
612 | 602 |
613 void OmniboxViewMac::OnTemporaryTextMaybeChanged(const string16& display_text, | 603 void OmniboxViewMac::OnTemporaryTextMaybeChanged(const string16& display_text, |
614 bool save_original_selection) { | 604 bool save_original_selection) { |
615 if (save_original_selection) | 605 if (save_original_selection) |
616 saved_temporary_selection_ = GetSelectedRange(); | 606 saved_temporary_selection_ = GetSelectedRange(); |
617 | 607 |
618 suggest_text_length_ = 0; | 608 suggest_text_length_ = 0; |
619 SetWindowTextAndCaretPos(display_text, display_text.size(), false, false); | 609 SetWindowTextAndCaretPos(display_text, display_text.size()); |
620 model_->OnChanged(); | 610 model_->OnChanged(); |
621 [field_ clearUndoChain]; | 611 [field_ clearUndoChain]; |
622 } | 612 } |
623 | 613 |
624 void OmniboxViewMac::OnStartingIME() { | 614 void OmniboxViewMac::OnStartingIME() { |
625 // Reset the suggest text just before starting an IME composition session, | 615 // Reset the suggest text just before starting an IME composition session, |
626 // otherwise the IME composition may be interrupted when the suggest text | 616 // otherwise the IME composition may be interrupted when the suggest text |
627 // gets reset by the IME composition change. | 617 // gets reset by the IME composition change. |
628 SetInstantSuggestion(string16(), false); | 618 SetInstantSuggestion(string16(), false); |
629 } | 619 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 !IsImeComposing()); | 691 !IsImeComposing()); |
702 | 692 |
703 if (delete_was_pressed_ && at_end_of_edit) | 693 if (delete_was_pressed_ && at_end_of_edit) |
704 delete_at_end_pressed_ = true; | 694 delete_at_end_pressed_ = true; |
705 | 695 |
706 // Restyle in case the user changed something. | 696 // Restyle in case the user changed something. |
707 // TODO(shess): I believe there are multiple-redraw cases, here. | 697 // TODO(shess): I believe there are multiple-redraw cases, here. |
708 // Linux watches for something_changed && text_differs, but that | 698 // Linux watches for something_changed && text_differs, but that |
709 // fails for us in case you copy the URL and paste the identical URL | 699 // fails for us in case you copy the URL and paste the identical URL |
710 // back (we'll lose the styling). | 700 // back (we'll lose the styling). |
711 TextChanged(); | 701 EmphasizeURLComponents(); |
| 702 model_->OnChanged(); |
712 | 703 |
713 delete_was_pressed_ = false; | 704 delete_was_pressed_ = false; |
714 | 705 |
715 return something_changed; | 706 return something_changed; |
716 } | 707 } |
717 | 708 |
718 gfx::NativeView OmniboxViewMac::GetNativeView() const { | 709 gfx::NativeView OmniboxViewMac::GetNativeView() const { |
719 return field_; | 710 return field_; |
720 } | 711 } |
721 | 712 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 cmd != @selector(insertTabIgnoringFieldEditor:)) { | 786 cmd != @selector(insertTabIgnoringFieldEditor:)) { |
796 // Reset the suggest text for any change other than key right or tab. | 787 // Reset the suggest text for any change other than key right or tab. |
797 // TODO(rohitrao): This is here to prevent complications when editing text. | 788 // TODO(rohitrao): This is here to prevent complications when editing text. |
798 // See if this can be removed. | 789 // See if this can be removed. |
799 SetInstantSuggestion(string16(), false); | 790 SetInstantSuggestion(string16(), false); |
800 } | 791 } |
801 | 792 |
802 if (cmd == @selector(deleteForward:)) | 793 if (cmd == @selector(deleteForward:)) |
803 delete_was_pressed_ = true; | 794 delete_was_pressed_ = true; |
804 | 795 |
805 // Don't intercept up/down-arrow or backtab if the popup isn't open. | 796 // Don't intercept up/down-arrow if the popup isn't open. |
806 if (popup_view_->IsOpen()) { | 797 if (popup_view_->IsOpen()) { |
807 if (cmd == @selector(moveDown:)) { | 798 if (cmd == @selector(moveDown:)) { |
808 model_->OnUpOrDownKeyPressed(1); | 799 model_->OnUpOrDownKeyPressed(1); |
809 return true; | 800 return true; |
810 } | 801 } |
811 | 802 |
812 if (cmd == @selector(moveUp:)) { | 803 if (cmd == @selector(moveUp:)) { |
813 model_->OnUpOrDownKeyPressed(-1); | 804 model_->OnUpOrDownKeyPressed(-1); |
814 return true; | 805 return true; |
815 } | 806 } |
816 | |
817 if (cmd == @selector(insertBacktab:) && | |
818 model_->popup_model()->selected_line_state() == | |
819 AutocompletePopupModel::KEYWORD) { | |
820 model_->ClearKeyword(GetText()); | |
821 return true; | |
822 } | |
823 } | 807 } |
824 | 808 |
825 if (cmd == @selector(moveRight:)) { | 809 if (cmd == @selector(moveRight:)) { |
826 // Only commit suggested text if the cursor is all the way to the right and | 810 // Only commit suggested text if the cursor is all the way to the right and |
827 // there is no selection. | 811 // there is no selection. |
828 if (suggest_text_length_ > 0 && IsCaretAtEnd()) { | 812 if (suggest_text_length_ > 0 && IsCaretAtEnd()) { |
829 model_->CommitSuggestedText(true); | 813 model_->CommitSuggestedText(true); |
830 return true; | 814 return true; |
831 } | 815 } |
832 } | 816 } |
833 | 817 |
834 if (cmd == @selector(scrollPageDown:)) { | 818 if (cmd == @selector(scrollPageDown:)) { |
835 model_->OnUpOrDownKeyPressed(model_->result().size()); | 819 model_->OnUpOrDownKeyPressed(model_->result().size()); |
836 return true; | 820 return true; |
837 } | 821 } |
838 | 822 |
839 if (cmd == @selector(scrollPageUp:)) { | 823 if (cmd == @selector(scrollPageUp:)) { |
840 model_->OnUpOrDownKeyPressed(-model_->result().size()); | 824 model_->OnUpOrDownKeyPressed(-model_->result().size()); |
841 return true; | 825 return true; |
842 } | 826 } |
843 | 827 |
844 if (cmd == @selector(cancelOperation:)) { | 828 if (cmd == @selector(cancelOperation:)) { |
845 return model_->OnEscapeKeyPressed(); | 829 return model_->OnEscapeKeyPressed(); |
846 } | 830 } |
847 | 831 |
848 if ((cmd == @selector(insertTab:) || | 832 if (cmd == @selector(insertTab:) || |
849 cmd == @selector(insertTabIgnoringFieldEditor:)) && | 833 cmd == @selector(insertTabIgnoringFieldEditor:)) { |
850 model_->is_keyword_hint()) { | 834 if (model_->is_keyword_hint()) |
851 return model_->AcceptKeyword(); | 835 return model_->AcceptKeyword(); |
| 836 |
| 837 if (suggest_text_length_ > 0) { |
| 838 model_->CommitSuggestedText(true); |
| 839 return true; |
| 840 } |
| 841 |
| 842 if (!IsCaretAtEnd()) { |
| 843 PlaceCaretAt(GetTextLength()); |
| 844 // OnDidChange() will not be triggered when setting selected range in this |
| 845 // method, so we need to call it explicitly. |
| 846 OnDidChange(); |
| 847 return true; |
| 848 } |
| 849 |
| 850 if (model_->AcceptCurrentInstantPreview()) |
| 851 return true; |
852 } | 852 } |
853 | 853 |
854 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op | 854 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op |
855 // behavior with the proper WindowOpenDisposition. | 855 // behavior with the proper WindowOpenDisposition. |
856 NSEvent* event = [NSApp currentEvent]; | 856 NSEvent* event = [NSApp currentEvent]; |
857 if (cmd == @selector(insertNewline:) || | 857 if (cmd == @selector(insertNewline:) || |
858 (cmd == @selector(noop:) && | 858 (cmd == @selector(noop:) && |
859 ([event type] == NSKeyDown || [event type] == NSKeyUp) && | 859 ([event type] == NSKeyDown || [event type] == NSKeyUp) && |
860 [event keyCode] == kVK_Return)) { | 860 [event keyCode] == kVK_Return)) { |
861 WindowOpenDisposition disposition = | 861 WindowOpenDisposition disposition = |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 | 1125 |
1126 void OmniboxViewMac::PlaceCaretAt(NSUInteger pos) { | 1126 void OmniboxViewMac::PlaceCaretAt(NSUInteger pos) { |
1127 DCHECK(pos <= GetTextLength()); | 1127 DCHECK(pos <= GetTextLength()); |
1128 SetSelectedRange(NSMakeRange(pos, pos)); | 1128 SetSelectedRange(NSMakeRange(pos, pos)); |
1129 } | 1129 } |
1130 | 1130 |
1131 bool OmniboxViewMac::IsCaretAtEnd() const { | 1131 bool OmniboxViewMac::IsCaretAtEnd() const { |
1132 const NSRange selection = GetSelectedRange(); | 1132 const NSRange selection = GetSelectedRange(); |
1133 return selection.length == 0 && selection.location == GetTextLength(); | 1133 return selection.length == 0 && selection.location == GetTextLength(); |
1134 } | 1134 } |
OLD | NEW |