[email protected] | 3cb0f8d9 | 2012-02-29 05:43:34 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | b76ac71 | 2011-05-03 22:17:11 | [diff] [blame] | 5 | // This file defines the interface class OmniboxView. Each toolkit will |
| 6 | // implement the edit view differently, so that code is inherently platform |
[email protected] | fbdc423 | 2012-06-24 15:28:37 | [diff] [blame] | 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. |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 10 | |
[email protected] | b76ac71 | 2011-05-03 22:17:11 | [diff] [blame] | 11 | #ifndef CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_H_ |
| 12 | #define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_H_ |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 13 | |
| 14 | #include <string> |
| 15 | |
[email protected] | 1152118 | 2013-06-11 04:06:36 | [diff] [blame] | 16 | #include "base/strings/string16.h" |
| 17 | #include "base/strings/string_util.h" |
[email protected] | 5846d58 | 2013-06-08 16:02:12 | [diff] [blame] | 18 | #include "base/strings/utf_string_conversions.h" |
[email protected] | 7e41c2b | 2011-05-06 10:31:16 | [diff] [blame] | 19 | #include "chrome/browser/autocomplete/autocomplete_match.h" |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 20 | #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
[email protected] | a1d2916 | 2011-10-14 17:14:03 | [diff] [blame] | 21 | #include "content/public/common/url_constants.h" |
[email protected] | f47621b | 2013-01-22 20:50:33 | [diff] [blame] | 22 | #include "ui/base/window_open_disposition.h" |
[email protected] | 08397d5 | 2011-02-05 01:53:38 | [diff] [blame] | 23 | #include "ui/gfx/native_widget_types.h" |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 24 | |
[email protected] | ce47a3c | 2010-03-04 03:30:55 | [diff] [blame] | 25 | class CommandUpdater; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 26 | class GURL; |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 27 | class OmniboxEditController; |
[email protected] | ac7cc2b6 | 2012-12-20 03:33:43 | [diff] [blame] | 28 | class OmniboxViewMacTest; |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 29 | class Profile; |
| 30 | class ToolbarModel; |
[email protected] | 83a2610a | 2012-01-05 01:00:27 | [diff] [blame] | 31 | |
| 32 | namespace content { |
| 33 | class WebContents; |
| 34 | } |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 35 | |
[email protected] | caa62f47 | 2011-01-07 17:46:59 | [diff] [blame] | 36 | #if defined(TOOLKIT_VIEWS) |
[email protected] | 33b6226 | 2011-11-09 00:58:47 | [diff] [blame] | 37 | // TODO(beng): Move all views-related code to a views-specific sub-interface. |
[email protected] | 2809425 | 2012-06-07 19:51:15 | [diff] [blame] | 38 | namespace gfx { |
| 39 | class Font; |
| 40 | } |
| 41 | |
[email protected] | caa62f47 | 2011-01-07 17:46:59 | [diff] [blame] | 42 | namespace views { |
[email protected] | caa62f47 | 2011-01-07 17:46:59 | [diff] [blame] | 43 | class View; |
[email protected] | 2809425 | 2012-06-07 19:51:15 | [diff] [blame] | 44 | } |
[email protected] | e833677 | 2012-08-14 23:31:37 | [diff] [blame] | 45 | |
| 46 | namespace ui { |
| 47 | class DropTargetEvent; |
| 48 | } |
[email protected] | caa62f47 | 2011-01-07 17:46:59 | [diff] [blame] | 49 | #endif |
| 50 | |
[email protected] | b76ac71 | 2011-05-03 22:17:11 | [diff] [blame] | 51 | class OmniboxView { |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 52 | public: |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 53 | virtual ~OmniboxView(); |
| 54 | |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 55 | // Used by the automation system for getting at the model from the view. |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 56 | OmniboxEditModel* model() { return model_.get(); } |
| 57 | const OmniboxEditModel* model() const { return model_.get(); } |
| 58 | |
| 59 | CommandUpdater* command_updater() { return command_updater_; } |
| 60 | const CommandUpdater* command_updater() const { return command_updater_; } |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 61 | |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 62 | // For use when switching tabs, this saves the current state onto the tab so |
| 63 | // that it can be restored during a later call to Update(). |
[email protected] | 83a2610a | 2012-01-05 01:00:27 | [diff] [blame] | 64 | virtual void SaveStateToTab(content::WebContents* tab) = 0; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 65 | |
[email protected] | 7c8147a | 2013-08-24 03:09:49 | [diff] [blame^] | 66 | // Called when the window's active tab changes. |
| 67 | virtual void OnTabChanged(const content::WebContents* web_contents) = 0; |
| 68 | |
| 69 | // Called when any relevant state changes other than changing tabs. |
| 70 | virtual void Update() = 0; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 71 | |
[email protected] | 7e41c2b | 2011-05-06 10:31:16 | [diff] [blame] | 72 | // Asks the browser to load the specified match's |destination_url|, which |
| 73 | // is assumed to be one of the popup entries, using the supplied disposition |
| 74 | // and transition type. |alternate_nav_url|, if non-empty, contains the |
| 75 | // alternate navigation URL for for this match. See comments on |
| 76 | // AutocompleteResult::GetAlternateNavURL(). |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 77 | // |
| 78 | // |selected_line| is passed to SendOpenNotification(); see comments there. |
| 79 | // |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 80 | // This may close the popup. |
[email protected] | 7e41c2b | 2011-05-06 10:31:16 | [diff] [blame] | 81 | virtual void OpenMatch(const AutocompleteMatch& match, |
| 82 | WindowOpenDisposition disposition, |
| 83 | const GURL& alternate_nav_url, |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 84 | size_t selected_line); |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 85 | |
| 86 | // Returns the current text of the edit control, which could be the |
| 87 | // "temporary" text set by the popup, the "permanent" text set by the |
| 88 | // browser, or just whatever the user has currently typed. |
[email protected] | a2fedb1e | 2011-01-25 15:23:36 | [diff] [blame] | 89 | virtual string16 GetText() const = 0; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 90 | |
[email protected] | 69c579e | 2010-04-23 20:01:00 | [diff] [blame] | 91 | // |true| if the user is in the process of editing the field, or if |
| 92 | // the field is empty. |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 93 | bool IsEditingOrEmpty() const; |
[email protected] | 69c579e | 2010-04-23 20:01:00 | [diff] [blame] | 94 | |
| 95 | // Returns the resource ID of the icon to show for the current text. |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 96 | int GetIcon() const; |
[email protected] | 69c579e | 2010-04-23 20:01:00 | [diff] [blame] | 97 | |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 98 | // The user text is the text the user has manually keyed in. When present, |
| 99 | // this is shown in preference to the permanent text; hitting escape will |
| 100 | // revert to the permanent text. |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 101 | void SetUserText(const string16& text); |
[email protected] | a2fedb1e | 2011-01-25 15:23:36 | [diff] [blame] | 102 | virtual void SetUserText(const string16& text, |
| 103 | const string16& display_text, |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 104 | bool update_popup); |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 105 | |
[email protected] | 01b8d650 | 2013-02-15 17:35:55 | [diff] [blame] | 106 | // Sets the window text and the caret position. |notify_text_changed| is true |
| 107 | // if the model should be notified of the change. |
[email protected] | a2fedb1e | 2011-01-25 15:23:36 | [diff] [blame] | 108 | virtual void SetWindowTextAndCaretPos(const string16& text, |
[email protected] | 3cb0f8d9 | 2012-02-29 05:43:34 | [diff] [blame] | 109 | size_t caret_pos, |
| 110 | bool update_popup, |
| 111 | bool notify_text_changed) = 0; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 112 | |
[email protected] | 731980c | 2009-06-05 19:41:46 | [diff] [blame] | 113 | // Sets the edit to forced query mode. Practically speaking, this means that |
| 114 | // if the edit is not in forced query mode, its text is set to "?" with the |
| 115 | // cursor at the end, and if the edit is in forced query mode (its first |
[email protected] | 3c11b5b0 | 2010-09-11 05:20:42 | [diff] [blame] | 116 | // non-whitespace character is '?'), the text after the '?' is selected. |
[email protected] | 731980c | 2009-06-05 19:41:46 | [diff] [blame] | 117 | // |
| 118 | // In the future we should display the search engine UI for the default engine |
| 119 | // rather than '?'. |
| 120 | virtual void SetForcedQuery() = 0; |
| 121 | |
[email protected] | 5fdafa3 | 2009-08-28 00:31:28 | [diff] [blame] | 122 | // Returns true if all text is selected or there is no text at all. |
[email protected] | fb8e3a3 | 2012-05-10 21:03:52 | [diff] [blame] | 123 | virtual bool IsSelectAll() const = 0; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 124 | |
[email protected] | b93b79ec | 2010-11-19 20:21:22 | [diff] [blame] | 125 | // Returns true if the user deleted the suggested text. |
| 126 | virtual bool DeleteAtEndPressed() = 0; |
| 127 | |
[email protected] | 3c11b5b0 | 2010-09-11 05:20:42 | [diff] [blame] | 128 | // Fills |start| and |end| with the indexes of the current selection's bounds. |
| 129 | // It is not guaranteed that |*start < *end|, as the selection can be |
| 130 | // directed. If there is no selection, |start| and |end| will both be equal |
| 131 | // to the current cursor position. |
[email protected] | 4003e72 | 2011-10-31 05:04:03 | [diff] [blame] | 132 | virtual void GetSelectionBounds(size_t* start, size_t* end) const = 0; |
[email protected] | 3c11b5b0 | 2010-09-11 05:20:42 | [diff] [blame] | 133 | |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 134 | // Selects all the text in the edit. Use this in place of SetSelAll() to |
| 135 | // avoid selecting the "phantom newline" at the end of the edit. |
| 136 | virtual void SelectAll(bool reversed) = 0; |
| 137 | |
| 138 | // Reverts the edit and popup back to their unedited state (permanent text |
| 139 | // showing, popup closed, no user input in progress). |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 140 | virtual void RevertAll(); |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 141 | |
| 142 | // Updates the autocomplete popup and other state after the text has been |
| 143 | // changed by the user. |
| 144 | virtual void UpdatePopup() = 0; |
| 145 | |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 146 | // Closes the autocomplete popup, if it's open. The name |ClosePopup| |
| 147 | // conflicts with the OSX class override as that has a base class that also |
| 148 | // defines a method with that name. |
| 149 | virtual void CloseOmniboxPopup(); |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 150 | |
[email protected] | 2be2c013 | 2009-09-14 20:20:35 | [diff] [blame] | 151 | // Sets the focus to the autocomplete view. |
| 152 | virtual void SetFocus() = 0; |
| 153 | |
[email protected] | c18cb67 | 2012-12-05 04:42:12 | [diff] [blame] | 154 | // Shows or hides the caret based on whether the model's is_caret_visible() is |
| 155 | // true. |
| 156 | virtual void ApplyCaretVisibility() = 0; |
| 157 | |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 158 | // Called when the temporary text in the model may have changed. |
| 159 | // |display_text| is the new text to show; |save_original_selection| is true |
| 160 | // when there wasn't previously a temporary text and thus we need to save off |
[email protected] | 01b8d650 | 2013-02-15 17:35:55 | [diff] [blame] | 161 | // the user's existing selection. |notify_text_changed| is true if the model |
| 162 | // should be notified of the change. |
[email protected] | a2fedb1e | 2011-01-25 15:23:36 | [diff] [blame] | 163 | virtual void OnTemporaryTextMaybeChanged(const string16& display_text, |
[email protected] | 01b8d650 | 2013-02-15 17:35:55 | [diff] [blame] | 164 | bool save_original_selection, |
| 165 | bool notify_text_changed) = 0; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 166 | |
| 167 | // Called when the inline autocomplete text in the model may have changed. |
| 168 | // |display_text| is the new text to show; |user_text_length| is the length of |
| 169 | // the user input portion of that (so, up to but not including the inline |
| 170 | // autocompletion). Returns whether the display text actually changed. |
| 171 | virtual bool OnInlineAutocompleteTextMaybeChanged( |
[email protected] | a2fedb1e | 2011-01-25 15:23:36 | [diff] [blame] | 172 | const string16& display_text, size_t user_text_length) = 0; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 173 | |
| 174 | // Called when the temporary text has been reverted by the user. This will |
| 175 | // reset the user's original selection. |
| 176 | virtual void OnRevertTemporaryText() = 0; |
| 177 | |
[email protected] | bbe5b49e | 2013-04-05 02:27:01 | [diff] [blame] | 178 | // Checkpoints the current edit state before an operation that might trigger |
| 179 | // a new autocomplete run to open or modify the popup. Call this before |
| 180 | // user-initiated edit actions that trigger autocomplete, but *not* for |
| 181 | // automatic changes to the textfield that should not affect autocomplete. |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 182 | virtual void OnBeforePossibleChange() = 0; |
| 183 | // OnAfterPossibleChange() returns true if there was a change that caused it |
| 184 | // to call UpdatePopup(). |
| 185 | virtual bool OnAfterPossibleChange() = 0; |
[email protected] | fb5153c5 | 2009-07-31 19:40:33 | [diff] [blame] | 186 | |
| 187 | // Returns the gfx::NativeView of the edit view. |
| 188 | virtual gfx::NativeView GetNativeView() const = 0; |
[email protected] | 135fd3b6 | 2009-12-16 01:07:08 | [diff] [blame] | 189 | |
[email protected] | b2544aa9 | 2012-06-21 04:20:09 | [diff] [blame] | 190 | // Gets the relative window for the pop up window of OmniboxPopupView. The pop |
| 191 | // up window will be shown under the relative window. When an IME is attached |
| 192 | // to the rich edit control, the IME window is the relative window. Otherwise, |
| 193 | // the top-most window is the relative window. |
[email protected] | 3510d44 | 2011-10-07 22:13:46 | [diff] [blame] | 194 | virtual gfx::NativeView GetRelativeWindowForPopup() const = 0; |
| 195 | |
[email protected] | b1a843a4 | 2013-07-11 15:11:41 | [diff] [blame] | 196 | // Shows |input| as gray suggested text after what the user has typed. |
| 197 | virtual void SetGrayTextAutocompletion(const string16& input) = 0; |
[email protected] | eec44d94 | 2011-01-11 08:27:24 | [diff] [blame] | 198 | |
[email protected] | b1a843a4 | 2013-07-11 15:11:41 | [diff] [blame] | 199 | // Returns the current gray suggested text. |
| 200 | virtual string16 GetGrayTextAutocompletion() const = 0; |
[email protected] | 911696b | 2011-01-28 02:36:49 | [diff] [blame] | 201 | |
[email protected] | eec44d94 | 2011-01-11 08:27:24 | [diff] [blame] | 202 | // Returns the width in pixels needed to display the current text. The |
| 203 | // returned value includes margins. |
| 204 | virtual int TextWidth() const = 0; |
| 205 | |
[email protected] | 28ea1c9 | 2011-01-13 00:30:18 | [diff] [blame] | 206 | // Returns true if the user is composing something in an IME. |
| 207 | virtual bool IsImeComposing() const = 0; |
| 208 | |
[email protected] | d4606b5d | 2013-06-20 22:38:59 | [diff] [blame] | 209 | // Returns true if we know for sure that an IME is showing a popup window, |
| 210 | // which may overlap the omnibox's popup window. |
[email protected] | 1317783 | 2013-05-31 07:46:05 | [diff] [blame] | 211 | virtual bool IsImeShowingPopup() const; |
| 212 | |
[email protected] | 40a0115 | 2013-06-20 03:52:00 | [diff] [blame] | 213 | // Returns true if the view is displaying UI that indicates that query |
| 214 | // refinement will take place when the user selects the current match. For |
| 215 | // search matches, this will cause the omnibox to search over the existing |
| 216 | // corpus (e.g. Images) rather than start a new Web search. This method will |
| 217 | // only ever return true on mobile ports. |
| 218 | virtual bool IsIndicatingQueryRefinement() const; |
| 219 | |
[email protected] | caa62f47 | 2011-01-07 17:46:59 | [diff] [blame] | 220 | #if defined(TOOLKIT_VIEWS) |
[email protected] | 33b6226 | 2011-11-09 00:58:47 | [diff] [blame] | 221 | virtual int GetMaxEditWidth(int entry_width) const = 0; |
| 222 | |
[email protected] | caa62f47 | 2011-01-07 17:46:59 | [diff] [blame] | 223 | // Adds the autocomplete edit view to view hierarchy and |
| 224 | // returns the views::View of the edit view. |
| 225 | virtual views::View* AddToView(views::View* parent) = 0; |
[email protected] | 557205c | 2011-02-17 18:44:01 | [diff] [blame] | 226 | |
| 227 | // Performs the drop of a drag and drop operation on the view. |
[email protected] | e833677 | 2012-08-14 23:31:37 | [diff] [blame] | 228 | virtual int OnPerformDrop(const ui::DropTargetEvent& event) = 0; |
[email protected] | caa62f47 | 2011-01-07 17:46:59 | [diff] [blame] | 229 | #endif |
| 230 | |
[email protected] | 6cf51b6 | 2013-08-10 13:49:22 | [diff] [blame] | 231 | // Returns |text| with any leading javascript schemas stripped. |
[email protected] | 067095a | 2011-05-24 23:43:44 | [diff] [blame] | 232 | static string16 StripJavascriptSchemas(const string16& text); |
| 233 | |
[email protected] | 6cf51b6 | 2013-08-10 13:49:22 | [diff] [blame] | 234 | // First, calls StripJavascriptSchemas(). Then automatically collapses |
| 235 | // internal whitespace as follows: |
| 236 | // * If the only whitespace in |text| is newlines, users are most likely |
| 237 | // pasting in URLs split into multiple lines by terminals, email programs, |
| 238 | // etc. So all newlines are removed. |
| 239 | // * Otherwise, users may be pasting in search data, e.g. street addresses. In |
| 240 | // this case, runs of whitespace are collapsed down to single spaces. |
| 241 | static string16 SanitizeTextForPaste(const string16& text); |
| 242 | |
[email protected] | b1ce3069 | 2012-05-15 18:26:35 | [diff] [blame] | 243 | // Returns the current clipboard contents as a string that can be pasted in. |
| 244 | // In addition to just getting CF_UNICODETEXT out, this can also extract URLs |
| 245 | // from bookmarks on the clipboard. |
| 246 | static string16 GetClipboardText(); |
| 247 | |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 248 | protected: |
| 249 | OmniboxView(Profile* profile, |
| 250 | OmniboxEditController* controller, |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 251 | CommandUpdater* command_updater); |
| 252 | |
| 253 | // Internally invoked whenever the text changes in some way. |
| 254 | virtual void TextChanged(); |
| 255 | |
| 256 | // Return the number of characters in the current buffer. The name |
| 257 | // |GetTextLength| can't be used as the Windows override of this class |
| 258 | // inherits from a class that defines a method with that name. |
| 259 | virtual int GetOmniboxTextLength() const = 0; |
| 260 | |
| 261 | // Try to parse the current text as a URL and colorize the components. |
| 262 | virtual void EmphasizeURLComponents() = 0; |
| 263 | |
| 264 | OmniboxEditController* controller() { return controller_; } |
[email protected] | a40be8b | 2013-08-22 20:12:14 | [diff] [blame] | 265 | const OmniboxEditController* controller() const { return controller_; } |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 266 | |
| 267 | private: |
[email protected] | ac7cc2b6 | 2012-12-20 03:33:43 | [diff] [blame] | 268 | friend class OmniboxViewMacTest; |
| 269 | |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 270 | // |model_| can be NULL in tests. |
| 271 | scoped_ptr<OmniboxEditModel> model_; |
| 272 | OmniboxEditController* controller_; |
[email protected] | c51eed7 | 2012-08-07 22:01:55 | [diff] [blame] | 273 | |
| 274 | // The object that handles additional command functionality exposed on the |
| 275 | // edit, such as invoking the keyword editor. |
| 276 | CommandUpdater* command_updater_; |
[email protected] | 93e5033 | 2009-03-02 18:58:26 | [diff] [blame] | 277 | }; |
| 278 | |
[email protected] | b76ac71 | 2011-05-03 22:17:11 | [diff] [blame] | 279 | #endif // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_H_ |