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/autocomplete/autocomplete_edit.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 keyword_.clear(); | 375 keyword_.clear(); |
376 is_keyword_hint_ = false; | 376 is_keyword_hint_ = false; |
377 has_temporary_text_ = false; | 377 has_temporary_text_ = false; |
378 view_->SetWindowTextAndCaretPos(permanent_text_, | 378 view_->SetWindowTextAndCaretPos(permanent_text_, |
379 has_focus_ ? permanent_text_.length() : 0); | 379 has_focus_ ? permanent_text_.length() : 0); |
380 } | 380 } |
381 | 381 |
382 void AutocompleteEditModel::StartAutocomplete( | 382 void AutocompleteEditModel::StartAutocomplete( |
383 bool has_selected_text, | 383 bool has_selected_text, |
384 bool prevent_inline_autocomplete) const { | 384 bool prevent_inline_autocomplete) const { |
385 ResetCurrentMatchKeywordMode(); | |
386 | |
385 bool keyword_is_selected = KeywordIsSelected(); | 387 bool keyword_is_selected = KeywordIsSelected(); |
386 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); | 388 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); |
387 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, | 389 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, |
388 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which | 390 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which |
389 // clears it. | 391 // clears it. |
390 autocomplete_controller_->Start( | 392 autocomplete_controller_->Start( |
391 user_text_, GetDesiredTLD(), | 393 user_text_, GetDesiredTLD(), |
392 prevent_inline_autocomplete || just_deleted_text_ || | 394 prevent_inline_autocomplete || just_deleted_text_ || |
393 (has_selected_text && inline_autocomplete_text_.empty()) || | 395 (has_selected_text && inline_autocomplete_text_.empty()) || |
394 (paste_state_ != NONE), keyword_is_selected, | 396 (paste_state_ != NONE), keyword_is_selected, |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
541 | 543 |
542 InstantController* instant = controller_->GetInstant(); | 544 InstantController* instant = controller_->GetInstant(); |
543 if (instant && !popup_->IsOpen()) | 545 if (instant && !popup_->IsOpen()) |
544 instant->DestroyPreviewContents(); | 546 instant->DestroyPreviewContents(); |
545 update_instant_ = true; | 547 update_instant_ = true; |
546 } | 548 } |
547 | 549 |
548 bool AutocompleteEditModel::AcceptKeyword() { | 550 bool AutocompleteEditModel::AcceptKeyword() { |
549 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 551 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
550 | 552 |
551 view_->OnBeforePossibleChange(); | 553 autocomplete_controller_->Stop(false); |
552 view_->SetWindowTextAndCaretPos(string16(), 0); | |
553 is_keyword_hint_ = false; | 554 is_keyword_hint_ = false; |
554 view_->OnAfterPossibleChange(); | 555 |
555 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this | 556 if (popup_->selected_line() != AutocompletePopupModel::kNoMatch) { |
Peter Kasting
2011/04/11 23:17:33
Nit: Ask if the popup is open instead (if it's ope
| |
556 // since the edit contents have disappeared. It | 557 AutocompleteMatch match = CurrentMatch(); |
Peter Kasting
2011/04/11 23:17:33
This function does not exist.
| |
557 // doesn't really matter, but we clear it to be | 558 |
558 // consistent. | 559 match.keyword->is_keyword_mode = true; |
560 popup_->view()->InvalidateLine(popup_->selected_line()); | |
561 } | |
562 | |
563 view_->SetUserText(string16(), string16(), false); | |
564 | |
559 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint"), profile_); | 565 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint"), profile_); |
560 return true; | 566 return true; |
561 } | 567 } |
562 | 568 |
563 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { | 569 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { |
564 view_->OnBeforePossibleChange(); | 570 autocomplete_controller_->Stop(false); |
571 ResetCurrentMatchKeywordMode(); | |
572 | |
565 const string16 window_text(keyword_ + visible_text); | 573 const string16 window_text(keyword_ + visible_text); |
566 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); | 574 |
567 keyword_.clear(); | 575 // Only reset the result if the edit text has changed since the |
568 is_keyword_hint_ = false; | 576 // keyword was accepted. |
569 view_->OnAfterPossibleChange(); | 577 if (just_deleted_text_) { |
570 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 578 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); |
571 // since the edit contents have actually grown | 579 keyword_.clear(); |
572 // longer. | 580 is_keyword_hint_ = false; |
581 view_->OnAfterPossibleChange(); | |
582 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | |
583 // since the edit contents have actually grown | |
584 // longer. | |
585 } else { | |
586 view_->SetUserText(window_text, window_text, false); | |
587 | |
588 is_keyword_hint_ = visible_text.empty(); | |
589 if (!is_keyword_hint_) | |
590 keyword_.clear(); | |
591 | |
592 OnChanged(); | |
593 } | |
594 } | |
595 | |
596 void AutocompleteEditModel::ResetCurrentMatchKeywordMode() const { | |
597 if (popup_->selected_line() != AutocompletePopupModel::kNoMatch) { | |
Peter Kasting
2011/04/11 23:17:33
Nit: Ask if the popup is open instead.
| |
598 AutocompleteMatch match; | |
599 InfoForCurrentSelection(&match, NULL); | |
600 | |
601 if (match.keyword.get() && match.keyword->is_keyword_hint && | |
602 match.keyword->is_keyword_mode) { | |
603 match.keyword->is_keyword_mode = false; | |
604 popup_->view()->InvalidateLine(popup_->selected_line()); | |
605 } | |
606 } | |
573 } | 607 } |
574 | 608 |
575 const AutocompleteResult& AutocompleteEditModel::result() const { | 609 const AutocompleteResult& AutocompleteEditModel::result() const { |
576 return autocomplete_controller_->result(); | 610 return autocomplete_controller_->result(); |
577 } | 611 } |
578 | 612 |
579 void AutocompleteEditModel::OnSetFocus(bool control_down) { | 613 void AutocompleteEditModel::OnSetFocus(bool control_down) { |
580 has_focus_ = true; | 614 has_focus_ = true; |
581 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 615 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
582 NotificationService::current()->Notify( | 616 NotificationService::current()->Notify( |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
661 if (!user_input_in_progress_) | 695 if (!user_input_in_progress_) |
662 InternalSetUserText(permanent_text_); | 696 InternalSetUserText(permanent_text_); |
663 view_->UpdatePopup(); | 697 view_->UpdatePopup(); |
664 } else { | 698 } else { |
665 // TODO(pkasting): The popup is working on a query but is not open. We | 699 // TODO(pkasting): The popup is working on a query but is not open. We |
666 // should force it to open immediately. | 700 // should force it to open immediately. |
667 } | 701 } |
668 } else { | 702 } else { |
669 // The popup is open, so the user should be able to interact with it | 703 // The popup is open, so the user should be able to interact with it |
670 // normally. | 704 // normally. |
705 if (popup_->selected_line() != AutocompletePopupModel::kNoMatch) { | |
Peter Kasting
2011/04/11 23:17:33
Nit: Ask if the popup is open instead.
| |
706 AutocompleteMatch match = CurrentMatch(); | |
Peter Kasting
2011/04/11 23:17:33
This function does not exist.
| |
707 | |
708 if (match.keyword.get() && match.keyword->is_keyword_hint && | |
709 match.keyword->is_keyword_mode) | |
710 ClearKeyword(string16()); | |
711 } | |
712 | |
671 popup_->Move(count); | 713 popup_->Move(count); |
672 } | 714 } |
673 } | 715 } |
674 | 716 |
675 void AutocompleteEditModel::OnPopupDataChanged( | 717 void AutocompleteEditModel::OnPopupDataChanged( |
676 const string16& text, | 718 const string16& text, |
677 GURL* destination_for_temporary_text_change, | 719 GURL* destination_for_temporary_text_change, |
678 const string16& keyword, | 720 const string16& keyword, |
679 bool is_keyword_hint) { | 721 bool is_keyword_hint) { |
680 // Update keyword/hint-related local state. | 722 // Update keyword/hint-related local state. |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
846 if (!match->destination_url.SchemeIs(chrome::kExtensionScheme)) { | 888 if (!match->destination_url.SchemeIs(chrome::kExtensionScheme)) { |
847 // Warm up DNS Prefetch cache, or preconnect to a search service. | 889 // Warm up DNS Prefetch cache, or preconnect to a search service. |
848 chrome_browser_net::AnticipateOmniboxUrl(match->destination_url, | 890 chrome_browser_net::AnticipateOmniboxUrl(match->destination_url, |
849 IsPreconnectable(match->type)); | 891 IsPreconnectable(match->type)); |
850 } | 892 } |
851 | 893 |
852 // We could prefetch the alternate nav URL, if any, but because there | 894 // We could prefetch the alternate nav URL, if any, but because there |
853 // can be many of these as a user types an initial series of characters, | 895 // can be many of these as a user types an initial series of characters, |
854 // the OS DNS cache could suffer eviction problems for minimal gain. | 896 // the OS DNS cache could suffer eviction problems for minimal gain. |
855 | 897 |
856 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); | 898 if (match->keyword.get()) { |
899 is_keyword_hint = match->keyword->is_keyword_hint; | |
900 keyword = match->keyword->text; | |
901 } | |
857 } | 902 } |
903 | |
858 popup_->OnResultChanged(); | 904 popup_->OnResultChanged(); |
859 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, | 905 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, |
860 is_keyword_hint); | 906 is_keyword_hint); |
861 } else { | 907 } else { |
862 popup_->OnResultChanged(); | 908 popup_->OnResultChanged(); |
863 } | 909 } |
864 | 910 |
865 if (popup_->IsOpen()) { | 911 if (popup_->IsOpen()) { |
866 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); | 912 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); |
867 } else if (was_open) { | 913 } else if (was_open) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
991 old_user_text.length() - caret_position + 1)) { | 1037 old_user_text.length() - caret_position + 1)) { |
992 return false; | 1038 return false; |
993 } | 1039 } |
994 | 1040 |
995 // Then check if the text before the inserted space matches a keyword. | 1041 // Then check if the text before the inserted space matches a keyword. |
996 string16 keyword; | 1042 string16 keyword; |
997 TrimWhitespace(new_user_text.substr(0, caret_position - 1), | 1043 TrimWhitespace(new_user_text.substr(0, caret_position - 1), |
998 TRIM_LEADING, &keyword); | 1044 TRIM_LEADING, &keyword); |
999 | 1045 |
1000 // Only allow exact keyword match if |keyword| represents a keyword hint. | 1046 // Only allow exact keyword match if |keyword| represents a keyword hint. |
1001 return keyword.length() && popup_->GetKeywordForText(keyword, &keyword); | 1047 return keyword.length() && |
1048 !autocomplete_controller_->GetKeywordForText(keyword).empty(); | |
1002 } | 1049 } |
1003 | 1050 |
1004 // static | 1051 // static |
1005 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1052 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
1006 switch (c) { | 1053 switch (c) { |
1007 case 0x0020: // Space | 1054 case 0x0020: // Space |
1008 case 0x3000: // Ideographic Space | 1055 case 0x3000: // Ideographic Space |
1009 return true; | 1056 return true; |
1010 default: | 1057 default: |
1011 return false; | 1058 return false; |
1012 } | 1059 } |
1013 } | 1060 } |
OLD | NEW |