1// Copyright (c) 2012 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.
4
5// This file defines the interface class OmniboxView.  Each toolkit will
6// implement the edit view differently, so that code is inherently platform
7// specific.  However, the OmniboxEditModel needs to do some communication with
8// the view.  Since the model is shared between platforms, we need to define an
9// interface that all view implementations will share.
10
11#ifndef CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_H_
12#define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_H_
13
14#include <string>
15
16#include "base/strings/string16.h"
17#include "base/strings/string_util.h"
18#include "base/strings/utf_string_conversions.h"
19#include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
20#include "components/omnibox/autocomplete_match.h"
21#include "content/public/common/url_constants.h"
22#include "ui/base/window_open_disposition.h"
23#include "ui/gfx/native_widget_types.h"
24
25class CommandUpdater;
26class GURL;
27class OmniboxEditController;
28class OmniboxViewMacTest;
29class Profile;
30class ToolbarModel;
31
32namespace content {
33class WebContents;
34}
35
36class OmniboxView {
37 public:
38  virtual ~OmniboxView();
39
40  // Used by the automation system for getting at the model from the view.
41  OmniboxEditModel* model() { return model_.get(); }
42  const OmniboxEditModel* model() const { return model_.get(); }
43
44  CommandUpdater* command_updater() { return command_updater_; }
45  const CommandUpdater* command_updater() const { return command_updater_; }
46
47  // Handle mouse release events concerning the origin chip.
48  void HandleOriginChipMouseRelease();
49
50  // Shared cross-platform focus handling.
51  void OnDidKillFocus();
52
53  // For use when switching tabs, this saves the current state onto the tab so
54  // that it can be restored during a later call to Update().
55  virtual void SaveStateToTab(content::WebContents* tab) = 0;
56
57  // Called when the window's active tab changes.
58  virtual void OnTabChanged(const content::WebContents* web_contents) = 0;
59
60  // Called when any relevant state changes other than changing tabs.
61  virtual void Update() = 0;
62
63  // Updates the placeholder text with the value of GetHintText() if the
64  // origin chip is enabled.
65  virtual void UpdatePlaceholderText() = 0;
66
67  // Asks the browser to load the specified match, using the supplied
68  // disposition. |alternate_nav_url|, if non-empty, contains the
69  // alternate navigation URL for for this match. See comments on
70  // AutocompleteResult::GetAlternateNavURL().
71  //
72  // |pasted_text| should only be set if this call is due to a
73  // Paste-And-Go/Search action.
74  //
75  // |selected_line| is passed to SendOpenNotification(); see comments there.
76  //
77  // This may close the popup.
78  virtual void OpenMatch(const AutocompleteMatch& match,
79                         WindowOpenDisposition disposition,
80                         const GURL& alternate_nav_url,
81                         const base::string16& pasted_text,
82                         size_t selected_line);
83
84  // Returns the current text of the edit control, which could be the
85  // "temporary" text set by the popup, the "permanent" text set by the
86  // browser, or just whatever the user has currently typed.
87  virtual base::string16 GetText() const = 0;
88
89  // |true| if the user is in the process of editing the field, or if
90  // the field is empty.
91  bool IsEditingOrEmpty() const;
92
93  // Returns the resource ID of the icon to show for the current text.
94  int GetIcon() const;
95
96  // Returns the hint text that should be displayed when there is no text in the
97  // omnibox.  In keyword mode, this is an empty string.  Otherwise, it's
98  // instructions to search the user's default search engine or type a URL.
99  base::string16 GetHintText() const;
100
101  // The user text is the text the user has manually keyed in.  When present,
102  // this is shown in preference to the permanent text; hitting escape will
103  // revert to the permanent text.
104  void SetUserText(const base::string16& text);
105  virtual void SetUserText(const base::string16& text,
106                           const base::string16& display_text,
107                           bool update_popup);
108
109  // Sets the window text and the caret position. |notify_text_changed| is true
110  // if the model should be notified of the change.
111  virtual void SetWindowTextAndCaretPos(const base::string16& text,
112                                        size_t caret_pos,
113                                        bool update_popup,
114                                        bool notify_text_changed) = 0;
115
116  // Sets the edit to forced query mode.  Practically speaking, this means that
117  // if the edit is not in forced query mode, its text is set to "?" with the
118  // cursor at the end, and if the edit is in forced query mode (its first
119  // non-whitespace character is '?'), the text after the '?' is selected.
120  //
121  // In the future we should display the search engine UI for the default engine
122  // rather than '?'.
123  virtual void SetForcedQuery() = 0;
124
125  // Returns true if all text is selected or there is no text at all.
126  virtual bool IsSelectAll() const = 0;
127
128  // Returns true if the user deleted the suggested text.
129  virtual bool DeleteAtEndPressed() = 0;
130
131  // Fills |start| and |end| with the indexes of the current selection's bounds.
132  // It is not guaranteed that |*start < *end|, as the selection can be
133  // directed.  If there is no selection, |start| and |end| will both be equal
134  // to the current cursor position.
135  virtual void GetSelectionBounds(size_t* start, size_t* end) const = 0;
136
137  // Selects all the text in the edit.  Use this in place of SetSelAll() to
138  // avoid selecting the "phantom newline" at the end of the edit.
139  virtual void SelectAll(bool reversed) = 0;
140
141  // Sets focus, disables search term replacement, reverts the omnibox, and
142  // selects all.
143  void ShowURL();
144
145  // Enables search term replacement and reverts the omnibox.
146  void HideURL();
147
148  // Re-enables search term replacement on the ToolbarModel, and reverts the
149  // edit and popup back to their unedited state (permanent text showing, popup
150  // closed, no user input in progress).
151  virtual void RevertAll();
152
153  // Like RevertAll(), but does not touch the search term replacement state.
154  void RevertWithoutResettingSearchTermReplacement();
155
156  // Updates the autocomplete popup and other state after the text has been
157  // changed by the user.
158  virtual void UpdatePopup() = 0;
159
160  // Closes the autocomplete popup, if it's open. The name |ClosePopup|
161  // conflicts with the OSX class override as that has a base class that also
162  // defines a method with that name.
163  virtual void CloseOmniboxPopup();
164
165  // Sets the focus to the autocomplete view.
166  virtual void SetFocus() = 0;
167
168  // Shows or hides the caret based on whether the model's is_caret_visible() is
169  // true.
170  virtual void ApplyCaretVisibility() = 0;
171
172  // Called when the temporary text in the model may have changed.
173  // |display_text| is the new text to show; |save_original_selection| is true
174  // when there wasn't previously a temporary text and thus we need to save off
175  // the user's existing selection. |notify_text_changed| is true if the model
176  // should be notified of the change.
177  virtual void OnTemporaryTextMaybeChanged(const base::string16& display_text,
178                                           bool save_original_selection,
179                                           bool notify_text_changed) = 0;
180
181  // Called when the inline autocomplete text in the model may have changed.
182  // |display_text| is the new text to show; |user_text_length| is the length of
183  // the user input portion of that (so, up to but not including the inline
184  // autocompletion).  Returns whether the display text actually changed.
185  virtual bool OnInlineAutocompleteTextMaybeChanged(
186      const base::string16& display_text, size_t user_text_length) = 0;
187
188  // Called when the inline autocomplete text in the model has been cleared.
189  virtual void OnInlineAutocompleteTextCleared() = 0;
190
191  // Called when the temporary text has been reverted by the user.  This will
192  // reset the user's original selection.
193  virtual void OnRevertTemporaryText() = 0;
194
195  // Checkpoints the current edit state before an operation that might trigger
196  // a new autocomplete run to open or modify the popup. Call this before
197  // user-initiated edit actions that trigger autocomplete, but *not* for
198  // automatic changes to the textfield that should not affect autocomplete.
199  virtual void OnBeforePossibleChange() = 0;
200  // OnAfterPossibleChange() returns true if there was a change that caused it
201  // to call UpdatePopup().
202  virtual bool OnAfterPossibleChange() = 0;
203
204  // Returns the gfx::NativeView of the edit view.
205  virtual gfx::NativeView GetNativeView() const = 0;
206
207  // Gets the relative window for the pop up window of OmniboxPopupView. The pop
208  // up window will be shown under the relative window. When an IME is attached
209  // to the rich edit control, the IME window is the relative window. Otherwise,
210  // the top-most window is the relative window.
211  virtual gfx::NativeView GetRelativeWindowForPopup() const = 0;
212
213  // Shows |input| as gray suggested text after what the user has typed.
214  virtual void SetGrayTextAutocompletion(const base::string16& input) = 0;
215
216  // Returns the current gray suggested text.
217  virtual base::string16 GetGrayTextAutocompletion() const = 0;
218
219  // Returns the width in pixels needed to display the current text. The
220  // returned value includes margins.
221  virtual int GetTextWidth() const = 0;
222
223  // Returns the omnibox's width in pixels.
224  virtual int GetWidth() const = 0;
225
226  // Returns true if the user is composing something in an IME.
227  virtual bool IsImeComposing() const = 0;
228
229  // Returns true if we know for sure that an IME is showing a popup window,
230  // which may overlap the omnibox's popup window.
231  virtual bool IsImeShowingPopup() const;
232
233  // Display a virtual keybaord or alternate input view if enabled.
234  virtual void ShowImeIfNeeded();
235
236  // Returns true if the view is displaying UI that indicates that query
237  // refinement will take place when the user selects the current match.  For
238  // search matches, this will cause the omnibox to search over the existing
239  // corpus (e.g. Images) rather than start a new Web search.  This method will
240  // only ever return true on mobile ports.
241  virtual bool IsIndicatingQueryRefinement() const;
242
243  // Called after a |match| has been opened for the given |web_contents|.
244  virtual void OnMatchOpened(const AutocompleteMatch& match,
245                             content::WebContents* web_contents);
246
247  // Returns |text| with any leading javascript schemas stripped.
248  static base::string16 StripJavascriptSchemas(const base::string16& text);
249
250  // First, calls StripJavascriptSchemas().  Then automatically collapses
251  // internal whitespace as follows:
252  // * If the only whitespace in |text| is newlines, users are most likely
253  // pasting in URLs split into multiple lines by terminals, email programs,
254  // etc. So all newlines are removed.
255  // * Otherwise, users may be pasting in search data, e.g. street addresses. In
256  // this case, runs of whitespace are collapsed down to single spaces.
257  static base::string16 SanitizeTextForPaste(const base::string16& text);
258
259  // Returns the current clipboard contents as a string that can be pasted in.
260  // In addition to just getting CF_UNICODETEXT out, this can also extract URLs
261  // from bookmarks on the clipboard.
262  static base::string16 GetClipboardText();
263
264 protected:
265  OmniboxView(Profile* profile,
266              OmniboxEditController* controller,
267              CommandUpdater* command_updater);
268
269  // Internally invoked whenever the text changes in some way.
270  virtual void TextChanged();
271
272  // Return the number of characters in the current buffer. The name
273  // |GetTextLength| can't be used as the Windows override of this class
274  // inherits from a class that defines a method with that name.
275  virtual int GetOmniboxTextLength() const = 0;
276
277  // Try to parse the current text as a URL and colorize the components.
278  virtual void EmphasizeURLComponents() = 0;
279
280  Profile* profile() { return model_->profile(); }
281  OmniboxEditController* controller() { return controller_; }
282  const OmniboxEditController* controller() const { return controller_; }
283
284 private:
285  friend class OmniboxViewMacTest;
286  FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, ShowURL);
287
288  // |model_| can be NULL in tests.
289  scoped_ptr<OmniboxEditModel> model_;
290  OmniboxEditController* controller_;
291
292  // The object that handles additional command functionality exposed on the
293  // edit, such as invoking the keyword editor.
294  CommandUpdater* command_updater_;
295};
296
297#endif  // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_H_
298