1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/app_list/search/omnibox_provider.h"
7 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
8 #include "chrome/browser/autocomplete/autocomplete_controller.h"
9 #include "chrome/browser/autocomplete/autocomplete_input.h"
10 #include "chrome/browser/autocomplete/autocomplete_match.h"
11 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
12 #include "chrome/browser/ui/browser_navigator.h"
13 #include "chrome/common/metrics/proto/omnibox_event.pb.h"
14 #include "grit/theme_resources.h"
15 #include "ui/base/resource/resource_bundle.h"
21 int ACMatchStyleToTagStyle(int styles
) {
23 if (styles
& ACMatchClassification::URL
)
24 tag_styles
|= SearchResult::Tag::URL
;
25 if (styles
& ACMatchClassification::MATCH
)
26 tag_styles
|= SearchResult::Tag::MATCH
;
27 if (styles
& ACMatchClassification::DIM
)
28 tag_styles
|= SearchResult::Tag::DIM
;
33 // Translates ACMatchClassifications into SearchResult tags.
34 void ACMatchClassificationsToTags(
36 const ACMatchClassifications
& text_classes
,
37 SearchResult::Tags
* tags
) {
38 int tag_styles
= SearchResult::Tag::NONE
;
41 for (size_t i
= 0; i
< text_classes
.size(); ++i
) {
42 const ACMatchClassification
& text_class
= text_classes
[i
];
44 // Closes current tag.
45 if (tag_styles
!= SearchResult::Tag::NONE
) {
46 tags
->push_back(SearchResult::Tag(
47 tag_styles
, tag_start
, text_class
.offset
));
48 tag_styles
= SearchResult::Tag::NONE
;
51 if (text_class
.style
== ACMatchClassification::NONE
)
54 tag_start
= text_class
.offset
;
55 tag_styles
= ACMatchStyleToTagStyle(text_class
.style
);
58 if (tag_styles
!= SearchResult::Tag::NONE
) {
59 tags
->push_back(SearchResult::Tag(
60 tag_styles
, tag_start
, text
.length()));
64 class OmniboxResult
: public ChromeSearchResult
{
66 OmniboxResult(Profile
* profile
, const AutocompleteMatch
& match
)
69 set_id(match
.destination_url
.spec());
71 // Derive relevance from omnibox relevance and normalize it to [0, 1].
72 // The magic number 1500 is the highest score of an omnibox result.
73 // See comments in autocomplete_provider.h.
74 set_relevance(match
.relevance
/ 1500.0);
77 UpdateTitleAndDetails();
79 virtual ~OmniboxResult() {}
81 // ChromeSearchResult overides:
82 virtual void Open(int event_flags
) OVERRIDE
{
83 chrome::NavigateParams
params(profile_
,
84 match_
.destination_url
,
86 params
.disposition
= ui::DispositionFromEventFlags(event_flags
);
87 chrome::Navigate(¶ms
);
90 virtual void InvokeAction(int action_index
, int event_flags
) OVERRIDE
{}
92 virtual scoped_ptr
<ChromeSearchResult
> Duplicate() OVERRIDE
{
93 return scoped_ptr
<ChromeSearchResult
>(
94 new OmniboxResult(profile_
, match_
)).Pass();
97 virtual ChromeSearchResultType
GetType() OVERRIDE
{
98 return OMNIBOX_SEARCH_RESULT
;
103 int resource_id
= match_
.starred
?
104 IDR_OMNIBOX_STAR
: AutocompleteMatch::TypeToIcon(match_
.type
);
105 SetIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
109 void UpdateTitleAndDetails() {
110 set_title(match_
.contents
);
111 SearchResult::Tags title_tags
;
112 ACMatchClassificationsToTags(match_
.contents
,
113 match_
.contents_class
,
115 set_title_tags(title_tags
);
117 set_details(match_
.description
);
118 SearchResult::Tags details_tags
;
119 ACMatchClassificationsToTags(match_
.description
,
120 match_
.description_class
,
122 set_details_tags(details_tags
);
126 AutocompleteMatch match_
;
128 DISALLOW_COPY_AND_ASSIGN(OmniboxResult
);
133 OmniboxProvider::OmniboxProvider(Profile
* profile
)
135 controller_(new AutocompleteController(
138 AutocompleteClassifier::kDefaultOmniboxProviders
)) {
141 OmniboxProvider::~OmniboxProvider() {}
143 void OmniboxProvider::Start(const base::string16
& query
) {
144 controller_
->Start(AutocompleteInput(query
,
145 base::string16::npos
,
148 AutocompleteInput::INVALID_SPEC
,
152 AutocompleteInput::ALL_MATCHES
));
155 void OmniboxProvider::Stop() {
156 controller_
->Stop(false);
159 void OmniboxProvider::PopulateFromACResult(const AutocompleteResult
& result
) {
161 for (ACMatches::const_iterator it
= result
.begin();
164 if (!it
->destination_url
.is_valid())
167 Add(scoped_ptr
<ChromeSearchResult
>(
168 new OmniboxResult(profile_
, *it
)).Pass());
172 void OmniboxProvider::OnResultChanged(bool default_match_changed
) {
173 const AutocompleteResult
& result
= controller_
->result();
174 PopulateFromACResult(result
);
177 } // namespace app_list