| OLD | NEW | 
 | (Empty) | 
|     1 // Copyright (c) 2010 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 #include "chrome/browser/gtk/options/advanced_contents_gtk.h" |  | 
|     6  |  | 
|     7 #include <sys/types.h> |  | 
|     8 #include <sys/wait.h> |  | 
|     9  |  | 
|    10 #include <string> |  | 
|    11 #include <vector> |  | 
|    12  |  | 
|    13 #include "app/gtk_signal.h" |  | 
|    14 #include "app/l10n_util.h" |  | 
|    15 #include "base/basictypes.h" |  | 
|    16 #include "base/command_line.h" |  | 
|    17 #include "base/environment.h" |  | 
|    18 #include "base/file_util.h" |  | 
|    19 #include "base/path_service.h" |  | 
|    20 #include "base/process_util.h" |  | 
|    21 #include "base/string_tokenizer.h" |  | 
|    22 #include "base/nix/xdg_util.h" |  | 
|    23 #include "chrome/browser/browser_list.h" |  | 
|    24 #include "chrome/browser/browser_process.h" |  | 
|    25 #include "chrome/browser/download/download_manager.h" |  | 
|    26 #include "chrome/browser/download/download_prefs.h" |  | 
|    27 #include "chrome/browser/fonts_languages_window.h" |  | 
|    28 #include "chrome/browser/google/google_util.h" |  | 
|    29 #include "chrome/browser/gtk/accessible_widget_helper_gtk.h" |  | 
|    30 #include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h" |  | 
|    31 #include "chrome/browser/gtk/gtk_chrome_link_button.h" |  | 
|    32 #include "chrome/browser/gtk/gtk_util.h" |  | 
|    33 #include "chrome/browser/gtk/options/content_settings_window_gtk.h" |  | 
|    34 #include "chrome/browser/gtk/options/options_layout_gtk.h" |  | 
|    35 #include "chrome/browser/prefs/pref_member.h" |  | 
|    36 #include "chrome/browser/prefs/pref_set_observer.h" |  | 
|    37 #include "chrome/browser/profiles/profile.h" |  | 
|    38 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |  | 
|    39 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |  | 
|    40 #include "chrome/browser/ui/options/options_page_base.h" |  | 
|    41 #include "chrome/browser/ui/options/options_util.h" |  | 
|    42 #include "chrome/browser/ui/options/show_options_url.h" |  | 
|    43 #include "chrome/common/chrome_paths.h" |  | 
|    44 #include "chrome/common/pref_names.h" |  | 
|    45 #include "chrome/common/process_watcher.h" |  | 
|    46 #include "chrome/common/url_constants.h" |  | 
|    47 #include "grit/chromium_strings.h" |  | 
|    48 #include "grit/generated_resources.h" |  | 
|    49 #include "grit/locale_settings.h" |  | 
|    50  |  | 
|    51 namespace { |  | 
|    52  |  | 
|    53 // Command used to configure GNOME proxy settings. The command was renamed |  | 
|    54 // in January 2009, so both are used to work on both old and new systems. |  | 
|    55 const char* kOldGNOMEProxyConfigCommand[] = {"gnome-network-preferences", NULL}; |  | 
|    56 const char* kGNOMEProxyConfigCommand[] = {"gnome-network-properties", NULL}; |  | 
|    57 // KDE3 and KDE4 are only slightly different, but incompatible. Go figure. |  | 
|    58 const char* kKDE3ProxyConfigCommand[] = {"kcmshell", "proxy", NULL}; |  | 
|    59 const char* kKDE4ProxyConfigCommand[] = {"kcmshell4", "proxy", NULL}; |  | 
|    60  |  | 
|    61 // The URL for Linux ssl certificate configuration help. |  | 
|    62 const char* const kLinuxCertificatesConfigUrl = |  | 
|    63     "http://code.google.com/p/chromium/wiki/LinuxCertManagement"; |  | 
|    64  |  | 
|    65 // The URL for Linux proxy configuration help when not running under a |  | 
|    66 // supported desktop environment. |  | 
|    67 const char kLinuxProxyConfigUrl[] = "about:linux-proxy-config"; |  | 
|    68  |  | 
|    69 // The pixel width we wrap labels at. |  | 
|    70 // TODO(evanm): make the labels wrap at the appropriate width. |  | 
|    71 #if defined(OS_CHROMEOS) |  | 
|    72 // ChromeOS uses IDS_OPTIONS_DIALOG_WIDTH_CHARS for options dialog width, which |  | 
|    73 // is slightly smaller than the Gtk options dialog's 500px. |  | 
|    74 const int kWrapWidth = 445; |  | 
|    75 #else |  | 
|    76 const int kWrapWidth = 475; |  | 
|    77 #endif |  | 
|    78  |  | 
|    79 GtkWidget* CreateWrappedLabel(int string_id) { |  | 
|    80   GtkWidget* label = gtk_label_new( |  | 
|    81       l10n_util::GetStringUTF8(string_id).c_str()); |  | 
|    82   gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); |  | 
|    83   gtk_util::SetLabelWidth(label, kWrapWidth); |  | 
|    84   return label; |  | 
|    85 } |  | 
|    86  |  | 
|    87 GtkWidget* CreateCheckButtonWithWrappedLabel(int string_id) { |  | 
|    88   GtkWidget* checkbox = gtk_check_button_new(); |  | 
|    89   gtk_container_add(GTK_CONTAINER(checkbox), |  | 
|    90                     CreateWrappedLabel(string_id)); |  | 
|    91   return checkbox; |  | 
|    92 } |  | 
|    93  |  | 
|    94 GtkWidget* AddCheckButtonWithWrappedLabel(int string_id, |  | 
|    95                                           GtkWidget* container, |  | 
|    96                                           GCallback handler, |  | 
|    97                                           gpointer data) { |  | 
|    98   GtkWidget* checkbox = CreateCheckButtonWithWrappedLabel(string_id); |  | 
|    99   gtk_box_pack_start(GTK_BOX(container), checkbox, FALSE, FALSE, 0); |  | 
|   100   g_signal_connect(checkbox, "toggled", handler, data); |  | 
|   101  |  | 
|   102   return checkbox; |  | 
|   103 } |  | 
|   104  |  | 
|   105 // Don't let the widget handle scroll events. Instead, pass it on to the |  | 
|   106 // parent widget. |  | 
|   107 gboolean PassScrollToParent(GtkWidget* widget, GdkEvent* event, |  | 
|   108                             gpointer unused) { |  | 
|   109   if (widget->parent) |  | 
|   110     gtk_propagate_event(widget->parent, event); |  | 
|   111  |  | 
|   112   return TRUE; |  | 
|   113 } |  | 
|   114  |  | 
|   115 // Recursively search for a combo box among the children of |widget|. |  | 
|   116 void SearchForComboBox(GtkWidget* widget, gpointer data) { |  | 
|   117   if (GTK_IS_COMBO_BOX(widget)) { |  | 
|   118     *reinterpret_cast<GtkWidget**>(data) = widget; |  | 
|   119   } else if (GTK_IS_CONTAINER(widget)) { |  | 
|   120     gtk_container_foreach(GTK_CONTAINER(widget), SearchForComboBox, data); |  | 
|   121   } |  | 
|   122 } |  | 
|   123  |  | 
|   124 // Letting the combo boxes in the advanced options page handle scroll events is |  | 
|   125 // annoying because they fight with the scrolled window. Also, |  | 
|   126 // GtkFileChooserButton is buggy in that if you scroll on it very quickly it |  | 
|   127 // spews Gtk-WARNINGs, which causes us to crash in debug. This function disables |  | 
|   128 // scrolling for the combo box in |widget| (the first one it finds in a DFS). |  | 
|   129 void DisableScrolling(GtkWidget* widget) { |  | 
|   130   gpointer combo_box_ptr = NULL; |  | 
|   131   SearchForComboBox(widget, &combo_box_ptr); |  | 
|   132  |  | 
|   133   if (!combo_box_ptr) { |  | 
|   134     NOTREACHED() << " Did not find a combo box in this widget."; |  | 
|   135     return; |  | 
|   136   } |  | 
|   137  |  | 
|   138   g_signal_connect(GTK_WIDGET(combo_box_ptr), "scroll-event", |  | 
|   139                    G_CALLBACK(PassScrollToParent), NULL); |  | 
|   140 } |  | 
|   141  |  | 
|   142 }  // anonymous namespace |  | 
|   143  |  | 
|   144  |  | 
|   145 /////////////////////////////////////////////////////////////////////////////// |  | 
|   146 // DownloadSection |  | 
|   147  |  | 
|   148 class DownloadSection : public OptionsPageBase { |  | 
|   149  public: |  | 
|   150   explicit DownloadSection(Profile* profile); |  | 
|   151   virtual ~DownloadSection() {} |  | 
|   152  |  | 
|   153   GtkWidget* get_page_widget() const { |  | 
|   154     return page_; |  | 
|   155   } |  | 
|   156  |  | 
|   157  private: |  | 
|   158   // Overridden from OptionsPageBase. |  | 
|   159   virtual void NotifyPrefChanged(const std::string* pref_name); |  | 
|   160  |  | 
|   161   // Callbacks for the widgets. |  | 
|   162   static void OnDownloadLocationChanged(GtkFileChooser* widget, |  | 
|   163                                         DownloadSection* section); |  | 
|   164   static void OnDownloadAskForSaveLocationChanged(GtkWidget* widget, |  | 
|   165                                                   DownloadSection* section); |  | 
|   166   static void OnResetFileHandlersClicked(GtkButton *button, |  | 
|   167                                          DownloadSection* section); |  | 
|   168  |  | 
|   169   // The widgets for the download options. |  | 
|   170   GtkWidget* download_location_button_; |  | 
|   171   GtkWidget* download_ask_for_save_location_checkbox_; |  | 
|   172   GtkWidget* reset_file_handlers_label_; |  | 
|   173   GtkWidget* reset_file_handlers_button_; |  | 
|   174  |  | 
|   175   // The widget containing the options for this section. |  | 
|   176   GtkWidget* page_; |  | 
|   177  |  | 
|   178   // Pref members. |  | 
|   179   FilePathPrefMember default_download_location_; |  | 
|   180   BooleanPrefMember ask_for_save_location_; |  | 
|   181   StringPrefMember auto_open_files_; |  | 
|   182  |  | 
|   183   // Flag to ignore gtk callbacks while we are loading prefs, to avoid |  | 
|   184   // then turning around and saving them again. |  | 
|   185   bool pref_changing_; |  | 
|   186  |  | 
|   187   scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_; |  | 
|   188  |  | 
|   189   DISALLOW_COPY_AND_ASSIGN(DownloadSection); |  | 
|   190 }; |  | 
|   191  |  | 
|   192 DownloadSection::DownloadSection(Profile* profile) |  | 
|   193     : OptionsPageBase(profile), |  | 
|   194       pref_changing_(true) { |  | 
|   195   page_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |  | 
|   196  |  | 
|   197   accessible_widget_helper_.reset(new AccessibleWidgetHelper( |  | 
|   198       page_, profile)); |  | 
|   199  |  | 
|   200   // Download location options. |  | 
|   201   download_location_button_ = gtk_file_chooser_button_new( |  | 
|   202       l10n_util::GetStringUTF8( |  | 
|   203           IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_WINDOW_TITLE).c_str(), |  | 
|   204       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); |  | 
|   205   g_signal_connect(download_location_button_, "selection-changed", |  | 
|   206                    G_CALLBACK(OnDownloadLocationChanged), this); |  | 
|   207   DisableScrolling(download_location_button_); |  | 
|   208  |  | 
|   209   // Add the default download path to the list of shortcuts in the selector. |  | 
|   210   FilePath default_download_path; |  | 
|   211   if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, |  | 
|   212                         &default_download_path)) { |  | 
|   213     NOTREACHED(); |  | 
|   214   } else { |  | 
|   215     if (!gtk_file_chooser_add_shortcut_folder( |  | 
|   216         GTK_FILE_CHOOSER(download_location_button_), |  | 
|   217         default_download_path.value().c_str(), |  | 
|   218         NULL)) { |  | 
|   219       NOTREACHED(); |  | 
|   220     } |  | 
|   221   } |  | 
|   222  |  | 
|   223   GtkWidget* download_location_control = gtk_util::CreateLabeledControlsGroup( |  | 
|   224       NULL, |  | 
|   225       l10n_util::GetStringUTF8( |  | 
|   226           IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE).c_str(), |  | 
|   227       download_location_button_, |  | 
|   228       NULL); |  | 
|   229   gtk_box_pack_start(GTK_BOX(page_), download_location_control, |  | 
|   230                      FALSE, FALSE, 0); |  | 
|   231  |  | 
|   232   download_ask_for_save_location_checkbox_ = CreateCheckButtonWithWrappedLabel( |  | 
|   233       IDS_OPTIONS_DOWNLOADLOCATION_ASKFORSAVELOCATION); |  | 
|   234   gtk_box_pack_start(GTK_BOX(page_), download_ask_for_save_location_checkbox_, |  | 
|   235                      FALSE, FALSE, 0); |  | 
|   236   g_signal_connect(download_ask_for_save_location_checkbox_, "clicked", |  | 
|   237                    G_CALLBACK(OnDownloadAskForSaveLocationChanged), this); |  | 
|   238   accessible_widget_helper_->SetWidgetName( |  | 
|   239       download_ask_for_save_location_checkbox_, |  | 
|   240       IDS_OPTIONS_DOWNLOADLOCATION_ASKFORSAVELOCATION); |  | 
|   241  |  | 
|   242   // Option for resetting file handlers. |  | 
|   243   reset_file_handlers_label_ = CreateWrappedLabel( |  | 
|   244       IDS_OPTIONS_AUTOOPENFILETYPES_INFO); |  | 
|   245   gtk_misc_set_alignment(GTK_MISC(reset_file_handlers_label_), 0, 0); |  | 
|   246   gtk_box_pack_start(GTK_BOX(page_), reset_file_handlers_label_, |  | 
|   247                      FALSE, FALSE, 0); |  | 
|   248  |  | 
|   249   reset_file_handlers_button_ = gtk_button_new_with_label( |  | 
|   250       l10n_util::GetStringUTF8( |  | 
|   251           IDS_OPTIONS_AUTOOPENFILETYPES_RESETTODEFAULT).c_str()); |  | 
|   252   g_signal_connect(reset_file_handlers_button_, "clicked", |  | 
|   253                    G_CALLBACK(OnResetFileHandlersClicked), this); |  | 
|   254   // Stick it in an hbox so it doesn't expand to the whole width. |  | 
|   255   GtkWidget* button_hbox = gtk_hbox_new(FALSE, 0); |  | 
|   256   gtk_box_pack_start(GTK_BOX(button_hbox), |  | 
|   257                      reset_file_handlers_button_, |  | 
|   258                      FALSE, FALSE, 0); |  | 
|   259   gtk_box_pack_start(GTK_BOX(page_), |  | 
|   260                      gtk_util::IndentWidget(button_hbox), |  | 
|   261                      FALSE, FALSE, 0); |  | 
|   262  |  | 
|   263   // Init prefs watchers. |  | 
|   264   default_download_location_.Init(prefs::kDownloadDefaultDirectory, |  | 
|   265                                   profile->GetPrefs(), this); |  | 
|   266   ask_for_save_location_.Init(prefs::kPromptForDownload, |  | 
|   267                               profile->GetPrefs(), this); |  | 
|   268   auto_open_files_.Init(prefs::kDownloadExtensionsToOpen, profile->GetPrefs(), |  | 
|   269                         this); |  | 
|   270  |  | 
|   271   NotifyPrefChanged(NULL); |  | 
|   272 } |  | 
|   273  |  | 
|   274 void DownloadSection::NotifyPrefChanged(const std::string* pref_name) { |  | 
|   275   pref_changing_ = true; |  | 
|   276   if (!pref_name || *pref_name == prefs::kDownloadDefaultDirectory) { |  | 
|   277     gtk_file_chooser_set_current_folder( |  | 
|   278         GTK_FILE_CHOOSER(download_location_button_), |  | 
|   279             default_download_location_.GetValue().value().c_str()); |  | 
|   280   } |  | 
|   281  |  | 
|   282   if (!pref_name || *pref_name == prefs::kPromptForDownload) { |  | 
|   283     gtk_toggle_button_set_active( |  | 
|   284         GTK_TOGGLE_BUTTON(download_ask_for_save_location_checkbox_), |  | 
|   285         ask_for_save_location_.GetValue()); |  | 
|   286   } |  | 
|   287  |  | 
|   288   if (!pref_name || *pref_name == prefs::kDownloadExtensionsToOpen) { |  | 
|   289     DownloadPrefs* prefs = profile()->GetDownloadManager()->download_prefs(); |  | 
|   290     bool enabled = prefs->IsAutoOpenUsed(); |  | 
|   291     gtk_widget_set_sensitive(reset_file_handlers_label_, enabled); |  | 
|   292     gtk_widget_set_sensitive(reset_file_handlers_button_, enabled); |  | 
|   293   } |  | 
|   294   pref_changing_ = false; |  | 
|   295 } |  | 
|   296  |  | 
|   297 // static |  | 
|   298 void DownloadSection::OnDownloadLocationChanged(GtkFileChooser* widget, |  | 
|   299                                                 DownloadSection* section) { |  | 
|   300   if (section->pref_changing_) |  | 
|   301     return; |  | 
|   302  |  | 
|   303   gchar* folder = gtk_file_chooser_get_filename(widget); |  | 
|   304   FilePath path(folder); |  | 
|   305   g_free(folder); |  | 
|   306   // Gtk seems to call this signal multiple times, so we only set the pref and |  | 
|   307   // metric if something actually changed. |  | 
|   308   if (path != section->default_download_location_.GetValue()) { |  | 
|   309     section->default_download_location_.SetValue(path); |  | 
|   310     section->UserMetricsRecordAction( |  | 
|   311         UserMetricsAction("Options_SetDownloadDirectory"), |  | 
|   312         section->profile()->GetPrefs()); |  | 
|   313   } |  | 
|   314 } |  | 
|   315  |  | 
|   316 // static |  | 
|   317 void DownloadSection::OnDownloadAskForSaveLocationChanged( |  | 
|   318     GtkWidget* widget, DownloadSection* section) { |  | 
|   319   if (section->pref_changing_) |  | 
|   320     return; |  | 
|   321   bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); |  | 
|   322   if (enabled) { |  | 
|   323     section->UserMetricsRecordAction( |  | 
|   324         UserMetricsAction("Options_AskForSaveLocation_Enable"), |  | 
|   325         section->profile()->GetPrefs()); |  | 
|   326   } else { |  | 
|   327     section->UserMetricsRecordAction( |  | 
|   328         UserMetricsAction("Options_AskForSaveLocation_Disable"), |  | 
|   329         section->profile()->GetPrefs()); |  | 
|   330   } |  | 
|   331   section->ask_for_save_location_.SetValue(enabled); |  | 
|   332 } |  | 
|   333  |  | 
|   334 // static |  | 
|   335 void DownloadSection::OnResetFileHandlersClicked(GtkButton *button, |  | 
|   336                                                  DownloadSection* section) { |  | 
|   337   section->profile()->GetDownloadManager()->download_prefs()->ResetAutoOpen(); |  | 
|   338   section->UserMetricsRecordAction( |  | 
|   339       UserMetricsAction("Options_ResetAutoOpenFiles"), |  | 
|   340       section->profile()->GetPrefs()); |  | 
|   341 } |  | 
|   342  |  | 
|   343 /////////////////////////////////////////////////////////////////////////////// |  | 
|   344 // NetworkSection |  | 
|   345  |  | 
|   346 class NetworkSection : public OptionsPageBase { |  | 
|   347  public: |  | 
|   348   explicit NetworkSection(Profile* profile); |  | 
|   349   virtual ~NetworkSection() {} |  | 
|   350  |  | 
|   351   GtkWidget* get_page_widget() const { |  | 
|   352     return page_; |  | 
|   353   } |  | 
|   354  |  | 
|   355  private: |  | 
|   356   // Overridden from OptionsPageBase. |  | 
|   357   virtual void NotifyPrefChanged(const std::string* pref_name); |  | 
|   358  |  | 
|   359   struct ProxyConfigCommand { |  | 
|   360     std::string binary; |  | 
|   361     const char** argv; |  | 
|   362   }; |  | 
|   363   // The callback functions for invoking the proxy config dialog. |  | 
|   364   static void OnChangeProxiesButtonClicked(GtkButton *button, |  | 
|   365                                            NetworkSection* section); |  | 
|   366   // Detect, and if possible, start the appropriate proxy config utility. On |  | 
|   367   // failure to do so, show the Linux proxy config URL in a new tab instead. |  | 
|   368   static void DetectAndStartProxyConfigUtil(Profile* profile); |  | 
|   369   // Show the proxy config URL in a new tab. |  | 
|   370   static void ShowLinuxProxyConfigUrl(Profile* profile); |  | 
|   371   // Search $PATH to find one of the commands. Store the full path to |  | 
|   372   // it in the |binary| field and the command array index in in |index|. |  | 
|   373   static bool SearchPATH(ProxyConfigCommand* commands, size_t ncommands, |  | 
|   374                          size_t* index); |  | 
|   375   // Start the given proxy configuration utility. |  | 
|   376   static void StartProxyConfigUtil(Profile* profile, |  | 
|   377                                    const ProxyConfigCommand& command); |  | 
|   378  |  | 
|   379   // Tracks the state of proxy preferences. |  | 
|   380   scoped_ptr<PrefSetObserver> proxy_prefs_; |  | 
|   381  |  | 
|   382   // The widget containing the options for this section. |  | 
|   383   GtkWidget* page_; |  | 
|   384  |  | 
|   385   // The proxy configuration button. |  | 
|   386   GtkWidget* change_proxies_button_; |  | 
|   387  |  | 
|   388   DISALLOW_COPY_AND_ASSIGN(NetworkSection); |  | 
|   389 }; |  | 
|   390  |  | 
|   391 NetworkSection::NetworkSection(Profile* profile) |  | 
|   392     : OptionsPageBase(profile) { |  | 
|   393   page_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |  | 
|   394  |  | 
|   395   GtkWidget* proxy_description_label = CreateWrappedLabel( |  | 
|   396       IDS_OPTIONS_PROXIES_LABEL); |  | 
|   397   gtk_misc_set_alignment(GTK_MISC(proxy_description_label), 0, 0); |  | 
|   398   gtk_box_pack_start(GTK_BOX(page_), proxy_description_label, |  | 
|   399                      FALSE, FALSE, 0); |  | 
|   400  |  | 
|   401   change_proxies_button_ = gtk_button_new_with_label( |  | 
|   402       l10n_util::GetStringUTF8( |  | 
|   403           IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON).c_str()); |  | 
|   404   g_signal_connect(change_proxies_button_, "clicked", |  | 
|   405                    G_CALLBACK(OnChangeProxiesButtonClicked), this); |  | 
|   406  |  | 
|   407   // Stick it in an hbox so it doesn't expand to the whole width. |  | 
|   408   GtkWidget* button_hbox = gtk_hbox_new(FALSE, 0); |  | 
|   409   gtk_box_pack_start(GTK_BOX(button_hbox), |  | 
|   410                      change_proxies_button_, |  | 
|   411                      FALSE, FALSE, 0); |  | 
|   412   gtk_box_pack_start(GTK_BOX(page_), |  | 
|   413                      gtk_util::IndentWidget(button_hbox), |  | 
|   414                      FALSE, FALSE, 0); |  | 
|   415  |  | 
|   416   proxy_prefs_.reset(PrefSetObserver::CreateProxyPrefSetObserver( |  | 
|   417       profile->GetPrefs(), this)); |  | 
|   418   NotifyPrefChanged(NULL); |  | 
|   419 } |  | 
|   420  |  | 
|   421 void NetworkSection::NotifyPrefChanged(const std::string* pref_name) { |  | 
|   422   if (!pref_name || proxy_prefs_->IsObserved(*pref_name)) |  | 
|   423     gtk_widget_set_sensitive(change_proxies_button_, |  | 
|   424                              !proxy_prefs_->IsManaged()); |  | 
|   425 } |  | 
|   426  |  | 
|   427 // static |  | 
|   428 void NetworkSection::DetectAndStartProxyConfigUtil(Profile* profile) { |  | 
|   429   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |  | 
|   430   scoped_ptr<base::Environment> env(base::Environment::Create()); |  | 
|   431  |  | 
|   432   ProxyConfigCommand command; |  | 
|   433   bool found_command = false; |  | 
|   434   switch (base::nix::GetDesktopEnvironment(env.get())) { |  | 
|   435     case base::nix::DESKTOP_ENVIRONMENT_GNOME: { |  | 
|   436       size_t index; |  | 
|   437       ProxyConfigCommand commands[2]; |  | 
|   438       commands[0].argv = kGNOMEProxyConfigCommand; |  | 
|   439       commands[1].argv = kOldGNOMEProxyConfigCommand; |  | 
|   440       found_command = SearchPATH(commands, 2, &index); |  | 
|   441       if (found_command) |  | 
|   442         command = commands[index]; |  | 
|   443       break; |  | 
|   444     } |  | 
|   445  |  | 
|   446     case base::nix::DESKTOP_ENVIRONMENT_KDE3: |  | 
|   447       command.argv = kKDE3ProxyConfigCommand; |  | 
|   448       found_command = SearchPATH(&command, 1, NULL); |  | 
|   449       break; |  | 
|   450  |  | 
|   451     case base::nix::DESKTOP_ENVIRONMENT_KDE4: |  | 
|   452       command.argv = kKDE4ProxyConfigCommand; |  | 
|   453       found_command = SearchPATH(&command, 1, NULL); |  | 
|   454       break; |  | 
|   455  |  | 
|   456     case base::nix::DESKTOP_ENVIRONMENT_XFCE: |  | 
|   457     case base::nix::DESKTOP_ENVIRONMENT_OTHER: |  | 
|   458       break; |  | 
|   459   } |  | 
|   460  |  | 
|   461   if (found_command) { |  | 
|   462     StartProxyConfigUtil(profile, command); |  | 
|   463   } else { |  | 
|   464     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |  | 
|   465         NewRunnableFunction(&NetworkSection::ShowLinuxProxyConfigUrl, profile)); |  | 
|   466   } |  | 
|   467 } |  | 
|   468  |  | 
|   469 // static |  | 
|   470 void NetworkSection::ShowLinuxProxyConfigUrl(Profile* profile) { |  | 
|   471   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |  | 
|   472   scoped_ptr<base::Environment> env(base::Environment::Create()); |  | 
|   473   const char* name = base::nix::GetDesktopEnvironmentName(env.get()); |  | 
|   474   if (name) |  | 
|   475     LOG(ERROR) << "Could not find " << name << " network settings in $PATH"; |  | 
|   476   browser::ShowOptionsURL(profile, GURL(kLinuxProxyConfigUrl)); |  | 
|   477 } |  | 
|   478  |  | 
|   479 // static |  | 
|   480 void NetworkSection::OnChangeProxiesButtonClicked(GtkButton *button, |  | 
|   481                                                   NetworkSection* section) { |  | 
|   482   section->UserMetricsRecordAction(UserMetricsAction("Options_ChangeProxies"), |  | 
|   483                                    NULL); |  | 
|   484   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |  | 
|   485       NewRunnableFunction(&NetworkSection::DetectAndStartProxyConfigUtil, |  | 
|   486                           section->profile())); |  | 
|   487 } |  | 
|   488  |  | 
|   489 // static |  | 
|   490 bool NetworkSection::SearchPATH(ProxyConfigCommand* commands, size_t ncommands, |  | 
|   491                                 size_t* index) { |  | 
|   492   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |  | 
|   493   const char* path = getenv("PATH"); |  | 
|   494   if (!path) |  | 
|   495     return false; |  | 
|   496   FilePath bin_path; |  | 
|   497   CStringTokenizer tk(path, path + strlen(path), ":"); |  | 
|   498   // Search $PATH looking for the commands in order. |  | 
|   499   while (tk.GetNext()) { |  | 
|   500     for (size_t i = 0; i < ncommands; i++) { |  | 
|   501       bin_path = FilePath(tk.token()).Append(commands[i].argv[0]); |  | 
|   502       if (file_util::PathExists(bin_path)) { |  | 
|   503         commands[i].binary = bin_path.value(); |  | 
|   504         if (index) |  | 
|   505           *index = i; |  | 
|   506         return true; |  | 
|   507       } |  | 
|   508     } |  | 
|   509   } |  | 
|   510   // Did not find any of the binaries in $PATH. |  | 
|   511   return false; |  | 
|   512 } |  | 
|   513  |  | 
|   514 // static |  | 
|   515 void NetworkSection::StartProxyConfigUtil(Profile* profile, |  | 
|   516                                           const ProxyConfigCommand& command) { |  | 
|   517   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |  | 
|   518   std::vector<std::string> argv; |  | 
|   519   argv.push_back(command.binary); |  | 
|   520   for (size_t i = 1; command.argv[i]; i++) |  | 
|   521     argv.push_back(command.argv[i]); |  | 
|   522   base::file_handle_mapping_vector no_files; |  | 
|   523   base::ProcessHandle handle; |  | 
|   524   if (!base::LaunchApp(argv, no_files, false, &handle)) { |  | 
|   525     LOG(ERROR) << "StartProxyConfigUtil failed to start " << command.binary; |  | 
|   526     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |  | 
|   527         NewRunnableFunction(&NetworkSection::ShowLinuxProxyConfigUrl, profile)); |  | 
|   528     return; |  | 
|   529   } |  | 
|   530   ProcessWatcher::EnsureProcessGetsReaped(handle); |  | 
|   531 } |  | 
|   532  |  | 
|   533 /////////////////////////////////////////////////////////////////////////////// |  | 
|   534 // TranslateSection |  | 
|   535  |  | 
|   536 class TranslateSection : public OptionsPageBase { |  | 
|   537  public: |  | 
|   538   explicit TranslateSection(Profile* profile); |  | 
|   539   virtual ~TranslateSection() {} |  | 
|   540  |  | 
|   541   GtkWidget* get_page_widget() const { |  | 
|   542     return page_; |  | 
|   543   } |  | 
|   544  |  | 
|   545  private: |  | 
|   546   // Overridden from OptionsPageBase. |  | 
|   547   virtual void NotifyPrefChanged(const std::string* pref_name); |  | 
|   548  |  | 
|   549   CHROMEGTK_CALLBACK_0(TranslateSection, void, OnTranslateClicked); |  | 
|   550  |  | 
|   551   // Preferences for this section: |  | 
|   552   BooleanPrefMember enable_translate_; |  | 
|   553  |  | 
|   554   // The widget containing the options for this section. |  | 
|   555   GtkWidget* page_; |  | 
|   556  |  | 
|   557   // The checkbox. |  | 
|   558   GtkWidget* translate_checkbox_; |  | 
|   559  |  | 
|   560   // Flag to ignore gtk callbacks while we are loading prefs, to avoid |  | 
|   561   // then turning around and saving them again. |  | 
|   562   bool pref_changing_; |  | 
|   563  |  | 
|   564   scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_; |  | 
|   565  |  | 
|   566   DISALLOW_COPY_AND_ASSIGN(TranslateSection); |  | 
|   567 }; |  | 
|   568  |  | 
|   569 TranslateSection::TranslateSection(Profile* profile) |  | 
|   570     : OptionsPageBase(profile), |  | 
|   571       pref_changing_(true) { |  | 
|   572   page_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |  | 
|   573  |  | 
|   574   accessible_widget_helper_.reset(new AccessibleWidgetHelper( |  | 
|   575       page_, profile)); |  | 
|   576  |  | 
|   577   translate_checkbox_ = CreateCheckButtonWithWrappedLabel( |  | 
|   578       IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE); |  | 
|   579   gtk_box_pack_start(GTK_BOX(page_), translate_checkbox_, |  | 
|   580                      FALSE, FALSE, 0); |  | 
|   581   g_signal_connect(translate_checkbox_, "clicked", |  | 
|   582                    G_CALLBACK(OnTranslateClickedThunk), this); |  | 
|   583   accessible_widget_helper_->SetWidgetName( |  | 
|   584       translate_checkbox_, |  | 
|   585       IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE); |  | 
|   586  |  | 
|   587   // Init member prefs so we can update the controls if prefs change. |  | 
|   588   enable_translate_.Init(prefs::kEnableTranslate, profile->GetPrefs(), this); |  | 
|   589  |  | 
|   590   NotifyPrefChanged(NULL); |  | 
|   591 } |  | 
|   592  |  | 
|   593 void TranslateSection::NotifyPrefChanged(const std::string* pref_name) { |  | 
|   594   pref_changing_ = true; |  | 
|   595   if (!pref_name || *pref_name == prefs::kEnableTranslate) { |  | 
|   596     gtk_toggle_button_set_active( |  | 
|   597         GTK_TOGGLE_BUTTON(translate_checkbox_), enable_translate_.GetValue()); |  | 
|   598   } |  | 
|   599   pref_changing_ = false; |  | 
|   600 } |  | 
|   601  |  | 
|   602 void TranslateSection::OnTranslateClicked(GtkWidget* widget) { |  | 
|   603   if (pref_changing_) |  | 
|   604     return; |  | 
|   605   bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); |  | 
|   606   UserMetricsRecordAction( |  | 
|   607       enabled ? |  | 
|   608       UserMetricsAction("Options_Translate_Enable") : |  | 
|   609       UserMetricsAction("Options_Translate_Disable"), |  | 
|   610       profile()->GetPrefs()); |  | 
|   611   enable_translate_.SetValue(enabled); |  | 
|   612 } |  | 
|   613  |  | 
|   614 /////////////////////////////////////////////////////////////////////////////// |  | 
|   615 // PrivacySection |  | 
|   616  |  | 
|   617 class PrivacySection : public OptionsPageBase { |  | 
|   618  public: |  | 
|   619   explicit PrivacySection(Profile* profile); |  | 
|   620   virtual ~PrivacySection() {} |  | 
|   621  |  | 
|   622   GtkWidget* get_page_widget() const { |  | 
|   623     return page_; |  | 
|   624   } |  | 
|   625  |  | 
|   626  private: |  | 
|   627   // Overridden from OptionsPageBase. |  | 
|   628   virtual void NotifyPrefChanged(const std::string* pref_name); |  | 
|   629  |  | 
|   630   // Try to make the the crash stats consent and the metrics upload |  | 
|   631   // permission match the |reporting_enabled_checkbox_|. |  | 
|   632   void ResolveMetricsReportingEnabled(); |  | 
|   633  |  | 
|   634   // The callback functions for the options widgets. |  | 
|   635   static void OnContentSettingsClicked(GtkButton* button, |  | 
|   636                                        PrivacySection* privacy_section); |  | 
|   637   static void OnClearBrowsingDataButtonClicked(GtkButton* widget, |  | 
|   638                                                PrivacySection* page); |  | 
|   639   static void OnLearnMoreLinkClicked(GtkButton *button, |  | 
|   640                                      PrivacySection* privacy_section); |  | 
|   641   static void OnEnableLinkDoctorChange(GtkWidget* widget, |  | 
|   642                                        PrivacySection* options_window); |  | 
|   643   static void OnEnableSuggestChange(GtkWidget* widget, |  | 
|   644                                     PrivacySection* options_window); |  | 
|   645   static void OnDNSPrefetchingChange(GtkWidget* widget, |  | 
|   646                                      PrivacySection* options_window); |  | 
|   647   static void OnSafeBrowsingChange(GtkWidget* widget, |  | 
|   648                                    PrivacySection* options_window); |  | 
|   649   static void OnLoggingChange(GtkWidget* widget, |  | 
|   650                               PrivacySection* options_window); |  | 
|   651  |  | 
|   652   // The widget containing the options for this section. |  | 
|   653   GtkWidget* page_; |  | 
|   654  |  | 
|   655   // The widgets for the privacy options. |  | 
|   656   GtkWidget* enable_link_doctor_checkbox_; |  | 
|   657   GtkWidget* enable_suggest_checkbox_; |  | 
|   658   GtkWidget* enable_dns_prefetching_checkbox_; |  | 
|   659   GtkWidget* enable_safe_browsing_checkbox_; |  | 
|   660 #if defined(GOOGLE_CHROME_BUILD) |  | 
|   661   GtkWidget* reporting_enabled_checkbox_; |  | 
|   662 #endif |  | 
|   663  |  | 
|   664   // Preferences for this section: |  | 
|   665   BooleanPrefMember alternate_error_pages_; |  | 
|   666   BooleanPrefMember use_suggest_; |  | 
|   667   BooleanPrefMember dns_prefetch_enabled_; |  | 
|   668   BooleanPrefMember safe_browsing_; |  | 
|   669   BooleanPrefMember enable_metrics_recording_; |  | 
|   670  |  | 
|   671   // Flag to ignore gtk callbacks while we are loading prefs, to avoid |  | 
|   672   // then turning around and saving them again. |  | 
|   673   bool pref_changing_; |  | 
|   674  |  | 
|   675   scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_; |  | 
|   676  |  | 
|   677   DISALLOW_COPY_AND_ASSIGN(PrivacySection); |  | 
|   678 }; |  | 
|   679  |  | 
|   680 PrivacySection::PrivacySection(Profile* profile) |  | 
|   681     : OptionsPageBase(profile), |  | 
|   682       pref_changing_(true) { |  | 
|   683   page_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |  | 
|   684  |  | 
|   685   accessible_widget_helper_.reset(new AccessibleWidgetHelper( |  | 
|   686       page_, profile)); |  | 
|   687  |  | 
|   688   GtkWidget* content_button = gtk_button_new_with_label( |  | 
|   689       l10n_util::GetStringUTF8( |  | 
|   690           IDS_OPTIONS_PRIVACY_CONTENT_SETTINGS_BUTTON).c_str()); |  | 
|   691   g_signal_connect(content_button, "clicked", |  | 
|   692                    G_CALLBACK(OnContentSettingsClicked), this); |  | 
|   693  |  | 
|   694   GtkWidget* clear_data_button = gtk_button_new_with_label( |  | 
|   695       l10n_util::GetStringUTF8(IDS_OPTIONS_PRIVACY_CLEAR_DATA_BUTTON).c_str()); |  | 
|   696   g_signal_connect(clear_data_button, "clicked", |  | 
|   697                    G_CALLBACK(OnClearBrowsingDataButtonClicked), this); |  | 
|   698  |  | 
|   699   // Stick it in an hbox so it doesn't expand to the whole width. |  | 
|   700   GtkWidget* button_hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing); |  | 
|   701   gtk_box_pack_start(GTK_BOX(button_hbox), content_button, FALSE, FALSE, 0); |  | 
|   702   gtk_box_pack_start(GTK_BOX(button_hbox), clear_data_button, FALSE, FALSE, 0); |  | 
|   703   gtk_box_pack_start(GTK_BOX(page_), gtk_util::IndentWidget(button_hbox), |  | 
|   704                      FALSE, FALSE, 0); |  | 
|   705  |  | 
|   706   GtkWidget* section_description_label = CreateWrappedLabel( |  | 
|   707       IDS_OPTIONS_DISABLE_SERVICES); |  | 
|   708   gtk_misc_set_alignment(GTK_MISC(section_description_label), 0, 0); |  | 
|   709   gtk_box_pack_start(GTK_BOX(page_), section_description_label, |  | 
|   710                      FALSE, FALSE, 0); |  | 
|   711  |  | 
|   712   GtkWidget* learn_more_link = gtk_chrome_link_button_new( |  | 
|   713       l10n_util::GetStringUTF8(IDS_LEARN_MORE).c_str()); |  | 
|   714   // Stick it in an hbox so it doesn't expand to the whole width. |  | 
|   715   GtkWidget* learn_more_hbox = gtk_hbox_new(FALSE, 0); |  | 
|   716   gtk_box_pack_start(GTK_BOX(learn_more_hbox), learn_more_link, |  | 
|   717                      FALSE, FALSE, 0); |  | 
|   718   gtk_box_pack_start(GTK_BOX(page_), learn_more_hbox, |  | 
|   719                      FALSE, FALSE, 0); |  | 
|   720   g_signal_connect(learn_more_link, "clicked", |  | 
|   721                    G_CALLBACK(OnLearnMoreLinkClicked), this); |  | 
|   722  |  | 
|   723   enable_link_doctor_checkbox_ = CreateCheckButtonWithWrappedLabel( |  | 
|   724       IDS_OPTIONS_LINKDOCTOR_PREF); |  | 
|   725   gtk_box_pack_start(GTK_BOX(page_), enable_link_doctor_checkbox_, |  | 
|   726                      FALSE, FALSE, 0); |  | 
|   727   g_signal_connect(enable_link_doctor_checkbox_, "clicked", |  | 
|   728                    G_CALLBACK(OnEnableLinkDoctorChange), this); |  | 
|   729   accessible_widget_helper_->SetWidgetName( |  | 
|   730       enable_link_doctor_checkbox_, IDS_OPTIONS_LINKDOCTOR_PREF); |  | 
|   731  |  | 
|   732   enable_suggest_checkbox_ = CreateCheckButtonWithWrappedLabel( |  | 
|   733       IDS_OPTIONS_SUGGEST_PREF); |  | 
|   734   gtk_box_pack_start(GTK_BOX(page_), enable_suggest_checkbox_, |  | 
|   735                      FALSE, FALSE, 0); |  | 
|   736   g_signal_connect(enable_suggest_checkbox_, "clicked", |  | 
|   737                    G_CALLBACK(OnEnableSuggestChange), this); |  | 
|   738   accessible_widget_helper_->SetWidgetName( |  | 
|   739       enable_suggest_checkbox_, IDS_OPTIONS_SUGGEST_PREF); |  | 
|   740  |  | 
|   741   enable_dns_prefetching_checkbox_ = CreateCheckButtonWithWrappedLabel( |  | 
|   742       IDS_NETWORK_DNS_PREFETCH_ENABLED_DESCRIPTION); |  | 
|   743   gtk_box_pack_start(GTK_BOX(page_), enable_dns_prefetching_checkbox_, |  | 
|   744                      FALSE, FALSE, 0); |  | 
|   745   g_signal_connect(enable_dns_prefetching_checkbox_, "clicked", |  | 
|   746                    G_CALLBACK(OnDNSPrefetchingChange), this); |  | 
|   747   accessible_widget_helper_->SetWidgetName( |  | 
|   748       enable_dns_prefetching_checkbox_, |  | 
|   749       IDS_NETWORK_DNS_PREFETCH_ENABLED_DESCRIPTION); |  | 
|   750  |  | 
|   751   enable_safe_browsing_checkbox_ = CreateCheckButtonWithWrappedLabel( |  | 
|   752       IDS_OPTIONS_SAFEBROWSING_ENABLEPROTECTION); |  | 
|   753   gtk_box_pack_start(GTK_BOX(page_), enable_safe_browsing_checkbox_, |  | 
|   754                      FALSE, FALSE, 0); |  | 
|   755   g_signal_connect(enable_safe_browsing_checkbox_, "clicked", |  | 
|   756                    G_CALLBACK(OnSafeBrowsingChange), this); |  | 
|   757   accessible_widget_helper_->SetWidgetName( |  | 
|   758       enable_safe_browsing_checkbox_, |  | 
|   759       IDS_OPTIONS_SAFEBROWSING_ENABLEPROTECTION); |  | 
|   760  |  | 
|   761 #if defined(GOOGLE_CHROME_BUILD) |  | 
|   762   reporting_enabled_checkbox_ = CreateCheckButtonWithWrappedLabel( |  | 
|   763       IDS_OPTIONS_ENABLE_LOGGING); |  | 
|   764   gtk_box_pack_start(GTK_BOX(page_), reporting_enabled_checkbox_, |  | 
|   765                      FALSE, FALSE, 0); |  | 
|   766   g_signal_connect(reporting_enabled_checkbox_, "clicked", |  | 
|   767                    G_CALLBACK(OnLoggingChange), this); |  | 
|   768   accessible_widget_helper_->SetWidgetName( |  | 
|   769       reporting_enabled_checkbox_, IDS_OPTIONS_ENABLE_LOGGING); |  | 
|   770 #endif |  | 
|   771  |  | 
|   772   // Init member prefs so we can update the controls if prefs change. |  | 
|   773   alternate_error_pages_.Init(prefs::kAlternateErrorPagesEnabled, |  | 
|   774                               profile->GetPrefs(), this); |  | 
|   775   use_suggest_.Init(prefs::kSearchSuggestEnabled, |  | 
|   776                     profile->GetPrefs(), this); |  | 
|   777   dns_prefetch_enabled_.Init(prefs::kDnsPrefetchingEnabled, |  | 
|   778                              profile->GetPrefs(), this); |  | 
|   779   safe_browsing_.Init(prefs::kSafeBrowsingEnabled, profile->GetPrefs(), this); |  | 
|   780   enable_metrics_recording_.Init(prefs::kMetricsReportingEnabled, |  | 
|   781                                  g_browser_process->local_state(), this); |  | 
|   782   NotifyPrefChanged(NULL); |  | 
|   783 } |  | 
|   784  |  | 
|   785 // static |  | 
|   786 void PrivacySection::OnContentSettingsClicked(GtkButton* button, |  | 
|   787                                               PrivacySection* privacy_section) { |  | 
|   788   ContentSettingsWindowGtk::Show( |  | 
|   789       GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))), |  | 
|   790       CONTENT_SETTINGS_TYPE_DEFAULT, |  | 
|   791       privacy_section->profile()); |  | 
|   792 } |  | 
|   793  |  | 
|   794 // static |  | 
|   795 void PrivacySection::OnClearBrowsingDataButtonClicked(GtkButton* widget, |  | 
|   796                                                       PrivacySection* section) { |  | 
|   797   ClearBrowsingDataDialogGtk::Show( |  | 
|   798       GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(widget))), |  | 
|   799       section->profile()); |  | 
|   800 } |  | 
|   801  |  | 
|   802 // static |  | 
|   803 void PrivacySection::OnLearnMoreLinkClicked(GtkButton *button, |  | 
|   804                                             PrivacySection* privacy_section) { |  | 
|   805   GURL url = google_util::AppendGoogleLocaleParam( |  | 
|   806       GURL(chrome::kPrivacyLearnMoreURL)); |  | 
|   807   browser::ShowOptionsURL(privacy_section->profile(), url); |  | 
|   808 } |  | 
|   809  |  | 
|   810 // static |  | 
|   811 void PrivacySection::OnEnableLinkDoctorChange(GtkWidget* widget, |  | 
|   812                                               PrivacySection* privacy_section) { |  | 
|   813   if (privacy_section->pref_changing_) |  | 
|   814     return; |  | 
|   815   bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); |  | 
|   816   privacy_section->UserMetricsRecordAction( |  | 
|   817       enabled ? |  | 
|   818           UserMetricsAction("Options_LinkDoctorCheckbox_Enable") : |  | 
|   819           UserMetricsAction("Options_LinkDoctorCheckbox_Disable"), |  | 
|   820       privacy_section->profile()->GetPrefs()); |  | 
|   821   privacy_section->alternate_error_pages_.SetValue(enabled); |  | 
|   822 } |  | 
|   823  |  | 
|   824 // static |  | 
|   825 void PrivacySection::OnEnableSuggestChange(GtkWidget* widget, |  | 
|   826                                            PrivacySection* privacy_section) { |  | 
|   827   if (privacy_section->pref_changing_) |  | 
|   828     return; |  | 
|   829   bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); |  | 
|   830   privacy_section->UserMetricsRecordAction( |  | 
|   831       enabled ? |  | 
|   832           UserMetricsAction("Options_UseSuggestCheckbox_Enable") : |  | 
|   833           UserMetricsAction("Options_UseSuggestCheckbox_Disable"), |  | 
|   834       privacy_section->profile()->GetPrefs()); |  | 
|   835   privacy_section->use_suggest_.SetValue(enabled); |  | 
|   836 } |  | 
|   837  |  | 
|   838 // static |  | 
|   839 void PrivacySection::OnDNSPrefetchingChange(GtkWidget* widget, |  | 
|   840                                            PrivacySection* privacy_section) { |  | 
|   841   if (privacy_section->pref_changing_) |  | 
|   842     return; |  | 
|   843   bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); |  | 
|   844   privacy_section->UserMetricsRecordAction( |  | 
|   845       enabled ? |  | 
|   846           UserMetricsAction("Options_DnsPrefetchCheckbox_Enable") : |  | 
|   847           UserMetricsAction("Options_DnsPrefetchCheckbox_Disable"), |  | 
|   848       privacy_section->profile()->GetPrefs()); |  | 
|   849   privacy_section->dns_prefetch_enabled_.SetValue(enabled); |  | 
|   850 } |  | 
|   851  |  | 
|   852 // static |  | 
|   853 void PrivacySection::OnSafeBrowsingChange(GtkWidget* widget, |  | 
|   854                                           PrivacySection* privacy_section) { |  | 
|   855   if (privacy_section->pref_changing_) |  | 
|   856     return; |  | 
|   857   bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); |  | 
|   858   privacy_section->UserMetricsRecordAction( |  | 
|   859       enabled ? |  | 
|   860           UserMetricsAction("Options_SafeBrowsingCheckbox_Enable") : |  | 
|   861           UserMetricsAction("Options_SafeBrowsingCheckbox_Disable"), |  | 
|   862       privacy_section->profile()->GetPrefs()); |  | 
|   863   privacy_section->safe_browsing_.SetValue(enabled); |  | 
|   864   SafeBrowsingService* safe_browsing_service = |  | 
|   865       g_browser_process->resource_dispatcher_host()->safe_browsing_service(); |  | 
|   866   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |  | 
|   867       safe_browsing_service, &SafeBrowsingService::OnEnable, enabled)); |  | 
|   868 } |  | 
|   869  |  | 
|   870 // static |  | 
|   871 void PrivacySection::OnLoggingChange(GtkWidget* widget, |  | 
|   872                                      PrivacySection* privacy_section) { |  | 
|   873   if (privacy_section->pref_changing_) |  | 
|   874     return; |  | 
|   875   bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); |  | 
|   876   privacy_section->UserMetricsRecordAction( |  | 
|   877       enabled ? |  | 
|   878           UserMetricsAction("Options_MetricsReportingCheckbox_Enable") : |  | 
|   879           UserMetricsAction("Options_MetricsReportingCheckbox_Disable"), |  | 
|   880       privacy_section->profile()->GetPrefs()); |  | 
|   881   // Prevent us from being called again by ResolveMetricsReportingEnabled |  | 
|   882   // resetting the checkbox if there was a problem. |  | 
|   883   g_signal_handlers_block_by_func(widget, |  | 
|   884                                   reinterpret_cast<gpointer>(OnLoggingChange), |  | 
|   885                                   privacy_section); |  | 
|   886   privacy_section->ResolveMetricsReportingEnabled(); |  | 
|   887   g_signal_handlers_unblock_by_func(widget, |  | 
|   888                                     reinterpret_cast<gpointer>(OnLoggingChange), |  | 
|   889                                     privacy_section); |  | 
|   890   privacy_section->enable_metrics_recording_.SetValue(enabled); |  | 
|   891 } |  | 
|   892  |  | 
|   893 void PrivacySection::NotifyPrefChanged(const std::string* pref_name) { |  | 
|   894   pref_changing_ = true; |  | 
|   895   if (!pref_name || *pref_name == prefs::kAlternateErrorPagesEnabled) { |  | 
|   896     gtk_widget_set_sensitive( |  | 
|   897         GTK_WIDGET(enable_link_doctor_checkbox_), |  | 
|   898         !alternate_error_pages_.IsManaged()); |  | 
|   899     gtk_toggle_button_set_active( |  | 
|   900         GTK_TOGGLE_BUTTON(enable_link_doctor_checkbox_), |  | 
|   901         alternate_error_pages_.GetValue()); |  | 
|   902   } |  | 
|   903   if (!pref_name || *pref_name == prefs::kSearchSuggestEnabled) { |  | 
|   904     gtk_widget_set_sensitive( |  | 
|   905         GTK_WIDGET(enable_suggest_checkbox_), |  | 
|   906         !use_suggest_.IsManaged()); |  | 
|   907     gtk_toggle_button_set_active( |  | 
|   908         GTK_TOGGLE_BUTTON(enable_suggest_checkbox_), |  | 
|   909         use_suggest_.GetValue()); |  | 
|   910   } |  | 
|   911   if (!pref_name || *pref_name == prefs::kDnsPrefetchingEnabled) { |  | 
|   912     gtk_widget_set_sensitive( |  | 
|   913         GTK_WIDGET(enable_dns_prefetching_checkbox_), |  | 
|   914         !dns_prefetch_enabled_.IsManaged()); |  | 
|   915     bool enabled = dns_prefetch_enabled_.GetValue(); |  | 
|   916     gtk_toggle_button_set_active( |  | 
|   917         GTK_TOGGLE_BUTTON(enable_dns_prefetching_checkbox_), enabled); |  | 
|   918   } |  | 
|   919   if (!pref_name || *pref_name == prefs::kSafeBrowsingEnabled) { |  | 
|   920     gtk_widget_set_sensitive( |  | 
|   921         GTK_WIDGET(enable_safe_browsing_checkbox_), |  | 
|   922         !safe_browsing_.IsManaged()); |  | 
|   923     gtk_toggle_button_set_active( |  | 
|   924         GTK_TOGGLE_BUTTON(enable_safe_browsing_checkbox_), |  | 
|   925         safe_browsing_.GetValue()); |  | 
|   926   } |  | 
|   927 #if defined(GOOGLE_CHROME_BUILD) |  | 
|   928   if (!pref_name || *pref_name == prefs::kMetricsReportingEnabled) { |  | 
|   929     gtk_widget_set_sensitive( |  | 
|   930         GTK_WIDGET(reporting_enabled_checkbox_), |  | 
|   931         !enable_metrics_recording_.IsManaged()); |  | 
|   932     gtk_toggle_button_set_active( |  | 
|   933         GTK_TOGGLE_BUTTON(reporting_enabled_checkbox_), |  | 
|   934         enable_metrics_recording_.GetValue()); |  | 
|   935     ResolveMetricsReportingEnabled(); |  | 
|   936   } |  | 
|   937 #endif |  | 
|   938   pref_changing_ = false; |  | 
|   939 } |  | 
|   940  |  | 
|   941 void PrivacySection::ResolveMetricsReportingEnabled() { |  | 
|   942 #if defined(GOOGLE_CHROME_BUILD) |  | 
|   943   bool enabled = gtk_toggle_button_get_active( |  | 
|   944       GTK_TOGGLE_BUTTON(reporting_enabled_checkbox_)); |  | 
|   945  |  | 
|   946   enabled = OptionsUtil::ResolveMetricsReportingEnabled(enabled); |  | 
|   947  |  | 
|   948   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(reporting_enabled_checkbox_), |  | 
|   949                                enabled); |  | 
|   950 #endif |  | 
|   951 } |  | 
|   952  |  | 
|   953 /////////////////////////////////////////////////////////////////////////////// |  | 
|   954 // SecuritySection |  | 
|   955  |  | 
|   956 class SecuritySection : public OptionsPageBase { |  | 
|   957  public: |  | 
|   958   explicit SecuritySection(Profile* profile); |  | 
|   959   virtual ~SecuritySection() {} |  | 
|   960  |  | 
|   961   GtkWidget* get_page_widget() const { |  | 
|   962     return page_; |  | 
|   963   } |  | 
|   964  |  | 
|   965  private: |  | 
|   966   // Overridden from OptionsPageBase. |  | 
|   967   virtual void NotifyPrefChanged(const std::string* pref_name); |  | 
|   968  |  | 
|   969   // The callback functions for the options widgets. |  | 
|   970   static void OnManageCertificatesClicked(GtkButton* button, |  | 
|   971                                           SecuritySection* section); |  | 
|   972   static void OnRevCheckingEnabledToggled(GtkToggleButton* togglebutton, |  | 
|   973                                           SecuritySection* section); |  | 
|   974   static void OnSSL3EnabledToggled(GtkToggleButton* togglebutton, |  | 
|   975                                    SecuritySection* section); |  | 
|   976   static void OnTLS1EnabledToggled(GtkToggleButton* togglebutton, |  | 
|   977                                    SecuritySection* section); |  | 
|   978  |  | 
|   979   // The widget containing the options for this section. |  | 
|   980   GtkWidget* page_; |  | 
|   981   GtkWidget* rev_checking_enabled_checkbox_; |  | 
|   982   GtkWidget* ssl3_enabled_checkbox_; |  | 
|   983   GtkWidget* tls1_enabled_checkbox_; |  | 
|   984  |  | 
|   985   // SSLConfigService prefs. |  | 
|   986   BooleanPrefMember rev_checking_enabled_; |  | 
|   987   BooleanPrefMember ssl3_enabled_; |  | 
|   988   BooleanPrefMember tls1_enabled_; |  | 
|   989  |  | 
|   990   // Flag to ignore gtk callbacks while we are loading prefs, to avoid |  | 
|   991   // then turning around and saving them again. |  | 
|   992   bool pref_changing_; |  | 
|   993  |  | 
|   994   scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_; |  | 
|   995  |  | 
|   996   DISALLOW_COPY_AND_ASSIGN(SecuritySection); |  | 
|   997 }; |  | 
|   998  |  | 
|   999 SecuritySection::SecuritySection(Profile* profile) |  | 
|  1000     : OptionsPageBase(profile), |  | 
|  1001       pref_changing_(true) { |  | 
|  1002   page_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |  | 
|  1003  |  | 
|  1004   accessible_widget_helper_.reset(new AccessibleWidgetHelper( |  | 
|  1005       page_, profile)); |  | 
|  1006  |  | 
|  1007   GtkWidget* manage_certificates_label = CreateWrappedLabel( |  | 
|  1008       IDS_OPTIONS_CERTIFICATES_LABEL); |  | 
|  1009   gtk_misc_set_alignment(GTK_MISC(manage_certificates_label), 0, 0); |  | 
|  1010   gtk_box_pack_start(GTK_BOX(page_), manage_certificates_label, |  | 
|  1011                      FALSE, FALSE, 0); |  | 
|  1012  |  | 
|  1013   // TODO(mattm): change this to a button to launch the system certificate |  | 
|  1014   // manager, when one exists. |  | 
|  1015   GtkWidget* manage_certificates_link = gtk_chrome_link_button_new( |  | 
|  1016       l10n_util::GetStringUTF8(IDS_OPTIONS_CERTIFICATES_MANAGE_BUTTON).c_str()); |  | 
|  1017   // Stick it in an hbox so it doesn't expand to the whole width. |  | 
|  1018   GtkWidget* manage_certificates_hbox = gtk_hbox_new(FALSE, 0); |  | 
|  1019   gtk_box_pack_start(GTK_BOX(manage_certificates_hbox), |  | 
|  1020                      manage_certificates_link, FALSE, FALSE, 0); |  | 
|  1021   gtk_box_pack_start(GTK_BOX(page_), |  | 
|  1022                      gtk_util::IndentWidget(manage_certificates_hbox), |  | 
|  1023                      FALSE, FALSE, 0); |  | 
|  1024   g_signal_connect(manage_certificates_link, "clicked", |  | 
|  1025                    G_CALLBACK(OnManageCertificatesClicked), this); |  | 
|  1026  |  | 
|  1027   // TODO(mattm): should have a description label here and have the checkboxes |  | 
|  1028   // indented, but IDS_OPTIONS_SSL_GROUP_DESCRIPTION isn't appropriate and |  | 
|  1029   // didn't think of adding a Linux specific one before the string freeze. |  | 
|  1030   rev_checking_enabled_checkbox_ = AddCheckButtonWithWrappedLabel( |  | 
|  1031       IDS_OPTIONS_SSL_CHECKREVOCATION, page_, |  | 
|  1032       G_CALLBACK(OnRevCheckingEnabledToggled), this); |  | 
|  1033   accessible_widget_helper_->SetWidgetName( |  | 
|  1034       rev_checking_enabled_checkbox_, IDS_OPTIONS_SSL_CHECKREVOCATION); |  | 
|  1035   ssl3_enabled_checkbox_ = AddCheckButtonWithWrappedLabel( |  | 
|  1036       IDS_OPTIONS_SSL_USESSL3, page_, G_CALLBACK(OnSSL3EnabledToggled), this); |  | 
|  1037   accessible_widget_helper_->SetWidgetName( |  | 
|  1038       ssl3_enabled_checkbox_, IDS_OPTIONS_SSL_USESSL3); |  | 
|  1039   tls1_enabled_checkbox_ = AddCheckButtonWithWrappedLabel( |  | 
|  1040       IDS_OPTIONS_SSL_USETLS1, page_, G_CALLBACK(OnTLS1EnabledToggled), this); |  | 
|  1041   accessible_widget_helper_->SetWidgetName( |  | 
|  1042       tls1_enabled_checkbox_, IDS_OPTIONS_SSL_USETLS1); |  | 
|  1043  |  | 
|  1044   rev_checking_enabled_.Init(prefs::kCertRevocationCheckingEnabled, |  | 
|  1045                              profile->GetPrefs(), this); |  | 
|  1046   ssl3_enabled_.Init(prefs::kSSL3Enabled, profile->GetPrefs(), this); |  | 
|  1047   tls1_enabled_.Init(prefs::kTLS1Enabled, profile->GetPrefs(), this); |  | 
|  1048  |  | 
|  1049   NotifyPrefChanged(NULL); |  | 
|  1050 } |  | 
|  1051  |  | 
|  1052 void SecuritySection::NotifyPrefChanged(const std::string* pref_name) { |  | 
|  1053   pref_changing_ = true; |  | 
|  1054   if (!pref_name || *pref_name == prefs::kCertRevocationCheckingEnabled) { |  | 
|  1055     gtk_toggle_button_set_active( |  | 
|  1056         GTK_TOGGLE_BUTTON(rev_checking_enabled_checkbox_), |  | 
|  1057         rev_checking_enabled_.GetValue()); |  | 
|  1058   } |  | 
|  1059   if (!pref_name || *pref_name == prefs::kSSL3Enabled) { |  | 
|  1060     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ssl3_enabled_checkbox_), |  | 
|  1061                                  ssl3_enabled_.GetValue()); |  | 
|  1062   } |  | 
|  1063   if (!pref_name || *pref_name == prefs::kTLS1Enabled) { |  | 
|  1064     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tls1_enabled_checkbox_), |  | 
|  1065                                  tls1_enabled_.GetValue()); |  | 
|  1066   } |  | 
|  1067   pref_changing_ = false; |  | 
|  1068 } |  | 
|  1069  |  | 
|  1070  |  | 
|  1071 // static |  | 
|  1072 void SecuritySection::OnManageCertificatesClicked(GtkButton* button, |  | 
|  1073                                                   SecuritySection* section) { |  | 
|  1074   browser::ShowOptionsURL(section->profile(), |  | 
|  1075                           GURL(kLinuxCertificatesConfigUrl)); |  | 
|  1076 } |  | 
|  1077  |  | 
|  1078 // static |  | 
|  1079 void SecuritySection::OnRevCheckingEnabledToggled(GtkToggleButton* togglebutton, |  | 
|  1080                                                   SecuritySection* section) { |  | 
|  1081   if (section->pref_changing_) |  | 
|  1082     return; |  | 
|  1083  |  | 
|  1084   bool enabled = gtk_toggle_button_get_active(togglebutton); |  | 
|  1085   if (enabled) { |  | 
|  1086     section->UserMetricsRecordAction( |  | 
|  1087         UserMetricsAction("Options_CheckCertRevocation_Enable"), |  | 
|  1088         NULL); |  | 
|  1089   } else { |  | 
|  1090     section->UserMetricsRecordAction( |  | 
|  1091         UserMetricsAction("Options_CheckCertRevocation_Disable"), |  | 
|  1092         NULL); |  | 
|  1093   } |  | 
|  1094   section->rev_checking_enabled_.SetValue(enabled); |  | 
|  1095 } |  | 
|  1096  |  | 
|  1097 // static |  | 
|  1098 void SecuritySection::OnSSL3EnabledToggled(GtkToggleButton* togglebutton, |  | 
|  1099                                            SecuritySection* section) { |  | 
|  1100   if (section->pref_changing_) |  | 
|  1101     return; |  | 
|  1102  |  | 
|  1103   bool enabled = gtk_toggle_button_get_active(togglebutton); |  | 
|  1104   if (enabled) { |  | 
|  1105     section->UserMetricsRecordAction(UserMetricsAction("Options_SSL3_Enable"), |  | 
|  1106                                      NULL); |  | 
|  1107   } else { |  | 
|  1108     section->UserMetricsRecordAction(UserMetricsAction("Options_SSL3_Disable"), |  | 
|  1109                                      NULL); |  | 
|  1110   } |  | 
|  1111   section->ssl3_enabled_.SetValue(enabled); |  | 
|  1112 } |  | 
|  1113  |  | 
|  1114 // static |  | 
|  1115 void SecuritySection::OnTLS1EnabledToggled(GtkToggleButton* togglebutton, |  | 
|  1116                                            SecuritySection* section) { |  | 
|  1117   if (section->pref_changing_) |  | 
|  1118     return; |  | 
|  1119  |  | 
|  1120   bool enabled = gtk_toggle_button_get_active(togglebutton); |  | 
|  1121   if (enabled) { |  | 
|  1122     section->UserMetricsRecordAction(UserMetricsAction("Options_TLS1_Enable"), |  | 
|  1123                                      NULL); |  | 
|  1124   } else { |  | 
|  1125     section->UserMetricsRecordAction(UserMetricsAction("Options_TLS1_Disable"), |  | 
|  1126                                      NULL); |  | 
|  1127   } |  | 
|  1128   section->tls1_enabled_.SetValue(enabled); |  | 
|  1129 } |  | 
|  1130  |  | 
|  1131 /////////////////////////////////////////////////////////////////////////////// |  | 
|  1132 // WebContentSection |  | 
|  1133  |  | 
|  1134 class WebContentSection : public OptionsPageBase { |  | 
|  1135  public: |  | 
|  1136   explicit WebContentSection(Profile* profile); |  | 
|  1137   virtual ~WebContentSection() {} |  | 
|  1138  |  | 
|  1139   GtkWidget* get_page_widget() const { |  | 
|  1140     return page_; |  | 
|  1141   } |  | 
|  1142  |  | 
|  1143  private: |  | 
|  1144   // The callback functions for the options widgets. |  | 
|  1145   static void OnFontsAndLanguagesButtonClicked(GtkButton *button, |  | 
|  1146                                                WebContentSection* section); |  | 
|  1147  |  | 
|  1148   // The widget containing the options for this section. |  | 
|  1149   GtkWidget* page_; |  | 
|  1150  |  | 
|  1151   DISALLOW_COPY_AND_ASSIGN(WebContentSection); |  | 
|  1152 }; |  | 
|  1153  |  | 
|  1154 WebContentSection::WebContentSection(Profile* profile) |  | 
|  1155     : OptionsPageBase(profile) { |  | 
|  1156   page_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |  | 
|  1157  |  | 
|  1158   GtkWidget* fonts_and_languages_label = CreateWrappedLabel( |  | 
|  1159       IDS_OPTIONS_FONTSETTINGS_INFO); |  | 
|  1160   gtk_misc_set_alignment(GTK_MISC(fonts_and_languages_label), 0, 0); |  | 
|  1161   gtk_box_pack_start(GTK_BOX(page_), fonts_and_languages_label, |  | 
|  1162                      FALSE, FALSE, 0); |  | 
|  1163  |  | 
|  1164   GtkWidget* fonts_and_languages_button = gtk_button_new_with_label( |  | 
|  1165       l10n_util::GetStringUTF8( |  | 
|  1166           IDS_OPTIONS_FONTSETTINGS_CONFIGUREFONTS_BUTTON).c_str()); |  | 
|  1167   g_signal_connect(fonts_and_languages_button, "clicked", |  | 
|  1168                    G_CALLBACK(OnFontsAndLanguagesButtonClicked), this); |  | 
|  1169   // Stick it in an hbox so it doesn't expand to the whole width. |  | 
|  1170   GtkWidget* button_hbox = gtk_hbox_new(FALSE, 0); |  | 
|  1171   gtk_box_pack_start(GTK_BOX(button_hbox), |  | 
|  1172                      fonts_and_languages_button, |  | 
|  1173                      FALSE, FALSE, 0); |  | 
|  1174   gtk_box_pack_start(GTK_BOX(page_), |  | 
|  1175                      gtk_util::IndentWidget(button_hbox), |  | 
|  1176                      FALSE, FALSE, 0); |  | 
|  1177  |  | 
|  1178   // TODO(mattm): gears options would go here if we supported gears |  | 
|  1179 } |  | 
|  1180  |  | 
|  1181 // static |  | 
|  1182 void WebContentSection::OnFontsAndLanguagesButtonClicked( |  | 
|  1183     GtkButton *button, WebContentSection* section) { |  | 
|  1184   ShowFontsLanguagesWindow(GTK_WINDOW(gtk_widget_get_toplevel(section->page_)), |  | 
|  1185                            FONTS_ENCODING_PAGE, |  | 
|  1186                            section->profile()); |  | 
|  1187 } |  | 
|  1188  |  | 
|  1189 /////////////////////////////////////////////////////////////////////////////// |  | 
|  1190 // AdvancedContentsGtk |  | 
|  1191  |  | 
|  1192 AdvancedContentsGtk::AdvancedContentsGtk(Profile* profile) |  | 
|  1193     : profile_(profile) { |  | 
|  1194   Init(); |  | 
|  1195 } |  | 
|  1196  |  | 
|  1197 AdvancedContentsGtk::~AdvancedContentsGtk() { |  | 
|  1198 } |  | 
|  1199  |  | 
|  1200 void AdvancedContentsGtk::Init() { |  | 
|  1201   scoped_ptr<OptionsLayoutBuilderGtk> |  | 
|  1202     options_builder(OptionsLayoutBuilderGtk::Create()); |  | 
|  1203  |  | 
|  1204   privacy_section_.reset(new PrivacySection(profile_)); |  | 
|  1205   options_builder->AddOptionGroup( |  | 
|  1206       l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY), |  | 
|  1207       privacy_section_->get_page_widget(), false); |  | 
|  1208  |  | 
|  1209   network_section_.reset(new NetworkSection(profile_)); |  | 
|  1210   options_builder->AddOptionGroup( |  | 
|  1211       l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_SECTION_TITLE_NETWORK), |  | 
|  1212       network_section_->get_page_widget(), false); |  | 
|  1213  |  | 
|  1214   translate_section_.reset(new TranslateSection(profile_)); |  | 
|  1215   options_builder->AddOptionGroup( |  | 
|  1216       l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_SECTION_TITLE_TRANSLATE), |  | 
|  1217       translate_section_->get_page_widget(), false); |  | 
|  1218  |  | 
|  1219   download_section_.reset(new DownloadSection(profile_)); |  | 
|  1220   options_builder->AddOptionGroup( |  | 
|  1221       l10n_util::GetStringUTF8(IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME), |  | 
|  1222       download_section_->get_page_widget(), false); |  | 
|  1223  |  | 
|  1224   web_content_section_.reset(new WebContentSection(profile_)); |  | 
|  1225   options_builder->AddOptionGroup( |  | 
|  1226       l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_SECTION_TITLE_CONTENT), |  | 
|  1227       web_content_section_->get_page_widget(), false); |  | 
|  1228  |  | 
|  1229   security_section_.reset(new SecuritySection(profile_)); |  | 
|  1230   options_builder->AddOptionGroup( |  | 
|  1231       l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_SECTION_TITLE_SECURITY), |  | 
|  1232       security_section_->get_page_widget(), false); |  | 
|  1233  |  | 
|  1234   page_ = options_builder->get_page_widget(); |  | 
|  1235 } |  | 
| OLD | NEW |