Chromium Code Reviews| 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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 keyword_.clear(); | 390 keyword_.clear(); |
| 391 is_keyword_hint_ = false; | 391 is_keyword_hint_ = false; |
| 392 has_temporary_text_ = false; | 392 has_temporary_text_ = false; |
| 393 view_->SetWindowTextAndCaretPos(permanent_text_, | 393 view_->SetWindowTextAndCaretPos(permanent_text_, |
| 394 has_focus_ ? permanent_text_.length() : 0); | 394 has_focus_ ? permanent_text_.length() : 0); |
| 395 } | 395 } |
| 396 | 396 |
| 397 void AutocompleteEditModel::StartAutocomplete( | 397 void AutocompleteEditModel::StartAutocomplete( |
| 398 bool has_selected_text, | 398 bool has_selected_text, |
| 399 bool prevent_inline_autocomplete) const { | 399 bool prevent_inline_autocomplete) const { |
| 400 ClearPopupKeywordMode(); | |
| 401 | |
| 400 bool keyword_is_selected = KeywordIsSelected(); | 402 bool keyword_is_selected = KeywordIsSelected(); |
| 401 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); | 403 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); |
| 402 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, | 404 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, |
| 403 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which | 405 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which |
| 404 // clears it. | 406 // clears it. |
| 405 autocomplete_controller_->Start( | 407 autocomplete_controller_->Start( |
| 406 user_text_, GetDesiredTLD(), | 408 user_text_, GetDesiredTLD(), |
| 407 prevent_inline_autocomplete || just_deleted_text_ || | 409 prevent_inline_autocomplete || just_deleted_text_ || |
| 408 (has_selected_text && inline_autocomplete_text_.empty()) || | 410 (has_selected_text && inline_autocomplete_text_.empty()) || |
| 409 (paste_state_ != NONE), keyword_is_selected, | 411 (paste_state_ != NONE), keyword_is_selected, |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 | 579 |
| 578 InstantController* instant = controller_->GetInstant(); | 580 InstantController* instant = controller_->GetInstant(); |
| 579 if (instant && !popup_->IsOpen()) | 581 if (instant && !popup_->IsOpen()) |
| 580 instant->DestroyPreviewContents(); | 582 instant->DestroyPreviewContents(); |
| 581 in_revert_ = false; | 583 in_revert_ = false; |
| 582 } | 584 } |
| 583 | 585 |
| 584 bool AutocompleteEditModel::AcceptKeyword() { | 586 bool AutocompleteEditModel::AcceptKeyword() { |
| 585 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 587 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
| 586 | 588 |
| 587 view_->OnBeforePossibleChange(); | 589 autocomplete_controller_->Stop(false); |
| 588 view_->SetWindowTextAndCaretPos(string16(), 0); | |
| 589 is_keyword_hint_ = false; | 590 is_keyword_hint_ = false; |
| 590 view_->OnAfterPossibleChange(); | 591 |
| 591 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this | 592 if (popup_->IsOpen()) |
| 592 // since the edit contents have disappeared. It | 593 popup_->SetSelectedLineState(AutocompletePopupModel::KEYWORD); |
| 593 // doesn't really matter, but we clear it to be | 594 |
| 594 // consistent. | 595 string16 display_text = autocomplete_controller_->keyword_provider()-> |
| 596 SplitReplacementStringFromInput( | |
| 597 CurrentMatch().associated_keyword->fill_into_edit, true); | |
| 598 view_->SetUserText(string16(), display_text, false); | |
| 599 | |
| 595 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 600 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
| 596 return true; | 601 return true; |
| 597 } | 602 } |
| 598 | 603 |
| 599 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { | 604 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { |
| 600 view_->OnBeforePossibleChange(); | 605 autocomplete_controller_->Stop(false); |
| 601 const string16 window_text(keyword_ + visible_text); | 606 ClearPopupKeywordMode(); |
| 602 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); | 607 |
| 603 keyword_.clear(); | 608 string16 window_text(keyword_); |
| 604 is_keyword_hint_ = false; | 609 |
| 605 view_->OnAfterPossibleChange(); | 610 if (!visible_text.empty()) |
| 606 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 611 window_text.append(char16(' ') + visible_text); |
| 607 // since the edit contents have actually grown | 612 |
| 608 // longer. | 613 // Only reset the result if the edit text has changed since the |
| 614 // keyword was accepted. | |
| 615 if (just_deleted_text_) { | |
| 616 view_->OnBeforePossibleChange(); | |
| 617 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); | |
| 618 keyword_.clear(); | |
| 619 is_keyword_hint_ = false; | |
| 620 view_->OnAfterPossibleChange(); | |
| 621 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | |
| 622 // since the edit contents have actually grown | |
| 623 // longer. | |
| 624 } else { | |
| 625 view_->SetUserText(window_text, window_text, false); | |
| 626 is_keyword_hint_ = true; | |
| 627 OnChanged(); | |
| 628 } | |
| 609 } | 629 } |
| 610 | 630 |
| 611 const AutocompleteResult& AutocompleteEditModel::result() const { | 631 const AutocompleteResult& AutocompleteEditModel::result() const { |
| 612 return autocomplete_controller_->result(); | 632 return autocomplete_controller_->result(); |
| 613 } | 633 } |
| 614 | 634 |
| 615 void AutocompleteEditModel::OnSetFocus(bool control_down) { | 635 void AutocompleteEditModel::OnSetFocus(bool control_down) { |
| 616 has_focus_ = true; | 636 has_focus_ = true; |
| 617 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 637 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
| 618 | 638 |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 match->fill_into_edit.substr(match->inline_autocomplete_offset); | 881 match->fill_into_edit.substr(match->inline_autocomplete_offset); |
| 862 } | 882 } |
| 863 | 883 |
| 864 if (!prerender::IsOmniboxEnabled(profile_)) | 884 if (!prerender::IsOmniboxEnabled(profile_)) |
| 865 DoPreconnect(*match); | 885 DoPreconnect(*match); |
| 866 | 886 |
| 867 // We could prefetch the alternate nav URL, if any, but because there | 887 // We could prefetch the alternate nav URL, if any, but because there |
| 868 // can be many of these as a user types an initial series of characters, | 888 // can be many of these as a user types an initial series of characters, |
| 869 // the OS DNS cache could suffer eviction problems for minimal gain. | 889 // the OS DNS cache could suffer eviction problems for minimal gain. |
| 870 | 890 |
| 871 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); | 891 keyword = match->keyword; |
|
Peter Kasting
2011/12/15 22:56:04
Nit: Shorter:
is_keyword_hint = match->asso
| |
| 892 is_keyword_hint = match->associated_keyword.get() != NULL; | |
| 893 if (is_keyword_hint) | |
| 894 keyword = match->associated_keyword->keyword; | |
| 872 } | 895 } |
| 896 | |
| 873 popup_->OnResultChanged(); | 897 popup_->OnResultChanged(); |
| 874 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, | 898 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, |
| 875 is_keyword_hint); | 899 is_keyword_hint); |
| 876 } else { | 900 } else { |
| 877 popup_->OnResultChanged(); | 901 popup_->OnResultChanged(); |
| 878 } | 902 } |
| 879 | 903 |
| 880 if (popup_->IsOpen()) { | 904 if (popup_->IsOpen()) { |
| 881 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); | 905 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); |
| 882 } else if (was_open) { | 906 } else if (was_open) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 895 void AutocompleteEditModel::InternalSetUserText(const string16& text) { | 919 void AutocompleteEditModel::InternalSetUserText(const string16& text) { |
| 896 user_text_ = text; | 920 user_text_ = text; |
| 897 just_deleted_text_ = false; | 921 just_deleted_text_ = false; |
| 898 inline_autocomplete_text_.clear(); | 922 inline_autocomplete_text_.clear(); |
| 899 } | 923 } |
| 900 | 924 |
| 901 bool AutocompleteEditModel::KeywordIsSelected() const { | 925 bool AutocompleteEditModel::KeywordIsSelected() const { |
| 902 return !is_keyword_hint_ && !keyword_.empty(); | 926 return !is_keyword_hint_ && !keyword_.empty(); |
| 903 } | 927 } |
| 904 | 928 |
| 929 void AutocompleteEditModel::ClearPopupKeywordMode() const { | |
| 930 if (popup_->IsOpen() && | |
| 931 popup_->selected_line_state() == AutocompletePopupModel::KEYWORD) | |
| 932 popup_->SetSelectedLineState(AutocompletePopupModel::NORMAL); | |
| 933 } | |
| 934 | |
| 905 string16 AutocompleteEditModel::DisplayTextFromUserText( | 935 string16 AutocompleteEditModel::DisplayTextFromUserText( |
| 906 const string16& text) const { | 936 const string16& text) const { |
| 907 return KeywordIsSelected() ? | 937 return KeywordIsSelected() ? |
| 908 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 938 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
| 909 } | 939 } |
| 910 | 940 |
| 911 string16 AutocompleteEditModel::UserTextFromDisplayText( | 941 string16 AutocompleteEditModel::UserTextFromDisplayText( |
| 912 const string16& text) const { | 942 const string16& text) const { |
| 913 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 943 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
| 914 } | 944 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 994 old_user_text.length() - caret_position + 1)) { | 1024 old_user_text.length() - caret_position + 1)) { |
| 995 return false; | 1025 return false; |
| 996 } | 1026 } |
| 997 | 1027 |
| 998 // Then check if the text before the inserted space matches a keyword. | 1028 // Then check if the text before the inserted space matches a keyword. |
| 999 string16 keyword; | 1029 string16 keyword; |
| 1000 TrimWhitespace(new_user_text.substr(0, caret_position - 1), | 1030 TrimWhitespace(new_user_text.substr(0, caret_position - 1), |
| 1001 TRIM_LEADING, &keyword); | 1031 TRIM_LEADING, &keyword); |
| 1002 | 1032 |
| 1003 // Only allow exact keyword match if |keyword| represents a keyword hint. | 1033 // Only allow exact keyword match if |keyword| represents a keyword hint. |
| 1004 return keyword.length() && popup_->GetKeywordForText(keyword, &keyword); | 1034 return keyword.length() && |
| 1035 !autocomplete_controller_->keyword_provider()-> | |
| 1036 GetKeywordForText(keyword).empty(); | |
| 1005 } | 1037 } |
| 1006 | 1038 |
| 1007 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, | 1039 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, |
| 1008 string16* suggested_text) { | 1040 string16* suggested_text) { |
| 1009 DCHECK(suggested_text); | 1041 DCHECK(suggested_text); |
| 1010 | 1042 |
| 1011 if (in_revert_) | 1043 if (in_revert_) |
| 1012 return false; | 1044 return false; |
| 1013 | 1045 |
| 1014 InstantController* instant = controller_->GetInstant(); | 1046 InstantController* instant = controller_->GetInstant(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1065 // static | 1097 // static |
| 1066 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1098 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
| 1067 switch (c) { | 1099 switch (c) { |
| 1068 case 0x0020: // Space | 1100 case 0x0020: // Space |
| 1069 case 0x3000: // Ideographic Space | 1101 case 0x3000: // Ideographic Space |
| 1070 return true; | 1102 return true; |
| 1071 default: | 1103 default: |
| 1072 return false; | 1104 return false; |
| 1073 } | 1105 } |
| 1074 } | 1106 } |
| OLD | NEW |