| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/omnibox/browser/omnibox_controller.h" |
| |
| #include "base/metrics/histogram.h" |
| #include "components/omnibox/browser/autocomplete_classifier.h" |
| #include "components/omnibox/browser/autocomplete_match.h" |
| #include "components/omnibox/browser/omnibox_client.h" |
| #include "components/omnibox/browser/omnibox_controller_emitter.h" |
| #include "components/omnibox/browser/omnibox_edit_controller.h" |
| #include "components/omnibox/browser/omnibox_edit_model.h" |
| #include "components/omnibox/browser/omnibox_popup_model.h" |
| #include "components/omnibox/browser/omnibox_popup_view.h" |
| #include "ui/gfx/geometry/rect.h" |
| |
| OmniboxController::OmniboxController(OmniboxEditModel* omnibox_edit_model, |
| OmniboxClient* client) |
| : omnibox_edit_model_(omnibox_edit_model), |
| client_(client), |
| popup_(nullptr), |
| autocomplete_controller_(new AutocompleteController( |
| client_->CreateAutocompleteProviderClient(), |
| this, |
| AutocompleteClassifier::DefaultOmniboxProviders())), |
| weak_ptr_factory_(this) {} |
| |
| OmniboxController::~OmniboxController() { |
| } |
| |
| void OmniboxController::StartAutocomplete( |
| const AutocompleteInput& input) const { |
| ClearPopupKeywordMode(); |
| |
| if (client_->GetOmniboxControllerEmitter()) |
| client_->GetOmniboxControllerEmitter()->NotifyOmniboxQuery( |
| autocomplete_controller_.get()); |
| |
| // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as |
| // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. |
| autocomplete_controller_->Start(input); |
| } |
| |
| void OmniboxController::OnResultChanged(bool default_match_changed) { |
| if (client_->GetOmniboxControllerEmitter()) |
| client_->GetOmniboxControllerEmitter()->NotifyOmniboxResultChanged( |
| default_match_changed, autocomplete_controller_.get()); |
| |
| const bool was_open = popup_ && popup_->IsOpen(); |
| if (default_match_changed) { |
| // The default match has changed, we need to let the OmniboxEditModel know |
| // about new inline autocomplete text (blue highlight). |
| const AutocompleteResult::const_iterator match(result().default_match()); |
| if (match != result().end()) { |
| current_match_ = *match; |
| omnibox_edit_model_->OnCurrentMatchChanged(); |
| } else { |
| InvalidateCurrentMatch(); |
| if (popup_) |
| popup_->OnResultChanged(); |
| omnibox_edit_model_->OnPopupDataChanged(base::string16(), nullptr, |
| base::string16(), false); |
| } |
| } else if (popup_) { |
| popup_->OnResultChanged(); |
| } |
| |
| if (was_open && !popup_->IsOpen()) { |
| // Accept the temporary text as the user text, because it makes little sense |
| // to have temporary text when the popup is closed. |
| omnibox_edit_model_->AcceptTemporaryTextAsUserText(); |
| } |
| |
| // Note: The client outlives |this|, so bind a weak pointer to the callback |
| // passed in to eliminate the potential for crashes on shutdown. |
| client_->OnResultChanged( |
| result(), default_match_changed, |
| base::Bind(&OmniboxController::SetRichSuggestionBitmap, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| void OmniboxController::InvalidateCurrentMatch() { |
| current_match_ = AutocompleteMatch(); |
| } |
| |
| void OmniboxController::ClearPopupKeywordMode() const { |
| // |popup_| can be nullptr in tests. |
| if (popup_ && popup_->IsOpen() && |
| popup_->selected_line_state() == OmniboxPopupModel::KEYWORD) { |
| popup_->SetSelectedLineState(OmniboxPopupModel::NORMAL); |
| } |
| } |
| |
| void OmniboxController::SetRichSuggestionBitmap(int result_index, |
| const SkBitmap& bitmap) { |
| popup_->SetRichSuggestionBitmap(result_index, bitmap); |
| } |