Home | History | Annotate | Download | only in gtk
      1 // Copyright (c) 2011 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_GTK_LOCATION_BAR_VIEW_GTK_H_
      6 #define CHROME_BROWSER_UI_GTK_LOCATION_BAR_VIEW_GTK_H_
      7 #pragma once
      8 
      9 #include <gtk/gtk.h>
     10 
     11 #include <map>
     12 #include <string>
     13 
     14 #include "base/basictypes.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/scoped_vector.h"
     17 #include "chrome/browser/autocomplete/autocomplete_edit.h"
     18 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
     19 #include "chrome/browser/extensions/extension_context_menu_model.h"
     20 #include "chrome/browser/extensions/image_loading_tracker.h"
     21 #include "chrome/browser/first_run/first_run.h"
     22 #include "chrome/browser/prefs/pref_member.h"
     23 #include "chrome/browser/ui/gtk/info_bubble_gtk.h"
     24 #include "chrome/browser/ui/gtk/menu_gtk.h"
     25 #include "chrome/browser/ui/gtk/owned_widget_gtk.h"
     26 #include "chrome/browser/ui/omnibox/location_bar.h"
     27 #include "chrome/common/content_settings_types.h"
     28 #include "content/common/notification_observer.h"
     29 #include "content/common/notification_registrar.h"
     30 #include "content/common/page_transition_types.h"
     31 #include "third_party/skia/include/core/SkBitmap.h"
     32 #include "ui/base/animation/slide_animation.h"
     33 #include "ui/base/gtk/gtk_signal.h"
     34 #include "webkit/glue/window_open_disposition.h"
     35 
     36 class AutocompleteEditViewGtk;
     37 class Browser;
     38 class CommandUpdater;
     39 class ContentSettingImageModel;
     40 class ContentSettingBubbleGtk;
     41 class ExtensionAction;
     42 class GtkThemeService;
     43 class Profile;
     44 class SkBitmap;
     45 class TabContents;
     46 class ToolbarModel;
     47 
     48 class LocationBarViewGtk : public AutocompleteEditController,
     49                            public LocationBar,
     50                            public LocationBarTesting,
     51                            public NotificationObserver {
     52  public:
     53   explicit LocationBarViewGtk(Browser* browser);
     54   virtual ~LocationBarViewGtk();
     55 
     56   void Init(bool popup_window_mode);
     57 
     58   void SetProfile(Profile* profile);
     59 
     60   // Returns the widget the caller should host.  You must call Init() first.
     61   GtkWidget* widget() { return hbox_.get(); }
     62 
     63   // Returns the widget the page info bubble should point to.
     64   GtkWidget* location_icon_widget() const { return location_icon_image_; }
     65 
     66   // Returns the widget the extension installed bubble should point to.
     67   GtkWidget* location_entry_widget() const { return entry_box_; }
     68 
     69   // Returns the current TabContents.
     70   TabContents* GetTabContents() const;
     71 
     72   // Sets |preview_enabled| for the PageActionViewGtk associated with this
     73   // |page_action|. If |preview_enabled| is true, the view will display the
     74   // page action's icon even though it has not been activated by the extension.
     75   // This is used by the ExtensionInstalledBubbleGtk to preview what the icon
     76   // will look like for the user upon installation of the extension.
     77   void SetPreviewEnabledPageAction(ExtensionAction *page_action,
     78                                    bool preview_enabled);
     79 
     80   // Retrieves the GtkWidget which is associated with PageActionView
     81   // corresponding to |page_action|.
     82   GtkWidget* GetPageActionWidget(ExtensionAction* page_action);
     83 
     84   // Updates the location bar.  We also reset the bar's permanent text and
     85   // security style, and, if |tab_for_state_restoring| is non-NULL, also
     86   // restore saved state that the tab holds.
     87   void Update(const TabContents* tab_for_state_restoring);
     88 
     89   // Show the bookmark bubble.
     90   void ShowStarBubble(const GURL& url, bool newly_boomkarked);
     91 
     92   // Set the starred state of the bookmark star.
     93   void SetStarred(bool starred);
     94 
     95   // Implement the AutocompleteEditController interface.
     96   virtual void OnAutocompleteAccept(const GURL& url,
     97                                     WindowOpenDisposition disposition,
     98                                     PageTransition::Type transition,
     99                                     const GURL& alternate_nav_url) OVERRIDE;
    100   virtual void OnChanged() OVERRIDE;
    101   virtual void OnSelectionBoundsChanged() OVERRIDE;
    102   virtual void OnKillFocus() OVERRIDE;
    103   virtual void OnSetFocus() OVERRIDE;
    104   virtual void OnInputInProgress(bool in_progress) OVERRIDE;
    105   virtual SkBitmap GetFavicon() const OVERRIDE;
    106   virtual string16 GetTitle() const OVERRIDE;
    107   virtual InstantController* GetInstant() OVERRIDE;
    108   virtual TabContentsWrapper* GetTabContentsWrapper() const OVERRIDE;
    109 
    110   // Implement the LocationBar interface.
    111   virtual void ShowFirstRunBubble(FirstRun::BubbleType bubble_type);
    112   virtual void SetSuggestedText(const string16& text,
    113                                 InstantCompleteBehavior behavior);
    114   virtual std::wstring GetInputString() const;
    115   virtual WindowOpenDisposition GetWindowOpenDisposition() const;
    116   virtual PageTransition::Type GetPageTransition() const;
    117   virtual void AcceptInput();
    118   virtual void FocusLocation(bool select_all);
    119   virtual void FocusSearch();
    120   virtual void UpdateContentSettingsIcons();
    121   virtual void UpdatePageActions();
    122   virtual void InvalidatePageActions();
    123   virtual void SaveStateToContents(TabContents* contents);
    124   virtual void Revert();
    125   virtual const AutocompleteEditView* location_entry() const;
    126   virtual AutocompleteEditView* location_entry();
    127   virtual LocationBarTesting* GetLocationBarForTesting();
    128 
    129   // Implement the LocationBarTesting interface.
    130   virtual int PageActionCount();
    131   virtual int PageActionVisibleCount();
    132   virtual ExtensionAction* GetPageAction(size_t index);
    133   virtual ExtensionAction* GetVisiblePageAction(size_t index);
    134   virtual void TestPageActionPressed(size_t index);
    135 
    136   // Implement the NotificationObserver interface.
    137   virtual void Observe(NotificationType type,
    138                        const NotificationSource& source,
    139                        const NotificationDetails& details);
    140 
    141   // Edit background color.
    142   static const GdkColor kBackgroundColor;
    143 
    144  private:
    145   class ContentSettingImageViewGtk : public InfoBubbleGtkDelegate,
    146                                      public ui::AnimationDelegate {
    147    public:
    148     ContentSettingImageViewGtk(ContentSettingsType content_type,
    149                                const LocationBarViewGtk* parent,
    150                                Profile* profile);
    151     virtual ~ContentSettingImageViewGtk();
    152 
    153     GtkWidget* widget() { return alignment_.get(); }
    154 
    155     void set_profile(Profile* profile) { profile_ = profile; }
    156 
    157     bool IsVisible() { return GTK_WIDGET_VISIBLE(widget()); }
    158     void UpdateFromTabContents(TabContents* tab_contents);
    159 
    160     // Overridden from ui::AnimationDelegate:
    161     virtual void AnimationProgressed(const ui::Animation* animation);
    162     virtual void AnimationEnded(const ui::Animation* animation);
    163     virtual void AnimationCanceled(const ui::Animation* animation);
    164 
    165    private:
    166     // Start the process of showing the label.
    167     void StartAnimating();
    168 
    169     // Slide the label shut.
    170     void CloseAnimation();
    171 
    172     CHROMEGTK_CALLBACK_1(ContentSettingImageViewGtk, gboolean, OnButtonPressed,
    173                          GdkEvent*);
    174     CHROMEGTK_CALLBACK_1(ContentSettingImageViewGtk, gboolean, OnExpose,
    175                          GdkEventExpose*);
    176 
    177     // InfoBubbleDelegate overrides:
    178     virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble,
    179                                    bool closed_by_escape);
    180 
    181     scoped_ptr<ContentSettingImageModel> content_setting_image_model_;
    182 
    183     // The widgets for this content settings view.
    184     OwnedWidgetGtk alignment_;
    185     OwnedWidgetGtk event_box_;
    186     GtkWidget* hbox_;
    187     OwnedWidgetGtk image_;
    188 
    189     // Explanatory text ("popup blocked").
    190     OwnedWidgetGtk label_;
    191 
    192     // The owning LocationBarViewGtk.
    193     const LocationBarViewGtk* parent_;
    194 
    195     // The currently active profile.
    196     Profile* profile_;
    197 
    198     // The currently shown info bubble if any.
    199     ContentSettingBubbleGtk* info_bubble_;
    200 
    201     // When we show explanatory text, we slide it in/out.
    202     ui::SlideAnimation animation_;
    203 
    204     // The label's default requisition (cached so we can animate accordingly).
    205     GtkRequisition label_req_;
    206 
    207     ScopedRunnableMethodFactory<ContentSettingImageViewGtk> method_factory_;
    208 
    209     DISALLOW_COPY_AND_ASSIGN(ContentSettingImageViewGtk);
    210   };
    211 
    212   class PageActionViewGtk : public ImageLoadingTracker::Observer,
    213                             public ExtensionContextMenuModel::PopupDelegate {
    214    public:
    215     PageActionViewGtk(
    216         LocationBarViewGtk* owner, Profile* profile,
    217         ExtensionAction* page_action);
    218     virtual ~PageActionViewGtk();
    219 
    220     GtkWidget* widget() { return event_box_.get(); }
    221 
    222     ExtensionAction* page_action() { return page_action_; }
    223 
    224     void set_preview_enabled(bool preview_enabled) {
    225       preview_enabled_ = preview_enabled;
    226     }
    227 
    228     bool IsVisible() { return GTK_WIDGET_VISIBLE(widget()); }
    229 
    230     // Called to notify the PageAction that it should determine whether to be
    231     // visible or hidden. |contents| is the TabContents that is active, |url|
    232     // is the current page URL.
    233     void UpdateVisibility(TabContents* contents, const GURL& url);
    234 
    235     // A callback from ImageLoadingTracker for when the image has loaded.
    236     virtual void OnImageLoaded(
    237         SkBitmap* image, const ExtensionResource& resource, int index);
    238 
    239     // Simulate left mouse click on the page action button.
    240     void TestActivatePageAction();
    241 
    242     // Overridden from ExtensionContextMenuModel::PopupDelegate:
    243     virtual void InspectPopup(ExtensionAction* action);
    244 
    245    private:
    246     // Show the popup for this page action. If |devtools| is true, show it
    247     // with a debugger window attached. Returns true if a popup was shown.
    248     bool ShowPopup(bool devtools);
    249 
    250     CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnButtonPressed,
    251                          GdkEventButton*);
    252     CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnExposeEvent,
    253                          GdkEventExpose*);
    254 
    255     // The location bar view that owns us.
    256     LocationBarViewGtk* owner_;
    257 
    258     // The current profile (not owned by us).
    259     Profile* profile_;
    260 
    261     // The PageAction that this view represents. The PageAction is not owned by
    262     // us, it resides in the extension of this particular profile.
    263     ExtensionAction* page_action_;
    264 
    265     // A cache of all the different icon paths associated with this page action.
    266     typedef std::map<std::string, GdkPixbuf*> PixbufMap;
    267     PixbufMap pixbufs_;
    268 
    269     // A cache of the last dynamically generated bitmap and the pixbuf that
    270     // corresponds to it. We keep track of both so we can free old pixbufs as
    271     // their icons are replaced.
    272     SkBitmap last_icon_skbitmap_;
    273     GdkPixbuf* last_icon_pixbuf_;
    274 
    275     // The object that is waiting for the image loading to complete
    276     // asynchronously.
    277     ImageLoadingTracker tracker_;
    278 
    279     // The widgets for this page action.
    280     OwnedWidgetGtk event_box_;
    281     OwnedWidgetGtk image_;
    282 
    283     // The tab id we are currently showing the icon for.
    284     int current_tab_id_;
    285 
    286     // The URL we are currently showing the icon for.
    287     GURL current_url_;
    288 
    289     // This is used for post-install visual feedback. The page_action icon
    290     // is briefly shown even if it hasn't been enabled by its extension.
    291     bool preview_enabled_;
    292 
    293     // The context menu view and model for this extension action.
    294     scoped_ptr<MenuGtk> context_menu_;
    295     scoped_refptr<ExtensionContextMenuModel> context_menu_model_;
    296 
    297     DISALLOW_COPY_AND_ASSIGN(PageActionViewGtk);
    298   };
    299   friend class PageActionViewGtk;
    300 
    301   // Creates, initializes, and packs the location icon, EV certificate name,
    302   // and optional border.
    303   void BuildSiteTypeArea();
    304 
    305   // Enable or disable the location icon/EV certificate as a drag source for
    306   // the URL.
    307   void SetSiteTypeDragSource();
    308 
    309   GtkWidget* site_type_area() { return site_type_alignment_; }
    310 
    311   CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, HandleExpose,
    312                        GdkEventExpose*);
    313   CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, OnIconReleased,
    314                        GdkEventButton*);
    315   CHROMEGTK_CALLBACK_4(LocationBarViewGtk, void, OnIconDragData,
    316                        GdkDragContext*, GtkSelectionData*, guint, guint);
    317   CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnIconDragBegin,
    318                        GdkDragContext*);
    319   CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnIconDragEnd,
    320                        GdkDragContext*);
    321   CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnHboxSizeAllocate,
    322                        GtkAllocation*);
    323   CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnEntryBoxSizeAllocate,
    324                        GtkAllocation*);
    325   CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, OnStarButtonPress,
    326                        GdkEventButton*);
    327 
    328   // Updates the site type area: changes the icon and shows/hides the EV
    329   // certificate information.
    330   void UpdateSiteTypeArea();
    331 
    332   // Updates the maximum size of the EV certificate label.
    333   void UpdateEVCertificateLabelSize();
    334 
    335   // Sets the text that should be displayed in the info label and its associated
    336   // tooltip text.  Call with an empty string if the info label should be
    337   // hidden.
    338   void SetInfoText();
    339 
    340   // Set the keyword text for the Search BLAH: keyword box.
    341   void SetKeywordLabel(const string16& keyword);
    342 
    343   // Set the keyword text for the "Press tab to search BLAH" hint box.
    344   void SetKeywordHintLabel(const string16& keyword);
    345 
    346   void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type);
    347 
    348   // Show or hide |tab_to_search_box_| and |tab_to_search_hint_| according to
    349   // the value of |show_selected_keyword_|, |show_keyword_hint_|, and the
    350   // available horizontal space in the location bar.
    351   void AdjustChildrenVisibility();
    352 
    353   // Build the star icon.
    354   void CreateStarButton();
    355 
    356   // Update the star icon after it is toggled or the theme changes.
    357   void UpdateStarIcon();
    358 
    359   // Returns true if we should only show the URL and none of the extras like
    360   // the star button or page actions.
    361   bool ShouldOnlyShowLocation();
    362 
    363   // The outermost widget we want to be hosted.
    364   OwnedWidgetGtk hbox_;
    365 
    366   // Star button.
    367   OwnedWidgetGtk star_;
    368   GtkWidget* star_image_;
    369   bool starred_;
    370 
    371   // An icon to the left of the address bar.
    372   GtkWidget* site_type_alignment_;
    373   GtkWidget* site_type_event_box_;
    374   GtkWidget* location_icon_image_;
    375   GtkWidget* drag_icon_;
    376   bool enable_location_drag_;
    377   // TODO(pkasting): Split this label off and move the rest of the items to the
    378   // left of the address bar.
    379   GtkWidget* security_info_label_;
    380 
    381   // Content setting icons.
    382   OwnedWidgetGtk content_setting_hbox_;
    383   ScopedVector<ContentSettingImageViewGtk> content_setting_views_;
    384 
    385   // Extension page action icons.
    386   OwnedWidgetGtk page_action_hbox_;
    387   ScopedVector<PageActionViewGtk> page_action_views_;
    388 
    389   // The widget that contains our tab hints and the location bar.
    390   GtkWidget* entry_box_;
    391 
    392   // Area on the left shown when in tab to search mode.
    393   GtkWidget* tab_to_search_alignment_;
    394   GtkWidget* tab_to_search_box_;
    395   GtkWidget* tab_to_search_magnifier_;
    396   GtkWidget* tab_to_search_full_label_;
    397   GtkWidget* tab_to_search_partial_label_;
    398 
    399   // Hint to user that they can tab-to-search by hitting tab.
    400   GtkWidget* tab_to_search_hint_;
    401   GtkWidget* tab_to_search_hint_leading_label_;
    402   GtkWidget* tab_to_search_hint_icon_;
    403   GtkWidget* tab_to_search_hint_trailing_label_;
    404 
    405   scoped_ptr<AutocompleteEditViewGtk> location_entry_;
    406 
    407   // Alignment used to wrap |location_entry_|.
    408   GtkWidget* location_entry_alignment_;
    409 
    410   Profile* profile_;
    411   CommandUpdater* command_updater_;
    412   ToolbarModel* toolbar_model_;
    413   Browser* browser_;
    414 
    415   // When we get an OnAutocompleteAccept notification from the autocomplete
    416   // edit, we save the input string so we can give it back to the browser on
    417   // the LocationBar interface via GetInputString().
    418   std::wstring location_input_;
    419 
    420   // The user's desired disposition for how their input should be opened.
    421   WindowOpenDisposition disposition_;
    422 
    423   // The transition type to use for the navigation.
    424   PageTransition::Type transition_;
    425 
    426   // Used to schedule a task for the first run info bubble.
    427   ScopedRunnableMethodFactory<LocationBarViewGtk> first_run_bubble_;
    428 
    429   // When true, the location bar view is read only and also is has a slightly
    430   // different presentation (font size / color). This is used for popups.
    431   bool popup_window_mode_;
    432 
    433   // Provides colors and rendering mode.
    434   GtkThemeService* theme_service_;
    435 
    436   NotificationRegistrar registrar_;
    437 
    438   // Width of the main |hbox_|. Used to properly elide the EV certificate.
    439   int hbox_width_;
    440 
    441   // Width of the hbox that holds |tab_to_search_box_|, |location_entry_| and
    442   // |tab_to_search_hint_|.
    443   int entry_box_width_;
    444 
    445   // Indicate if |tab_to_search_box_| should be shown.
    446   bool show_selected_keyword_;
    447 
    448   // Indicate if |tab_to_search_hint_| should be shown.
    449   bool show_keyword_hint_;
    450 
    451   // The last search keyword that was shown via the |tab_to_search_box_|.
    452   string16 last_keyword_;
    453 
    454   // Used to change the visibility of the star decoration.
    455   BooleanPrefMember edit_bookmarks_enabled_;
    456 
    457   DISALLOW_COPY_AND_ASSIGN(LocationBarViewGtk);
    458 };
    459 
    460 #endif  // CHROME_BROWSER_UI_GTK_LOCATION_BAR_VIEW_GTK_H_
    461