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

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

Issue 6731036: Enabled pressing TAB to cycle through the Omnibox results. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years, 4 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
(...skipping 13 matching lines...) Expand all
24 // AutocompletePopupModel 24 // AutocompletePopupModel
25 25
26 AutocompletePopupModel::AutocompletePopupModel( 26 AutocompletePopupModel::AutocompletePopupModel(
27 AutocompletePopupView* popup_view, 27 AutocompletePopupView* popup_view,
28 AutocompleteEditModel* edit_model, 28 AutocompleteEditModel* edit_model,
29 Profile* profile) 29 Profile* profile)
30 : view_(popup_view), 30 : view_(popup_view),
31 edit_model_(edit_model), 31 edit_model_(edit_model),
32 profile_(profile), 32 profile_(profile),
33 hovered_line_(kNoMatch), 33 hovered_line_(kNoMatch),
34 selected_line_(kNoMatch) { 34 selected_line_(kNoMatch),
35 match_state_(NORMAL) {
35 edit_model->set_popup_model(this); 36 edit_model->set_popup_model(this);
36 } 37 }
37 38
38 AutocompletePopupModel::~AutocompletePopupModel() { 39 AutocompletePopupModel::~AutocompletePopupModel() {
39 } 40 }
40 41
41 bool AutocompletePopupModel::IsOpen() const { 42 bool AutocompletePopupModel::IsOpen() const {
42 return view_->IsOpen(); 43 return view_->IsOpen();
43 } 44 }
44 45
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 88
88 // We need to update |selected_line_| before calling OnPopupDataChanged(), so 89 // We need to update |selected_line_| before calling OnPopupDataChanged(), so
89 // that when the edit notifies its controller that something has changed, the 90 // that when the edit notifies its controller that something has changed, the
90 // controller can get the correct updated data. 91 // controller can get the correct updated data.
91 // 92 //
92 // NOTE: We should never reach here with no selected line; the same code that 93 // NOTE: We should never reach here with no selected line; the same code that
93 // opened the popup and made it possible to get here should have also set a 94 // opened the popup and made it possible to get here should have also set a
94 // selected line. 95 // selected line.
95 CHECK(selected_line_ != kNoMatch); 96 CHECK(selected_line_ != kNoMatch);
96 GURL current_destination(result.match_at(selected_line_).destination_url); 97 GURL current_destination(result.match_at(selected_line_).destination_url);
98 match_state_ = NORMAL;
97 view_->InvalidateLine(selected_line_); 99 view_->InvalidateLine(selected_line_);
98 selected_line_ = line; 100 selected_line_ = line;
99 view_->InvalidateLine(selected_line_); 101 view_->InvalidateLine(selected_line_);
100 102
101 // Update the edit with the new data for this match. 103 // Update the edit with the new data for this match.
102 // TODO(pkasting): If |selected_line_| moves to the controller, this can be 104 // TODO(pkasting): If |selected_line_| moves to the controller, this can be
103 // eliminated and just become a call to the observer on the edit. 105 // eliminated and just become a call to the observer on the edit.
104 string16 keyword; 106 string16 keyword = match.keyword;
105 const bool is_keyword_hint = GetKeywordForMatch(match, &keyword); 107 const bool is_keyword_hint = match.associated_keyword.get() != NULL;
108 if (is_keyword_hint)
109 keyword = match.associated_keyword->keyword;
110
106 if (reset_to_default) { 111 if (reset_to_default) {
107 string16 inline_autocomplete_text; 112 string16 inline_autocomplete_text;
108 if ((match.inline_autocomplete_offset != string16::npos) && 113 if ((match.inline_autocomplete_offset != string16::npos) &&
109 (match.inline_autocomplete_offset < match.fill_into_edit.length())) { 114 (match.inline_autocomplete_offset < match.fill_into_edit.length())) {
110 inline_autocomplete_text = 115 inline_autocomplete_text =
111 match.fill_into_edit.substr(match.inline_autocomplete_offset); 116 match.fill_into_edit.substr(match.inline_autocomplete_offset);
112 } 117 }
113 edit_model_->OnPopupDataChanged(inline_autocomplete_text, NULL, 118 edit_model_->OnPopupDataChanged(inline_autocomplete_text, NULL,
114 keyword, is_keyword_hint); 119 keyword, is_keyword_hint);
115 } else { 120 } else {
116 edit_model_->OnPopupDataChanged(match.fill_into_edit, &current_destination, 121 edit_model_->OnPopupDataChanged(match.fill_into_edit, &current_destination,
117 keyword, is_keyword_hint); 122 keyword, is_keyword_hint);
118 } 123 }
119 124
120 // Repaint old and new selected lines immediately, so that the edit doesn't 125 // Repaint old and new selected lines immediately, so that the edit doesn't
121 // appear to update [much] faster than the popup. 126 // appear to update [much] faster than the popup.
122 view_->PaintUpdatesNow(); 127 view_->PaintUpdatesNow();
123 } 128 }
124 129
125 void AutocompletePopupModel::ResetToDefaultMatch() { 130 void AutocompletePopupModel::ResetToDefaultMatch() {
126 const AutocompleteResult& result = this->result(); 131 const AutocompleteResult& result = this->result();
127 CHECK(!result.empty()); 132 CHECK(!result.empty());
128 SetSelectedLine(result.default_match() - result.begin(), true, false); 133 SetSelectedLine(result.default_match() - result.begin(), true, false);
129 view_->OnDragCanceled(); 134 view_->OnDragCanceled();
130 } 135 }
131 136
132 bool AutocompletePopupModel::GetKeywordForMatch(const AutocompleteMatch& match,
133 string16* keyword) const {
134 // Assume we have no keyword until we find otherwise.
135 keyword->clear();
136
137 if (match.template_url) {
138 TemplateURLService* url_service =
139 TemplateURLServiceFactory::GetForProfile(profile_);
140 if (!url_service)
141 return false;
142
143 // Only show the keyword for the default provider if the user typed in
144 // the keyword and it isn't SEARCH_WHAT_YOU_TYPED.
145 const TemplateURL* default_url = url_service->GetDefaultSearchProvider();
146 if (default_url && (default_url->id() == match.template_url->id())) {
147 if (StartsWith(autocomplete_controller()->input().text(),
148 default_url->keyword(), false) &&
149 (match.type != AutocompleteMatch::SEARCH_WHAT_YOU_TYPED)) {
150 keyword->assign(match.template_url->keyword());
151 return false;
152 }
153 } else if (TemplateURL::SupportsReplacement(match.template_url)) {
154 // The current match is a keyword, return that as the selected keyword.
155 keyword->assign(match.template_url->keyword());
156 return false;
157 }
158 }
159
160 // See if the current match's fill_into_edit corresponds to a keyword.
161 return GetKeywordForText(match.fill_into_edit, keyword);
162 }
163
164 bool AutocompletePopupModel::GetKeywordForText(const string16& text,
165 string16* keyword) const {
166 // Creates keyword_hint first in case |keyword| is a pointer to |text|.
167 const string16 keyword_hint(TemplateURLService::CleanUserInputKeyword(text));
168
169 // Assume we have no keyword until we find otherwise.
170 keyword->clear();
171
172 if (keyword_hint.empty())
173 return false;
174 TemplateURLService* url_service =
175 TemplateURLServiceFactory::GetForProfile(profile_);
176 if (!url_service)
177 return false;
178 url_service->Load();
179
180 // Don't provide a hint if this keyword doesn't support replacement.
181 const TemplateURL* const template_url =
182 url_service->GetTemplateURLForKeyword(keyword_hint);
183 if (!TemplateURL::SupportsReplacement(template_url))
184 return false;
185
186 // Don't provide a hint for inactive/disabled extension keywords.
187 if (template_url->IsExtensionKeyword()) {
188 const Extension* extension = profile_->GetExtensionService()->
189 GetExtensionById(template_url->GetExtensionId(), false);
190 if (!extension ||
191 (profile_->IsOffTheRecord() &&
192 !profile_->GetExtensionService()->
193 IsIncognitoEnabled(extension->id())))
194 return false;
195 }
196
197 keyword->assign(keyword_hint);
198 return true;
199 }
200
201 void AutocompletePopupModel::Move(int count) { 137 void AutocompletePopupModel::Move(int count) {
202 const AutocompleteResult& result = this->result(); 138 const AutocompleteResult& result = this->result();
203 if (result.empty()) 139 if (result.empty())
204 return; 140 return;
205 141
206 // The user is using the keyboard to change the selection, so stop tracking 142 // The user is using the keyboard to change the selection, so stop tracking
207 // hover. 143 // hover.
208 SetHoveredLine(kNoMatch); 144 SetHoveredLine(kNoMatch);
209 145
210 // Clamp the new line to [0, result_.count() - 1]. 146 // Clamp the new line to [0, result_.count() - 1].
211 const size_t new_line = selected_line_ + count; 147 const size_t new_line = selected_line_ + count;
212 SetSelectedLine(((count < 0) && (new_line >= selected_line_)) ? 0 : new_line, 148 SetSelectedLine(((count < 0) && (new_line >= selected_line_)) ? 0 : new_line,
213 false, false); 149 false, false);
214 } 150 }
215 151
152 void AutocompletePopupModel::SetSelectedMatch(MatchState state) {
153 DCHECK(!result().empty());
154 DCHECK_NE(selected_line_, kNoMatch);
155
156 const AutocompleteMatch& match = result().match_at(selected_line_);
157 DCHECK(match.associated_keyword.get());
158
159 match_state_ = state;
160 view_->InvalidateLine(selected_line_);
161 }
162
216 void AutocompletePopupModel::TryDeletingCurrentItem() { 163 void AutocompletePopupModel::TryDeletingCurrentItem() {
217 // We could use InfoForCurrentSelection() here, but it seems better to try 164 // We could use InfoForCurrentSelection() here, but it seems better to try
218 // and shift-delete the actual selection, rather than any "in progress, not 165 // and shift-delete the actual selection, rather than any "in progress, not
219 // yet visible" one. 166 // yet visible" one.
220 if (selected_line_ == kNoMatch) 167 if (selected_line_ == kNoMatch)
221 return; 168 return;
222 169
223 // Cancel the query so the matches don't change on the user. 170 // Cancel the query so the matches don't change on the user.
224 autocomplete_controller()->Stop(false); 171 autocomplete_controller()->Stop(false);
225 172
(...skipping 28 matching lines...) Expand all
254 match.template_url->GetExtensionId()); 201 match.template_url->GetExtensionId());
255 } 202 }
256 203
257 void AutocompletePopupModel::OnResultChanged() { 204 void AutocompletePopupModel::OnResultChanged() {
258 const AutocompleteResult& result = this->result(); 205 const AutocompleteResult& result = this->result();
259 selected_line_ = result.default_match() == result.end() ? 206 selected_line_ = result.default_match() == result.end() ?
260 kNoMatch : static_cast<size_t>(result.default_match() - result.begin()); 207 kNoMatch : static_cast<size_t>(result.default_match() - result.begin());
261 // There had better not be a nonempty result set with no default match. 208 // There had better not be a nonempty result set with no default match.
262 CHECK((selected_line_ != kNoMatch) || result.empty()); 209 CHECK((selected_line_ != kNoMatch) || result.empty());
263 manually_selected_match_.Clear(); 210 manually_selected_match_.Clear();
211 match_state_ = NORMAL;
264 // If we're going to trim the window size to no longer include the hovered 212 // If we're going to trim the window size to no longer include the hovered
265 // line, turn hover off. Practically, this shouldn't happen, but it 213 // line, turn hover off. Practically, this shouldn't happen, but it
266 // doesn't hurt to be defensive. 214 // doesn't hurt to be defensive.
267 if ((hovered_line_ != kNoMatch) && (result.size() <= hovered_line_)) 215 if ((hovered_line_ != kNoMatch) && (result.size() <= hovered_line_))
268 SetHoveredLine(kNoMatch); 216 SetHoveredLine(kNoMatch);
269 217
270 view_->UpdatePopupAppearance(); 218 view_->UpdatePopupAppearance();
271 } 219 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698