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/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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 has_temporary_text_ = false; | 166 has_temporary_text_ = false; |
167 } | 167 } |
168 | 168 |
169 void AutocompleteEditModel::FinalizeInstantQuery( | 169 void AutocompleteEditModel::FinalizeInstantQuery( |
170 const string16& input_text, | 170 const string16& input_text, |
171 const string16& suggest_text, | 171 const string16& suggest_text, |
172 bool skip_inline_autocomplete) { | 172 bool skip_inline_autocomplete) { |
173 if (skip_inline_autocomplete) { | 173 if (skip_inline_autocomplete) { |
174 const string16 final_text = input_text + suggest_text; | 174 const string16 final_text = input_text + suggest_text; |
175 view_->OnBeforePossibleChange(); | 175 view_->OnBeforePossibleChange(); |
176 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, | 176 view_->SetWindowTextAndCaretPos(final_text, final_text.length()); |
177 false); | |
178 view_->OnAfterPossibleChange(); | 177 view_->OnAfterPossibleChange(); |
179 } else if (popup_->IsOpen()) { | 178 } else if (popup_->IsOpen()) { |
180 SearchProvider* search_provider = | 179 SearchProvider* search_provider = |
181 autocomplete_controller_->search_provider(); | 180 autocomplete_controller_->search_provider(); |
182 // There may be no providers during testing; guard against that. | 181 // There may be no providers during testing; guard against that. |
183 if (search_provider) | 182 if (search_provider) |
184 search_provider->FinalizeInstantQuery(input_text, suggest_text); | 183 search_provider->FinalizeInstantQuery(input_text, suggest_text); |
185 } | 184 } |
186 } | 185 } |
187 | 186 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 } | 399 } |
401 | 400 |
402 void AutocompleteEditModel::Revert() { | 401 void AutocompleteEditModel::Revert() { |
403 SetInputInProgress(false); | 402 SetInputInProgress(false); |
404 paste_state_ = NONE; | 403 paste_state_ = NONE; |
405 InternalSetUserText(string16()); | 404 InternalSetUserText(string16()); |
406 keyword_.clear(); | 405 keyword_.clear(); |
407 is_keyword_hint_ = false; | 406 is_keyword_hint_ = false; |
408 has_temporary_text_ = false; | 407 has_temporary_text_ = false; |
409 view_->SetWindowTextAndCaretPos(permanent_text_, | 408 view_->SetWindowTextAndCaretPos(permanent_text_, |
410 has_focus_ ? permanent_text_.length() : 0, | 409 has_focus_ ? permanent_text_.length() : 0); |
411 false, true); | |
412 NetworkActionPredictor* network_action_predictor = | 410 NetworkActionPredictor* network_action_predictor = |
413 NetworkActionPredictorFactory::GetForProfile(profile_); | 411 NetworkActionPredictorFactory::GetForProfile(profile_); |
414 if (network_action_predictor) | 412 if (network_action_predictor) |
415 network_action_predictor->ClearTransitionalMatches(); | 413 network_action_predictor->ClearTransitionalMatches(); |
416 } | 414 } |
417 | 415 |
418 void AutocompleteEditModel::StartAutocomplete( | 416 void AutocompleteEditModel::StartAutocomplete( |
419 bool has_selected_text, | 417 bool has_selected_text, |
420 bool prevent_inline_autocomplete) const { | 418 bool prevent_inline_autocomplete) const { |
421 ClearPopupKeywordMode(); | |
422 | |
423 bool keyword_is_selected = KeywordIsSelected(); | 419 bool keyword_is_selected = KeywordIsSelected(); |
424 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); | 420 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); |
425 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, | 421 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, |
426 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which | 422 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which |
427 // clears it. | 423 // clears it. |
428 autocomplete_controller_->Start( | 424 autocomplete_controller_->Start( |
429 user_text_, GetDesiredTLD(), | 425 user_text_, GetDesiredTLD(), |
430 prevent_inline_autocomplete || just_deleted_text_ || | 426 prevent_inline_autocomplete || just_deleted_text_ || |
431 (has_selected_text && inline_autocomplete_text_.empty()) || | 427 (has_selected_text && inline_autocomplete_text_.empty()) || |
432 (paste_state_ != NONE), keyword_is_selected, | 428 (paste_state_ != NONE), keyword_is_selected, |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 | 611 |
616 InstantController* instant = controller_->GetInstant(); | 612 InstantController* instant = controller_->GetInstant(); |
617 if (instant && !popup_->IsOpen()) | 613 if (instant && !popup_->IsOpen()) |
618 instant->DestroyPreviewContents(); | 614 instant->DestroyPreviewContents(); |
619 in_revert_ = false; | 615 in_revert_ = false; |
620 } | 616 } |
621 | 617 |
622 bool AutocompleteEditModel::AcceptKeyword() { | 618 bool AutocompleteEditModel::AcceptKeyword() { |
623 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 619 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
624 | 620 |
625 autocomplete_controller_->Stop(false); | 621 view_->OnBeforePossibleChange(); |
| 622 view_->SetWindowTextAndCaretPos(string16(), 0); |
626 is_keyword_hint_ = false; | 623 is_keyword_hint_ = false; |
627 | 624 view_->OnAfterPossibleChange(); |
628 if (popup_->IsOpen()) | 625 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this |
629 popup_->SetSelectedLineState(AutocompletePopupModel::KEYWORD); | 626 // since the edit contents have disappeared. It |
630 else | 627 // doesn't really matter, but we clear it to be |
631 StartAutocomplete(false, true); | 628 // consistent. |
632 | |
633 // Ensure the current selection is saved before showing keyword mode | |
634 // so that moving to another line and then reverting the text will restore | |
635 // the current state properly. | |
636 view_->OnTemporaryTextMaybeChanged( | |
637 DisplayTextFromUserText(CurrentMatch().fill_into_edit), | |
638 !has_temporary_text_); | |
639 has_temporary_text_ = true; | |
640 | |
641 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 629 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
642 return true; | 630 return true; |
643 } | 631 } |
644 | 632 |
645 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { | 633 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { |
646 autocomplete_controller_->Stop(false); | 634 view_->OnBeforePossibleChange(); |
647 ClearPopupKeywordMode(); | |
648 | |
649 const string16 window_text(keyword_ + visible_text); | 635 const string16 window_text(keyword_ + visible_text); |
650 | 636 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); |
651 // Only reset the result if the edit text has changed since the | 637 keyword_.clear(); |
652 // keyword was accepted, or if the popup is closed. | 638 is_keyword_hint_ = false; |
653 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { | 639 view_->OnAfterPossibleChange(); |
654 view_->OnBeforePossibleChange(); | 640 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
655 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 641 // since the edit contents have actually grown |
656 false, false); | 642 // longer. |
657 keyword_.clear(); | |
658 is_keyword_hint_ = false; | |
659 view_->OnAfterPossibleChange(); | |
660 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | |
661 // since the edit contents have actually grown | |
662 // longer. | |
663 } else { | |
664 is_keyword_hint_ = true; | |
665 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | |
666 false, true); | |
667 } | |
668 } | 643 } |
669 | 644 |
670 const AutocompleteResult& AutocompleteEditModel::result() const { | 645 const AutocompleteResult& AutocompleteEditModel::result() const { |
671 return autocomplete_controller_->result(); | 646 return autocomplete_controller_->result(); |
672 } | 647 } |
673 | 648 |
674 void AutocompleteEditModel::OnSetFocus(bool control_down) { | 649 void AutocompleteEditModel::OnSetFocus(bool control_down) { |
675 has_focus_ = true; | 650 has_focus_ = true; |
676 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 651 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
677 | 652 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 match->fill_into_edit.substr(match->inline_autocomplete_offset); | 895 match->fill_into_edit.substr(match->inline_autocomplete_offset); |
921 } | 896 } |
922 | 897 |
923 if (!prerender::IsOmniboxEnabled(profile_)) | 898 if (!prerender::IsOmniboxEnabled(profile_)) |
924 DoPreconnect(*match); | 899 DoPreconnect(*match); |
925 | 900 |
926 // We could prefetch the alternate nav URL, if any, but because there | 901 // We could prefetch the alternate nav URL, if any, but because there |
927 // can be many of these as a user types an initial series of characters, | 902 // can be many of these as a user types an initial series of characters, |
928 // the OS DNS cache could suffer eviction problems for minimal gain. | 903 // the OS DNS cache could suffer eviction problems for minimal gain. |
929 | 904 |
930 is_keyword_hint = match->GetKeyword(&keyword); | 905 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); |
931 } | 906 } |
932 | |
933 popup_->OnResultChanged(); | 907 popup_->OnResultChanged(); |
934 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, | 908 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, |
935 is_keyword_hint); | 909 is_keyword_hint); |
936 } else { | 910 } else { |
937 popup_->OnResultChanged(); | 911 popup_->OnResultChanged(); |
938 } | 912 } |
939 | 913 |
940 if (popup_->IsOpen()) { | 914 if (popup_->IsOpen()) { |
941 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); | 915 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); |
942 } else if (was_open) { | 916 } else if (was_open) { |
(...skipping 12 matching lines...) Expand all Loading... |
955 void AutocompleteEditModel::InternalSetUserText(const string16& text) { | 929 void AutocompleteEditModel::InternalSetUserText(const string16& text) { |
956 user_text_ = text; | 930 user_text_ = text; |
957 just_deleted_text_ = false; | 931 just_deleted_text_ = false; |
958 inline_autocomplete_text_.clear(); | 932 inline_autocomplete_text_.clear(); |
959 } | 933 } |
960 | 934 |
961 bool AutocompleteEditModel::KeywordIsSelected() const { | 935 bool AutocompleteEditModel::KeywordIsSelected() const { |
962 return !is_keyword_hint_ && !keyword_.empty(); | 936 return !is_keyword_hint_ && !keyword_.empty(); |
963 } | 937 } |
964 | 938 |
965 void AutocompleteEditModel::ClearPopupKeywordMode() const { | |
966 if (popup_->IsOpen() && | |
967 popup_->selected_line_state() == AutocompletePopupModel::KEYWORD) | |
968 popup_->SetSelectedLineState(AutocompletePopupModel::NORMAL); | |
969 } | |
970 | |
971 string16 AutocompleteEditModel::DisplayTextFromUserText( | 939 string16 AutocompleteEditModel::DisplayTextFromUserText( |
972 const string16& text) const { | 940 const string16& text) const { |
973 return KeywordIsSelected() ? | 941 return KeywordIsSelected() ? |
974 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 942 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
975 } | 943 } |
976 | 944 |
977 string16 AutocompleteEditModel::UserTextFromDisplayText( | 945 string16 AutocompleteEditModel::UserTextFromDisplayText( |
978 const string16& text) const { | 946 const string16& text) const { |
979 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 947 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
980 } | 948 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 old_user_text.length() - caret_position + 1)) { | 1028 old_user_text.length() - caret_position + 1)) { |
1061 return false; | 1029 return false; |
1062 } | 1030 } |
1063 | 1031 |
1064 // Then check if the text before the inserted space matches a keyword. | 1032 // Then check if the text before the inserted space matches a keyword. |
1065 string16 keyword; | 1033 string16 keyword; |
1066 TrimWhitespace(new_user_text.substr(0, caret_position - 1), | 1034 TrimWhitespace(new_user_text.substr(0, caret_position - 1), |
1067 TRIM_LEADING, &keyword); | 1035 TRIM_LEADING, &keyword); |
1068 | 1036 |
1069 // Only allow exact keyword match if |keyword| represents a keyword hint. | 1037 // Only allow exact keyword match if |keyword| represents a keyword hint. |
1070 return keyword.length() && | 1038 return keyword.length() && popup_->GetKeywordForText(keyword, &keyword); |
1071 !autocomplete_controller_->keyword_provider()-> | |
1072 GetKeywordForText(keyword).empty(); | |
1073 } | 1039 } |
1074 | 1040 |
1075 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, | 1041 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, |
1076 string16* suggested_text) { | 1042 string16* suggested_text) { |
1077 DCHECK(suggested_text); | 1043 DCHECK(suggested_text); |
1078 | 1044 |
1079 if (in_revert_) | 1045 if (in_revert_) |
1080 return false; | 1046 return false; |
1081 | 1047 |
1082 InstantController* instant = controller_->GetInstant(); | 1048 InstantController* instant = controller_->GetInstant(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 // static | 1104 // static |
1139 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1105 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
1140 switch (c) { | 1106 switch (c) { |
1141 case 0x0020: // Space | 1107 case 0x0020: // Space |
1142 case 0x3000: // Ideographic Space | 1108 case 0x3000: // Ideographic Space |
1143 return true; | 1109 return true; |
1144 default: | 1110 default: |
1145 return false; | 1111 return false; |
1146 } | 1112 } |
1147 } | 1113 } |
OLD | NEW |