Home | History | Annotate | Download | only in omnibox
      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 
     26 class CommandUpdater;
     27 class GURL;
     28 class OmniboxEditController;
     29 class OmniboxViewMacTest;
     30 class Profile;
     31 class ToolbarModel;
     32 
     33 namespace content {
     34 class WebContents;
     35 }
     36 
     37 #if defined(TOOLKIT_VIEWS)
     38 // TODO(beng): Move all views-related code to a views-specific sub-interface.
     39 namespace gfx {
     40 class Font;
     41 }
     42 
     43 namespace views {
     44 class View;
     45 }
     46 
     47 namespace ui {
     48 class DropTargetEvent;
     49 }
     50 #endif
     51 
     52 class 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