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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 | 620 |
625 InstantController* instant = controller_->GetInstant(); | 621 InstantController* instant = controller_->GetInstant(); |
626 if (instant && !popup_->IsOpen()) | 622 if (instant && !popup_->IsOpen()) |
627 instant->DestroyPreviewContents(); | 623 instant->DestroyPreviewContents(); |
628 in_revert_ = false; | 624 in_revert_ = false; |
629 } | 625 } |
630 | 626 |
631 bool AutocompleteEditModel::AcceptKeyword() { | 627 bool AutocompleteEditModel::AcceptKeyword() { |
632 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 628 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
633 | 629 |
634 autocomplete_controller_->Stop(false); | 630 view_->OnBeforePossibleChange(); |
| 631 view_->SetWindowTextAndCaretPos(string16(), 0); |
635 is_keyword_hint_ = false; | 632 is_keyword_hint_ = false; |
636 | 633 view_->OnAfterPossibleChange(); |
637 if (popup_->IsOpen()) | 634 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this |
638 popup_->SetSelectedLineState(AutocompletePopupModel::KEYWORD); | 635 // since the edit contents have disappeared. It |
639 else | 636 // doesn't really matter, but we clear it to be |
640 StartAutocomplete(false, true); | 637 // consistent. |
641 | |
642 // Ensure the current selection is saved before showing keyword mode | |
643 // so that moving to another line and then reverting the text will restore | |
644 // the current state properly. | |
645 view_->OnTemporaryTextMaybeChanged( | |
646 DisplayTextFromUserText(CurrentMatch().fill_into_edit), | |
647 !has_temporary_text_); | |
648 has_temporary_text_ = true; | |
649 | |
650 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 638 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
651 return true; | 639 return true; |
652 } | 640 } |
653 | 641 |
654 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { | 642 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { |
655 autocomplete_controller_->Stop(false); | 643 view_->OnBeforePossibleChange(); |
656 ClearPopupKeywordMode(); | |
657 | |
658 const string16 window_text(keyword_ + visible_text); | 644 const string16 window_text(keyword_ + visible_text); |
659 | 645 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); |
660 // Only reset the result if the edit text has changed since the | 646 keyword_.clear(); |
661 // keyword was accepted, or if the popup is closed. | 647 is_keyword_hint_ = false; |
662 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { | 648 view_->OnAfterPossibleChange(); |
663 view_->OnBeforePossibleChange(); | 649 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
664 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 650 // since the edit contents have actually grown |
665 false, false); | 651 // longer. |
666 keyword_.clear(); | |
667 is_keyword_hint_ = false; | |
668 view_->OnAfterPossibleChange(); | |
669 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | |
670 // since the edit contents have actually grown | |
671 // longer. | |
672 } else { | |
673 is_keyword_hint_ = true; | |
674 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | |
675 false, true); | |
676 } | |
677 } | 652 } |
678 | 653 |
679 const AutocompleteResult& AutocompleteEditModel::result() const { | 654 const AutocompleteResult& AutocompleteEditModel::result() const { |
680 return autocomplete_controller_->result(); | 655 return autocomplete_controller_->result(); |
681 } | 656 } |
682 | 657 |
683 void AutocompleteEditModel::OnSetFocus(bool control_down) { | 658 void AutocompleteEditModel::OnSetFocus(bool control_down) { |
684 has_focus_ = true; | 659 has_focus_ = true; |
685 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 660 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
686 | 661 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 match->fill_into_edit.substr(match->inline_autocomplete_offset); | 904 match->fill_into_edit.substr(match->inline_autocomplete_offset); |
930 } | 905 } |
931 | 906 |
932 if (!prerender::IsOmniboxEnabled(profile_)) | 907 if (!prerender::IsOmniboxEnabled(profile_)) |
933 DoPreconnect(*match); | 908 DoPreconnect(*match); |
934 | 909 |
935 // We could prefetch the alternate nav URL, if any, but because there | 910 // We could prefetch the alternate nav URL, if any, but because there |
936 // can be many of these as a user types an initial series of characters, | 911 // can be many of these as a user types an initial series of characters, |
937 // the OS DNS cache could suffer eviction problems for minimal gain. | 912 // the OS DNS cache could suffer eviction problems for minimal gain. |
938 | 913 |
939 is_keyword_hint = match->GetKeyword(&keyword); | 914 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); |
940 } | 915 } |
941 | |
942 popup_->OnResultChanged(); | 916 popup_->OnResultChanged(); |
943 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, | 917 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, |
944 is_keyword_hint); | 918 is_keyword_hint); |
945 } else { | 919 } else { |
946 popup_->OnResultChanged(); | 920 popup_->OnResultChanged(); |
947 } | 921 } |
948 | 922 |
949 if (popup_->IsOpen()) { | 923 if (popup_->IsOpen()) { |
950 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); | 924 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); |
951 } else if (was_open) { | 925 } else if (was_open) { |
(...skipping 12 matching lines...) Expand all Loading... |
964 void AutocompleteEditModel::InternalSetUserText(const string16& text) { | 938 void AutocompleteEditModel::InternalSetUserText(const string16& text) { |
965 user_text_ = text; | 939 user_text_ = text; |
966 just_deleted_text_ = false; | 940 just_deleted_text_ = false; |
967 inline_autocomplete_text_.clear(); | 941 inline_autocomplete_text_.clear(); |
968 } | 942 } |
969 | 943 |
970 bool AutocompleteEditModel::KeywordIsSelected() const { | 944 bool AutocompleteEditModel::KeywordIsSelected() const { |
971 return !is_keyword_hint_ && !keyword_.empty(); | 945 return !is_keyword_hint_ && !keyword_.empty(); |
972 } | 946 } |
973 | 947 |
974 void AutocompleteEditModel::ClearPopupKeywordMode() const { | |
975 if (popup_->IsOpen() && | |
976 popup_->selected_line_state() == AutocompletePopupModel::KEYWORD) | |
977 popup_->SetSelectedLineState(AutocompletePopupModel::NORMAL); | |
978 } | |
979 | |
980 string16 AutocompleteEditModel::DisplayTextFromUserText( | 948 string16 AutocompleteEditModel::DisplayTextFromUserText( |
981 const string16& text) const { | 949 const string16& text) const { |
982 return KeywordIsSelected() ? | 950 return KeywordIsSelected() ? |
983 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 951 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
984 } | 952 } |
985 | 953 |
986 string16 AutocompleteEditModel::UserTextFromDisplayText( | 954 string16 AutocompleteEditModel::UserTextFromDisplayText( |
987 const string16& text) const { | 955 const string16& text) const { |
988 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 956 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
989 } | 957 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 old_user_text.length() - caret_position + 1)) { | 1037 old_user_text.length() - caret_position + 1)) { |
1070 return false; | 1038 return false; |
1071 } | 1039 } |
1072 | 1040 |
1073 // 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. |
1074 string16 keyword; | 1042 string16 keyword; |
1075 TrimWhitespace(new_user_text.substr(0, caret_position - 1), | 1043 TrimWhitespace(new_user_text.substr(0, caret_position - 1), |
1076 TRIM_LEADING, &keyword); | 1044 TRIM_LEADING, &keyword); |
1077 | 1045 |
1078 // Only allow exact keyword match if |keyword| represents a keyword hint. | 1046 // Only allow exact keyword match if |keyword| represents a keyword hint. |
1079 return keyword.length() && | 1047 return keyword.length() && popup_->GetKeywordForText(keyword, &keyword); |
1080 !autocomplete_controller_->keyword_provider()-> | |
1081 GetKeywordForText(keyword).empty(); | |
1082 } | 1048 } |
1083 | 1049 |
1084 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, | 1050 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, |
1085 string16* suggested_text) { | 1051 string16* suggested_text) { |
1086 DCHECK(suggested_text); | 1052 DCHECK(suggested_text); |
1087 | 1053 |
1088 if (in_revert_) | 1054 if (in_revert_) |
1089 return false; | 1055 return false; |
1090 | 1056 |
1091 InstantController* instant = controller_->GetInstant(); | 1057 InstantController* instant = controller_->GetInstant(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 // static | 1113 // static |
1148 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1114 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
1149 switch (c) { | 1115 switch (c) { |
1150 case 0x0020: // Space | 1116 case 0x0020: // Space |
1151 case 0x3000: // Ideographic Space | 1117 case 0x3000: // Ideographic Space |
1152 return true; | 1118 return true; |
1153 default: | 1119 default: |
1154 return false; | 1120 return false; |
1155 } | 1121 } |
1156 } | 1122 } |
OLD | NEW |