• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
widget()61   GtkWidget* widget() { return hbox_.get(); }
62 
63   // Returns the widget the page info bubble should point to.
location_icon_widget()64   GtkWidget* location_icon_widget() const { return location_icon_image_; }
65 
66   // Returns the widget the extension installed bubble should point to.
location_entry_widget()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 
widget()153     GtkWidget* widget() { return alignment_.get(); }
154 
set_profile(Profile * profile)155     void set_profile(Profile* profile) { profile_ = profile; }
156 
IsVisible()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 
widget()220     GtkWidget* widget() { return event_box_.get(); }
221 
page_action()222     ExtensionAction* page_action() { return page_action_; }
223 
set_preview_enabled(bool preview_enabled)224     void set_preview_enabled(bool preview_enabled) {
225       preview_enabled_ = preview_enabled;
226     }
227 
IsVisible()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 
site_type_area()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