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/autocomplete/autocomplete_match.h"
20#include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
21#include "chrome/browser/ui/toolbar/toolbar_model.h"
22#include "content/public/common/url_constants.h"
23#include "ui/base/window_open_disposition.h"
24#include "ui/gfx/native_widget_types.h"
25
26class CommandUpdater;
27class GURL;
28class OmniboxEditController;
29class OmniboxViewMacTest;
30class Profile;
31class ToolbarModel;
32
33namespace content {
34class WebContents;
35}
36
37#if defined(TOOLKIT_VIEWS)
38// TODO(beng): Move all views-related code to a views-specific sub-interface.
39namespace gfx {
40class Font;
41}
42
43namespace views {
44class View;
45}
46
47namespace ui {
48class DropTargetEvent;
49}
50#endif
51
52class OmniboxView {
53 public:
54  virtual ~OmniboxView();
55
56  // Used by the automation system for getting at the model from the view.
57  OmniboxEditModel* model() { return model_.get(); }
58  const OmniboxEditModel* model() const { return model_.get(); }
59
60  CommandUpdater* command_updater() { return command_updater_; }
61  const CommandUpdater* command_updater() const { return command_updater_; }
62
63  ToolbarModel* toolbar_model() { return toolbar_model_; }
64  const ToolbarModel* toolbar_model() const { return toolbar_model_; }
65
66  // For use when switching tabs, this saves the current state onto the tab so
67  // that it can be restored during a later call to Update().
68  virtual void SaveStateToTab(content::WebContents* tab) = 0;
69
70  // Called when any LocationBarView state changes. If
71  // |tab_for_state_restoring| is non-NULL, it points to a WebContents whose
72  // state we should restore.
73  virtual void Update(const content::WebContents* tab_for_state_restoring) = 0;
74
75  // Asks the browser to load the specified match's |destination_url|, which
76  // is assumed to be one of the popup entries, using the supplied disposition
77  // and transition type. |alternate_nav_url|, if non-empty, contains the
78  // alternate navigation URL for for this match. See comments on
79  // AutocompleteResult::GetAlternateNavURL().
80  //
81  // |selected_line| is passed to SendOpenNotification(); see comments there.
82  //
83  // This may close the popup.
84  virtual void OpenMatch(const AutocompleteMatch& match,
85                         WindowOpenDisposition disposition,
86                         const GURL& alternate_nav_url,
87                         size_t selected_line);
88
89  // Returns the current text of the edit control, which could be the
90  // "temporary" text set by the popup, the "permanent" text set by the
91  // browser, or just whatever the user has currently typed.
92  virtual string16 GetText() const = 0;
93
94  // |true| if the user is in the process of editing the field, or if
95  // the field is empty.
96  bool IsEditingOrEmpty() const;
97
98  // Returns the resource ID of the icon to show for the current text.
99  int GetIcon() 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 string16& text);
105  virtual void SetUserText(const string16& text,
106                           const 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 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  // Reverts the edit and popup back to their unedited state (permanent text
142  // showing, popup closed, no user input in progress).
143  virtual void RevertAll();
144
145  // Updates the autocomplete popup and other state after the text has been
146  // changed by the user.
147  virtual void UpdatePopup() = 0;
148
149  // Closes the autocomplete popup, if it's open. The name |ClosePopup|
150  // conflicts with the OSX class override as that has a base class that also
151  // defines a method with that name.
152  virtual void CloseOmniboxPopup();
153
154  // Sets the focus to the autocomplete view.
155  virtual void SetFocus() = 0;
156
157  // Shows or hides the caret based on whether the model's is_caret_visible() is
158  // true.
159  virtual void ApplyCaretVisibility() = 0;
160
161  // Called when the temporary text in the model may have changed.
162  // |display_text| is the new text to show; |save_original_selection| is true
163  // when there wasn't previously a temporary text and thus we need to save off
164  // the user's existing selection. |notify_text_changed| is true if the model
165  // should be notified of the change.
166  virtual void OnTemporaryTextMaybeChanged(const string16& display_text,
167                                           bool save_original_selection,
168                                           bool notify_text_changed) = 0;
169
170  // Called when the inline autocomplete text in the model may have changed.
171  // |display_text| is the new text to show; |user_text_length| is the length of
172  // the user input portion of that (so, up to but not including the inline
173  // autocompletion).  Returns whether the display text actually changed.
174  virtual bool OnInlineAutocompleteTextMaybeChanged(
175      const string16& display_text, size_t user_text_length) = 0;
176
177  // Called when the temporary text has been reverted by the user.  This will
178  // reset the user's original selection.
179  virtual void OnRevertTemporaryText() = 0;
180
181  // Checkpoints the current edit state before an operation that might trigger
182  // a new autocomplete run to open or modify the popup. Call this before
183  // user-initiated edit actions that trigger autocomplete, but *not* for
184  // automatic changes to the textfield that should not affect autocomplete.
185  virtual void OnBeforePossibleChange() = 0;
186  // OnAfterPossibleChange() returns true if there was a change that caused it
187  // to call UpdatePopup().
188  virtual bool OnAfterPossibleChange() = 0;
189
190  // Returns the gfx::NativeView of the edit view.
191  virtual gfx::NativeView GetNativeView() const = 0;
192
193  // Gets the relative window for the pop up window of OmniboxPopupView. The pop
194  // up window will be shown under the relative window. When an IME is attached
195  // to the rich edit control, the IME window is the relative window. Otherwise,
196  // the top-most window is the relative window.
197  virtual gfx::NativeView GetRelativeWindowForPopup() const = 0;
198
199  // Shows |input| as gray suggested text after what the user has typed.
200  virtual void SetGrayTextAutocompletion(const string16& input) = 0;
201
202  // Returns the current gray suggested text.
203  virtual string16 GetGrayTextAutocompletion() const = 0;
204
205  // Returns the width in pixels needed to display the current text. The
206  // returned value includes margins.
207  virtual int TextWidth() const = 0;
208
209  // Returns true if the user is composing something in an IME.
210  virtual bool IsImeComposing() const = 0;
211
212  // Returns true if we know for sure that an IME is showing a popup window,
213  // which may overlap the omnibox's popup window.
214  virtual bool IsImeShowingPopup() const;
215
216  // Returns true if the view is displaying UI that indicates that query
217  // refinement will take place when the user selects the current match.  For
218  // search matches, this will cause the omnibox to search over the existing
219  // corpus (e.g. Images) rather than start a new Web search.  This method will
220  // only ever return true on mobile ports.
221  virtual bool IsIndicatingQueryRefinement() const;
222
223#if defined(TOOLKIT_VIEWS)
224  virtual int GetMaxEditWidth(int entry_width) const = 0;
225
226  // Adds the autocomplete edit view to view hierarchy and
227  // returns the views::View of the edit view.
228  virtual views::View* AddToView(views::View* parent) = 0;
229
230  // Performs the drop of a drag and drop operation on the view.
231  virtual int OnPerformDrop(const ui::DropTargetEvent& event) = 0;
232#endif
233
234  // Returns |text| with any leading javascript schemas stripped.
235  static string16 StripJavascriptSchemas(const string16& text);
236
237  // First, calls StripJavascriptSchemas().  Then automatically collapses
238  // internal whitespace as follows:
239  // * If the only whitespace in |text| is newlines, users are most likely
240  // pasting in URLs split into multiple lines by terminals, email programs,
241  // etc. So all newlines are removed.
242  // * Otherwise, users may be pasting in search data, e.g. street addresses. In
243  // this case, runs of whitespace are collapsed down to single spaces.
244  static string16 SanitizeTextForPaste(const string16& text);
245
246  // Returns the current clipboard contents as a string that can be pasted in.
247  // In addition to just getting CF_UNICODETEXT out, this can also extract URLs
248  // from bookmarks on the clipboard.
249  static string16 GetClipboardText();
250
251 protected:
252  OmniboxView(Profile* profile,
253              OmniboxEditController* controller,
254              ToolbarModel* toolbar_model,
255              CommandUpdater* command_updater);
256
257  // Internally invoked whenever the text changes in some way.
258  virtual void TextChanged();
259
260  // Return the number of characters in the current buffer. The name
261  // |GetTextLength| can't be used as the Windows override of this class
262  // inherits from a class that defines a method with that name.
263  virtual int GetOmniboxTextLength() const = 0;
264
265  // Try to parse the current text as a URL and colorize the components.
266  virtual void EmphasizeURLComponents() = 0;
267
268  OmniboxEditController* controller() { return controller_; }
269
270 private:
271  friend class OmniboxViewMacTest;
272
273  // |model_| can be NULL in tests.
274  scoped_ptr<OmniboxEditModel> model_;
275  OmniboxEditController* controller_;
276  ToolbarModel* toolbar_model_;
277
278  // The object that handles additional command functionality exposed on the
279  // edit, such as invoking the keyword editor.
280  CommandUpdater* command_updater_;
281};
282
283#endif  // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_H_
284