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