diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-10 18:58:54 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-10 18:58:54 +0000 |
commit | d8e7a54e37ed11d60f7d8dd8f5d5732cffe94b95 (patch) | |
tree | 8912ce2d6acc77fda0119d872283268390eeef15 | |
parent | 13044cdc2b1e8fb304af65a7913c083f52c623bc (diff) | |
download | chromium_src-d8e7a54e37ed11d60f7d8dd8f5d5732cffe94b95.zip chromium_src-d8e7a54e37ed11d60f7d8dd8f5d5732cffe94b95.tar.gz chromium_src-d8e7a54e37ed11d60f7d8dd8f5d5732cffe94b95.tar.bz2 |
GTK: Implements the content settings window and the minor changes to the options dialog.
The "Exceptions" dialogs are still not implemented; they're the next step but
this changelist is already getting pretty huge.
BUG=35178
TEST=none
Review URL: http://codereview.chromium.org/602005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38642 0039d316-1c4b-4281-b951-d872f2087c98
19 files changed, 823 insertions, 150 deletions
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc index 551c323..3287168 100644 --- a/chrome/browser/browser_prefs.cc +++ b/chrome/browser/browser_prefs.cc @@ -37,7 +37,6 @@ #if defined(TOOLKIT_VIEWS) // TODO(port): whittle this down as we port #include "chrome/browser/views/browser_actions_container.h" #include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/options/content_settings_window_view.h" #endif #if defined(TOOLKIT_GTK) @@ -106,9 +105,6 @@ void RegisterUserPrefs(PrefService* user_prefs) { Blacklist::RegisterUserPrefs(user_prefs); #if defined(TOOLKIT_VIEWS) // TODO(port): whittle this down as we port. BrowserActionsContainer::RegisterUserPrefs(user_prefs); -#if defined(OS_WIN) - ContentSettingsWindowView::RegisterUserPrefs(user_prefs); -#endif #endif #if defined(TOOLKIT_GTK) BrowserWindowGtk::RegisterUserPrefs(user_prefs); diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index c370b66..7dc5431 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -59,6 +59,7 @@ #include "chrome/browser/gtk/infobar_container_gtk.h" #include "chrome/browser/gtk/keyword_editor_view.h" #include "chrome/browser/gtk/nine_box.h" +#include "chrome/browser/gtk/options/content_settings_window_gtk.h" #include "chrome/browser/gtk/repost_form_warning_gtk.h" #include "chrome/browser/gtk/status_bubble_gtk.h" #include "chrome/browser/gtk/tab_contents_container_gtk.h" @@ -874,7 +875,7 @@ void BrowserWindowGtk::ShowRepostFormWarningDialog( void BrowserWindowGtk::ShowContentSettingsWindow( ContentSettingsType content_type, Profile* profile) { - NOTIMPLEMENTED(); + ContentSettingsWindowGtk::Show(GetNativeHandle(), content_type, profile); } void BrowserWindowGtk::ShowProfileErrorDialog(int message_id) { diff --git a/chrome/browser/gtk/content_blocked_bubble_gtk.cc b/chrome/browser/gtk/content_blocked_bubble_gtk.cc index 6f81658..2399281 100644 --- a/chrome/browser/gtk/content_blocked_bubble_gtk.cc +++ b/chrome/browser/gtk/content_blocked_bubble_gtk.cc @@ -7,6 +7,7 @@ #include "app/l10n_util.h" #include "chrome/browser/blocked_popup_container.h" #include "chrome/browser/gtk/gtk_chrome_link_button.h" +#include "chrome/browser/gtk/options/content_settings_window_gtk.h" #include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" @@ -224,6 +225,13 @@ void ContentBlockedBubbleGtk::OnCloseButtonClicked( void ContentBlockedBubbleGtk::OnManageLinkClicked( GtkButton* button, ContentBlockedBubbleGtk* bubble) { - // TODO(erg): Attach this to the options page once that's been written. - NOTIMPLEMENTED(); + if (bubble->tab_contents_) { + bubble->tab_contents_->delegate()->ShowContentSettingsWindow( + bubble->content_type_); + } else { + ContentSettingsWindowGtk::Show(NULL, bubble->content_type_, + bubble->profile_); + } + + bubble->Close(); } diff --git a/chrome/browser/gtk/options/advanced_contents_gtk.cc b/chrome/browser/gtk/options/advanced_contents_gtk.cc index 84cb54c..3e1ff53 100644 --- a/chrome/browser/gtk/options/advanced_contents_gtk.cc +++ b/chrome/browser/gtk/options/advanced_contents_gtk.cc @@ -19,8 +19,9 @@ #include "chrome/browser/download/download_manager.h" #include "chrome/browser/fonts_languages_window.h" #include "chrome/browser/gtk/accessible_widget_helper_gtk.h" +#include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h" #include "chrome/browser/gtk/gtk_chrome_link_button.h" -#include "chrome/browser/gtk/options/cookies_view.h" +#include "chrome/browser/gtk/options/content_settings_window_gtk.h" #include "chrome/browser/gtk/options/options_layout_gtk.h" #include "chrome/browser/net/dns_global.h" #include "chrome/browser/options_page_base.h" @@ -495,6 +496,10 @@ class PrivacySection : public OptionsPageBase { void ShowRestartMessageBox() const; // The callback functions for the options widgets. + static void OnContentSettingsClicked(GtkButton* button, + PrivacySection* privacy_section); + static void OnClearBrowsingDataButtonClicked(GtkButton* widget, + PrivacySection* page); static void OnLearnMoreLinkClicked(GtkButton *button, PrivacySection* privacy_section); static void OnEnableLinkDoctorChange(GtkWidget* widget, @@ -507,10 +512,6 @@ class PrivacySection : public OptionsPageBase { PrivacySection* options_window); static void OnLoggingChange(GtkWidget* widget, PrivacySection* options_window); - static void OnCookieBehaviorChanged(GtkComboBox* combo_box, - PrivacySection* privacy_section); - static void OnShowCookiesButtonClicked(GtkButton *button, - PrivacySection* privacy_section); // The widget containing the options for this section. GtkWidget* page_; @@ -523,7 +524,6 @@ class PrivacySection : public OptionsPageBase { #if defined(GOOGLE_CHROME_BUILD) GtkWidget* reporting_enabled_checkbox_; #endif - GtkWidget* cookie_behavior_combobox_; // Preferences for this section: BooleanPrefMember alternate_error_pages_; @@ -549,6 +549,24 @@ PrivacySection::PrivacySection(Profile* profile) accessible_widget_helper_.reset(new AccessibleWidgetHelper( page_, profile)); + GtkWidget* content_button = gtk_button_new_with_label( + l10n_util::GetStringUTF8( + IDS_OPTIONS_PRIVACY_CONTENT_SETTINGS_BUTTON).c_str()); + g_signal_connect(content_button, "clicked", + G_CALLBACK(OnContentSettingsClicked), this); + + GtkWidget* clear_data_button = gtk_button_new_with_label( + l10n_util::GetStringUTF8(IDS_OPTIONS_PRIVACY_CLEAR_DATA_BUTTON).c_str()); + g_signal_connect(clear_data_button, "clicked", + G_CALLBACK(OnClearBrowsingDataButtonClicked), this); + + // Stick it in an hbox so it doesn't expand to the whole width. + GtkWidget* button_hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing); + gtk_box_pack_start(GTK_BOX(button_hbox), content_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(button_hbox), clear_data_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(page_), gtk_util::IndentWidget(button_hbox), + FALSE, FALSE, 0); + GtkWidget* section_description_label = CreateWrappedLabel( IDS_OPTIONS_DISABLE_SERVICES); gtk_misc_set_alignment(GTK_MISC(section_description_label), 0, 0); @@ -615,45 +633,6 @@ PrivacySection::PrivacySection(Profile* profile) reporting_enabled_checkbox_, IDS_OPTIONS_ENABLE_LOGGING); #endif - GtkWidget* cookie_description_label = gtk_label_new( - l10n_util::GetStringUTF8(IDS_OPTIONS_COOKIES_ACCEPT_LABEL).c_str()); - gtk_misc_set_alignment(GTK_MISC(cookie_description_label), 0, 0); - gtk_box_pack_start(GTK_BOX(page_), cookie_description_label, FALSE, FALSE, 0); - - GtkWidget* cookie_controls = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); - gtk_box_pack_start(GTK_BOX(page_), - gtk_util::IndentWidget(cookie_controls), - FALSE, FALSE, 0); - - cookie_behavior_combobox_ = gtk_combo_box_new_text(); - DisableScrolling(cookie_behavior_combobox_); - gtk_combo_box_append_text( - GTK_COMBO_BOX(cookie_behavior_combobox_), - l10n_util::GetStringUTF8(IDS_OPTIONS_COOKIES_ACCEPT_ALL_COOKIES).c_str()); - gtk_combo_box_append_text( - GTK_COMBO_BOX(cookie_behavior_combobox_), - l10n_util::GetStringUTF8( - IDS_OPTIONS_COOKIES_RESTRICT_THIRD_PARTY_COOKIES).c_str()); - gtk_combo_box_append_text( - GTK_COMBO_BOX(cookie_behavior_combobox_), - l10n_util::GetStringUTF8(IDS_OPTIONS_COOKIES_BLOCK_ALL_COOKIES).c_str()); - g_signal_connect(cookie_behavior_combobox_, "changed", - G_CALLBACK(OnCookieBehaviorChanged), this); - gtk_box_pack_start(GTK_BOX(cookie_controls), cookie_behavior_combobox_, - FALSE, FALSE, 0); - - GtkWidget* show_cookies_button = gtk_button_new_with_label( - l10n_util::GetStringUTF8( - IDS_OPTIONS_COOKIES_SHOWCOOKIES_WEBSITE_PERMISSIONS).c_str()); - g_signal_connect(show_cookies_button, "clicked", - G_CALLBACK(OnShowCookiesButtonClicked), this); - - // Stick it in an hbox so it doesn't expand to the whole width. - GtkWidget* button_hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(button_hbox), show_cookies_button, - FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(cookie_controls), button_hbox, FALSE, FALSE, 0); - // Init member prefs so we can update the controls if prefs change. alternate_error_pages_.Init(prefs::kAlternateErrorPagesEnabled, profile->GetPrefs(), this); @@ -669,6 +648,23 @@ PrivacySection::PrivacySection(Profile* profile) } // static +void PrivacySection::OnContentSettingsClicked(GtkButton* button, + PrivacySection* privacy_section) { + ContentSettingsWindowGtk::Show( + GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))), + CONTENT_SETTINGS_TYPE_DEFAULT, + privacy_section->profile()); +} + +// static +void PrivacySection::OnClearBrowsingDataButtonClicked(GtkButton* widget, + PrivacySection* section) { + ClearBrowsingDataDialogGtk::Show( + GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(widget))), + section->profile()); +} + +// static void PrivacySection::OnLearnMoreLinkClicked(GtkButton *button, PrivacySection* privacy_section) { BrowserList::GetLastActive()-> @@ -762,23 +758,6 @@ void PrivacySection::OnLoggingChange(GtkWidget* widget, privacy_section->enable_metrics_recording_.SetValue(enabled); } -// static -void PrivacySection::OnCookieBehaviorChanged(GtkComboBox* combo_box, - PrivacySection* privacy_section) { - // TODO(darin): Remove everything else related to this setter. -} - -// static -void PrivacySection::OnShowCookiesButtonClicked( - GtkButton *button, PrivacySection* privacy_section) { - privacy_section->UserMetricsRecordAction("Options_ShowCookies", NULL); - CookiesView::Show(privacy_section->profile(), - new BrowsingDataDatabaseHelper( - privacy_section->profile()), - new BrowsingDataLocalStorageHelper( - privacy_section->profile())); -} - void PrivacySection::NotifyPrefChanged(const std::wstring* pref_name) { pref_changing_ = true; if (!pref_name || *pref_name == prefs::kAlternateErrorPagesEnabled) { diff --git a/chrome/browser/gtk/options/content_filter_page_gtk.cc b/chrome/browser/gtk/options/content_filter_page_gtk.cc new file mode 100644 index 0000000..5bab461 --- /dev/null +++ b/chrome/browser/gtk/options/content_filter_page_gtk.cc @@ -0,0 +1,121 @@ +// 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/options/content_filter_page_gtk.h" + +#include "app/l10n_util.h" +#include "chrome/browser/host_content_settings_map.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/gtk/options/options_layout_gtk.h" +#include "chrome/common/gtk_util.h" +#include "chrome/common/pref_names.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" + +ContentFilterPageGtk::ContentFilterPageGtk(Profile* profile, + ContentSettingsType content_type) + : OptionsPageBase(profile), + content_type_(content_type) { + static const int kTitleIDs[CONTENT_SETTINGS_NUM_TYPES] = { + 0, // This dialog isn't used for cookies. + IDS_IMAGES_SETTING_LABEL, + IDS_JS_SETTING_LABEL, + IDS_PLUGIN_SETTING_LABEL, + IDS_POPUP_SETTING_LABEL, + }; + DCHECK_EQ(arraysize(kTitleIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + + OptionsLayoutBuilderGtk options_builder; + options_builder.AddOptionGroup( + l10n_util::GetStringUTF8(kTitleIDs[content_type_]), + InitGroup(), true); + page_ = options_builder.get_page_widget(); +} + +ContentFilterPageGtk::~ContentFilterPageGtk() { +} + + +GtkWidget* ContentFilterPageGtk::InitGroup() { + GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); + + static const int kAllowIDs[CONTENT_SETTINGS_NUM_TYPES] = { + 0, // This dialog isn't used for cookies. + IDS_IMAGES_LOAD_RADIO, + IDS_JS_ALLOW_RADIO, + IDS_PLUGIN_LOAD_RADIO, + IDS_POPUP_ALLOW_RADIO, + }; + DCHECK_EQ(arraysize(kAllowIDs), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + allow_radio_ = gtk_radio_button_new_with_label(NULL, + l10n_util::GetStringUTF8(kAllowIDs[content_type_]).c_str()); + gtk_box_pack_start(GTK_BOX(vbox), allow_radio_, FALSE, FALSE, 0); + + static const int kBlockIDs[CONTENT_SETTINGS_NUM_TYPES] = { + 0, // This dialog isn't used for cookies. + IDS_IMAGES_NOLOAD_RADIO, + IDS_JS_DONOTALLOW_RADIO, + IDS_PLUGIN_NOLOAD_RADIO, + IDS_POPUP_BLOCK_RADIO, + }; + 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(vbox), block_radio_, FALSE, FALSE, 0); + + ContentSetting default_setting = profile()->GetHostContentSettingsMap()-> + GetDefaultContentSetting(content_type_); + // Now that these have been added to the view hierarchy, it's safe to call + // SetChecked() on them. + if (default_setting == CONTENT_SETTING_ALLOW) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(allow_radio_), TRUE); + } else { + DCHECK(default_setting == CONTENT_SETTING_BLOCK); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(block_radio_), TRUE); + } + + // Now that we've set the default value, we can connect to the radio button's + // toggled signal. + g_signal_connect(G_OBJECT(allow_radio_), "toggled", + G_CALLBACK(OnAllowToggled), this); + g_signal_connect(G_OBJECT(block_radio_), "toggled", + G_CALLBACK(OnAllowToggled), this); + + GtkWidget* exceptions_button = gtk_button_new_with_label( + l10n_util::GetStringUTF8(IDS_COOKIES_EXCEPTIONS_BUTTON).c_str()); + // TODO(erg): Disable the exceptions button until that is implemented. + gtk_widget_set_sensitive(exceptions_button, FALSE); + g_signal_connect(G_OBJECT(exceptions_button), "clicked", + G_CALLBACK(OnExceptionsClicked), this); + + GtkWidget* hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), exceptions_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + return vbox; +} + +void ContentFilterPageGtk::OnAllowToggled( + GtkWidget* toggle_button, + ContentFilterPageGtk* content_page) { + DCHECK((toggle_button == content_page->allow_radio_) || + (toggle_button == content_page->block_radio_)); + + bool allow = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(content_page->allow_radio_)); + content_page->profile()->GetHostContentSettingsMap()-> + SetDefaultContentSetting( + content_page->content_type_, + allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK); +} + +void ContentFilterPageGtk::OnExceptionsClicked( + GtkWidget* button, + ContentFilterPageGtk* content_page) { + // TODO(erg): Implement a GTK equivalent of ExceptionsView. +} diff --git a/chrome/browser/gtk/options/content_filter_page_gtk.h b/chrome/browser/gtk/options/content_filter_page_gtk.h new file mode 100644 index 0000000..48e1fe3 --- /dev/null +++ b/chrome/browser/gtk/options/content_filter_page_gtk.h @@ -0,0 +1,48 @@ +// 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_OPTIONS_CONTENT_FILTER_PAGE_GTK_H_ +#define CHROME_BROWSER_GTK_OPTIONS_CONTENT_FILTER_PAGE_GTK_H_ + +#include <gtk/gtk.h> + +#include <string> + +#include "chrome/browser/options_page_base.h" +#include "chrome/common/content_settings_types.h" + +// A page in the content settings window. Used for everything but the Cookies +// page (which has a much more complex dialog). A |content_type| is passed into +// the constructor and the correct strings and settings are used. +class ContentFilterPageGtk : public OptionsPageBase { + public: + ContentFilterPageGtk(Profile* profile, ContentSettingsType content_type); + virtual ~ContentFilterPageGtk(); + + GtkWidget* get_page_widget() const { + return page_; + } + + private: + // Builds the content of the dialog. + GtkWidget* InitGroup(); + + // GTK callbacks + static void OnAllowToggled(GtkWidget* toggle_button, + ContentFilterPageGtk* content_page); + static void OnExceptionsClicked(GtkWidget* button, + ContentFilterPageGtk* content_page); + + ContentSettingsType content_type_; + + GtkWidget* page_; + + // Controls for the content filter tab page. + GtkWidget* allow_radio_; + GtkWidget* block_radio_; + + DISALLOW_COPY_AND_ASSIGN(ContentFilterPageGtk); +}; + +#endif // CHROME_BROWSER_GTK_OPTIONS_CONTENT_FILTER_PAGE_GTK_H_ diff --git a/chrome/browser/gtk/options/content_page_gtk.cc b/chrome/browser/gtk/options/content_page_gtk.cc index b577462..e1aa8be 100644 --- a/chrome/browser/gtk/options/content_page_gtk.cc +++ b/chrome/browser/gtk/options/content_page_gtk.cc @@ -11,7 +11,6 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/defaults.h" -#include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h" #include "chrome/browser/gtk/gtk_chrome_link_button.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/import_dialog_gtk.h" @@ -238,15 +237,6 @@ GtkWidget* ContentPageGtk::InitBrowsingDataGroup() { G_CALLBACK(OnImportButtonClicked), this); gtk_box_pack_start(GTK_BOX(button_hbox), import_button, FALSE, FALSE, 0); - // Clear data button. - // TODO(pkasting): This should move to the advanced settings page (see - // Windows). - GtkWidget* clear_data_button = gtk_button_new_with_label( - l10n_util::GetStringUTF8(IDS_OPTIONS_PRIVACY_CLEAR_DATA_BUTTON).c_str()); - g_signal_connect(clear_data_button, "clicked", - G_CALLBACK(OnClearBrowsingDataButtonClicked), this); - gtk_box_pack_start(GTK_BOX(button_hbox), clear_data_button, FALSE, FALSE, 0); - return vbox; } @@ -394,14 +384,6 @@ void ContentPageGtk::OnImportButtonClicked(GtkButton* widget, } // static -void ContentPageGtk::OnClearBrowsingDataButtonClicked(GtkButton* widget, - ContentPageGtk* page) { - ClearBrowsingDataDialogGtk::Show( - GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(widget))), - page->profile()); -} - -// static void ContentPageGtk::OnGtkThemeButtonClicked(GtkButton* widget, ContentPageGtk* page) { page->UserMetricsRecordAction("Options_GtkThemeSet", diff --git a/chrome/browser/gtk/options/content_page_gtk.h b/chrome/browser/gtk/options/content_page_gtk.h index b5ed627a..cbf96d0 100644 --- a/chrome/browser/gtk/options/content_page_gtk.h +++ b/chrome/browser/gtk/options/content_page_gtk.h @@ -50,10 +50,6 @@ class ContentPageGtk : public OptionsPageBase, // Callback for import button. static void OnImportButtonClicked(GtkButton* widget, ContentPageGtk* page); - // Callback for clear data button. - static void OnClearBrowsingDataButtonClicked(GtkButton* widget, - ContentPageGtk* page); - // Callback for the GTK theme button. static void OnGtkThemeButtonClicked(GtkButton* widget, ContentPageGtk* page); diff --git a/chrome/browser/gtk/options/content_settings_window_gtk.cc b/chrome/browser/gtk/options/content_settings_window_gtk.cc new file mode 100644 index 0000000..853de5b --- /dev/null +++ b/chrome/browser/gtk/options/content_settings_window_gtk.cc @@ -0,0 +1,181 @@ +// 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/options/content_settings_window_gtk.h" + +#include "app/l10n_util.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/gtk/browser_window_gtk.h" +#include "chrome/browser/profile.h" +#include "chrome/common/content_settings_types.h" +#include "chrome/common/gtk_util.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "grit/chromium_strings.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" + +namespace { + +// The singleton options window object. +ContentSettingsWindowGtk* settings_window = NULL; + +} // namespace + +// static +void ContentSettingsWindowGtk::Show(GtkWindow* parent, + ContentSettingsType page, + Profile* profile) { + DCHECK(profile); + + if (!settings_window) { + // Creating and initializing a bunch of controls generates a bunch of + // spurious events as control values change. Temporarily suppress + // accessibility events until the window is created. + profile->PauseAccessibilityEvents(); + + // Create the options window. + settings_window = new ContentSettingsWindowGtk(parent, profile); + + // Resume accessibility events. + profile->ResumeAccessibilityEvents(); + } + settings_window->ShowContentSettingsTab(page); + + std::string name = l10n_util::GetStringUTF8( + IDS_CONTENT_SETTINGS_TITLE); + AccessibilityWindowInfo info(profile, name); + + NotificationService::current()->Notify( + NotificationType::ACCESSIBILITY_WINDOW_OPENED, + Source<Profile>(profile), + Details<AccessibilityWindowInfo>(&info)); +} + +ContentSettingsWindowGtk::ContentSettingsWindowGtk(GtkWindow* parent, + Profile* profile) + : profile_(profile), + cookie_page_(profile), + image_page_(profile, CONTENT_SETTINGS_TYPE_IMAGES), + javascript_page_(profile, CONTENT_SETTINGS_TYPE_JAVASCRIPT), + plugin_page_(profile, CONTENT_SETTINGS_TYPE_PLUGINS), + popup_page_(profile, CONTENT_SETTINGS_TYPE_POPUPS) { + // We don't need to observe changes in this value. + last_selected_page_.Init(prefs::kContentSettingsWindowLastTabIndex, + profile->GetPrefs(), NULL); + + dialog_ = gtk_dialog_new_with_buttons( + l10n_util::GetStringUTF8(IDS_CONTENT_SETTINGS_TITLE).c_str(), + parent, + // Non-modal. + static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), + GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, + NULL); + gtk_window_set_default_size(GTK_WINDOW(dialog_), 500, -1); + // Allow browser windows to go in front of the options dialog in metacity. + gtk_window_set_type_hint(GTK_WINDOW(dialog_), GDK_WINDOW_TYPE_HINT_NORMAL); + gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), + gtk_util::kContentAreaSpacing); + + accessibility_widget_helper_.reset(new AccessibleWidgetHelper( + dialog_, profile)); + + notebook_ = gtk_notebook_new(); + + gtk_notebook_append_page( + GTK_NOTEBOOK(notebook_), + cookie_page_.get_page_widget(), + gtk_label_new( + l10n_util::GetStringUTF8(IDS_COOKIES_TAB_LABEL).c_str())); + gtk_notebook_append_page( + GTK_NOTEBOOK(notebook_), + image_page_.get_page_widget(), + gtk_label_new( + l10n_util::GetStringUTF8(IDS_IMAGES_TAB_LABEL).c_str())); + gtk_notebook_append_page( + GTK_NOTEBOOK(notebook_), + javascript_page_.get_page_widget(), + gtk_label_new( + l10n_util::GetStringUTF8(IDS_JAVASCRIPT_TAB_LABEL).c_str())); + gtk_notebook_append_page( + GTK_NOTEBOOK(notebook_), + plugin_page_.get_page_widget(), + gtk_label_new( + l10n_util::GetStringUTF8(IDS_PLUGIN_TAB_LABEL).c_str())); + gtk_notebook_append_page( + GTK_NOTEBOOK(notebook_), + popup_page_.get_page_widget(), + gtk_label_new( + l10n_util::GetStringUTF8(IDS_POPUP_TAB_LABEL).c_str())); + + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), notebook_); + + DCHECK_EQ(gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_)), + CONTENT_SETTINGS_NUM_TYPES); + + // Need to show the notebook before connecting switch-page signal, otherwise + // we'll immediately get a signal switching to page 0 and overwrite our + // last_selected_page_ value. + gtk_widget_show_all(dialog_); + + g_signal_connect(notebook_, "switch-page", G_CALLBACK(OnSwitchPage), this); + + // We only have one button and don't do any special handling, so just hook it + // directly to gtk_widget_destroy. + g_signal_connect(dialog_, "response", G_CALLBACK(gtk_widget_destroy), NULL); + + g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this); +} + +ContentSettingsWindowGtk::~ContentSettingsWindowGtk() { +} + +void ContentSettingsWindowGtk::ShowContentSettingsTab( + ContentSettingsType page) { + if (Browser* b = BrowserList::GetLastActive()) { + gtk_util::CenterOverWindow(GTK_WINDOW(dialog_), + b->window()->GetNativeHandle()); + } + + // Bring options window to front if it already existed and isn't already + // in front + gtk_window_present_with_time(GTK_WINDOW(dialog_), + gtk_get_current_event_time()); + + if (page == CONTENT_SETTINGS_TYPE_DEFAULT) { + // Remember the last visited page from local state. + page = static_cast<ContentSettingsType>(last_selected_page_.GetValue()); + if (page == CONTENT_SETTINGS_TYPE_DEFAULT) + page = CONTENT_SETTINGS_TYPE_COOKIES; + } + // If the page number is out of bounds, reset to the first tab. + if (page < 0 || page >= gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_))) + page = CONTENT_SETTINGS_TYPE_COOKIES; + + gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), page); +} + +// static +void ContentSettingsWindowGtk::OnSwitchPage( + GtkNotebook* notebook, + GtkNotebookPage* page, + guint page_num, + ContentSettingsWindowGtk* window) { + int index = page_num; + DCHECK(index > CONTENT_SETTINGS_TYPE_DEFAULT && + index < CONTENT_SETTINGS_NUM_TYPES); + window->last_selected_page_.SetValue(index); +} + +// static +void ContentSettingsWindowGtk::OnWindowDestroy( + GtkWidget* widget, + ContentSettingsWindowGtk* window) { + settings_window = NULL; + MessageLoop::current()->DeleteSoon(FROM_HERE, window); +} diff --git a/chrome/browser/gtk/options/content_settings_window_gtk.h b/chrome/browser/gtk/options/content_settings_window_gtk.h new file mode 100644 index 0000000..40d5789 --- /dev/null +++ b/chrome/browser/gtk/options/content_settings_window_gtk.h @@ -0,0 +1,68 @@ +// 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_OPTIONS_CONTENT_SETTINGS_WINDOW_GTK_H_ +#define CHROME_BROWSER_GTK_OPTIONS_CONTENT_SETTINGS_WINDOW_GTK_H_ + +#include <gtk/gtk.h> + +#include "base/scoped_ptr.h" +#include "chrome/browser/gtk/accessible_widget_helper_gtk.h" +#include "chrome/browser/gtk/options/cookie_filter_page_gtk.h" +#include "chrome/browser/gtk/options/content_filter_page_gtk.h" +#include "chrome/common/content_settings_types.h" +#include "chrome/common/pref_member.h" + +class AccessibleWidgetHelper; + +// A window that presents options to the user for blocking various kinds of +// content in webpages (cookies, javascript, images, popups). +class ContentSettingsWindowGtk { + public: + // Shows the current content settings page, opening a new one if it doesn't + // exist. + static void Show(GtkWindow* parent, ContentSettingsType page, + Profile* profile); + static void RegisterUserPrefs(PrefService* prefs); + + explicit ContentSettingsWindowGtk(GtkWindow* parent, Profile* profile); + virtual ~ContentSettingsWindowGtk(); + + private: + // Shows the Tab corresponding to the specified Content Settings page. + void ShowContentSettingsTab(ContentSettingsType page); + + // GTK callbacks + static void OnSwitchPage(GtkNotebook* notebook, GtkNotebookPage* page, + guint page_num, ContentSettingsWindowGtk* window); + static void OnWindowDestroy(GtkWidget* widget, + ContentSettingsWindowGtk* window); + + // The options dialog. + GtkWidget* dialog_; + + // The container of the option pages. + GtkWidget* notebook_; + + // The Profile associated with these options. + Profile* profile_; + + // The last page the user was on when they opened the ContentSettings window. + IntegerPrefMember last_selected_page_; + + // The individual page implementations. Note that we have a specialized one + // for cookies (which have more complex rules) and use the same basic page + // layout for each other type. + CookieFilterPageGtk cookie_page_; + ContentFilterPageGtk image_page_; + ContentFilterPageGtk javascript_page_; + ContentFilterPageGtk plugin_page_; + ContentFilterPageGtk popup_page_; + + scoped_ptr<AccessibleWidgetHelper> accessibility_widget_helper_; + + DISALLOW_COPY_AND_ASSIGN(ContentSettingsWindowGtk); +}; + +#endif // CHROME_BROWSER_GTK_OPTIONS_CONTENT_SETTINGS_WINDOW_GTK_H_ diff --git a/chrome/browser/gtk/options/cookie_filter_page_gtk.cc b/chrome/browser/gtk/options/cookie_filter_page_gtk.cc new file mode 100644 index 0000000..e83c263 --- /dev/null +++ b/chrome/browser/gtk/options/cookie_filter_page_gtk.cc @@ -0,0 +1,219 @@ +// 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/options/cookie_filter_page_gtk.h" + +#include "app/l10n_util.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browsing_data_local_storage_helper.h" +#include "chrome/browser/gtk/gtk_chrome_link_button.h" +#include "chrome/browser/gtk/options/cookies_view.h" +#include "chrome/browser/gtk/options/options_layout_gtk.h" +#include "chrome/browser/host_content_settings_map.h" +#include "chrome/browser/profile.h" +#include "chrome/common/gtk_util.h" +#include "chrome/common/pref_names.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" + +namespace { + +// Stick small widgets in an hbox so it doesn't expand to the whole width. +GtkWidget* WrapInHBox(GtkWidget* widget) { + GtkWidget* hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); + return hbox; +} + +} // namespace + +CookieFilterPageGtk::CookieFilterPageGtk(Profile* profile) + : OptionsPageBase(profile), + initializing_(true) { + OptionsLayoutBuilderGtk options_builder; + options_builder.AddOptionGroup( + l10n_util::GetStringUTF8(IDS_MODIFY_COOKIE_STORING_LABEL), + InitCookieStoringGroup(), true); + page_ = options_builder.get_page_widget(); + + clear_site_data_on_exit_.Init(prefs::kClearSiteDataOnExit, + profile->GetPrefs(), NULL); + + // Load initial values + NotifyPrefChanged(NULL); +} + +CookieFilterPageGtk::~CookieFilterPageGtk() { +} + +void CookieFilterPageGtk::NotifyPrefChanged(const std::wstring* pref_name) { + initializing_ = true; + + if (!pref_name || *pref_name == prefs::kClearSiteDataOnExit) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clear_on_close_check_), + clear_site_data_on_exit_.GetValue()); + } + + initializing_ = false; +} + +void CookieFilterPageGtk::HighlightGroup(OptionsGroup highlight_group) { + // TODO(erg): implement group highlighting +} + +GtkWidget* CookieFilterPageGtk::InitCookieStoringGroup() { + GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); + + allow_radio_ = gtk_radio_button_new_with_label(NULL, + l10n_util::GetStringUTF8(IDS_COOKIES_ALLOW_RADIO).c_str()); + g_signal_connect(G_OBJECT(allow_radio_), "toggled", + G_CALLBACK(OnCookiesAllowToggled), this); + gtk_box_pack_start(GTK_BOX(vbox), allow_radio_, FALSE, FALSE, 0); + + ask_every_time_radio_ = gtk_radio_button_new_with_label_from_widget( + GTK_RADIO_BUTTON(allow_radio_), + l10n_util::GetStringUTF8(IDS_COOKIES_ASK_EVERY_TIME_RADIO).c_str()); + g_signal_connect(G_OBJECT(ask_every_time_radio_), "toggled", + G_CALLBACK(OnCookiesAllowToggled), this); + gtk_box_pack_start(GTK_BOX(vbox), ask_every_time_radio_, FALSE, FALSE, 0); + + block_radio_ = gtk_radio_button_new_with_label_from_widget( + GTK_RADIO_BUTTON(allow_radio_), + l10n_util::GetStringUTF8(IDS_COOKIES_BLOCK_RADIO).c_str()); + g_signal_connect(G_OBJECT(block_radio_), "toggled", + G_CALLBACK(OnCookiesAllowToggled), this); + gtk_box_pack_start(GTK_BOX(vbox), block_radio_, FALSE, FALSE, 0); + + // Set up the current value for the button. + const HostContentSettingsMap* settings_map = + profile()->GetHostContentSettingsMap(); + ContentSetting default_setting = + settings_map->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES); + // Now that these have been added to the view hierarchy, it's safe to call + // SetChecked() on them. + GtkWidget* radio_button = NULL; + if (default_setting == CONTENT_SETTING_ALLOW) { + radio_button = allow_radio_; + } else if (default_setting == CONTENT_SETTING_BLOCK) { + radio_button = block_radio_; + } else { + DCHECK(default_setting == CONTENT_SETTING_ASK); + radio_button = ask_every_time_radio_; + } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button), TRUE); + + // Exception button. + GtkWidget* exceptions_button = gtk_button_new_with_label( + l10n_util::GetStringUTF8(IDS_COOKIES_EXCEPTIONS_BUTTON).c_str()); + // TODO(erg): Disable the exceptions button until that is implemented. + gtk_widget_set_sensitive(exceptions_button, FALSE); + g_signal_connect(G_OBJECT(exceptions_button), "clicked", + G_CALLBACK(OnExceptionsClicked), this); + gtk_box_pack_start(GTK_BOX(vbox), WrapInHBox(exceptions_button), + FALSE, FALSE, 0); + + block_3rdparty_check_ = gtk_check_button_new_with_label( + l10n_util::GetStringUTF8(IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX).c_str()); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(block_3rdparty_check_), + settings_map->BlockThirdPartyCookies()); + g_signal_connect(G_OBJECT(block_3rdparty_check_), "toggled", + G_CALLBACK(OnBlock3rdpartyToggled), this); + gtk_box_pack_start(GTK_BOX(vbox), block_3rdparty_check_, FALSE, FALSE, 0); + + clear_on_close_check_ = gtk_check_button_new_with_label( + l10n_util::GetStringUTF8(IDS_COOKIES_CLEAR_WHEN_CLOSE_CHKBOX).c_str()); + g_signal_connect(G_OBJECT(clear_on_close_check_), "toggled", + G_CALLBACK(OnClearOnCloseToggled), this); + gtk_box_pack_start(GTK_BOX(vbox), clear_on_close_check_, FALSE, FALSE, 0); + + show_cookies_button_ = gtk_button_new_with_label( + l10n_util::GetStringUTF8(IDS_COOKIES_SHOW_COOKIES_BUTTON).c_str()); + g_signal_connect(G_OBJECT(show_cookies_button_), "clicked", + G_CALLBACK(OnShowCookiesClicked), this); + gtk_box_pack_start(GTK_BOX(vbox), WrapInHBox(show_cookies_button_), + FALSE, FALSE, 0); + + GtkWidget* flash_settings_link = gtk_chrome_link_button_new( + l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_SETTINGS).c_str()); + g_signal_connect(G_OBJECT(flash_settings_link), "clicked", + G_CALLBACK(OnFlashLinkClicked), this); + gtk_box_pack_start(GTK_BOX(vbox), WrapInHBox(flash_settings_link), + FALSE, FALSE, 0); + + return vbox; +}; + +void CookieFilterPageGtk::OnCookiesAllowToggled( + GtkWidget* toggle_button, + CookieFilterPageGtk* cookie_page) { + if (cookie_page->initializing_) + return; + + if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))) { + // When selecting a radio button, we get two signals (one for the old radio + // being toggled off, one for the new one being toggled on.) Ignore the + // signal for toggling off the old button. + return; + } + + ContentSetting setting; + if (toggle_button == cookie_page->allow_radio_) + setting = CONTENT_SETTING_ALLOW; + else if (toggle_button == cookie_page->ask_every_time_radio_) + setting = CONTENT_SETTING_ASK; + else if (toggle_button == cookie_page->block_radio_) + setting = CONTENT_SETTING_BLOCK; + + cookie_page->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( + CONTENT_SETTINGS_TYPE_COOKIES, setting); +} + +void CookieFilterPageGtk::OnExceptionsClicked( + GtkToggleButton* toggle_button, + CookieFilterPageGtk* cookie_page) { + // TODO(erg): Implement the exceptions button. +} + +void CookieFilterPageGtk::OnBlock3rdpartyToggled( + GtkToggleButton* toggle_button, + CookieFilterPageGtk* cookie_page) { + if (cookie_page->initializing_) + return; + + HostContentSettingsMap* settings_map = + cookie_page->profile()->GetHostContentSettingsMap(); + settings_map->SetBlockThirdPartyCookies( + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))); +} + +void CookieFilterPageGtk::OnClearOnCloseToggled( + GtkToggleButton* toggle_button, + CookieFilterPageGtk* cookie_page) { + if (cookie_page->initializing_) + return; + + cookie_page->clear_site_data_on_exit_.SetValue( + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))); +} + +void CookieFilterPageGtk::OnShowCookiesClicked( + GtkWidget* button, + CookieFilterPageGtk* cookie_page) { + cookie_page->UserMetricsRecordAction("Options_ShowCookies", NULL); + CookiesView::Show(cookie_page->profile(), + new BrowsingDataDatabaseHelper( + cookie_page->profile()), + new BrowsingDataLocalStorageHelper( + cookie_page->profile())); +} + +void CookieFilterPageGtk::OnFlashLinkClicked( + GtkWidget* button, + CookieFilterPageGtk* cookie_page) { + // We open a new browser window so the Options dialog doesn't get lost + // behind other windows. + Browser* browser = Browser::Create(cookie_page->profile()); + browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), + GURL(), NEW_WINDOW, PageTransition::LINK); +} diff --git a/chrome/browser/gtk/options/cookie_filter_page_gtk.h b/chrome/browser/gtk/options/cookie_filter_page_gtk.h new file mode 100644 index 0000000..e18f6db --- /dev/null +++ b/chrome/browser/gtk/options/cookie_filter_page_gtk.h @@ -0,0 +1,73 @@ +// 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_OPTIONS_COOKIE_FILTER_PAGE_GTK_H_ +#define CHROME_BROWSER_GTK_OPTIONS_COOKIE_FILTER_PAGE_GTK_H_ + +#include <gtk/gtk.h> + +#include <string> + +#include "chrome/browser/options_page_base.h" +#include "chrome/common/pref_member.h" + +class Profile; + +// A page in the content settings window for cookie options. This dialog has +// more options as is more complicated then all the other pages implemented +// with ContentPageGtk. +class CookieFilterPageGtk : public OptionsPageBase { + public: + explicit CookieFilterPageGtk(Profile* profile); + virtual ~CookieFilterPageGtk(); + + GtkWidget* get_page_widget() const { + return page_; + } + + private: + // Overridden from OptionsPageBase + virtual void NotifyPrefChanged(const std::wstring* pref_name); + virtual void HighlightGroup(OptionsGroup highlight_group); + + // GTK callbacks + static void OnCookiesAllowToggled(GtkWidget* toggle_button, + CookieFilterPageGtk* cookie_page); + static void OnExceptionsClicked(GtkToggleButton* toggle_button, + CookieFilterPageGtk* cookie_page); + static void OnBlock3rdpartyToggled(GtkToggleButton* toggle_button, + CookieFilterPageGtk* cookie_page); + static void OnClearOnCloseToggled(GtkToggleButton* toggle_button, + CookieFilterPageGtk* cookie_page); + static void OnShowCookiesClicked(GtkWidget* button, + CookieFilterPageGtk* cookie_page); + static void OnFlashLinkClicked(GtkWidget* button, + CookieFilterPageGtk* cookie_page); + + GtkWidget* InitCookieStoringGroup(); + + // Widgets of the cookie storing group + GtkWidget* allow_radio_; + GtkWidget* ask_every_time_radio_; + GtkWidget* block_radio_; + + GtkWidget* exceptions_button_; + GtkWidget* block_3rdparty_check_; + GtkWidget* clear_on_close_check_; + GtkWidget* show_cookies_button_; + + // The parent GtkTable widget + GtkWidget* page_; + + // Whether we're currently setting values (and thus should ignore "toggled" + // events). + bool initializing_; + + // Clear locally stored site data on exit pref. + BooleanPrefMember clear_site_data_on_exit_; + + DISALLOW_COPY_AND_ASSIGN(CookieFilterPageGtk); +}; + +#endif // CHROME_BROWSER_GTK_OPTIONS_COOKIE_FILTER_PAGE_GTK_H_ diff --git a/chrome/browser/gtk/options/options_window_gtk.cc b/chrome/browser/gtk/options/options_window_gtk.cc index aa451f9..d0330b9 100644 --- a/chrome/browser/gtk/options/options_window_gtk.cc +++ b/chrome/browser/gtk/options/options_window_gtk.cc @@ -24,7 +24,6 @@ #include "chrome/common/pref_member.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "chrome/common/x11_util.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -81,51 +80,6 @@ class OptionsWindowGtk { // The singleton options window object. static OptionsWindowGtk* options_window = NULL; -// Places |window| approximately over center of |parent|, it also moves window -// to parent's desktop. -// NOTE: It's better to use transient_for to center dialog but options dialog -// is not modal so we don't want to set transient_for. -static void CenterOverWindow(GtkWindow* window, GtkWindow* parent) { - gfx::Rect frame_bounds = gtk_util::GetWidgetScreenBounds(GTK_WIDGET(parent)); - gfx::Point origin = frame_bounds.origin(); - gfx::Size size = gtk_util::GetWidgetSize(GTK_WIDGET(window)); - origin.Offset( - (frame_bounds.width() - size.width()) / 2, - (frame_bounds.height() - size.height()) / 2); - - // Prevent moving window out of monitor bounds. - GdkScreen* screen = gtk_window_get_screen(parent); - if (screen) { - // It would be better to check against workarea for given monitor - // but getting workarea for particular monitor is tricky. - gint monitor = gdk_screen_get_monitor_at_window(screen, - GTK_WIDGET(parent)->window); - GdkRectangle rect; - gdk_screen_get_monitor_geometry(screen, monitor, &rect); - - // Check the right bottom corner. - if (origin.x() > rect.x + rect.width - size.width()) - origin.set_x(rect.x + rect.width - size.width()); - if (origin.y() > rect.y + rect.height - size.height()) - origin.set_y(rect.y + rect.height - size.height()); - - // Check the left top corner. - if (origin.x() < rect.x) - origin.set_x(rect.x); - if (origin.y() < rect.y) - origin.set_y(rect.y); - } - - gtk_window_move(window, origin.x(), origin.y()); - - // Move to user expected desktop if window is already visible. - if (GTK_WIDGET(window)->window) { - x11_util::ChangeWindowDesktop( - x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(window)), - x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(parent))); - } -} - /////////////////////////////////////////////////////////////////////////////// // OptionsWindowGtk, public: @@ -203,7 +157,8 @@ OptionsWindowGtk::OptionsWindowGtk(Profile* profile) if (Browser* b = BrowserList::GetLastActive()) { // Show container content so that we can compute full dialog size. gtk_widget_show_all(notebook_); - CenterOverWindow(GTK_WINDOW(dialog_), b->window()->GetNativeHandle()); + gtk_util::CenterOverWindow(GTK_WINDOW(dialog_), + b->window()->GetNativeHandle()); } // Need to show the notebook before connecting switch-page signal, otherwise @@ -226,7 +181,8 @@ OptionsWindowGtk::~OptionsWindowGtk() { void OptionsWindowGtk::ShowOptionsPage(OptionsPage page, OptionsGroup highlight_group) { if (Browser* b = BrowserList::GetLastActive()) { - CenterOverWindow(GTK_WINDOW(dialog_), b->window()->GetNativeHandle()); + gtk_util::CenterOverWindow(GTK_WINDOW(dialog_), + b->window()->GetNativeHandle()); } // Bring options window to front if it already existed and isn't already diff --git a/chrome/browser/host_content_settings_map.cc b/chrome/browser/host_content_settings_map.cc index 3603215..f09fe8c 100644 --- a/chrome/browser/host_content_settings_map.cc +++ b/chrome/browser/host_content_settings_map.cc @@ -108,6 +108,7 @@ void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings); prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings); prefs->RegisterBooleanPref(prefs::kBlockThirdPartyCookies, false); + prefs->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex, 0); // Obsolete prefs, for migration: prefs->RegisterIntegerPref(prefs::kCookieBehavior, diff --git a/chrome/browser/views/options/content_settings_window_view.cc b/chrome/browser/views/options/content_settings_window_view.cc index 060e4c9..fb58d7c 100644 --- a/chrome/browser/views/options/content_settings_window_view.cc +++ b/chrome/browser/views/options/content_settings_window_view.cc @@ -45,15 +45,7 @@ void ShowContentSettingsWindow(gfx::NativeWindow parent_window, instance_->ShowContentSettingsTab(content_type); } -}; - -/////////////////////////////////////////////////////////////////////////////// -// ContentSettingsWindowView, public: - -// static -void ContentSettingsWindowView::RegisterUserPrefs(PrefService* prefs) { - prefs->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex, 0); -} +} // namespace browser ContentSettingsWindowView::ContentSettingsWindowView(Profile* profile) // Always show preferences for the original profile. Most state when off diff --git a/chrome/browser/views/options/content_settings_window_view.h b/chrome/browser/views/options/content_settings_window_view.h index 634416d..c4ce14f 100644 --- a/chrome/browser/views/options/content_settings_window_view.h +++ b/chrome/browser/views/options/content_settings_window_view.h @@ -24,8 +24,6 @@ class ContentSettingsWindowView : public views::View, public views::DialogDelegate, public views::TabbedPane::Listener { public: - static void RegisterUserPrefs(PrefService* prefs); - explicit ContentSettingsWindowView(Profile* profile); virtual ~ContentSettingsWindowView(); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index a47c848..46fce41 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1055,8 +1055,14 @@ 'browser/gtk/options/advanced_contents_gtk.h', 'browser/gtk/options/advanced_page_gtk.cc', 'browser/gtk/options/advanced_page_gtk.h', + 'browser/gtk/options/content_filter_page_gtk.cc', + 'browser/gtk/options/content_filter_page_gtk.h', 'browser/gtk/options/content_page_gtk.cc', 'browser/gtk/options/content_page_gtk.h', + 'browser/gtk/options/content_settings_window_gtk.cc', + 'browser/gtk/options/content_settings_window_gtk.h', + 'browser/gtk/options/cookie_filter_page_gtk.cc', + 'browser/gtk/options/cookie_filter_page_gtk.h', 'browser/gtk/options/cookies_view.cc', 'browser/gtk/options/cookies_view.h', 'browser/gtk/options/exceptions_page_gtk.cc', diff --git a/chrome/common/gtk_util.cc b/chrome/common/gtk_util.cc index c175330..7972edb 100644 --- a/chrome/common/gtk_util.cc +++ b/chrome/common/gtk_util.cc @@ -17,6 +17,7 @@ #include "chrome/browser/gtk/cairo_cached_surface.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/common/renderer_preferences.h" +#include "chrome/common/x11_util.h" #include "grit/theme_resources.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" @@ -237,6 +238,47 @@ void SetWindowSizeFromResources(GtkWindow* window, gtk_window_set_resizable(window, resizable ? TRUE : FALSE); } +void CenterOverWindow(GtkWindow* window, GtkWindow* parent) { + gfx::Rect frame_bounds = gtk_util::GetWidgetScreenBounds(GTK_WIDGET(parent)); + gfx::Point origin = frame_bounds.origin(); + gfx::Size size = gtk_util::GetWidgetSize(GTK_WIDGET(window)); + origin.Offset( + (frame_bounds.width() - size.width()) / 2, + (frame_bounds.height() - size.height()) / 2); + + // Prevent moving window out of monitor bounds. + GdkScreen* screen = gtk_window_get_screen(parent); + if (screen) { + // It would be better to check against workarea for given monitor + // but getting workarea for particular monitor is tricky. + gint monitor = gdk_screen_get_monitor_at_window(screen, + GTK_WIDGET(parent)->window); + GdkRectangle rect; + gdk_screen_get_monitor_geometry(screen, monitor, &rect); + + // Check the right bottom corner. + if (origin.x() > rect.x + rect.width - size.width()) + origin.set_x(rect.x + rect.width - size.width()); + if (origin.y() > rect.y + rect.height - size.height()) + origin.set_y(rect.y + rect.height - size.height()); + + // Check the left top corner. + if (origin.x() < rect.x) + origin.set_x(rect.x); + if (origin.y() < rect.y) + origin.set_y(rect.y); + } + + gtk_window_move(window, origin.x(), origin.y()); + + // Move to user expected desktop if window is already visible. + if (GTK_WIDGET(window)->window) { + x11_util::ChangeWindowDesktop( + x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(window)), + x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(parent))); + } +} + void RemoveAllChildren(GtkWidget* container) { gtk_container_foreach(GTK_CONTAINER(container), RemoveWidget, container); } diff --git a/chrome/common/gtk_util.h b/chrome/common/gtk_util.h index f1bc1b6..93533fd 100644 --- a/chrome/common/gtk_util.h +++ b/chrome/common/gtk_util.h @@ -94,6 +94,12 @@ void GetWidgetSizeFromCharacters(GtkWidget* widget, double width_chars, void SetWindowSizeFromResources(GtkWindow* window, int width_id, int height_id, bool resizable); +// Places |window| approximately over center of |parent|, it also moves window +// to parent's desktop. Use this only for non-modal dialogs, such as the +// options window and content settings window; otherwise you should be using +// transient_for. +void CenterOverWindow(GtkWindow* window, GtkWindow* parent); + // Remove all children from this container. void RemoveAllChildren(GtkWidget* container); |