<commit_before>// 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_page_gtk.h"

#include <string>

#include "app/gtk_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/import_dialog_gtk.h"
#include "chrome/browser/gtk/options/options_layout_gtk.h"
#include "chrome/browser/gtk/options/passwords_exceptions_window_gtk.h"
#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "gfx/gtk_util.h"
#include "grit/app_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/options/options_window_view.h"
#endif  // defined(OS_CHROMEOS)

namespace {

// Background color for the status label when it's showing an error.
static const GdkColor kSyncLabelErrorBgColor = GDK_COLOR_RGB(0xff, 0x9a, 0x9a);

// Helper for WrapLabelAtAllocationHack.
void OnLabelAllocate(GtkWidget* label, GtkAllocation* allocation) {
  gtk_widget_set_size_request(label, allocation->width, -1);

  // Disconnect ourselves.  Repeatedly resizing based on allocation causes
  // the dialog to become unshrinkable.
  g_signal_handlers_disconnect_by_func(
      label, reinterpret_cast<gpointer>(OnLabelAllocate), NULL);
}

// Set the label to use a request size equal to its initial allocation
// size.  This causes the label to wrap at the width of the container
// it is in, instead of at the default width.  This is called a hack
// because GTK doesn't really work when a widget to make its size
// request depend on its allocation.  It does, however, have the
// intended effect of wrapping the label at the proper width.
void WrapLabelAtAllocationHack(GtkWidget* label) {
  g_signal_connect(label, "size-allocate",
                   G_CALLBACK(OnLabelAllocate), NULL);
}

}  // anonymous namespace

///////////////////////////////////////////////////////////////////////////////
// ContentPageGtk, public:

ContentPageGtk::ContentPageGtk(Profile* profile)
    : OptionsPageBase(profile),
      sync_status_label_background_(NULL),
      sync_status_label_(NULL),
#if !defined(OS_CHROMEOS)
      sync_action_link_background_(NULL),
      sync_action_link_(NULL),
      sync_start_stop_button_(NULL),
#endif
      sync_customize_button_(NULL),
      privacy_dashboard_link_(NULL),
      initializing_(true),
      sync_service_(NULL),
      managed_prefs_banner_(profile->GetPrefs(), OPTIONS_PAGE_CONTENT) {
  if (profile->GetProfileSyncService()) {
    sync_service_ = profile->GetProfileSyncService();
    sync_service_->AddObserver(this);
  }

  // Prepare the group options layout.
  scoped_ptr<OptionsLayoutBuilderGtk>
    options_builder(OptionsLayoutBuilderGtk::CreateOptionallyCompactLayout());
  options_builder->AddWidget(managed_prefs_banner_.banner_widget(), false);
  if (sync_service_) {
    options_builder->AddOptionGroup(
        l10n_util::GetStringUTF8(IDS_SYNC_OPTIONS_GROUP_NAME),
        InitSyncGroup(), false);
    UpdateSyncControls();
  }

  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_OPTIONS_PASSWORDS_GROUP_NAME),
      InitPasswordSavingGroup(), false);
  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_AUTOFILL_SETTING_WINDOWS_GROUP_NAME),
      InitFormAutoFillGroup(), false);
#if !defined(OS_CHROMEOS)
  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_OPTIONS_BROWSING_DATA_GROUP_NAME),
      InitBrowsingDataGroup(), false);
#endif
  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_APPEARANCE_GROUP_NAME),
      InitThemesGroup(), false);
  page_ = options_builder->get_page_widget();

  // Add preferences observers.
  ask_to_save_passwords_.Init(prefs::kPasswordManagerEnabled,
                              profile->GetPrefs(), this);

  if (browser_defaults::kCanToggleSystemTitleBar) {
    use_custom_chrome_frame_.Init(prefs::kUseCustomChromeFrame,
                                  profile->GetPrefs(), this);
  }

  // Load initial values.
  NotifyPrefChanged(NULL);

  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                 NotificationService::AllSources());
  ObserveThemeChanged();
}

ContentPageGtk::~ContentPageGtk() {
  if (sync_service_)
    sync_service_->RemoveObserver(this);
}

///////////////////////////////////////////////////////////////////////////////
// ContentsPageView, ProfileSyncServiceObserver implementation:

void ContentPageGtk::OnStateChanged() {
  // If the UI controls are not yet initialized, then don't do anything. This
  // can happen if the Options dialog is up, but the Content tab is not yet
  // clicked.
  if (!initializing_)
    UpdateSyncControls();
}

///////////////////////////////////////////////////////////////////////////////
// ContentPageGtk, private:
<commit_msg>[GTK] Fix pref initialization order so options page doesn't instantly crash.<commit_after>// 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_page_gtk.h"

#include <string>

#include "app/gtk_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/import_dialog_gtk.h"
#include "chrome/browser/gtk/options/options_layout_gtk.h"
#include "chrome/browser/gtk/options/passwords_exceptions_window_gtk.h"
#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "gfx/gtk_util.h"
#include "grit/app_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/options/options_window_view.h"
#endif  // defined(OS_CHROMEOS)

namespace {

// Background color for the status label when it's showing an error.
static const GdkColor kSyncLabelErrorBgColor = GDK_COLOR_RGB(0xff, 0x9a, 0x9a);

// Helper for WrapLabelAtAllocationHack.
void OnLabelAllocate(GtkWidget* label, GtkAllocation* allocation) {
  gtk_widget_set_size_request(label, allocation->width, -1);

  // Disconnect ourselves.  Repeatedly resizing based on allocation causes
  // the dialog to become unshrinkable.
  g_signal_handlers_disconnect_by_func(
      label, reinterpret_cast<gpointer>(OnLabelAllocate), NULL);
}

// Set the label to use a request size equal to its initial allocation
// size.  This causes the label to wrap at the width of the container
// it is in, instead of at the default width.  This is called a hack
// because GTK doesn't really work when a widget to make its size
// request depend on its allocation.  It does, however, have the
// intended effect of wrapping the label at the proper width.
void WrapLabelAtAllocationHack(GtkWidget* label) {
  g_signal_connect(label, "size-allocate",
                   G_CALLBACK(OnLabelAllocate), NULL);
}

}  // anonymous namespace

///////////////////////////////////////////////////////////////////////////////
// ContentPageGtk, public:

ContentPageGtk::ContentPageGtk(Profile* profile)
    : OptionsPageBase(profile),
      sync_status_label_background_(NULL),
      sync_status_label_(NULL),
#if !defined(OS_CHROMEOS)
      sync_action_link_background_(NULL),
      sync_action_link_(NULL),
      sync_start_stop_button_(NULL),
#endif
      sync_customize_button_(NULL),
      privacy_dashboard_link_(NULL),
      initializing_(true),
      sync_service_(NULL),
      managed_prefs_banner_(profile->GetPrefs(), OPTIONS_PAGE_CONTENT) {
  if (profile->GetProfileSyncService()) {
    sync_service_ = profile->GetProfileSyncService();
    sync_service_->AddObserver(this);
  }

  // Prepare the group options layout.
  scoped_ptr<OptionsLayoutBuilderGtk>
    options_builder(OptionsLayoutBuilderGtk::CreateOptionallyCompactLayout());
  options_builder->AddWidget(managed_prefs_banner_.banner_widget(), false);
  if (sync_service_) {
    options_builder->AddOptionGroup(
        l10n_util::GetStringUTF8(IDS_SYNC_OPTIONS_GROUP_NAME),
        InitSyncGroup(), false);
    UpdateSyncControls();
  }

  // Add preferences observers.
  ask_to_save_passwords_.Init(prefs::kPasswordManagerEnabled,
                              profile->GetPrefs(), this);
  if (browser_defaults::kCanToggleSystemTitleBar) {
    use_custom_chrome_frame_.Init(prefs::kUseCustomChromeFrame,
                                  profile->GetPrefs(), this);
  }

  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_OPTIONS_PASSWORDS_GROUP_NAME),
      InitPasswordSavingGroup(), false);
  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_AUTOFILL_SETTING_WINDOWS_GROUP_NAME),
      InitFormAutoFillGroup(), false);
#if !defined(OS_CHROMEOS)
  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_OPTIONS_BROWSING_DATA_GROUP_NAME),
      InitBrowsingDataGroup(), false);
#endif
  options_builder->AddOptionGroup(
      l10n_util::GetStringUTF8(IDS_APPEARANCE_GROUP_NAME),
      InitThemesGroup(), false);
  page_ = options_builder->get_page_widget();

  // Load initial values.
  NotifyPrefChanged(NULL);

  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                 NotificationService::AllSources());
  ObserveThemeChanged();
}

ContentPageGtk::~ContentPageGtk() {
  if (sync_service_)
    sync_service_->RemoveObserver(this);
}

///////////////////////////////////////////////////////////////////////////////
// ContentsPageView, ProfileSyncServiceObserver implementation:

void ContentPageGtk::OnStateChanged() {
  // If the UI controls are not yet initialized, then don't do anything. This
  // can happen if the Options dialog is up, but the Content tab is not yet
  // clicked.
  if (!initializing_)
    UpdateSyncControls();
}

///////////////////////////////////////////////////////////////////////////////
// ContentPageGtk, private:

{'fraction_non_alphanumeric': 0.14227061763655838, 'fraction_numerical': 0.004819707247411638, 'mean_word_length': 3.8235040895393886, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4815013', 'n_tokens_mistral': 3473, 'n_tokens_neox': 3390, 'n_words': 694}