| 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/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 DCHECK_LE(caret_pos, text.size()); | 344 DCHECK_LE(caret_pos, text.size()); |
| 345 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, 0)); | 345 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, 0)); |
| 346 | 346 |
| 347 if (update_popup) | 347 if (update_popup) |
| 348 UpdatePopup(); | 348 UpdatePopup(); |
| 349 | 349 |
| 350 if (notify_text_changed) | 350 if (notify_text_changed) |
| 351 TextChanged(); | 351 TextChanged(); |
| 352 } | 352 } |
| 353 | 353 |
| 354 void OmniboxViewMac::SetForcedQuery() { | 354 void OmniboxViewMac::EnterKeywordModeForDefaultSearchProvider() { |
| 355 // We need to do this first, else |SetSelectedRange()| won't work. | 355 // We need to do this first, else |SetSelectedRange()| won't work. |
| 356 FocusLocation(true); | 356 FocusLocation(true); |
| 357 | 357 |
| 358 const base::string16 current_text(GetText()); | 358 // Transition the user into keyword mode using their default search provider. |
| 359 const size_t start = current_text.find_first_not_of(base::kWhitespaceUTF16); | 359 // Select their query if they typed one. |
| 360 if (start == base::string16::npos || (current_text[start] != '?')) { | 360 model()->EnterKeywordModeForDefaultSearchProvider( |
| 361 SetUserText(base::ASCIIToUTF16("?")); | 361 METHOD_KEYBOARD_SHORTCUT); |
| 362 } else { | 362 NSRange range = NSMakeRange(0, GetText().size()); |
| 363 NSRange range = NSMakeRange(start + 1, current_text.size() - start - 1); | 363 [[field_ currentEditor] setSelectedRange:range]; |
| 364 [[field_ currentEditor] setSelectedRange:range]; | |
| 365 } | |
| 366 } | 364 } |
| 367 | 365 |
| 368 bool OmniboxViewMac::IsSelectAll() const { | 366 bool OmniboxViewMac::IsSelectAll() const { |
| 369 if (![field_ currentEditor]) | 367 if (![field_ currentEditor]) |
| 370 return true; | 368 return true; |
| 371 const NSRange all_range = NSMakeRange(0, GetTextLength()); | 369 const NSRange all_range = NSMakeRange(0, GetTextLength()); |
| 372 return NSEqualRanges(all_range, GetSelectedRange()); | 370 return NSEqualRanges(all_range, GetSelectedRange()); |
| 373 } | 371 } |
| 374 | 372 |
| 375 bool OmniboxViewMac::DeleteAtEndPressed() { | 373 bool OmniboxViewMac::DeleteAtEndPressed() { |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 bool OmniboxViewMac::IsFirstResponder() const { | 645 bool OmniboxViewMac::IsFirstResponder() const { |
| 648 return [field_ currentEditor] != nil ? true : false; | 646 return [field_ currentEditor] != nil ? true : false; |
| 649 } | 647 } |
| 650 | 648 |
| 651 void OmniboxViewMac::OnBeforePossibleChange() { | 649 void OmniboxViewMac::OnBeforePossibleChange() { |
| 652 // We should only arrive here when the field is focused. | 650 // We should only arrive here when the field is focused. |
| 653 DCHECK(IsFirstResponder()); | 651 DCHECK(IsFirstResponder()); |
| 654 | 652 |
| 655 selection_before_change_ = GetSelectedRange(); | 653 selection_before_change_ = GetSelectedRange(); |
| 656 text_before_change_ = GetText(); | 654 text_before_change_ = GetText(); |
| 655 keyword_before_change_ = model()->keyword(); |
| 656 is_keyword_selected_before_change_ = model()->is_keyword_selected(); |
| 657 marked_range_before_change_ = GetMarkedRange(); | 657 marked_range_before_change_ = GetMarkedRange(); |
| 658 } | 658 } |
| 659 | 659 |
| 660 bool OmniboxViewMac::OnAfterPossibleChange(bool allow_keyword_ui_change) { | 660 bool OmniboxViewMac::OnAfterPossibleChange(bool allow_keyword_ui_change) { |
| 661 // We should only arrive here when the field is focused. | 661 // We should only arrive here when the field is focused. |
| 662 DCHECK(IsFirstResponder()); | 662 DCHECK(IsFirstResponder()); |
| 663 | 663 |
| 664 const NSRange new_selection(GetSelectedRange()); | 664 const NSRange new_selection(GetSelectedRange()); |
| 665 const base::string16 new_text(GetText()); | 665 const base::string16 new_text(GetText()); |
| 666 const base::string16 new_keyword(model()->keyword()); |
| 667 const bool new_is_keyword_selected = model()->is_keyword_selected(); |
| 666 const size_t length = new_text.length(); | 668 const size_t length = new_text.length(); |
| 667 | 669 |
| 668 const bool selection_differs = | 670 const bool selection_differs = |
| 669 (new_selection.length || selection_before_change_.length) && | 671 (new_selection.length || selection_before_change_.length) && |
| 670 !NSEqualRanges(new_selection, selection_before_change_); | 672 !NSEqualRanges(new_selection, selection_before_change_); |
| 671 const bool at_end_of_edit = (length == new_selection.location); | 673 const bool at_end_of_edit = (length == new_selection.location); |
| 672 const bool text_differs = (new_text != text_before_change_) || | 674 const bool text_differs = (new_text != text_before_change_) || |
| 673 !NSEqualRanges(marked_range_before_change_, GetMarkedRange()); | 675 !NSEqualRanges(marked_range_before_change_, GetMarkedRange()); |
| 676 const bool keyword_differs = |
| 677 (new_is_keyword_selected != is_keyword_selected_before_change_) || |
| 678 (new_is_keyword_selected && is_keyword_selected_before_change_ && |
| 679 new_keyword != keyword_before_change_); |
| 674 | 680 |
| 675 // When the user has deleted text, we don't allow inline | 681 // When the user has deleted text, we don't allow inline |
| 676 // autocomplete. This is assumed if the text has gotten shorter AND | 682 // autocomplete. This is assumed if the text has gotten shorter AND |
| 677 // the selection has shifted towards the front of the text. During | 683 // the selection has shifted towards the front of the text. During |
| 678 // normal typing the text will almost always be shorter (as the new | 684 // normal typing the text will almost always be shorter (as the new |
| 679 // input replaces the autocomplete suggestion), but in that case the | 685 // input replaces the autocomplete suggestion), but in that case the |
| 680 // selection point will have moved towards the end of the text. | 686 // selection point will have moved towards the end of the text. |
| 681 // TODO(shess): In our implementation, we can catch -deleteBackward: | 687 // TODO(shess): In our implementation, we can catch -deleteBackward: |
| 682 // and other methods to provide positive knowledge that a delete | 688 // and other methods to provide positive knowledge that a delete |
| 683 // occurred, rather than intuiting it from context. Consider whether | 689 // occurred, rather than intuiting it from context. Consider whether |
| 684 // that would be a stronger approach. | 690 // that would be a stronger approach. |
| 685 const bool just_deleted_text = | 691 const bool just_deleted_text = |
| 686 (length < text_before_change_.length() && | 692 (length < text_before_change_.length() && |
| 687 new_selection.location <= selection_before_change_.location); | 693 new_selection.location <= selection_before_change_.location); |
| 688 | 694 |
| 689 delete_at_end_pressed_ = false; | 695 delete_at_end_pressed_ = false; |
| 690 | 696 |
| 691 const bool something_changed = model()->OnAfterPossibleChange( | 697 const bool something_changed = model()->OnAfterPossibleChange( |
| 692 text_before_change_, new_text, new_selection.location, | 698 text_before_change_, new_text, new_selection.location, |
| 693 NSMaxRange(new_selection), selection_differs, text_differs, | 699 NSMaxRange(new_selection), selection_differs, text_differs, |
| 694 just_deleted_text, allow_keyword_ui_change && !IsImeComposing()); | 700 keyword_differs, just_deleted_text, |
| 701 allow_keyword_ui_change && !IsImeComposing()); |
| 695 | 702 |
| 696 if (delete_was_pressed_ && at_end_of_edit) | 703 if (delete_was_pressed_ && at_end_of_edit) |
| 697 delete_at_end_pressed_ = true; | 704 delete_at_end_pressed_ = true; |
| 698 | 705 |
| 699 // Restyle in case the user changed something. | 706 // Restyle in case the user changed something. |
| 700 // TODO(shess): I believe there are multiple-redraw cases, here. | 707 // TODO(shess): I believe there are multiple-redraw cases, here. |
| 701 // Linux watches for something_changed && text_differs, but that | 708 // Linux watches for something_changed && text_differs, but that |
| 702 // fails for us in case you copy the URL and paste the identical URL | 709 // fails for us in case you copy the URL and paste the identical URL |
| 703 // back (we'll lose the styling). | 710 // back (we'll lose the styling). |
| 704 TextChanged(); | 711 TextChanged(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 return true; | 839 return true; |
| 833 } | 840 } |
| 834 | 841 |
| 835 if (cmd == @selector(cancelOperation:)) { | 842 if (cmd == @selector(cancelOperation:)) { |
| 836 return model()->OnEscapeKeyPressed(); | 843 return model()->OnEscapeKeyPressed(); |
| 837 } | 844 } |
| 838 | 845 |
| 839 if ((cmd == @selector(insertTab:) || | 846 if ((cmd == @selector(insertTab:) || |
| 840 cmd == @selector(insertTabIgnoringFieldEditor:)) && | 847 cmd == @selector(insertTabIgnoringFieldEditor:)) && |
| 841 model()->is_keyword_hint()) { | 848 model()->is_keyword_hint()) { |
| 842 return model()->AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_TAB); | 849 return model()->AcceptKeyword(METHOD_TAB); |
| 843 } | 850 } |
| 844 | 851 |
| 845 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op | 852 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op |
| 846 // behavior with the proper WindowOpenDisposition. | 853 // behavior with the proper WindowOpenDisposition. |
| 847 NSEvent* event = [NSApp currentEvent]; | 854 NSEvent* event = [NSApp currentEvent]; |
| 848 if (cmd == @selector(insertNewline:) || | 855 if (cmd == @selector(insertNewline:) || |
| 849 (cmd == @selector(noop:) && | 856 (cmd == @selector(noop:) && |
| 850 ([event type] == NSKeyDown || [event type] == NSKeyUp) && | 857 ([event type] == NSKeyDown || [event type] == NSKeyUp) && |
| 851 [event keyCode] == kVK_Return)) { | 858 [event keyCode] == kVK_Return)) { |
| 852 WindowOpenDisposition disposition = | 859 WindowOpenDisposition disposition = |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 | 1108 |
| 1102 NSUInteger OmniboxViewMac::GetTextLength() const { | 1109 NSUInteger OmniboxViewMac::GetTextLength() const { |
| 1103 return [field_ currentEditor] ? [[[field_ currentEditor] string] length] : | 1110 return [field_ currentEditor] ? [[[field_ currentEditor] string] length] : |
| 1104 [[field_ stringValue] length]; | 1111 [[field_ stringValue] length]; |
| 1105 } | 1112 } |
| 1106 | 1113 |
| 1107 bool OmniboxViewMac::IsCaretAtEnd() const { | 1114 bool OmniboxViewMac::IsCaretAtEnd() const { |
| 1108 const NSRange selection = GetSelectedRange(); | 1115 const NSRange selection = GetSelectedRange(); |
| 1109 return NSMaxRange(selection) == GetTextLength(); | 1116 return NSMaxRange(selection) == GetTextLength(); |
| 1110 } | 1117 } |
| OLD | NEW |