Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: chrome/browser/autocomplete/autocomplete_popup_model.cc

Issue 9419043: Revert 122412 - Enabled pressing TAB to traverse through the Omnibox results (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_popup_model.h" 5 #include "chrome/browser/autocomplete/autocomplete_popup_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "unicode/ubidi.h" 9 #include "unicode/ubidi.h"
10 10
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/autocomplete/autocomplete_edit.h" 13 #include "chrome/browser/autocomplete/autocomplete_edit.h"
14 #include "chrome/browser/autocomplete/autocomplete_match.h" 14 #include "chrome/browser/autocomplete/autocomplete_match.h"
15 #include "chrome/browser/autocomplete/autocomplete_popup_view.h" 15 #include "chrome/browser/autocomplete/autocomplete_popup_view.h"
16 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/search_engines/template_url.h" 18 #include "chrome/browser/search_engines/template_url.h"
19 #include "chrome/browser/search_engines/template_url_service.h" 19 #include "chrome/browser/search_engines/template_url_service.h"
20 #include "chrome/browser/search_engines/template_url_service_factory.h" 20 #include "chrome/browser/search_engines/template_url_service_factory.h"
21 #include "ui/gfx/rect.h" 21 #include "ui/gfx/rect.h"
22 22
23 /////////////////////////////////////////////////////////////////////////////// 23 ///////////////////////////////////////////////////////////////////////////////
24 // AutocompletePopupModel 24 // AutocompletePopupModel
25 25
26 const size_t AutocompletePopupModel::kNoMatch = -1;
27
28 AutocompletePopupModel::AutocompletePopupModel( 26 AutocompletePopupModel::AutocompletePopupModel(
29 AutocompletePopupView* popup_view, 27 AutocompletePopupView* popup_view,
30 AutocompleteEditModel* edit_model) 28 AutocompleteEditModel* edit_model)
31 : view_(popup_view), 29 : view_(popup_view),
32 edit_model_(edit_model), 30 edit_model_(edit_model),
33 hovered_line_(kNoMatch), 31 hovered_line_(kNoMatch),
34 selected_line_(kNoMatch), 32 selected_line_(kNoMatch) {
35 selected_line_state_(NORMAL) {
36 edit_model->set_popup_model(this); 33 edit_model->set_popup_model(this);
37 } 34 }
38 35
39 AutocompletePopupModel::~AutocompletePopupModel() { 36 AutocompletePopupModel::~AutocompletePopupModel() {
40 } 37 }
41 38
42 bool AutocompletePopupModel::IsOpen() const { 39 bool AutocompletePopupModel::IsOpen() const {
43 return view_->IsOpen(); 40 return view_->IsOpen();
44 } 41 }
45 42
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // Track the user's selection until they cancel it. 76 // Track the user's selection until they cancel it.
80 manually_selected_match_.destination_url = match.destination_url; 77 manually_selected_match_.destination_url = match.destination_url;
81 manually_selected_match_.provider_affinity = match.provider; 78 manually_selected_match_.provider_affinity = match.provider;
82 manually_selected_match_.is_history_what_you_typed_match = 79 manually_selected_match_.is_history_what_you_typed_match =
83 match.is_history_what_you_typed_match; 80 match.is_history_what_you_typed_match;
84 } 81 }
85 82
86 if (line == selected_line_ && !force) 83 if (line == selected_line_ && !force)
87 return; // Nothing else to do. 84 return; // Nothing else to do.
88 85
89 // We need to update |selected_line_state_| and |selected_line_| before 86 // We need to update |selected_line_| before calling OnPopupDataChanged(), so
90 // calling InvalidateLine(), since it will check them to determine how to 87 // that when the edit notifies its controller that something has changed, the
91 // draw. We also need to update |selected_line_| before calling 88 // controller can get the correct updated data.
92 // OnPopupDataChanged(), so that when the edit notifies its controller that
93 // something has changed, the controller can get the correct updated data.
94 // 89 //
95 // NOTE: We should never reach here with no selected line; the same code that 90 // NOTE: We should never reach here with no selected line; the same code that
96 // opened the popup and made it possible to get here should have also set a 91 // opened the popup and made it possible to get here should have also set a
97 // selected line. 92 // selected line.
98 CHECK(selected_line_ != kNoMatch); 93 CHECK(selected_line_ != kNoMatch);
99 GURL current_destination(result.match_at(selected_line_).destination_url); 94 GURL current_destination(result.match_at(selected_line_).destination_url);
100 const size_t prev_selected_line = selected_line_; 95 view_->InvalidateLine(selected_line_);
101 selected_line_state_ = NORMAL;
102 selected_line_ = line; 96 selected_line_ = line;
103 view_->InvalidateLine(prev_selected_line);
104 view_->InvalidateLine(selected_line_); 97 view_->InvalidateLine(selected_line_);
105 98
106 // Update the edit with the new data for this match. 99 // Update the edit with the new data for this match.
107 // TODO(pkasting): If |selected_line_| moves to the controller, this can be 100 // TODO(pkasting): If |selected_line_| moves to the controller, this can be
108 // eliminated and just become a call to the observer on the edit. 101 // eliminated and just become a call to the observer on the edit.
109 string16 keyword; 102 string16 keyword;
110 const bool is_keyword_hint = match.GetKeyword(&keyword); 103 const bool is_keyword_hint = GetKeywordForMatch(match, &keyword);
111
112 if (reset_to_default) { 104 if (reset_to_default) {
113 string16 inline_autocomplete_text; 105 string16 inline_autocomplete_text;
114 if ((match.inline_autocomplete_offset != string16::npos) && 106 if ((match.inline_autocomplete_offset != string16::npos) &&
115 (match.inline_autocomplete_offset < match.fill_into_edit.length())) { 107 (match.inline_autocomplete_offset < match.fill_into_edit.length())) {
116 inline_autocomplete_text = 108 inline_autocomplete_text =
117 match.fill_into_edit.substr(match.inline_autocomplete_offset); 109 match.fill_into_edit.substr(match.inline_autocomplete_offset);
118 } 110 }
119 edit_model_->OnPopupDataChanged(inline_autocomplete_text, NULL, 111 edit_model_->OnPopupDataChanged(inline_autocomplete_text, NULL,
120 keyword, is_keyword_hint); 112 keyword, is_keyword_hint);
121 } else { 113 } else {
122 edit_model_->OnPopupDataChanged(match.fill_into_edit, &current_destination, 114 edit_model_->OnPopupDataChanged(match.fill_into_edit, &current_destination,
123 keyword, is_keyword_hint); 115 keyword, is_keyword_hint);
124 } 116 }
125 117
126 // Repaint old and new selected lines immediately, so that the edit doesn't 118 // Repaint old and new selected lines immediately, so that the edit doesn't
127 // appear to update [much] faster than the popup. 119 // appear to update [much] faster than the popup.
128 view_->PaintUpdatesNow(); 120 view_->PaintUpdatesNow();
129 } 121 }
130 122
131 void AutocompletePopupModel::ResetToDefaultMatch() { 123 void AutocompletePopupModel::ResetToDefaultMatch() {
132 const AutocompleteResult& result = this->result(); 124 const AutocompleteResult& result = this->result();
133 CHECK(!result.empty()); 125 CHECK(!result.empty());
134 SetSelectedLine(result.default_match() - result.begin(), true, false); 126 SetSelectedLine(result.default_match() - result.begin(), true, false);
135 view_->OnDragCanceled(); 127 view_->OnDragCanceled();
136 } 128 }
137 129
130 bool AutocompletePopupModel::GetKeywordForMatch(const AutocompleteMatch& match,
131 string16* keyword) const {
132 // Assume we have no keyword until we find otherwise.
133 keyword->clear();
134
135 if (match.template_url &&
136 TemplateURL::SupportsReplacement(match.template_url) &&
137 match.transition == content::PAGE_TRANSITION_KEYWORD) {
138 // The current match is a keyword, return that as the selected keyword.
139 keyword->assign(match.template_url->keyword());
140 return false;
141 }
142
143 // See if the current match's fill_into_edit corresponds to a keyword.
144 return GetKeywordForText(match.fill_into_edit, keyword);
145 }
146
147 bool AutocompletePopupModel::GetKeywordForText(const string16& text,
148 string16* keyword) const {
149 // Creates keyword_hint first in case |keyword| is a pointer to |text|.
150 const string16 keyword_hint(TemplateURLService::CleanUserInputKeyword(text));
151
152 // Assume we have no keyword until we find otherwise.
153 keyword->clear();
154
155 if (keyword_hint.empty())
156 return false;
157 Profile* profile = edit_model_->profile();
158 TemplateURLService* url_service =
159 TemplateURLServiceFactory::GetForProfile(profile);
160 if (!url_service)
161 return false;
162 url_service->Load();
163
164 // Don't provide a hint if this keyword doesn't support replacement.
165 const TemplateURL* const template_url =
166 url_service->GetTemplateURLForKeyword(keyword_hint);
167 if (!TemplateURL::SupportsReplacement(template_url))
168 return false;
169
170 // Don't provide a hint for inactive/disabled extension keywords.
171 if (template_url->IsExtensionKeyword()) {
172 const Extension* extension = profile->GetExtensionService()->
173 GetExtensionById(template_url->GetExtensionId(), false);
174 if (!extension || (profile->IsOffTheRecord() &&
175 !profile->GetExtensionService()->IsIncognitoEnabled(extension->id())))
176 return false;
177 }
178
179 keyword->assign(keyword_hint);
180 return true;
181 }
182
138 void AutocompletePopupModel::Move(int count) { 183 void AutocompletePopupModel::Move(int count) {
139 const AutocompleteResult& result = this->result(); 184 const AutocompleteResult& result = this->result();
140 if (result.empty()) 185 if (result.empty())
141 return; 186 return;
142 187
143 // The user is using the keyboard to change the selection, so stop tracking 188 // The user is using the keyboard to change the selection, so stop tracking
144 // hover. 189 // hover.
145 SetHoveredLine(kNoMatch); 190 SetHoveredLine(kNoMatch);
146 191
147 // Clamp the new line to [0, result_.count() - 1]. 192 // Clamp the new line to [0, result_.count() - 1].
148 const size_t new_line = selected_line_ + count; 193 const size_t new_line = selected_line_ + count;
149 SetSelectedLine(((count < 0) && (new_line >= selected_line_)) ? 0 : new_line, 194 SetSelectedLine(((count < 0) && (new_line >= selected_line_)) ? 0 : new_line,
150 false, false); 195 false, false);
151 } 196 }
152 197
153 void AutocompletePopupModel::SetSelectedLineState(LineState state) {
154 DCHECK(!result().empty());
155 DCHECK_NE(kNoMatch, selected_line_);
156
157 const AutocompleteMatch& match = result().match_at(selected_line_);
158 DCHECK(match.associated_keyword.get());
159
160 selected_line_state_ = state;
161 view_->InvalidateLine(selected_line_);
162 }
163
164 void AutocompletePopupModel::TryDeletingCurrentItem() { 198 void AutocompletePopupModel::TryDeletingCurrentItem() {
165 // We could use InfoForCurrentSelection() here, but it seems better to try 199 // We could use InfoForCurrentSelection() here, but it seems better to try
166 // and shift-delete the actual selection, rather than any "in progress, not 200 // and shift-delete the actual selection, rather than any "in progress, not
167 // yet visible" one. 201 // yet visible" one.
168 if (selected_line_ == kNoMatch) 202 if (selected_line_ == kNoMatch)
169 return; 203 return;
170 204
171 // Cancel the query so the matches don't change on the user. 205 // Cancel the query so the matches don't change on the user.
172 autocomplete_controller()->Stop(false); 206 autocomplete_controller()->Stop(false);
173 207
(...skipping 28 matching lines...) Expand all
202 match.template_url->GetExtensionId()); 236 match.template_url->GetExtensionId());
203 } 237 }
204 238
205 void AutocompletePopupModel::OnResultChanged() { 239 void AutocompletePopupModel::OnResultChanged() {
206 const AutocompleteResult& result = this->result(); 240 const AutocompleteResult& result = this->result();
207 selected_line_ = result.default_match() == result.end() ? 241 selected_line_ = result.default_match() == result.end() ?
208 kNoMatch : static_cast<size_t>(result.default_match() - result.begin()); 242 kNoMatch : static_cast<size_t>(result.default_match() - result.begin());
209 // There had better not be a nonempty result set with no default match. 243 // There had better not be a nonempty result set with no default match.
210 CHECK((selected_line_ != kNoMatch) || result.empty()); 244 CHECK((selected_line_ != kNoMatch) || result.empty());
211 manually_selected_match_.Clear(); 245 manually_selected_match_.Clear();
212 selected_line_state_ = NORMAL;
213 // If we're going to trim the window size to no longer include the hovered 246 // If we're going to trim the window size to no longer include the hovered
214 // line, turn hover off. Practically, this shouldn't happen, but it 247 // line, turn hover off. Practically, this shouldn't happen, but it
215 // doesn't hurt to be defensive. 248 // doesn't hurt to be defensive.
216 if ((hovered_line_ != kNoMatch) && (result.size() <= hovered_line_)) 249 if ((hovered_line_ != kNoMatch) && (result.size() <= hovered_line_))
217 SetHoveredLine(kNoMatch); 250 SetHoveredLine(kNoMatch);
218 251
219 view_->UpdatePopupAppearance(); 252 view_->UpdatePopupAppearance();
220 } 253 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_popup_model.h ('k') | chrome/browser/autocomplete/autocomplete_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698