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.
5 #ifndef CHROME_BROWSER_UI_GTK_LOCATION_BAR_VIEW_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_LOCATION_BAR_VIEW_GTK_H_
13 #include "base/basictypes.h"
14 #include "base/callback.h"
15 #include "base/compiler_specific.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/memory/scoped_vector.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/prefs/pref_member.h"
20 #include "chrome/browser/extensions/extension_action.h"
21 #include "chrome/browser/extensions/extension_action_icon_factory.h"
22 #include "chrome/browser/extensions/extension_context_menu_model.h"
23 #include "chrome/browser/ui/gtk/bubble/bubble_gtk.h"
24 #include "chrome/browser/ui/gtk/menu_gtk.h"
25 #include "chrome/browser/ui/omnibox/location_bar.h"
26 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
27 #include "chrome/browser/ui/view_ids.h"
28 #include "chrome/common/content_settings_types.h"
29 #include "content/public/browser/notification_observer.h"
30 #include "content/public/browser/notification_registrar.h"
31 #include "content/public/common/page_transition_types.h"
32 #include "ui/base/gtk/gtk_signal.h"
33 #include "ui/base/gtk/owned_widget_gtk.h"
34 #include "ui/base/window_open_disposition.h"
35 #include "ui/gfx/animation/animation_delegate.h"
36 #include "ui/gfx/animation/slide_animation.h"
41 class ContentSettingImageModel
;
42 class ContentSettingBubbleGtk
;
43 class ExtensionAction
;
44 class GtkThemeService
;
59 class LocationBarViewGtk
: public OmniboxEditController
,
61 public LocationBarTesting
,
62 public content::NotificationObserver
{
64 explicit LocationBarViewGtk(Browser
* browser
);
65 virtual ~LocationBarViewGtk();
67 void Init(bool popup_window_mode
);
69 // Returns the widget the caller should host. You must call Init() first.
70 GtkWidget
* widget() { return hbox_
.get(); }
72 // Returns the widget the page info bubble should point to.
73 GtkWidget
* location_icon_widget() const { return location_icon_image_
; }
75 // Returns the widget the extension installed bubble should point to.
76 GtkWidget
* location_entry_widget() const { return entry_box_
; }
78 Browser
* browser() const { return browser_
; }
80 // Sets |preview_enabled| for the PageActionViewGtk associated with this
81 // |page_action|. If |preview_enabled| is true, the view will display the
82 // page action's icon even though it has not been activated by the extension.
83 // This is used by the ExtensionInstalledBubbleGtk to preview what the icon
84 // will look like for the user upon installation of the extension.
85 void SetPreviewEnabledPageAction(ExtensionAction
*page_action
,
86 bool preview_enabled
);
88 // Retrieves the GtkWidget which is associated with PageActionView
89 // corresponding to |page_action|.
90 GtkWidget
* GetPageActionWidget(ExtensionAction
* page_action
);
92 // Show the bookmark bubble.
93 void ShowStarBubble(const GURL
& url
, bool newly_boomkarked
);
95 // Happens when the zoom changes for the active tab. |can_show_bubble| will be
96 // true if it was a user action and a bubble could be shown.
97 void ZoomChangedForActiveTab(bool can_show_bubble
);
99 // Returns the zoom widget. Used by the zoom bubble for an anchor.
100 GtkWidget
* zoom_widget() { return zoom_
.get(); }
102 // Returns the manage passwords widget. Used by the manage passwords bubble
104 GtkWidget
* manage_passwords_icon_widget() {
105 return manage_passwords_icon_
.get();
108 // Set the starred state of the bookmark star.
109 void SetStarred(bool starred
);
111 // OmniboxEditController:
112 virtual void Update(const content::WebContents
* contents
) OVERRIDE
;
113 virtual void OnChanged() OVERRIDE
;
114 virtual void OnSetFocus() OVERRIDE
;
115 virtual InstantController
* GetInstant() OVERRIDE
;
116 virtual content::WebContents
* GetWebContents() OVERRIDE
;
117 virtual ToolbarModel
* GetToolbarModel() OVERRIDE
;
118 virtual const ToolbarModel
* GetToolbarModel() const OVERRIDE
;
121 virtual void ShowFirstRunBubble() OVERRIDE
;
122 virtual GURL
GetDestinationURL() const OVERRIDE
;
123 virtual WindowOpenDisposition
GetWindowOpenDisposition() const OVERRIDE
;
124 virtual content::PageTransition
GetPageTransition() const OVERRIDE
;
125 virtual void AcceptInput() OVERRIDE
;
126 virtual void FocusLocation(bool select_all
) OVERRIDE
;
127 virtual void FocusSearch() OVERRIDE
;
128 virtual void UpdateContentSettingsIcons() OVERRIDE
;
129 virtual void UpdateManagePasswordsIconAndBubble() OVERRIDE
;
130 virtual void UpdatePageActions() OVERRIDE
;
131 virtual void InvalidatePageActions() OVERRIDE
;
132 virtual void UpdateOpenPDFInReaderPrompt() OVERRIDE
;
133 virtual void UpdateGeneratedCreditCardView() OVERRIDE
;
134 virtual void SaveStateToContents(content::WebContents
* contents
) OVERRIDE
;
135 virtual void Revert() OVERRIDE
;
136 virtual const OmniboxView
* GetOmniboxView() const OVERRIDE
;
137 virtual OmniboxView
* GetOmniboxView() OVERRIDE
;
138 virtual LocationBarTesting
* GetLocationBarForTesting() OVERRIDE
;
140 // LocationBarTesting:
141 virtual int PageActionCount() OVERRIDE
;
142 virtual int PageActionVisibleCount() OVERRIDE
;
143 virtual ExtensionAction
* GetPageAction(size_t index
) OVERRIDE
;
144 virtual ExtensionAction
* GetVisiblePageAction(size_t index
) OVERRIDE
;
145 virtual void TestPageActionPressed(size_t index
) OVERRIDE
;
146 virtual bool GetBookmarkStarVisibility() OVERRIDE
;
148 // content::NotificationObserver:
149 virtual void Observe(int type
,
150 const content::NotificationSource
& source
,
151 const content::NotificationDetails
& details
) OVERRIDE
;
153 // Edit background color.
154 static const GdkColor kBackgroundColor
;
156 // Superclass for content settings icons shown at the left side of the
158 class PageToolViewGtk
: public gfx::AnimationDelegate
{
161 virtual ~PageToolViewGtk();
163 GtkWidget
* widget() { return alignment_
.get(); }
167 virtual void Update(content::WebContents
* web_contents
) = 0;
169 // Overridden from gfx::AnimationDelegate:
170 virtual void AnimationProgressed(const gfx::Animation
* animation
) OVERRIDE
;
171 virtual void AnimationEnded(const gfx::Animation
* animation
) OVERRIDE
;
172 virtual void AnimationCanceled(const gfx::Animation
* animation
) OVERRIDE
;
175 // Theme constants for solid background elements.
176 virtual GdkColor
GetButtonBorderColor() const = 0;
177 virtual GdkColor
GetGradientTopColor() const = 0;
178 virtual GdkColor
GetGradientBottomColor() const = 0;
180 // Delegate for ButtonPressed message.
181 virtual void OnClick(GtkWidget
* sender
) = 0;
183 // Start the process of showing the label.
184 void StartAnimating();
186 // Slide the label shut.
187 void CloseAnimation();
189 CHROMEGTK_CALLBACK_1(PageToolViewGtk
, gboolean
, OnButtonPressed
, GdkEvent
*);
190 CHROMEGTK_CALLBACK_1(PageToolViewGtk
, gboolean
, OnExpose
, GdkEventExpose
*);
192 // The widgets for this view.
193 ui::OwnedWidgetGtk alignment_
;
194 ui::OwnedWidgetGtk event_box_
;
196 ui::OwnedWidgetGtk image_
;
198 // Explanatory text (e.g. "popup blocked").
199 ui::OwnedWidgetGtk label_
;
201 // When we show explanatory text, we slide it in/out.
202 gfx::SlideAnimation animation_
;
204 // The label's default requisition (cached so we can animate accordingly).
205 GtkRequisition label_req_
;
207 base::WeakPtrFactory
<PageToolViewGtk
> weak_factory_
;
210 DISALLOW_COPY_AND_ASSIGN(PageToolViewGtk
);
214 class PageActionViewGtk
:
215 public ExtensionActionIconFactory::Observer
,
216 public content::NotificationObserver
,
217 public ExtensionContextMenuModel::PopupDelegate
,
218 public ExtensionAction::IconAnimation::Observer
{
220 PageActionViewGtk(LocationBarViewGtk
* owner
, ExtensionAction
* page_action
);
221 virtual ~PageActionViewGtk();
223 GtkWidget
* widget() { return event_box_
.get(); }
225 ExtensionAction
* page_action() { return page_action_
; }
227 void set_preview_enabled(bool preview_enabled
) {
228 preview_enabled_
= preview_enabled
;
233 // Called to notify the PageAction that it should determine whether to be
234 // visible or hidden. |contents| is the WebContents that is active, |url|
235 // is the current page URL.
236 void UpdateVisibility(content::WebContents
* contents
, const GURL
& url
);
238 // Overriden from ExtensionActionIconFactory::Observer.
239 virtual void OnIconUpdated() OVERRIDE
;
241 // Simulate left mouse click on the page action button.
242 void TestActivatePageAction();
244 // Implement the content::NotificationObserver interface.
245 virtual void Observe(int type
,
246 const content::NotificationSource
& source
,
247 const content::NotificationDetails
& details
) OVERRIDE
;
249 // Overridden from ExtensionContextMenuModel::PopupDelegate:
250 virtual void InspectPopup(ExtensionAction
* action
) OVERRIDE
;
253 // Connect the accelerator for the page action popup.
254 void ConnectPageActionAccelerator();
256 // Disconnect the accelerator for the page action popup.
257 void DisconnectPageActionAccelerator();
259 CHROMEGTK_CALLBACK_1(PageActionViewGtk
, gboolean
, OnButtonPressed
,
261 CHROMEGTK_CALLBACK_1(PageActionViewGtk
, gboolean
, OnExposeEvent
,
263 CHROMEGTK_CALLBACK_0(PageActionViewGtk
, void, OnRealize
);
265 // The accelerator handler for when the shortcuts to open the popup is
267 static gboolean
OnGtkAccelerator(GtkAccelGroup
* accel_group
,
268 GObject
* acceleratable
,
270 GdkModifierType modifier
,
273 // ExtensionAction::IconAnimationDelegate implementation.
274 virtual void OnIconChanged() OVERRIDE
;
276 // The location bar view that owns us.
277 LocationBarViewGtk
* owner_
;
279 // The PageAction that this view represents. The PageAction is not owned by
280 // us, it resides in the extension of this particular profile.
281 ExtensionAction
* page_action_
;
283 // The object that will be used to get the extension action icon for us.
284 // It may load the icon asynchronously (in which case the initial icon
285 // returned by the factory will be transparent), so we have to observe it
286 // for updates to the icon.
287 scoped_ptr
<ExtensionActionIconFactory
> icon_factory_
;
289 // The widgets for this page action.
290 ui::OwnedWidgetGtk event_box_
;
291 ui::OwnedWidgetGtk image_
;
293 // The tab id we are currently showing the icon for.
296 // The URL we are currently showing the icon for.
299 // The native browser window of the location bar that owns us.
300 gfx::NativeWindow window_
;
302 // The Notification registrar.
303 content::NotificationRegistrar registrar_
;
305 // The accelerator group used to handle accelerators, owned by this object.
306 GtkAccelGroup
* accel_group_
;
308 // The keybinding accelerator registered to show the page action popup.
309 scoped_ptr
<ui::Accelerator
> page_action_keybinding_
;
310 // The keybinding accelerator registered to show the script badge popup.
311 scoped_ptr
<ui::Accelerator
> script_badge_keybinding_
;
313 // This is used for post-install visual feedback. The page_action icon
314 // is briefly shown even if it hasn't been enabled by its extension.
315 bool preview_enabled_
;
317 // The context menu view and model for this extension action.
318 scoped_ptr
<MenuGtk
> context_menu_
;
319 scoped_refptr
<ExtensionContextMenuModel
> context_menu_model_
;
321 // Fade-in animation for the icon with observer scoped to this.
322 ExtensionAction::IconAnimation::ScopedObserver
323 scoped_icon_animation_observer_
;
325 DISALLOW_COPY_AND_ASSIGN(PageActionViewGtk
);
327 friend class PageActionViewGtk
;
329 // Creates, initializes, and packs the location icon, EV certificate name,
330 // and optional border.
331 void BuildSiteTypeArea();
333 // Enable or disable the location icon/EV certificate as a drag source for
335 void SetSiteTypeDragSource();
337 GtkWidget
* site_type_area() { return site_type_alignment_
; }
339 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, gboolean
, HandleExpose
,
341 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, gboolean
, OnIconReleased
,
343 CHROMEGTK_CALLBACK_4(LocationBarViewGtk
, void, OnIconDragData
,
344 GdkDragContext
*, GtkSelectionData
*, guint
, guint
);
345 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, void, OnIconDragBegin
,
347 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, void, OnIconDragEnd
,
349 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, void, OnHboxSizeAllocate
,
351 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, void, OnEntryBoxSizeAllocate
,
353 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, gboolean
, OnZoomButtonPress
,
355 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, gboolean
,
356 OnManagePasswordsIconButtonPress
, GdkEventButton
*);
357 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, gboolean
, OnScriptBubbleButtonPress
,
359 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, void, OnStarButtonSizeAllocate
,
361 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, gboolean
, OnStarButtonPress
,
363 CHROMEGTK_CALLBACK_1(LocationBarViewGtk
, gboolean
,
364 OnScriptBubbleButtonExpose
, GdkEventExpose
*);
366 // Updates the site type area: changes the icon and shows/hides the EV
367 // certificate information.
368 void UpdateSiteTypeArea();
370 // Updates the maximum size of the EV certificate label.
371 void UpdateEVCertificateLabelSize();
373 // Set the keyword text for the Search BLAH: keyword box.
374 void SetKeywordLabel(const base::string16
& keyword
);
376 // Set the keyword text for the "Press tab to search BLAH" hint box.
377 void SetKeywordHintLabel(const base::string16
& keyword
);
379 void ShowFirstRunBubbleInternal();
381 // Shows the zoom bubble.
382 void ShowZoomBubble();
384 // Shows the manage password bubble.
385 void ShowManagePasswordsBubble();
387 // Show or hide |tab_to_search_box_| and |tab_to_search_hint_| according to
388 // the value of |show_selected_keyword_|, |show_keyword_hint_|, and the
389 // available horizontal space in the location bar.
390 void AdjustChildrenVisibility();
392 // Helpers to build create the various buttons that show up in the location
394 GtkWidget
* CreateIconButton(
399 gboolean (click_callback
)(GtkWidget
*, GdkEventButton
*, gpointer
));
400 void CreateZoomButton();
401 void CreateManagePasswordsIconButton();
402 void CreateScriptBubbleButton();
403 void CreateStarButton();
405 // Helpers to update state of the various buttons that show up in the
407 void UpdateZoomIcon();
408 void UpdateManagePasswordsIcon();
409 void UpdateScriptBubbleIcon();
410 void UpdateStarIcon();
412 // Shows the managepassword bubble in case there is a password to be saved.
413 void ShowManagePasswordsBubbleIfNeeded();
415 // Returns true if we should only show the URL and none of the extras like
416 // the star button or page actions.
417 bool ShouldOnlyShowLocation();
419 // The outermost widget we want to be hosted.
420 ui::OwnedWidgetGtk hbox_
;
423 ui::OwnedWidgetGtk zoom_
;
424 GtkWidget
* zoom_image_
;
426 // Manage passwords button.
427 ui::OwnedWidgetGtk manage_passwords_icon_
;
428 GtkWidget
* manage_passwords_icon_image_
;
430 ui::OwnedWidgetGtk script_bubble_button_
;
431 GtkWidget
* script_bubble_button_image_
;
432 size_t num_running_scripts_
;
435 ui::OwnedWidgetGtk star_
;
436 GtkWidget
* star_image_
;
438 bool star_sized_
; // True after a size-allocate signal to the star widget.
440 // Action to execute after the star icon has been sized, can refer to a NULL
441 // function to indicate no such action should be taken.
442 base::Closure on_star_sized_
;
444 // An icon to the left of the address bar.
445 GtkWidget
* site_type_alignment_
;
446 GtkWidget
* site_type_event_box_
;
447 GtkWidget
* location_icon_image_
;
448 GtkWidget
* drag_icon_
;
449 bool enable_location_drag_
;
450 // TODO(pkasting): Split this label off and move the rest of the items to the
451 // left of the address bar.
452 GtkWidget
* security_info_label_
;
454 // Content setting icons.
455 ui::OwnedWidgetGtk content_setting_hbox_
;
456 ScopedVector
<PageToolViewGtk
> content_setting_views_
;
458 // Extension page actions.
459 std::vector
<ExtensionAction
*> page_actions_
;
461 // Extension page action icons.
462 ui::OwnedWidgetGtk page_action_hbox_
;
463 ScopedVector
<PageActionViewGtk
> page_action_views_
;
465 // The widget that contains our tab hints and the location bar.
466 GtkWidget
* entry_box_
;
468 // Area on the left shown when in tab to search mode.
469 GtkWidget
* tab_to_search_alignment_
;
470 GtkWidget
* tab_to_search_box_
;
471 GtkWidget
* tab_to_search_magnifier_
;
472 GtkWidget
* tab_to_search_full_label_
;
473 GtkWidget
* tab_to_search_partial_label_
;
475 // Hint to user that they can tab-to-search by hitting tab.
476 GtkWidget
* tab_to_search_hint_
;
477 GtkWidget
* tab_to_search_hint_leading_label_
;
478 GtkWidget
* tab_to_search_hint_icon_
;
479 GtkWidget
* tab_to_search_hint_trailing_label_
;
481 scoped_ptr
<OmniboxViewGtk
> omnibox_view_
;
483 // Alignment used to wrap |omnibox_view_|.
484 GtkWidget
* omnibox_view_alignment_
;
488 // When true, the location bar view is read only and also is has a slightly
489 // different presentation (font size / color). This is used for popups.
490 bool popup_window_mode_
;
492 // Provides colors and rendering mode.
493 GtkThemeService
* theme_service_
;
495 content::NotificationRegistrar registrar_
;
497 // Width of the main |hbox_|. Used to properly elide the EV certificate.
500 // Width of the hbox that holds |tab_to_search_box_|, |omnibox_view_| and
501 // |tab_to_search_hint_|.
502 int entry_box_width_
;
504 // Indicate if |tab_to_search_box_| should be shown.
505 bool show_selected_keyword_
;
507 // Indicate if |tab_to_search_hint_| should be shown.
508 bool show_keyword_hint_
;
510 // The last search keyword that was shown via the |tab_to_search_box_|.
511 base::string16 last_keyword_
;
513 // Used to change the visibility of the star decoration.
514 BooleanPrefMember edit_bookmarks_enabled_
;
516 // Used to remember the URL and title text when drag&drop has begun.
518 base::string16 drag_title_
;
520 // Used to schedule a task for the first run bubble.
521 base::WeakPtrFactory
<LocationBarViewGtk
> weak_ptr_factory_
;
523 DISALLOW_COPY_AND_ASSIGN(LocationBarViewGtk
);
526 #endif // CHROME_BROWSER_UI_GTK_LOCATION_BAR_VIEW_GTK_H_