Home | History | Annotate | Download | only in location_bar
      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 #ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
      6 #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "base/prefs/pref_member.h"
     14 #include "chrome/browser/extensions/extension_context_menu_model.h"
     15 #include "chrome/browser/search_engines/template_url_service_observer.h"
     16 #include "chrome/browser/ui/omnibox/location_bar.h"
     17 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
     18 #include "chrome/browser/ui/search/search_model_observer.h"
     19 #include "chrome/browser/ui/toolbar/toolbar_model.h"
     20 #include "chrome/browser/ui/views/dropdown_bar_host.h"
     21 #include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
     22 #include "chrome/browser/ui/views/extensions/extension_popup.h"
     23 #include "content/public/browser/notification_observer.h"
     24 #include "content/public/browser/notification_registrar.h"
     25 #include "ui/gfx/font.h"
     26 #include "ui/gfx/rect.h"
     27 #include "ui/views/controls/button/button.h"
     28 #include "ui/views/controls/native/native_view_host.h"
     29 #include "ui/views/drag_controller.h"
     30 
     31 #if defined(USE_AURA)
     32 #include "ui/compositor/layer_animation_observer.h"
     33 #endif
     34 
     35 class ActionBoxButtonView;
     36 class CommandUpdater;
     37 class ContentSettingBubbleModelDelegate;
     38 class ContentSettingImageView;
     39 class EVBubbleView;
     40 class ExtensionAction;
     41 class GURL;
     42 class GeneratedCreditCardView;
     43 class InstantController;
     44 class KeywordHintView;
     45 class LocationIconView;
     46 class OpenPDFInReaderView;
     47 class PageActionWithBadgeView;
     48 class PageActionImageView;
     49 class Profile;
     50 class ScriptBubbleIconView;
     51 class SelectedKeywordView;
     52 class StarView;
     53 class TemplateURLService;
     54 class ZoomView;
     55 
     56 namespace views {
     57 class BubbleDelegateView;
     58 class ImageButton;
     59 class Label;
     60 class Widget;
     61 }
     62 
     63 /////////////////////////////////////////////////////////////////////////////
     64 //
     65 // LocationBarView class
     66 //
     67 //   The LocationBarView class is a View subclass that paints the background
     68 //   of the URL bar strip and contains its content.
     69 //
     70 /////////////////////////////////////////////////////////////////////////////
     71 class LocationBarView : public LocationBar,
     72                         public LocationBarTesting,
     73                         public views::View,
     74                         public views::ButtonListener,
     75                         public views::DragController,
     76                         public OmniboxEditController,
     77                         public DropdownBarHostDelegate,
     78                         public TemplateURLServiceObserver,
     79                         public content::NotificationObserver,
     80                         public SearchModelObserver {
     81  public:
     82   // The location bar view's class name.
     83   static const char kViewClassName[];
     84 
     85   // DropdownBarHostDelegate:
     86   virtual void SetFocusAndSelection(bool select_all) OVERRIDE;
     87   virtual void SetAnimationOffset(int offset) OVERRIDE;
     88 
     89   // Returns the offset used while animating.
     90   int animation_offset() const { return animation_offset_; }
     91 
     92   class Delegate {
     93    public:
     94     // Should return the current web contents.
     95     virtual content::WebContents* GetWebContents() const = 0;
     96 
     97     // Returns the InstantController, or NULL if there isn't one.
     98     virtual InstantController* GetInstant() = 0;
     99 
    100     // Creates Widget for the given delegate.
    101     virtual views::Widget* CreateViewsBubble(
    102         views::BubbleDelegateView* bubble_delegate) = 0;
    103 
    104     // Creates PageActionImageView. Caller gets an ownership.
    105     virtual PageActionImageView* CreatePageActionImageView(
    106         LocationBarView* owner,
    107         ExtensionAction* action) = 0;
    108 
    109     // Returns ContentSettingBubbleModelDelegate.
    110     virtual ContentSettingBubbleModelDelegate*
    111         GetContentSettingBubbleModelDelegate() = 0;
    112 
    113     // Shows permissions and settings for the given web contents.
    114     virtual void ShowWebsiteSettings(content::WebContents* web_contents,
    115                                      const GURL& url,
    116                                      const content::SSLStatus& ssl) = 0;
    117 
    118     // Called by the location bar view when the user starts typing in the edit.
    119     // This forces our security style to be UNKNOWN for the duration of the
    120     // editing.
    121     virtual void OnInputInProgress(bool in_progress) = 0;
    122 
    123    protected:
    124     virtual ~Delegate() {}
    125   };
    126 
    127   enum ColorKind {
    128     BACKGROUND = 0,
    129     TEXT,
    130     SELECTED_TEXT,
    131     DEEMPHASIZED_TEXT,
    132     SECURITY_TEXT,
    133   };
    134 
    135   LocationBarView(Browser* browser,
    136                   Profile* profile,
    137                   CommandUpdater* command_updater,
    138                   ToolbarModel* model,
    139                   Delegate* delegate,
    140                   bool is_popup_mode);
    141 
    142   virtual ~LocationBarView();
    143 
    144   // Uses GetBuiltInHorizontalPaddingForChildViews() to optionally add
    145   // additional padding (via an empty border) to |view|. This should be called
    146   // during creation on all child views which are potentially touchable so that
    147   // when touch is enabled they will have sufficient padding.
    148   static void InitTouchableLocationBarChildView(views::View* view);
    149 
    150   // Initializes the LocationBarView.
    151   void Init();
    152 
    153   // True if this instance has been initialized by calling Init, which can only
    154   // be called when the receiving instance is attached to a view container.
    155   bool IsInitialized() const;
    156 
    157   // Returns the appropriate color for the desired kind, based on the user's
    158   // system theme.
    159   SkColor GetColor(ToolbarModel::SecurityLevel security_level,
    160                    ColorKind kind) const;
    161 
    162   // Updates the location bar.  We also reset the bar's permanent text and
    163   // security style, and, if |tab_for_state_restoring| is non-NULL, also restore
    164   // saved state that the tab holds.
    165   void Update(const content::WebContents* tab_for_state_restoring);
    166 
    167   // Returns corresponding profile.
    168   Profile* profile() const { return profile_; }
    169 
    170   // Returns the delegate.
    171   Delegate* delegate() const { return delegate_; }
    172 
    173   // See comment in browser_window.h for more info.
    174   void ZoomChangedForActiveTab(bool can_show_bubble);
    175 
    176   // The zoom icon view. It may not be visible.
    177   ZoomView* zoom_view() { return zoom_view_; }
    178 
    179   // Sets |preview_enabled| for the PageAction View associated with this
    180   // |page_action|. If |preview_enabled| is true, the view will display the
    181   // PageActions icon even though it has not been activated by the extension.
    182   // This is used by the ExtensionInstalledBubble to preview what the icon
    183   // will look like for the user upon installation of the extension.
    184   void SetPreviewEnabledPageAction(ExtensionAction* page_action,
    185                                    bool preview_enabled);
    186 
    187   // Retrieves the PageAction View which is associated with |page_action|.
    188   views::View* GetPageActionView(ExtensionAction* page_action);
    189 
    190   // Toggles the star on or off.
    191   void SetStarToggled(bool on);
    192 
    193   // Returns the star view. It may not be visible.
    194   StarView* star_view() { return star_view_; }
    195 
    196   // Shows the bookmark prompt.
    197   void ShowBookmarkPrompt();
    198 
    199   // Returns the screen coordinates of the location entry (where the URL text
    200   // appears, not where the icons are shown).
    201   gfx::Point GetLocationEntryOrigin() const;
    202 
    203   // Shows |text| as an inline autocompletion.  This is useful for IMEs, where
    204   // we can't show the autocompletion inside the actual OmniboxView.  See
    205   // comments on |ime_inline_autocomplete_view_|.
    206   void SetImeInlineAutocompletion(const string16& text);
    207 
    208   // Invoked from OmniboxViewWin to show gray text autocompletion.
    209   void SetGrayTextAutocompletion(const string16& text);
    210 
    211   // Returns the current gray text autocompletion.
    212   string16 GetGrayTextAutocompletion() const;
    213 
    214   // Sets whether the location entry can accept focus.
    215   void SetLocationEntryFocusable(bool focusable);
    216 
    217   // Returns true if the location entry is focusable and visible in
    218   // the root view.
    219   bool IsLocationEntryFocusableInRootView() const;
    220 
    221   // Sizing functions
    222   virtual gfx::Size GetPreferredSize() OVERRIDE;
    223 
    224   // Layout and Painting functions
    225   virtual void Layout() OVERRIDE;
    226   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
    227 
    228   // No focus border for the location bar, the caret is enough.
    229   virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE { }
    230 
    231   // Set if we should show a focus rect while the location entry field is
    232   // focused. Used when the toolbar is in full keyboard accessibility mode.
    233   // Repaints if necessary.
    234   virtual void SetShowFocusRect(bool show);
    235 
    236   // Select all of the text. Needed when the user tabs through controls
    237   // in the toolbar in full keyboard accessibility mode.
    238   virtual void SelectAll();
    239 
    240 #if defined(OS_WIN) && !defined(USE_AURA)
    241   // Event Handlers
    242   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
    243   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
    244   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
    245   virtual void OnMouseCaptureLost() OVERRIDE;
    246 #endif
    247 
    248   LocationIconView* location_icon_view() { return location_icon_view_; }
    249   const LocationIconView* location_icon_view() const {
    250     return location_icon_view_;
    251   }
    252 
    253   views::View* location_entry_view() const { return location_entry_view_; }
    254 
    255   views::View* generated_credit_card_view();
    256 
    257   // OmniboxEditController:
    258   virtual void OnAutocompleteAccept(const GURL& url,
    259                                     WindowOpenDisposition disposition,
    260                                     content::PageTransition transition,
    261                                     const GURL& alternate_nav_url) OVERRIDE;
    262   virtual void OnChanged() OVERRIDE;
    263   virtual void OnSelectionBoundsChanged() OVERRIDE;
    264   virtual void OnInputInProgress(bool in_progress) OVERRIDE;
    265   virtual void OnKillFocus() OVERRIDE;
    266   virtual void OnSetFocus() OVERRIDE;
    267   virtual gfx::Image GetFavicon() const OVERRIDE;
    268   virtual string16 GetTitle() const OVERRIDE;
    269   virtual InstantController* GetInstant() OVERRIDE;
    270   virtual content::WebContents* GetWebContents() const OVERRIDE;
    271 
    272   // views::View:
    273   virtual const char* GetClassName() const OVERRIDE;
    274   virtual bool SkipDefaultKeyEventProcessing(
    275       const ui::KeyEvent& event) OVERRIDE;
    276   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
    277   virtual bool HasFocus() const OVERRIDE;
    278   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
    279 
    280   // views::ButtonListener:
    281   virtual void ButtonPressed(views::Button* sender,
    282                              const ui::Event& event) OVERRIDE;
    283 
    284   // views::DragController:
    285   virtual void WriteDragDataForView(View* sender,
    286                                     const gfx::Point& press_pt,
    287                                     OSExchangeData* data) OVERRIDE;
    288   virtual int GetDragOperationsForView(View* sender,
    289                                        const gfx::Point& p) OVERRIDE;
    290   virtual bool CanStartDragForView(View* sender,
    291                                    const gfx::Point& press_pt,
    292                                    const gfx::Point& p) OVERRIDE;
    293 
    294   // LocationBar:
    295   virtual void ShowFirstRunBubble() OVERRIDE;
    296   virtual string16 GetInputString() const OVERRIDE;
    297   virtual WindowOpenDisposition GetWindowOpenDisposition() const OVERRIDE;
    298   virtual content::PageTransition GetPageTransition() const OVERRIDE;
    299   virtual void AcceptInput() OVERRIDE;
    300   virtual void FocusLocation(bool select_all) OVERRIDE;
    301   virtual void FocusSearch() OVERRIDE;
    302   virtual void UpdateContentSettingsIcons() OVERRIDE;
    303   virtual void UpdatePageActions() OVERRIDE;
    304   virtual void InvalidatePageActions() OVERRIDE;
    305   virtual void UpdateOpenPDFInReaderPrompt() OVERRIDE;
    306   virtual void UpdateGeneratedCreditCardView() OVERRIDE;
    307   virtual void SaveStateToContents(content::WebContents* contents) OVERRIDE;
    308   virtual void Revert() OVERRIDE;
    309   virtual const OmniboxView* GetLocationEntry() const OVERRIDE;
    310   virtual OmniboxView* GetLocationEntry() OVERRIDE;
    311   virtual LocationBarTesting* GetLocationBarForTesting() OVERRIDE;
    312 
    313   // LocationBarTesting:
    314   virtual int PageActionCount() OVERRIDE;
    315   virtual int PageActionVisibleCount() OVERRIDE;
    316   virtual ExtensionAction* GetPageAction(size_t index) OVERRIDE;
    317   virtual ExtensionAction* GetVisiblePageAction(size_t index) OVERRIDE;
    318   virtual void TestPageActionPressed(size_t index) OVERRIDE;
    319   virtual bool GetBookmarkStarVisibility() OVERRIDE;
    320 
    321   // TemplateURLServiceObserver:
    322   virtual void OnTemplateURLServiceChanged() OVERRIDE;
    323 
    324   // content::NotificationObserver:
    325   virtual void Observe(int type,
    326                        const content::NotificationSource& source,
    327                        const content::NotificationDetails& details) OVERRIDE;
    328 
    329   // SearchModelObserver:
    330   virtual void ModelChanged(const SearchModel::State& old_state,
    331                             const SearchModel::State& new_state) OVERRIDE;
    332 
    333   // Returns the height of the control without the top and bottom
    334   // edges(i.e.  the height of the edit control inside).  If
    335   // |use_preferred_size| is true this will be the preferred height,
    336   // otherwise it will be the current height.
    337   int GetInternalHeight(bool use_preferred_size);
    338 
    339   // Returns the position and width that the popup should be, and also the left
    340   // edge that the results should align themselves to (which will leave some
    341   // border on the left of the popup).
    342   void GetOmniboxPopupPositioningInfo(gfx::Point* top_left_screen_coord,
    343                                       int* popup_width,
    344                                       int* left_margin,
    345                                       int* right_margin);
    346 
    347   // Space between items in the location bar, as well as between items and the
    348   // edges.
    349   static int GetItemPadding();
    350 
    351   // Thickness of the edges of the omnibox background images, in normal mode.
    352   static const int kNormalEdgeThickness;
    353   // The same, but for popup mode.
    354   static const int kPopupEdgeThickness;
    355   // Amount of padding built into the standard omnibox icons.
    356   static const int kIconInternalPadding;
    357   // Space between the edge and a bubble.
    358   static const int kBubblePadding;
    359 
    360  protected:
    361   virtual void OnFocus() OVERRIDE;
    362 
    363  private:
    364   typedef std::vector<ContentSettingImageView*> ContentSettingViews;
    365 
    366   friend class PageActionImageView;
    367   friend class PageActionWithBadgeView;
    368   typedef std::vector<PageActionWithBadgeView*> PageActionViews;
    369 
    370   // Returns the number of pixels of built-in padding to the left and right for
    371   // child views. This is nonzero when touch UI is enabled so as to space out
    372   // child views for easier targeting. See InitTouchableLocationBarChildView().
    373   static int GetBuiltInHorizontalPaddingForChildViews();
    374 
    375   // Returns the thickness of any visible left and right edge, in pixels.
    376   int GetHorizontalEdgeThickness() const;
    377 
    378   // The same, but for the top and bottom edges.
    379   int vertical_edge_thickness() const {
    380     return is_popup_mode_ ? kPopupEdgeThickness : kNormalEdgeThickness;
    381   }
    382 
    383   // Update the visibility state of the Content Blocked icons to reflect what is
    384   // actually blocked on the current page.
    385   void RefreshContentSettingViews();
    386 
    387   // Delete all page action views that we have created.
    388   void DeletePageActionViews();
    389 
    390   // Update the views for the Page Actions, to reflect state changes for
    391   // PageActions.
    392   void RefreshPageActionViews();
    393 
    394   // Returns the number of scripts currently running on the page.
    395   size_t ScriptBubbleScriptsRunning();
    396 
    397   // Update the Script Bubble Icon, to reflect the number of content scripts
    398   // running on the page.
    399   void RefreshScriptBubble();
    400 
    401   // Update the view for the zoom icon based on the current tab's zoom.
    402   void RefreshZoomView();
    403 
    404 #if !defined(USE_AURA)
    405   // Helper for the Mouse event handlers that does all the real work.
    406   void OnMouseEvent(const ui::MouseEvent& event, UINT msg);
    407 #endif
    408 
    409   // Returns true if the suggest text is valid.
    410   bool HasValidSuggestText() const;
    411 
    412   // Helper to show the first run info bubble.
    413   void ShowFirstRunBubbleInternal();
    414 
    415   // Draw backgrounds and borders for page actions.  Must be called
    416   // after layout, so the |page_action_views_| have their bounds.
    417   void PaintPageActionBackgrounds(gfx::Canvas* canvas);
    418 
    419   // Handles a request to change the value of this text field from software
    420   // using an accessibility API (typically automation software, screen readers
    421   // don't normally use this). Sets the value and clears the selection.
    422   void AccessibilitySetValue(const string16& new_value);
    423 
    424   // The Browser this LocationBarView is in.  Note that at least
    425   // chromeos::SimpleWebViewDialog uses a LocationBarView outside any browser
    426   // window, so this may be NULL.
    427   Browser* browser_;
    428 
    429   // The Autocomplete Edit field.
    430   scoped_ptr<OmniboxView> location_entry_;
    431 
    432   // The profile which corresponds to this View.
    433   Profile* profile_;
    434 
    435   // Command updater which corresponds to this View.
    436   CommandUpdater* command_updater_;
    437 
    438   // The model.
    439   ToolbarModel* model_;
    440 
    441   // Our delegate.
    442   Delegate* delegate_;
    443 
    444   // This is the string of text from the autocompletion session that the user
    445   // entered or selected.
    446   string16 location_input_;
    447 
    448   // The user's desired disposition for how their input should be opened
    449   WindowOpenDisposition disposition_;
    450 
    451   // The transition type to use for the navigation
    452   content::PageTransition transition_;
    453 
    454   // An object used to paint the normal-mode background.
    455   scoped_ptr<views::Painter> background_border_painter_;
    456   scoped_ptr<views::Painter> background_filling_painter_;
    457 
    458   // An icon to the left of the edit field.
    459   LocationIconView* location_icon_view_;
    460 
    461   // A bubble displayed for EV HTTPS sites.
    462   EVBubbleView* ev_bubble_view_;
    463 
    464   // Location_entry view
    465   views::View* location_entry_view_;
    466 
    467   // A view to show inline autocompletion when an IME is active.  In this case,
    468   // we shouldn't change the text or selection inside the OmniboxView itself,
    469   // since this will conflict with the IME's control over the text.  So instead
    470   // we show any autocompletion in a separate field after the OmniboxView.
    471   views::Label* ime_inline_autocomplete_view_;
    472 
    473   // The following views are used to provide hints and remind the user as to
    474   // what is going in the edit. They are all added a children of the
    475   // LocationBarView. At most one is visible at a time. Preference is
    476   // given to the keyword_view_, then hint_view_.
    477   // These autocollapse when the edit needs the room.
    478 
    479   // Shown if the user has selected a keyword.
    480   SelectedKeywordView* selected_keyword_view_;
    481 
    482   // View responsible for showing suggested text. This is NULL when there is no
    483   // suggested text.
    484   views::Label* suggested_text_view_;
    485 
    486   // Shown if the selected url has a corresponding keyword.
    487   KeywordHintView* keyword_hint_view_;
    488 
    489   // The voice search icon.
    490   views::ImageButton* mic_search_view_;
    491 
    492   // The content setting views.
    493   ContentSettingViews content_setting_views_;
    494 
    495   // The zoom icon.
    496   ZoomView* zoom_view_;
    497 
    498   // A bubble that shows after successfully generating a new credit card number.
    499   GeneratedCreditCardView* generated_credit_card_view_;
    500 
    501   // The icon to open a PDF in Reader.
    502   OpenPDFInReaderView* open_pdf_in_reader_view_;
    503 
    504   // The current page actions.
    505   std::vector<ExtensionAction*> page_actions_;
    506 
    507   // The page action icon views.
    508   PageActionViews page_action_views_;
    509 
    510   // The script bubble.
    511   ScriptBubbleIconView* script_bubble_icon_view_;
    512 
    513   // The star.
    514   StarView* star_view_;
    515 
    516   // Whether we're in popup mode.
    517   const bool is_popup_mode_;
    518 
    519   // True if we should show a focus rect while the location entry field is
    520   // focused. Used when the toolbar is in full keyboard accessibility mode.
    521   bool show_focus_rect_;
    522 
    523   // This is in case we're destroyed before the model loads. We need to make
    524   // Add/RemoveObserver calls.
    525   TemplateURLService* template_url_service_;
    526 
    527   // Tracks this preference to determine whether bookmark editing is allowed.
    528   BooleanPrefMember edit_bookmarks_enabled_;
    529 
    530   // While animating, the host clips the widget and draws only the bottom
    531   // part of it. The view needs to know the pixel offset at which we are drawing
    532   // the widget so that we can draw the curved edges that attach to the toolbar
    533   // in the right location.
    534   int animation_offset_;
    535 
    536   // Used to register for notifications received by NotificationObserver.
    537   content::NotificationRegistrar registrar_;
    538 
    539   // Used to bind callback functions to this object.
    540   base::WeakPtrFactory<LocationBarView> weak_ptr_factory_;
    541 
    542   DISALLOW_COPY_AND_ASSIGN(LocationBarView);
    543 };
    544 
    545 #endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
    546