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/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 DCHECK_LE(caret_pos, text.size()); | 353 DCHECK_LE(caret_pos, text.size()); |
354 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, 0)); | 354 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, 0)); |
355 | 355 |
356 if (update_popup) | 356 if (update_popup) |
357 UpdatePopup(); | 357 UpdatePopup(); |
358 | 358 |
359 if (notify_text_changed) | 359 if (notify_text_changed) |
360 TextChanged(); | 360 TextChanged(); |
361 } | 361 } |
362 | 362 |
363 void OmniboxViewMac::SetForcedQuery() { | 363 void OmniboxViewMac::EnterKeywordModeForDefaultSearchProvider() { |
364 // We need to do this first, else |SetSelectedRange()| won't work. | 364 // We need to do this first, else |SetSelectedRange()| won't work. |
365 FocusLocation(true); | 365 FocusLocation(true); |
366 | 366 |
367 const base::string16 current_text(GetText()); | 367 // Transition the user into keyword mode using their default search provider. |
368 const size_t start = current_text.find_first_not_of(base::kWhitespaceUTF16); | 368 // Select their query if they typed one. |
369 if (start == base::string16::npos || (current_text[start] != '?')) { | 369 model()->EnterKeywordModeForDefaultSearchProvider( |
370 SetUserText(base::ASCIIToUTF16("?")); | 370 KeywordModeEntryMethod::KEYBOARD_SHORTCUT); |
371 } else { | 371 SelectAll(false); |
372 NSRange range = NSMakeRange(start + 1, current_text.size() - start - 1); | |
373 [[field_ currentEditor] setSelectedRange:range]; | |
374 } | |
375 } | 372 } |
376 | 373 |
377 bool OmniboxViewMac::IsSelectAll() const { | 374 bool OmniboxViewMac::IsSelectAll() const { |
378 if (![field_ currentEditor]) | 375 if (![field_ currentEditor]) |
379 return true; | 376 return true; |
380 const NSRange all_range = NSMakeRange(0, GetTextLength()); | 377 const NSRange all_range = NSMakeRange(0, GetTextLength()); |
381 return NSEqualRanges(all_range, GetSelectedRange()); | 378 return NSEqualRanges(all_range, GetSelectedRange()); |
382 } | 379 } |
383 | 380 |
384 bool OmniboxViewMac::DeleteAtEndPressed() { | 381 bool OmniboxViewMac::DeleteAtEndPressed() { |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 bool OmniboxViewMac::IsFirstResponder() const { | 665 bool OmniboxViewMac::IsFirstResponder() const { |
669 return [field_ currentEditor] != nil ? true : false; | 666 return [field_ currentEditor] != nil ? true : false; |
670 } | 667 } |
671 | 668 |
672 void OmniboxViewMac::OnBeforePossibleChange() { | 669 void OmniboxViewMac::OnBeforePossibleChange() { |
673 // We should only arrive here when the field is focused. | 670 // We should only arrive here when the field is focused. |
674 DCHECK(IsFirstResponder()); | 671 DCHECK(IsFirstResponder()); |
675 | 672 |
676 selection_before_change_ = GetSelectedRange(); | 673 selection_before_change_ = GetSelectedRange(); |
677 text_before_change_ = GetText(); | 674 text_before_change_ = GetText(); |
| 675 keyword_before_change_ = model()->keyword(); |
| 676 is_keyword_selected_before_change_ = model()->is_keyword_selected(); |
678 marked_range_before_change_ = GetMarkedRange(); | 677 marked_range_before_change_ = GetMarkedRange(); |
679 } | 678 } |
680 | 679 |
681 bool OmniboxViewMac::OnAfterPossibleChange(bool allow_keyword_ui_change) { | 680 bool OmniboxViewMac::OnAfterPossibleChange(bool allow_keyword_ui_change) { |
682 // We should only arrive here when the field is focused. | 681 // We should only arrive here when the field is focused. |
683 DCHECK(IsFirstResponder()); | 682 DCHECK(IsFirstResponder()); |
684 | 683 |
685 const NSRange new_selection(GetSelectedRange()); | 684 const NSRange new_selection(GetSelectedRange()); |
686 const base::string16 new_text(GetText()); | 685 const base::string16 new_text(GetText()); |
| 686 const base::string16 new_keyword(model()->keyword()); |
| 687 const bool new_is_keyword_selected = model()->is_keyword_selected(); |
687 const size_t length = new_text.length(); | 688 const size_t length = new_text.length(); |
688 | 689 |
689 const bool selection_differs = | 690 const bool selection_differs = |
690 (new_selection.length || selection_before_change_.length) && | 691 (new_selection.length || selection_before_change_.length) && |
691 !NSEqualRanges(new_selection, selection_before_change_); | 692 !NSEqualRanges(new_selection, selection_before_change_); |
692 const bool at_end_of_edit = (length == new_selection.location); | 693 const bool at_end_of_edit = (length == new_selection.location); |
693 const bool text_differs = (new_text != text_before_change_) || | 694 const bool text_differs = (new_text != text_before_change_) || |
694 !NSEqualRanges(marked_range_before_change_, GetMarkedRange()); | 695 !NSEqualRanges(marked_range_before_change_, GetMarkedRange()); |
| 696 const bool keyword_differs = |
| 697 (new_is_keyword_selected != is_keyword_selected_before_change_) || |
| 698 (new_is_keyword_selected && is_keyword_selected_before_change_ && |
| 699 new_keyword != keyword_before_change_); |
695 | 700 |
696 // When the user has deleted text, we don't allow inline | 701 // When the user has deleted text, we don't allow inline |
697 // autocomplete. This is assumed if the text has gotten shorter AND | 702 // autocomplete. This is assumed if the text has gotten shorter AND |
698 // the selection has shifted towards the front of the text. During | 703 // the selection has shifted towards the front of the text. During |
699 // normal typing the text will almost always be shorter (as the new | 704 // normal typing the text will almost always be shorter (as the new |
700 // input replaces the autocomplete suggestion), but in that case the | 705 // input replaces the autocomplete suggestion), but in that case the |
701 // selection point will have moved towards the end of the text. | 706 // selection point will have moved towards the end of the text. |
702 // TODO(shess): In our implementation, we can catch -deleteBackward: | 707 // TODO(shess): In our implementation, we can catch -deleteBackward: |
703 // and other methods to provide positive knowledge that a delete | 708 // and other methods to provide positive knowledge that a delete |
704 // occurred, rather than intuiting it from context. Consider whether | 709 // occurred, rather than intuiting it from context. Consider whether |
705 // that would be a stronger approach. | 710 // that would be a stronger approach. |
706 const bool just_deleted_text = | 711 const bool just_deleted_text = |
707 (length < text_before_change_.length() && | 712 (length < text_before_change_.length() && |
708 new_selection.location <= selection_before_change_.location); | 713 new_selection.location <= selection_before_change_.location); |
709 | 714 |
710 delete_at_end_pressed_ = false; | 715 delete_at_end_pressed_ = false; |
711 | 716 |
712 const bool something_changed = model()->OnAfterPossibleChange( | 717 const bool something_changed = model()->OnAfterPossibleChange( |
713 text_before_change_, new_text, new_selection.location, | 718 text_before_change_, new_text, new_selection.location, |
714 NSMaxRange(new_selection), selection_differs, text_differs, | 719 NSMaxRange(new_selection), selection_differs, text_differs, |
715 just_deleted_text, allow_keyword_ui_change && !IsImeComposing()); | 720 keyword_differs, just_deleted_text, |
| 721 allow_keyword_ui_change && !IsImeComposing()); |
716 | 722 |
717 if (delete_was_pressed_ && at_end_of_edit) | 723 if (delete_was_pressed_ && at_end_of_edit) |
718 delete_at_end_pressed_ = true; | 724 delete_at_end_pressed_ = true; |
719 | 725 |
720 // Restyle in case the user changed something. | 726 // Restyle in case the user changed something. |
721 // TODO(shess): I believe there are multiple-redraw cases, here. | 727 // TODO(shess): I believe there are multiple-redraw cases, here. |
722 // Linux watches for something_changed && text_differs, but that | 728 // Linux watches for something_changed && text_differs, but that |
723 // fails for us in case you copy the URL and paste the identical URL | 729 // fails for us in case you copy the URL and paste the identical URL |
724 // back (we'll lose the styling). | 730 // back (we'll lose the styling). |
725 TextChanged(); | 731 TextChanged(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 return true; | 859 return true; |
854 } | 860 } |
855 | 861 |
856 if (cmd == @selector(cancelOperation:)) { | 862 if (cmd == @selector(cancelOperation:)) { |
857 return model()->OnEscapeKeyPressed(); | 863 return model()->OnEscapeKeyPressed(); |
858 } | 864 } |
859 | 865 |
860 if ((cmd == @selector(insertTab:) || | 866 if ((cmd == @selector(insertTab:) || |
861 cmd == @selector(insertTabIgnoringFieldEditor:)) && | 867 cmd == @selector(insertTabIgnoringFieldEditor:)) && |
862 model()->is_keyword_hint()) { | 868 model()->is_keyword_hint()) { |
863 return model()->AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_TAB); | 869 return model()->AcceptKeyword(KeywordModeEntryMethod::TAB); |
864 } | 870 } |
865 | 871 |
866 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op | 872 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op |
867 // behavior with the proper WindowOpenDisposition. | 873 // behavior with the proper WindowOpenDisposition. |
868 NSEvent* event = [NSApp currentEvent]; | 874 NSEvent* event = [NSApp currentEvent]; |
869 if (cmd == @selector(insertNewline:) || | 875 if (cmd == @selector(insertNewline:) || |
870 (cmd == @selector(noop:) && | 876 (cmd == @selector(noop:) && |
871 ([event type] == NSKeyDown || [event type] == NSKeyUp) && | 877 ([event type] == NSKeyDown || [event type] == NSKeyUp) && |
872 [event keyCode] == kVK_Return)) { | 878 [event keyCode] == kVK_Return)) { |
873 WindowOpenDisposition disposition = | 879 WindowOpenDisposition disposition = |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 | 1139 |
1134 NSUInteger OmniboxViewMac::GetTextLength() const { | 1140 NSUInteger OmniboxViewMac::GetTextLength() const { |
1135 return [field_ currentEditor] ? [[[field_ currentEditor] string] length] : | 1141 return [field_ currentEditor] ? [[[field_ currentEditor] string] length] : |
1136 [[field_ stringValue] length]; | 1142 [[field_ stringValue] length]; |
1137 } | 1143 } |
1138 | 1144 |
1139 bool OmniboxViewMac::IsCaretAtEnd() const { | 1145 bool OmniboxViewMac::IsCaretAtEnd() const { |
1140 const NSRange selection = GetSelectedRange(); | 1146 const NSRange selection = GetSelectedRange(); |
1141 return NSMaxRange(selection) == GetTextLength(); | 1147 return NSMaxRange(selection) == GetTextLength(); |
1142 } | 1148 } |
OLD | NEW |