12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_EDIT_MODEL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_EDIT_MODEL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_controller_delegate.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_controller.h"
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/common/instant_types.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/omnibox_focus_state.h"
176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/metrics/proto/omnibox_event.pb.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/autocomplete_input.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/autocomplete_match.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/window_open_disposition.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h"
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AutocompleteController;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AutocompleteResult;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class OmniboxCurrentPageDelegate;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxEditController;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxPopupModel;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxView;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Image;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Rect;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Reasons why the Omnibox could change into keyword mode.
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// These numeric values are used in UMA logs; do not change them.
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum EnteredKeywordModeMethod {
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ENTERED_KEYWORD_MODE_VIA_TAB = 0,
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ENTERED_KEYWORD_MODE_VIA_SPACE_AT_END = 1,
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ENTERED_KEYWORD_MODE_VIA_SPACE_IN_MIDDLE = 2,
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ENTERED_KEYWORD_MODE_NUM_ITEMS
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class OmniboxEditModel {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Did the Omnibox focus originate via the user clicking on the Omnibox or on
493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // the Fakebox?
503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  enum FocusSource {
513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    INVALID = 0,
523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    OMNIBOX = 1,
533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    FAKEBOX = 2
543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  };
553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct State {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State(bool user_input_in_progress,
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const base::string16& user_text,
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const base::string16& gray_text,
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const base::string16& keyword,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          bool is_keyword_hint,
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          bool url_replacement_enabled,
633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          OmniboxFocusState focus_state,
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          FocusSource focus_source,
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          const AutocompleteInput& autocomplete_input);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~State();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool user_input_in_progress;
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16 user_text;
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16 gray_text;
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16 keyword;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool is_keyword_hint;
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool url_replacement_enabled;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OmniboxFocusState focus_state;
753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    FocusSource focus_source;
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const AutocompleteInput autocomplete_input;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxEditModel(OmniboxView* view,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   OmniboxEditController* controller,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   Profile* profile);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OmniboxEditModel();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(beaudoin): Remove this accessor when the AutocompleteController has
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     completely moved to OmniboxController.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutocompleteController* autocomplete_controller() const {
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return omnibox_controller_->autocomplete_controller();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_popup_model(OmniboxPopupModel* popup_model) {
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    omnibox_controller_->set_popup_model(popup_model);
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: The edit and popup should be siblings owned by the LocationBarView,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // making this accessor unnecessary.
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // NOTE: popup_model() can be NULL for testing.
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  OmniboxPopupModel* popup_model() const {
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return omnibox_controller_->popup_model();
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxEditController* controller() const { return controller_; }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile() const { return profile_; }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the current state.  This assumes we are switching tabs, and changes
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the internal state appropriately.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const State GetStateForTabSwitch();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Resets the tab state, then restores local state from the saved |state|.
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // |state| may be NULL if there is no saved state.
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void RestoreState(const State* state);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the match for the current text. If the user has not edited the text
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // this is the match corresponding to the permanent text. Returns the
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // alternate nav URL, if |alternate_nav_url| is non-NULL and there is such a
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // URL.
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutocompleteMatch CurrentMatch(GURL* alternate_nav_url) const;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user wants to export the entire current text as a URL.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the url, and if known, the title and favicon.
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void GetDataForURLExport(GURL* url,
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           base::string16* title,
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           gfx::Image* favicon);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the current edit contents will be treated as a
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URL/navigation, as opposed to a search.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CurrentTextIsURL() const;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the match type for the current edit contents.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutocompleteMatch::Type CurrentTextType() const;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked to adjust the text before writting to the clipboard for a copy
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (e.g. by adding 'http' to the front). |sel_min| gives the minimum position
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the selection e.g. min(selection_start, selection_end). |text| is the
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // currently selected text. If |is_all_selected| is true all the text in the
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // edit is selected. If the url should be copied to the clipboard |write_url|
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is set to true and |url| set to the url to write.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AdjustTextForCopy(int sel_min,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool is_all_selected,
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         base::string16* text,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         GURL* url,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool* write_url);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool user_input_in_progress() const { return user_input_in_progress_; }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the state of user_input_in_progress_, and notifies the observer if
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that state has changed.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetInputInProgress(bool in_progress);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Updates permanent_text_ to the current permanent text from the toolbar
151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // model.  Returns true if the permanent text changed and the change should be
152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // immediately user-visible, because either the user is not editing or the
153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // edit does not have focus.
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool UpdatePermanentText();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the URL corresponding to the permanent text.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL PermanentURL();
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the user_text_ to |text|.  Only the View should call this.
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetUserText(const base::string16& text);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Commits the gray suggested text as if it's been input by the user.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the text was committed.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: can the return type be void?
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool CommitSuggestedText();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Invoked any time the text may have changed in the edit. Notifies the
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // controller.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnChanged();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reverts the edit model back to its unedited state (permanent text showing,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no user input in progress).
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Revert();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Directs the popup to start autocomplete.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartAutocomplete(bool has_selected_text,
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         bool prevent_inline_autocomplete);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Closes the popup and cancels any pending asynchronous queries.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StopAutocomplete();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determines whether the user can "paste and go", given the specified text.
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool CanPasteAndGo(const base::string16& text) const;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigates to the destination last supplied to CanPasteAndGo.
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void PasteAndGo(const base::string16& text);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if this is a paste-and-search rather than paste-and-go (or
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // nothing).
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool IsPasteAndSearch(const base::string16& text) const;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Asks the browser to load the popup's currently selected item, using the
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied disposition.  This may close the popup. If |for_drop| is true,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it indicates the input is being accepted as part of a drop operation and
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the transition should be treated as LINK (so that it won't trigger the
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URL to be autocompleted).
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AcceptInput(WindowOpenDisposition disposition,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   bool for_drop);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Asks the browser to load the item at |index|, with the given properties.
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // OpenMatch() needs to know the original text that drove this action.  If
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |pasted_text| is non-empty, this is a Paste-And-Go/Search action, and
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // that's the relevant input text.  Otherwise, the relevant input text is
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // either the user text or the permanent text, depending on if user input is
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in progress.
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |match| is passed by value for two reasons:
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // (1) This function needs to modify |match|, so a const ref isn't
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //     appropriate.  Callers don't actually care about the modifications, so a
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //     pointer isn't required.
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // (2) The passed-in match is, on the caller side, typically coming from data
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //     associated with the popup.  Since this call can close the popup, that
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //     could clear that data, leaving us with a pointer-to-garbage.  So at
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //     some point someone needs to make a copy of the match anyway, to
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //     preserve it past the popup closure.
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OpenMatch(AutocompleteMatch match,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 WindowOpenDisposition disposition,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const GURL& alternate_nav_url,
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 const base::string16& pasted_text,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 size_t index);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OmniboxFocusState focus_state() const { return focus_state_; }
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_focus() const { return focus_state_ != OMNIBOX_FOCUS_NONE; }
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_caret_visible() const {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return focus_state_ == OMNIBOX_FOCUS_VISIBLE;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accessors for keyword-related state (see comments on keyword_ and
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is_keyword_hint_).
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16& keyword() const { return keyword_; }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_keyword_hint() const { return is_keyword_hint_; }
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool is_keyword_selected() const {
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return !is_keyword_hint_ && !keyword_.empty();
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accepts the current keyword hint as a keyword. It always returns true for
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // caller convenience. |entered_method| indicates how the use entered
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // keyword mode. This parameter is only used for metrics/logging; it's not
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // used to change user-visible behavior.
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool AcceptKeyword(EnteredKeywordModeMethod entered_method);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Accepts the current temporary text as the user text.
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void AcceptTemporaryTextAsUserText();
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clears the current keyword.  |visible_text| is the (non-keyword) text
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // currently visible in the edit.
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ClearKeyword(const base::string16& visible_text);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the current autocomplete result.  This logic should in the future
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // live in AutocompleteController but resides here for now.  This method is
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // used by AutomationProvider::AutocompleteEditGetMatches.
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const AutocompleteResult& result() const {
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return omnibox_controller_->result();
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the view is gaining focus.  |control_down| is whether the
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // control key is down (at the time we're gaining focus).
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSetFocus(bool control_down);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the visibility of the caret in the omnibox, if it has focus. The
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visibility of the caret is reset to visible if either
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - The user starts typing, or
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - We explicitly focus the omnibox again.
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The latter case must be handled in three separate places--OnSetFocus(),
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // OmniboxView::SetFocus(), and the mouse handlers in OmniboxView. See
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // accompanying comments for why each of these is necessary.
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Caret visibility is tracked per-tab and updates automatically upon
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // switching tabs.
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetCaretVisibility(bool visible);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sent before |OnKillFocus| and before the popup is closed.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnWillKillFocus(gfx::NativeView view_gaining_focus);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the view is losing focus.  Resets some state.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnKillFocus();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user presses the escape key.  Decides what, if anything, to
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // revert about any current edits.  Returns whether the key was handled.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool OnEscapeKeyPressed();
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user presses or releases the control key.  Changes state as
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // necessary.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnControlKeyChanged(bool pressed);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user pastes in text.
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnPaste();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if pasting is in progress.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_pasting() const { return paste_state_ == PASTING; }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(beaudoin): Try not to expose this.
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool in_revert() const { return in_revert_; }
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user presses up or down.  |count| is a repeat count,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // negative for moving up, positive for moving down.
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnUpOrDownKeyPressed(int count);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when any relevant data changes.  This rolls together several
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // separate pieces of data into one call so we can update all the UI
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // efficiently:
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   |text| is either the new temporary text from the user manually selecting
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     a different match, or the inline autocomplete text.  We distinguish by
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     checking if |destination_for_temporary_text_change| is NULL.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   |destination_for_temporary_text_change| is NULL (if temporary text should
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     not change) or the pre-change destination URL (if temporary text should
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     change) so we can save it off to restore later.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   |keyword| is the keyword to show a hint for if |is_keyword_hint| is true,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     or the currently selected keyword if |is_keyword_hint| is false (see
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     comments on keyword_ and is_keyword_hint_).
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnPopupDataChanged(
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& text,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL* destination_for_temporary_text_change,
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& keyword,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool is_keyword_hint);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by the OmniboxView after something changes, with details about what
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // state changes occured.  Updates internal state, updates the popup if
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // necessary, and returns true if any significant changes occurred.  Note that
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |text_differs| may be set even if |old_text| == |new_text|, e.g. if we've
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just committed an IME composition.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |allow_keyword_ui_change| is false then the change should not affect
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keyword ui state, even if the text matches a keyword exactly. This value
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may be false when the user is composing a text with an IME.
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool OnAfterPossibleChange(const base::string16& old_text,
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const base::string16& new_text,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             size_t selection_start,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             size_t selection_end,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool selection_differs,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool text_differs,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool just_deleted_text,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool allow_keyword_ui_change);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Called when the current match has changed in the OmniboxController.
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void OnCurrentMatchChanged();
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Sends the current SearchProvider suggestion to the Instant page if any.
339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void SetSuggestionToPrefetch(const InstantSuggestion& suggestion);
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Name of the histogram tracking cut or copy omnibox commands.
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static const char kCutOrCopyAllTextHistogram[];
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  friend class OmniboxControllerTest;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum PasteState {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NONE,           // Most recent edit was not a paste.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PASTING,        // In the middle of doing a paste. We need this intermediate
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // state because OnPaste() does the actual detection of
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // paste, but OnAfterPossibleChange() has to update the
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // paste state for every edit. If OnPaste() set the state
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // directly to PASTED, OnAfterPossibleChange() wouldn't know
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // whether that represented the current edit or a past one.
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PASTED,         // Most recent edit was a paste.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ControlKeyState {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UP,                   // The control key is not depressed.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DOWN_WITHOUT_CHANGE,  // The control key is depressed, and the edit's
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // contents/selection have not changed since it was
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // depressed.  This is the only state in which we
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // do the "ctrl-enter" behavior when the user hits
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // enter.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DOWN_WITH_CHANGE,     // The control key is depressed, and the edit's
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // contents/selection have changed since it was
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // depressed.  If the user now hits enter, we assume
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // he simply hasn't released the key, rather than that
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // he intended to hit "ctrl-enter".
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if a query to an autocomplete provider is currently
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in progress.  This logic should in the future live in
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AutocompleteController but resides here for now.  This method is used by
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AutomationProvider::AutocompleteEditIsQueryInProgress.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool query_in_progress() const;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called whenever user_text_ should change.
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void InternalSetUserText(const base::string16& text);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Turns off keyword mode for the current match.
382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void ClearPopupKeywordMode() const;
383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Conversion between user text and display text. User text is the text the
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // user has input. Display text is the text being shown in the edit. The
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // two are different if a keyword is selected.
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 DisplayTextFromUserText(const base::string16& text) const;
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 UserTextFromDisplayText(const base::string16& text) const;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // If there's a selected match, copies it into |match|. Else, returns the
391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // default match for the current text, as well as the alternate nav URL, if
392b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // |alternate_nav_url| is non-NULL and there is such a URL.
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetInfoForCurrentText(AutocompleteMatch* match,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             GURL* alternate_nav_url) const;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reverts the edit box from a temporary text back to the original user text.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |revert_popup| is true then the popup will be reverted as well.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RevertTemporaryText(bool revert_popup);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accepts current keyword if the user just typed a space at the end of
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |new_text|.  This handles both of the following cases:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   (assume "foo" is a keyword, | is the input caret, [] is selected text)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   foo| -> foo |      (a space was appended to a keyword)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   foo[bar] -> foo |  (a space replaced other text after a keyword)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the current keyword is accepted.
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool MaybeAcceptKeywordBySpace(const base::string16& new_text);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks whether the user inserted a space into |old_text| and by doing so
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // created a |new_text| that looks like "<keyword> <search phrase>".
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CreatedKeywordSearchByInsertingSpaceInMiddle(
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& old_text,
412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& new_text,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t caret_position) const;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks if a given character is a valid space character for accepting
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keyword.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsSpaceCharForAcceptingKeyword(wchar_t c);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Classify the current page being viewed as, for example, the new tab
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // page or a normal web page.  Used for logging omnibox events for
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UMA opted-in users.  Examines the user's profile to determine if the
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // current page is the user's home page.
4236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  metrics::OmniboxEventProto::PageClassification ClassifyPage() const;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets |match| and |alternate_nav_url| based on classifying |text|.
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |alternate_nav_url| may be NULL.
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ClassifyStringForPasteAndGo(const base::string16& text,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   AutocompleteMatch* match,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GURL* alternate_nav_url) const;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If focus_state_ does not match |state|, we update it and notify the
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // InstantController about the change (passing along the |reason| for the
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // change). If the caret visibility changes, we call ApplyCaretVisibility() on
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the view.
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetFocusState(OmniboxFocusState state, OmniboxFocusChangeReason reason);
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<OmniboxController> omnibox_controller_;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxView* view_;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxEditController* controller_;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<OmniboxCurrentPageDelegate> delegate_;
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OmniboxFocusState focus_state_;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Used to keep track whether the input currently in progress originated by
4483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // focusing in the Omnibox or in the Fakebox. This will be INVALID if no input
4493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // is in progress or the Omnibox is not focused.
4503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FocusSource focus_source_;
4513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL of the currently displayed page.
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 permanent_text_;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This flag is true when the user has modified the contents of the edit, but
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not yet accepted them.  We use this to determine when we need to save
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // state (on switching tabs) and whether changes to the page URL should be
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // immediately displayed.
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This flag will be true in a superset of the cases where the popup is open.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool user_input_in_progress_;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The text that the user has entered.  This does not include inline
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // autocomplete text that has not yet been accepted.
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 user_text_;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // We keep track of when the user last focused on the omnibox.
4672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::TimeTicks last_omnibox_focus_;
4682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
4692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Whether any user input has occurred since focusing on the omnibox. This is
4702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // used along with |last_omnibox_focus_| to calculate the time between a user
4712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // focusing on the omnibox and editing. It is initialized to true since
4722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // there was no focus event.
4732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  bool user_input_since_focus_;
4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We keep track of when the user began modifying the omnibox text.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should be valid whenever user_input_in_progress_ is true.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks time_user_first_modified_omnibox_;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the user closes the popup, we need to remember the URL for their
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // desired choice, so that if they hit enter without reopening the popup we
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // know where to go.  We could simply rerun autocomplete in this case, but
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we'd need to either wait for all results to come in (unacceptably slow) or
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // do the wrong thing when the user had chosen some provider whose results
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // were not returned instantaneously.
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This variable is only valid when user_input_in_progress_ is true, since
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when it is false the user has either never input anything (so there won't
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be a value here anyway) or has canceled their input, which should be
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // treated the same way.  Also, since this is for preserving a desired URL
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after the popup has been closed, we ignore this if the popup is open, and
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simply ask the popup for the desired URL directly.  As a result, the
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contents of this variable only need to be updated when the popup is closed
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but user_input_in_progress_ is not being cleared.
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 url_for_remembered_user_selection_;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inline autocomplete is allowed if the user has not just deleted text, and
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no temporary text is showing.  In this case, inline_autocomplete_text_ is
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // appended to the user_text_ and displayed selected (at least initially).
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: When the popup is closed there should never be inline autocomplete
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // text (actions that close the popup should either accept the text, convert
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it to a normal selection, or change the edit entirely).
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool just_deleted_text_;
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 inline_autocomplete_text_;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used by OnPopupDataChanged to keep track of whether there is currently a
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // temporary text.
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Example of use: If the user types "goog", then arrows down in the
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // autocomplete popup until, say, "google.com" appears in the edit box, then
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the user_text_ is still "goog", and "google.com" is "temporary text".
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the user hits <esc>, the edit box reverts to "goog".  Hit <esc> again
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the popup is closed and "goog" is replaced by the permanent_text_,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which is the URL of the current page.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // original_url_ is only valid when there is temporary text, and is used as
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the unique identifier of the originally selected item.  Thus, if the user
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // arrows to a different item with the same text, we can still distinguish
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // them and not revert all the way to the permanent_text_.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_temporary_text_;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL original_url_;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the user's last action was to paste, we disallow inline autocomplete
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (on the theory that the user is trying to paste in a new URL or part of
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one, and in either case inline autocomplete would get in the way).
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PasteState paste_state_;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the control key is depressed.  We track this to avoid calling
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdatePopup() repeatedly if the user holds down the key, and to know
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whether to trigger "ctrl-enter" behavior.
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ControlKeyState control_key_state_;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The keyword associated with the current match.  The user may have an actual
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // selected keyword, or just some input text that looks like a keyword (so we
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can show a hint to press <tab>).  This is the keyword in either case;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is_keyword_hint_ (below) distinguishes the two cases.
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 keyword_;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if the keyword associated with this match is merely a hint, i.e. the
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // user hasn't actually selected a keyword yet.  When this is true, we can use
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keyword_ to show a "Press <tab> to search" sort of hint.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_keyword_hint_;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // This is needed to properly update the SearchModel state when the user
5477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // presses escape.
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool in_revert_;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates if the upcoming autocomplete search is allowed to be treated as
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an exact keyword match.  If this is true then keyword mode will be
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // triggered automatically if the input is "<keyword> <search string>".  We
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allow this when CreatedKeywordSearchByInsertingSpaceInMiddle() is true.
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This has no effect if we're already in keyword mode.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allow_exact_keyword_match_;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // The input that was sent to the AutocompleteController. Since no
5585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // autocomplete query is started after a tab switch, it is possible for this
5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |input_| to differ from the one currently stored in AutocompleteController.
5605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  AutocompleteInput input_;
5615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OmniboxEditModel);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_EDIT_MODEL_H_
566