diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 21:10:38 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 21:10:38 +0000 |
commit | d7313ce9aecaed59829e57bf12521eaf135e5f74 (patch) | |
tree | ec6762fad10912ab698397856f67d37709c97ff2 /chrome | |
parent | be82dced35dab699b978c6b9f256f78b3ee99900 (diff) | |
download | chromium_src-d7313ce9aecaed59829e57bf12521eaf135e5f74.zip chromium_src-d7313ce9aecaed59829e57bf12521eaf135e5f74.tar.gz chromium_src-d7313ce9aecaed59829e57bf12521eaf135e5f74.tar.bz2 |
GTK: Implement the new content blocking address bar bubbles on Linux.
BUG=33314
TEST=none
Review URL: http://codereview.chromium.org/573023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38246 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 6 | ||||
-rw-r--r-- | chrome/browser/gtk/content_blocked_bubble_gtk.cc | 226 | ||||
-rw-r--r-- | chrome/browser/gtk/content_blocked_bubble_gtk.h | 95 | ||||
-rw-r--r-- | chrome/browser/gtk/location_bar_view_gtk.cc | 119 | ||||
-rw-r--r-- | chrome/browser/gtk/location_bar_view_gtk.h | 53 | ||||
-rw-r--r-- | chrome/browser/views/content_blocked_bubble_contents.cc | 2 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 |
7 files changed, 500 insertions, 3 deletions
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index 4652097..8976e52 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -246,6 +246,10 @@ void BrowserToolbarGtk::Init(Profile* profile, gtk_widget_hide(actions_toolbar_->widget()); } + // Because the above does a recursive show all on all widgets we need to + // update the icon visibility to hide them. + location_bar_->UpdateContentBlockedIcons(); + SetViewIDs(); } diff --git a/chrome/browser/gtk/content_blocked_bubble_gtk.cc b/chrome/browser/gtk/content_blocked_bubble_gtk.cc new file mode 100644 index 0000000..4f87c5a --- /dev/null +++ b/chrome/browser/gtk/content_blocked_bubble_gtk.cc @@ -0,0 +1,226 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gtk/content_blocked_bubble_gtk.h" + +#include "app/l10n_util.h" +#include "chrome/browser/blocked_popup_container.h" +#include "chrome/browser/gtk/gtk_chrome_link_button.h" +#include "chrome/browser/host_content_settings_map.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/content_settings.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" +#include "grit/generated_resources.h" + +ContentBlockedBubbleGtk::ContentBlockedBubbleGtk( + GtkWindow* toplevel_window, + const gfx::Rect& bounds, + InfoBubbleGtkDelegate* delegate, + ContentSettingsType content_type, + const std::string& host, + const std::wstring& display_host, + Profile* profile, + TabContents* tab_contents) + : toplevel_window_(toplevel_window), + bounds_(bounds), + content_type_(content_type), + host_(host), + display_host_(display_host), + profile_(profile), + tab_contents_(tab_contents), + delegate_(delegate), + info_bubble_(NULL), + allow_radio_(NULL), + block_radio_(NULL) { + registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, + Source<TabContents>(tab_contents)); + BuildBubble(); +} + +ContentBlockedBubbleGtk::~ContentBlockedBubbleGtk() { +} + +void ContentBlockedBubbleGtk::Close() { + if (info_bubble_) + info_bubble_->Close(); +} + +void ContentBlockedBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble, + bool closed_by_escape) { + delegate_->InfoBubbleClosing(info_bubble, closed_by_escape); + delete this; +} + +void ContentBlockedBubbleGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED); + DCHECK(source == Source<TabContents>(tab_contents_)); + tab_contents_ = NULL; +} + +void ContentBlockedBubbleGtk::BuildBubble() { + GtkThemeProvider* theme_provider = GtkThemeProvider::GetFrom(profile_); + + GtkWidget* bubble_content = gtk_vbox_new(FALSE, 5); + + // Add the content label. + static const int kTitleIDs[CONTENT_SETTINGS_NUM_TYPES] = { + IDS_BLOCKED_COOKIES_TITLE, + IDS_BLOCKED_IMAGES_TITLE, + IDS_BLOCKED_JAVASCRIPT_TITLE, + IDS_BLOCKED_PLUGINS_TITLE, + IDS_BLOCKED_POPUPS_TITLE, + }; + DCHECK_EQ(arraysize(kTitleIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + GtkWidget* label = gtk_label_new(l10n_util::GetStringUTF8( + kTitleIDs[content_type_]).c_str()); + gtk_box_pack_start(GTK_BOX(bubble_content), label, FALSE, FALSE, 0); + + if (content_type_ == CONTENT_SETTINGS_TYPE_POPUPS) { + BlockedPopupContainer::BlockedContents blocked_contents; + DCHECK(tab_contents_->blocked_popup_container()); + tab_contents_->blocked_popup_container()->GetBlockedContents( + &blocked_contents); + for (BlockedPopupContainer::BlockedContents::const_iterator + i(blocked_contents.begin()); i != blocked_contents.end(); ++i) { + GtkWidget* button = + gtk_chrome_link_button_new(UTF16ToUTF8((*i)->GetTitle()).c_str()); + popup_links_[button] = *i; + g_signal_connect(button, "clicked", G_CALLBACK(OnPopupLinkClicked), + this); + gtk_box_pack_start(GTK_BOX(bubble_content), button, FALSE, FALSE, 0); + } + } + + if (content_type_ != CONTENT_SETTINGS_TYPE_COOKIES) { + static const int kAllowIDs[CONTENT_SETTINGS_NUM_TYPES] = { + 0, // Not displayed for cookies + IDS_BLOCKED_IMAGES_UNBLOCK, + IDS_BLOCKED_JAVASCRIPT_UNBLOCK, + IDS_BLOCKED_PLUGINS_UNBLOCK, + IDS_BLOCKED_POPUPS_UNBLOCK, + }; + DCHECK_EQ(arraysize(kAllowIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + allow_radio_ = gtk_radio_button_new_with_label( + NULL, + l10n_util::GetStringFUTF8(kAllowIDs[content_type_], + WideToUTF16Hack(display_host_)).c_str()); + gtk_box_pack_start(GTK_BOX(bubble_content), allow_radio_, FALSE, + FALSE, 0); + + static const int kBlockIDs[CONTENT_SETTINGS_NUM_TYPES] = { + 0, // Not displayed for cookies + IDS_BLOCKED_IMAGES_NO_ACTION, + IDS_BLOCKED_JAVASCRIPT_NO_ACTION, + IDS_BLOCKED_PLUGINS_NO_ACTION, + IDS_BLOCKED_POPUPS_NO_ACTION, + }; + DCHECK_EQ(arraysize(kBlockIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + block_radio_ = gtk_radio_button_new_with_label_from_widget( + GTK_RADIO_BUTTON(allow_radio_), + l10n_util::GetStringUTF8(kBlockIDs[content_type_]).c_str()); + gtk_box_pack_start(GTK_BOX(bubble_content), block_radio_, FALSE, + FALSE, 0); + + // We must set the default value before we attach the signal handlers or + // pain occurs. + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(block_radio_), TRUE); + + g_signal_connect(G_OBJECT(allow_radio_), "toggled", + G_CALLBACK(OnAllowBlockToggled), this); + g_signal_connect(G_OBJECT(block_radio_), "toggled", + G_CALLBACK(OnAllowBlockToggled), this); + } + + gtk_box_pack_start(GTK_BOX(bubble_content), gtk_hseparator_new(), FALSE, + FALSE, 0); + + GtkWidget* bottom_box = gtk_hbox_new(FALSE, 0); + + static const int kLinkIDs[CONTENT_SETTINGS_NUM_TYPES] = { + IDS_BLOCKED_COOKIES_LINK, + IDS_BLOCKED_IMAGES_LINK, + IDS_BLOCKED_JAVASCRIPT_LINK, + IDS_BLOCKED_PLUGINS_LINK, + IDS_BLOCKED_POPUPS_LINK, + }; + DCHECK_EQ(arraysize(kLinkIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + GtkWidget* manage_link = gtk_chrome_link_button_new(l10n_util::GetStringUTF8( + kLinkIDs[content_type_]).c_str()); + g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClicked), + this); + gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0); + + GtkWidget* button = gtk_button_new_with_label( + l10n_util::GetStringUTF8(IDS_CLOSE).c_str()); + g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClicked), this); + gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0); + + InfoBubbleGtk::ArrowLocationGtk arrow_location = + (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT) ? + InfoBubbleGtk::ARROW_LOCATION_TOP_RIGHT : + InfoBubbleGtk::ARROW_LOCATION_TOP_LEFT; + info_bubble_ = InfoBubbleGtk::Show( + toplevel_window_, + bounds_, + bubble_content, + arrow_location, + true, + theme_provider, + this); +} + +// static +void ContentBlockedBubbleGtk::OnPopupLinkClicked( + GtkWidget* button, + ContentBlockedBubbleGtk* bubble) { + PopupLinks::iterator i(bubble->popup_links_.find(button)); + DCHECK(i != bubble->popup_links_.end()); + if (bubble->tab_contents_ && + bubble->tab_contents_->blocked_popup_container()) { + bubble->tab_contents_->blocked_popup_container()-> + LaunchPopupForContents(i->second); + + // The views interface implicitly closes because of the launching of a new + // window; we need to do that explicitly. + bubble->Close(); + } +} + +// static +void ContentBlockedBubbleGtk::OnAllowBlockToggled( + GtkWidget* widget, + ContentBlockedBubbleGtk* bubble) { + DCHECK((widget == bubble->allow_radio_) || (widget == bubble->block_radio_)); + bubble->profile_->GetHostContentSettingsMap()->SetContentSetting( + bubble->host_, + bubble->content_type_, + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bubble->allow_radio_)) ? + CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK); +} + +// static +void ContentBlockedBubbleGtk::OnCloseButtonClicked( + GtkButton *button, + ContentBlockedBubbleGtk* bubble) { + bubble->Close(); +} + +// static +void ContentBlockedBubbleGtk::OnManageLinkClicked( + GtkButton* button, + ContentBlockedBubbleGtk* bubble) { + // TODO(erg): Attach this to the options page once that's been written. + NOTIMPLEMENTED(); +} diff --git a/chrome/browser/gtk/content_blocked_bubble_gtk.h b/chrome/browser/gtk/content_blocked_bubble_gtk.h new file mode 100644 index 0000000..3679a38 --- /dev/null +++ b/chrome/browser/gtk/content_blocked_bubble_gtk.h @@ -0,0 +1,95 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GTK_CONTENT_BLOCKED_BUBBLE_GTK_H_ +#define CHROME_BROWSER_GTK_CONTENT_BLOCKED_BUBBLE_GTK_H_ + +#include "chrome/browser/gtk/info_bubble_gtk.h" +#include "chrome/common/content_settings_types.h" +#include "chrome/common/notification_registrar.h" + +class Profile; +class TabContents; + +// ContentBlockedBubbleGtk is used when the user turns on different kinds of +// content blocking (e.g. "block images"). An icon appears in the location bar, +// and when clicked, an instance of this class is created specialized for the +// type of content being blocked. +class ContentBlockedBubbleGtk : public InfoBubbleGtkDelegate, + public NotificationObserver { + public: + ContentBlockedBubbleGtk(GtkWindow* toplevel_window, + const gfx::Rect& bounds, + InfoBubbleGtkDelegate* delegate, + ContentSettingsType content_type, + const std::string& host, + const std::wstring& display_host, + Profile* profile, + TabContents* tab_contents); + virtual ~ContentBlockedBubbleGtk(); + + // Dismisses the infobubble. + void Close(); + + private: + typedef std::map<GtkWidget*, TabContents*> PopupLinks; + + // InfoBubbleGtkDelegate: + virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble, + bool closed_by_escape); + + // NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Builds the info bubble and all the widgets that it displays. + void BuildBubble(); + + // Widget callback methods. + static void OnPopupLinkClicked(GtkWidget* button, + ContentBlockedBubbleGtk* bubble); + static void OnAllowBlockToggled(GtkWidget* widget, + ContentBlockedBubbleGtk* bubble); + static void OnCloseButtonClicked(GtkButton *button, + ContentBlockedBubbleGtk* bubble); + static void OnManageLinkClicked(GtkButton* button, + ContentBlockedBubbleGtk* bubble); + + // A reference to the toplevel browser window, which we pass to the + // InfoBubbleGtk implementation so it can tell the WM that it's a subwindow. + GtkWindow* toplevel_window_; + + // Positioning information for the info bubble. + gfx::Rect bounds_; + + // The type of content handled by this view. + ContentSettingsType content_type_; + + // The hostname affected. + std::string host_; + std::wstring display_host_; + + // The active profile. + Profile* profile_; + + // The active tab contents. + TabContents* tab_contents_; + + // A registrar for listening for TAB_CONTENTS_DESTROYED notifications. + NotificationRegistrar registrar_; + + // Pass on delegate messages to this. + InfoBubbleGtkDelegate* delegate_; + + // The info bubble. + InfoBubbleGtk* info_bubble_; + + // Stored controls so we can figure out what was clicked. + PopupLinks popup_links_; + GtkWidget* allow_radio_; + GtkWidget* block_radio_; +}; + +#endif // CHROME_BROWSER_GTK_CONTENT_BLOCKED_BUBBLE_GTK_H_ diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc index 3a9462ca..270e63b 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/gtk/location_bar_view_gtk.cc @@ -25,6 +25,7 @@ #include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/gtk/cairo_cached_surface.h" +#include "chrome/browser/gtk/content_blocked_bubble_gtk.h" #include "chrome/browser/gtk/extension_popup_gtk.h" #include "chrome/browser/gtk/first_run_bubble.h" #include "chrome/browser/gtk/gtk_theme_provider.h" @@ -39,8 +40,10 @@ #include "chrome/common/gtk_util.h" #include "chrome/common/notification_service.h" #include "chrome/common/page_transition_types.h" +#include "chrome/common/pref_names.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" +#include "net/base/net_util.h" #include "webkit/glue/window_open_disposition.h" namespace { @@ -167,6 +170,7 @@ LocationBarViewGtk::LocationBarViewGtk( LocationBarViewGtk::~LocationBarViewGtk() { // All of our widgets should have be children of / owned by the alignment. hbox_.Destroy(); + content_blocking_hbox_.Destroy(); page_action_hbox_.Destroy(); } @@ -323,6 +327,22 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { gtk_box_pack_end(GTK_BOX(hbox_.get()), security_icon_event_box_, FALSE, FALSE, 0); + content_blocking_hbox_.Own(gtk_hbox_new(FALSE, kInnerPadding)); + gtk_widget_set_name(content_blocking_hbox_.get(), + "chrome-content-blocking-hbox"); + gtk_box_pack_end(GTK_BOX(hbox_.get()), content_blocking_hbox_.get(), + FALSE, FALSE, 0); + + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { + ContentBlockedViewGtk* content_blocked_view = + new ContentBlockedViewGtk(static_cast<ContentSettingsType>(i), this, + profile_); + content_blocked_views_.push_back(content_blocked_view); + gtk_box_pack_end(GTK_BOX(content_blocking_hbox_.get()), + content_blocked_view->widget(), FALSE, FALSE, 0); + content_blocked_view->SetVisible(false); + } + page_action_hbox_.Own(gtk_hbox_new(FALSE, kInnerPadding)); gtk_widget_set_name(page_action_hbox_.get(), "chrome-page-action-hbox"); @@ -511,7 +531,13 @@ void LocationBarViewGtk::FocusSearch() { } void LocationBarViewGtk::UpdateContentBlockedIcons() { - // TODO(pkasting): Implement. + const TabContents* tab_contents = browser_->GetSelectedTabContents(); + for (ScopedVector<ContentBlockedViewGtk>::iterator i( + content_blocked_views_.begin()); + i != content_blocked_views_.end(); ++i) { + (*i)->SetVisible((!toolbar_model_->input_in_progress() && tab_contents) ? + tab_contents->IsContentBlocked((*i)->content_type()) : false); + } } void LocationBarViewGtk::UpdatePageActions() { @@ -898,6 +924,97 @@ void LocationBarViewGtk::AdjustChildrenVisibility() { } //////////////////////////////////////////////////////////////////////////////// +// LocationBarViewGtk::ContentBlockedViewGtk +LocationBarViewGtk::ContentBlockedViewGtk::ContentBlockedViewGtk( + ContentSettingsType content_type, + const LocationBarViewGtk* parent, + Profile* profile) + : content_type_(content_type), + parent_(parent), + profile_(profile), + info_bubble_(NULL) { + event_box_.Own(gtk_event_box_new()); + + // Make the event box not visible so it does not paint a background. + gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), FALSE); + g_signal_connect(event_box_.get(), "button-press-event", + G_CALLBACK(&OnButtonPressedThunk), this); + + image_.Own(gtk_image_new()); + gtk_container_add(GTK_CONTAINER(event_box_.get()), image_.get()); + + static const int kIconIDs[CONTENT_SETTINGS_NUM_TYPES] = { + IDR_BLOCKED_COOKIES, + IDR_BLOCKED_IMAGES, + IDR_BLOCKED_JAVASCRIPT, + IDR_BLOCKED_PLUGINS, + IDR_BLOCKED_POPUPS, + }; + DCHECK_EQ(arraysize(kIconIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + gtk_image_set_from_pixbuf(GTK_IMAGE(image_.get()), + ResourceBundle::GetSharedInstance().GetPixbufNamed( + kIconIDs[content_type])); + + static const int kTooltipIDs[CONTENT_SETTINGS_NUM_TYPES] = { + IDS_BLOCKED_COOKIES_TITLE, + IDS_BLOCKED_IMAGES_TITLE, + IDS_BLOCKED_JAVASCRIPT_TITLE, + IDS_BLOCKED_PLUGINS_TITLE, + IDS_BLOCKED_POPUPS_TOOLTIP, + }; + DCHECK_EQ(arraysize(kTooltipIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + gtk_widget_set_tooltip_text( + widget(), + l10n_util::GetStringUTF8(kTooltipIDs[content_type_]).c_str()); +} + +LocationBarViewGtk::ContentBlockedViewGtk::~ContentBlockedViewGtk() { + image_.Destroy(); + event_box_.Destroy(); + + if (info_bubble_) + info_bubble_->Close(); +} + +void LocationBarViewGtk::ContentBlockedViewGtk::SetVisible(bool visible) { + if (visible) + gtk_widget_show(widget()); + else + gtk_widget_hide(widget()); +} + +gboolean LocationBarViewGtk::ContentBlockedViewGtk::OnButtonPressed( + GtkWidget* sender, GdkEvent* event) { + gfx::Rect bounds = + gtk_util::GetWidgetRectRelativeToToplevel(sender); + + TabContents* tab_contents = + BrowserList::GetLastActive()->GetSelectedTabContents(); + if (!tab_contents) + return true; + GURL url = tab_contents->GetURL(); + std::wstring display_host; + net::AppendFormattedHost(url, + profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), &display_host, + NULL, NULL); + + GtkWindow* toplevel = GTK_WINDOW(gtk_widget_get_toplevel(sender)); + + info_bubble_ = new ContentBlockedBubbleGtk( + toplevel, bounds, this, content_type_, url.host(), display_host, profile_, + tab_contents); + return TRUE; +} + +void LocationBarViewGtk::ContentBlockedViewGtk::InfoBubbleClosing( + InfoBubbleGtk* info_bubble, + bool closed_by_escape) { + info_bubble_ = NULL; +} + +//////////////////////////////////////////////////////////////////////////////// // LocationBarViewGtk::PageActionViewGtk LocationBarViewGtk::PageActionViewGtk::PageActionViewGtk( diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h index 112aeba..6e6cfb5 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.h +++ b/chrome/browser/gtk/location_bar_view_gtk.h @@ -16,8 +16,10 @@ #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" #include "chrome/browser/extensions/image_loading_tracker.h" +#include "chrome/browser/gtk/info_bubble_gtk.h" #include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/location_bar.h" +#include "chrome/common/content_settings_types.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" @@ -29,6 +31,7 @@ class AutocompleteEditViewGtk; class BubblePositioner; class Browser; class CommandUpdater; +class ContentBlockedBubbleGtk; class ExtensionAction; class ExtensionActionContextMenuModel; class GtkThemeProvider; @@ -120,6 +123,52 @@ class LocationBarViewGtk : public AutocompleteEditController, static const GdkColor kBackgroundColorByLevel[3]; private: + class ContentBlockedViewGtk : public InfoBubbleGtkDelegate { + public: + ContentBlockedViewGtk(ContentSettingsType content_type, + const LocationBarViewGtk* parent, + Profile* profile); + virtual ~ContentBlockedViewGtk(); + + GtkWidget* widget() { return event_box_.get(); } + + ContentSettingsType content_type() const { return content_type_; } + void set_profile(Profile* profile) { profile_ = profile; } + + bool IsVisible() { return GTK_WIDGET_VISIBLE(widget()); } + void SetVisible(bool visible); + + private: + static gboolean OnButtonPressedThunk(GtkWidget* sender, + GdkEvent* event, + ContentBlockedViewGtk* view) { + return view->OnButtonPressed(sender, event); + } + gboolean OnButtonPressed(GtkWidget* sender, GdkEvent* event); + + // InfoBubbleDelegate overrides: + virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble, + bool closed_by_escape); + + // The widgets for this content blocked view. + OwnedWidgetGtk event_box_; + OwnedWidgetGtk image_; + + // The type of content handled by this view. + ContentSettingsType content_type_; + + // The owning LocationBarViewGtk. + const LocationBarViewGtk* parent_; + + // The currently active profile. + Profile* profile_; + + // The currently shown info bubble if any. + ContentBlockedBubbleGtk* info_bubble_; + + DISALLOW_COPY_AND_ASSIGN(ContentBlockedViewGtk); + }; + class PageActionViewGtk : public ImageLoadingTracker::Observer { public: PageActionViewGtk( @@ -261,6 +310,10 @@ class LocationBarViewGtk : public AutocompleteEditController, // Toolbar info text (EV cert info). GtkWidget* info_label_; + // Content blocking icons. + OwnedWidgetGtk content_blocking_hbox_; + ScopedVector<ContentBlockedViewGtk> content_blocked_views_; + // Extension page action icons. OwnedWidgetGtk page_action_hbox_; ScopedVector<PageActionViewGtk> page_action_views_; diff --git a/chrome/browser/views/content_blocked_bubble_contents.cc b/chrome/browser/views/content_blocked_bubble_contents.cc index 35eb5b4..601562f 100644 --- a/chrome/browser/views/content_blocked_bubble_contents.cc +++ b/chrome/browser/views/content_blocked_bubble_contents.cc @@ -166,7 +166,7 @@ void ContentBlockedBubbleContents::InitControlLayout() { IDS_BLOCKED_PLUGINS_NO_ACTION, IDS_BLOCKED_POPUPS_NO_ACTION, }; - DCHECK_EQ(arraysize(kAllowIDs), + DCHECK_EQ(arraysize(kBlockIDs), static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); block_radio_ = new views::RadioButton( l10n_util::GetString(kBlockIDs[content_type_]), radio_button_group); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 2a524b2..6b6ddbd 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -938,6 +938,8 @@ 'browser/gtk/clear_browsing_data_dialog_gtk.h', 'browser/gtk/constrained_window_gtk.cc', 'browser/gtk/constrained_window_gtk.h', + 'browser/gtk/content_blocked_bubble_gtk.cc', + 'browser/gtk/content_blocked_bubble_gtk.h', 'browser/gtk/create_application_shortcuts_dialog_gtk.cc', 'browser/gtk/create_application_shortcuts_dialog_gtk.h', 'browser/gtk/custom_button.cc', |