Index: chrome/browser/gtk/first_run_dialog.cc |
=================================================================== |
--- chrome/browser/gtk/first_run_dialog.cc (revision 71352) |
+++ chrome/browser/gtk/first_run_dialog.cc (working copy) |
@@ -1,426 +0,0 @@ |
-// 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/first_run_dialog.h" |
- |
-#include <string> |
-#include <vector> |
- |
-#include "app/l10n_util.h" |
-#include "app/resource_bundle.h" |
-#include "base/i18n/rtl.h" |
-#include "base/message_loop.h" |
-#include "base/utf_string_conversions.h" |
-#include "chrome/browser/google/google_util.h" |
-#include "chrome/browser/gtk/gtk_chrome_link_button.h" |
-#include "chrome/browser/gtk/gtk_floating_container.h" |
-#include "chrome/browser/gtk/gtk_util.h" |
-#include "chrome/browser/platform_util.h" |
-#include "chrome/browser/process_singleton.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/browser/search_engines/template_url.h" |
-#include "chrome/browser/search_engines/template_url_model.h" |
-#include "chrome/browser/shell_integration.h" |
-#include "chrome/common/pref_names.h" |
-#include "chrome/common/url_constants.h" |
-#include "chrome/installer/util/google_update_settings.h" |
-#include "grit/chromium_strings.h" |
-#include "grit/generated_resources.h" |
-#include "grit/locale_settings.h" |
-#include "grit/theme_resources.h" |
- |
-#if defined(USE_LINUX_BREAKPAD) |
-#include "chrome/app/breakpad_linux.h" |
-#endif |
- |
-#if defined(GOOGLE_CHROME_BUILD) |
-#include "chrome/browser/browser_process.h" |
-#include "chrome/browser/prefs/pref_service.h" |
-#endif |
- |
-namespace { |
- |
-const gchar* kSearchEngineKey = "template-url-search-engine"; |
- |
-// Height of the label that displays the search engine's logo (in lieu of the |
-// actual logo) in chromium. |
-const int kLogoLabelHeight = 100; |
- |
-// Size of the small logo (for when we show 4 search engines). |
-const int kLogoLabelWidthSmall = 132; |
-const int kLogoLabelHeightSmall = 88; |
- |
-// The number of search engine options we normally show. It may be less than |
-// this number if there are not enough search engines for the current locale, |
-// or more if the user's imported default is not one of the top search engines |
-// for the current locale. |
-const size_t kNormalBallotSize = 3; |
- |
-// The width of the explanatory label. The 180 is the width of the large images. |
-const int kExplanationWidth = kNormalBallotSize * 180; |
- |
-// Horizontal spacing between search engine choices. |
-const int kSearchEngineSpacing = 6; |
- |
-// Set the (x, y) coordinates of the welcome message (which floats on top of |
-// the omnibox image at the top of the first run dialog). |
-void SetWelcomePosition(GtkFloatingContainer* container, |
- GtkAllocation* allocation, |
- GtkWidget* label) { |
- GValue value = { 0, }; |
- g_value_init(&value, G_TYPE_INT); |
- |
- GtkRequisition req; |
- gtk_widget_size_request(label, &req); |
- |
- int x = base::i18n::IsRTL() ? |
- allocation->width - req.width - gtk_util::kContentAreaSpacing : |
- gtk_util::kContentAreaSpacing; |
- g_value_set_int(&value, x); |
- gtk_container_child_set_property(GTK_CONTAINER(container), |
- label, "x", &value); |
- |
- int y = allocation->height / 2 - req.height / 2; |
- g_value_set_int(&value, y); |
- gtk_container_child_set_property(GTK_CONTAINER(container), |
- label, "y", &value); |
- g_value_unset(&value); |
-} |
- |
-} // namespace |
- |
-// static |
-bool FirstRunDialog::Show(Profile* profile, |
- bool randomize_search_engine_order) { |
- // Figure out which dialogs we will show. |
- // If the default search is managed via policy, we won't ask. |
- const TemplateURLModel* search_engines_model = profile->GetTemplateURLModel(); |
- bool show_search_engines_dialog = search_engines_model && |
- !search_engines_model->is_default_search_managed(); |
- |
-#if defined(GOOGLE_CHROME_BUILD) |
- // If the metrics reporting is managed, we won't ask. |
- const PrefService::Preference* metrics_reporting_pref = |
- g_browser_process->local_state()->FindPreference( |
- prefs::kMetricsReportingEnabled); |
- bool show_reporting_dialog = !metrics_reporting_pref || |
- !metrics_reporting_pref->IsManaged(); |
-#else |
- bool show_reporting_dialog = false; |
-#endif |
- |
- if (!show_search_engines_dialog && !show_reporting_dialog) |
- return true; // Nothing to do |
- |
- int response = -1; |
- // Object deletes itself. |
- new FirstRunDialog(profile, |
- show_reporting_dialog, |
- show_search_engines_dialog, |
- &response); |
- |
- // TODO(port): it should be sufficient to just run the dialog: |
- // int response = gtk_dialog_run(GTK_DIALOG(dialog)); |
- // but that spins a nested message loop and hoses us. :( |
- // http://code.google.com/p/chromium/issues/detail?id=12552 |
- // Instead, run a loop and extract the response manually. |
- MessageLoop::current()->Run(); |
- |
- return (response == GTK_RESPONSE_ACCEPT); |
-} |
- |
-FirstRunDialog::FirstRunDialog(Profile* profile, |
- bool show_reporting_dialog, |
- bool show_search_engines_dialog, |
- int* response) |
- : search_engine_window_(NULL), |
- dialog_(NULL), |
- report_crashes_(NULL), |
- make_default_(NULL), |
- profile_(profile), |
- chosen_search_engine_(NULL), |
- show_reporting_dialog_(show_reporting_dialog), |
- response_(response) { |
- if (!show_search_engines_dialog) { |
- ShowReportingDialog(); |
- return; |
- } |
- search_engines_model_ = profile_->GetTemplateURLModel(); |
- |
- ShowSearchEngineWindow(); |
- |
- search_engines_model_->AddObserver(this); |
- if (search_engines_model_->loaded()) |
- OnTemplateURLModelChanged(); |
- else |
- search_engines_model_->Load(); |
-} |
- |
-FirstRunDialog::~FirstRunDialog() { |
-} |
- |
-void FirstRunDialog::ShowSearchEngineWindow() { |
- search_engine_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
- gtk_window_set_deletable(GTK_WINDOW(search_engine_window_), FALSE); |
- gtk_window_set_title( |
- GTK_WINDOW(search_engine_window_), |
- l10n_util::GetStringUTF8(IDS_FIRSTRUN_DLG_TITLE).c_str()); |
- gtk_window_set_resizable(GTK_WINDOW(search_engine_window_), FALSE); |
- g_signal_connect(search_engine_window_, "destroy", |
- G_CALLBACK(OnSearchEngineWindowDestroyThunk), this); |
- GtkWidget* content_area = gtk_vbox_new(FALSE, 0); |
- gtk_container_add(GTK_CONTAINER(search_engine_window_), content_area); |
- |
- GdkPixbuf* pixbuf = |
- ResourceBundle::GetSharedInstance().GetRTLEnabledPixbufNamed( |
- IDR_SEARCH_ENGINE_DIALOG_TOP); |
- GtkWidget* top_image = gtk_image_new_from_pixbuf(pixbuf); |
- // Right align the image. |
- gtk_misc_set_alignment(GTK_MISC(top_image), 1, 0); |
- gtk_widget_set_size_request(top_image, 0, -1); |
- |
- GtkWidget* welcome_message = gtk_util::CreateBoldLabel( |
- l10n_util::GetStringUTF8(IDS_FR_SEARCH_MAIN_LABEL)); |
- // Force the font size to make sure the label doesn't overlap the image. |
- // 13.4px == 10pt @ 96dpi |
- gtk_util::ForceFontSizePixels(welcome_message, 13.4); |
- |
- GtkWidget* top_area = gtk_floating_container_new(); |
- gtk_container_add(GTK_CONTAINER(top_area), top_image); |
- gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(top_area), |
- welcome_message); |
- g_signal_connect(top_area, "set-floating-position", |
- G_CALLBACK(SetWelcomePosition), welcome_message); |
- |
- gtk_box_pack_start(GTK_BOX(content_area), top_area, |
- FALSE, FALSE, 0); |
- |
- GtkWidget* bubble_area_background = gtk_event_box_new(); |
- gtk_widget_modify_bg(bubble_area_background, |
- GTK_STATE_NORMAL, >k_util::kGdkWhite); |
- |
- GtkWidget* bubble_area_box = gtk_vbox_new(FALSE, 0); |
- gtk_container_set_border_width(GTK_CONTAINER(bubble_area_box), |
- gtk_util::kContentAreaSpacing); |
- gtk_container_add(GTK_CONTAINER(bubble_area_background), |
- bubble_area_box); |
- |
- GtkWidget* explanation = gtk_label_new( |
- l10n_util::GetStringFUTF8(IDS_FR_SEARCH_TEXT, |
- l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)).c_str()); |
- gtk_misc_set_alignment(GTK_MISC(explanation), 0, 0.5); |
- gtk_util::SetLabelColor(explanation, >k_util::kGdkBlack); |
- gtk_util::SetLabelWidth(explanation, kExplanationWidth); |
- gtk_box_pack_start(GTK_BOX(bubble_area_box), explanation, FALSE, FALSE, 0); |
- |
- // We will fill this in after the TemplateURLModel has loaded. |
- // GtkHButtonBox because we want all children to have the same size. |
- search_engine_hbox_ = gtk_hbutton_box_new(); |
- gtk_box_set_spacing(GTK_BOX(search_engine_hbox_), kSearchEngineSpacing); |
- gtk_box_pack_start(GTK_BOX(bubble_area_box), search_engine_hbox_, |
- FALSE, FALSE, 0); |
- |
- gtk_box_pack_start(GTK_BOX(content_area), bubble_area_background, |
- TRUE, TRUE, 0); |
- |
- gtk_widget_show_all(content_area); |
- gtk_window_present(GTK_WINDOW(search_engine_window_)); |
-} |
- |
-void FirstRunDialog::ShowReportingDialog() { |
- // The purpose of the dialog is to ask the user to enable stats and crash |
- // reporting. This setting may be controlled through configuration management |
- // in enterprise scenarios. If that is the case, skip the dialog entirely, |
- // it's not worth bothering the user for only the default browser question |
- // (which is likely to be forced in enterprise deployments anyway). |
- if (!show_reporting_dialog_) { |
- OnResponseDialog(NULL, GTK_RESPONSE_ACCEPT); |
- return; |
- } |
- |
- dialog_ = gtk_dialog_new_with_buttons( |
- l10n_util::GetStringUTF8(IDS_FIRSTRUN_DLG_TITLE).c_str(), |
- NULL, // No parent |
- (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), |
- NULL); |
- gtk_util::AddButtonToDialog(dialog_, |
- l10n_util::GetStringUTF8(IDS_FIRSTRUN_DLG_OK).c_str(), |
- GTK_STOCK_APPLY, GTK_RESPONSE_ACCEPT); |
- gtk_window_set_deletable(GTK_WINDOW(dialog_), FALSE); |
- |
- gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE); |
- |
- g_signal_connect(dialog_, "delete-event", |
- G_CALLBACK(gtk_widget_hide_on_delete), NULL); |
- |
- GtkWidget* content_area = GTK_DIALOG(dialog_)->vbox; |
- |
- make_default_ = gtk_check_button_new_with_label( |
- l10n_util::GetStringUTF8(IDS_FR_CUSTOMIZE_DEFAULT_BROWSER).c_str()); |
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(make_default_), TRUE); |
- gtk_box_pack_start(GTK_BOX(content_area), make_default_, FALSE, FALSE, 0); |
- |
- report_crashes_ = gtk_check_button_new(); |
- GtkWidget* check_label = gtk_label_new( |
- l10n_util::GetStringUTF8(IDS_OPTIONS_ENABLE_LOGGING).c_str()); |
- gtk_label_set_line_wrap(GTK_LABEL(check_label), TRUE); |
- gtk_container_add(GTK_CONTAINER(report_crashes_), check_label); |
- GtkWidget* learn_more_vbox = gtk_vbox_new(FALSE, 0); |
- gtk_box_pack_start(GTK_BOX(learn_more_vbox), report_crashes_, |
- FALSE, FALSE, 0); |
- |
- GtkWidget* learn_more_link = gtk_chrome_link_button_new( |
- l10n_util::GetStringUTF8(IDS_LEARN_MORE).c_str()); |
- gtk_button_set_alignment(GTK_BUTTON(learn_more_link), 0.0, 0.5); |
- gtk_box_pack_start(GTK_BOX(learn_more_vbox), |
- gtk_util::IndentWidget(learn_more_link), |
- FALSE, FALSE, 0); |
- g_signal_connect(learn_more_link, "clicked", |
- G_CALLBACK(OnLearnMoreLinkClickedThunk), this); |
- |
- gtk_box_pack_start(GTK_BOX(content_area), learn_more_vbox, FALSE, FALSE, 0); |
- |
- g_signal_connect(dialog_, "response", |
- G_CALLBACK(OnResponseDialogThunk), this); |
- gtk_widget_show_all(dialog_); |
-} |
- |
-void FirstRunDialog::OnTemplateURLModelChanged() { |
- // We only watch the search engine model change once, on load. Remove |
- // observer so we don't try to redraw if engines change under us. |
- search_engines_model_->RemoveObserver(this); |
- |
- // Add search engines in |search_engines_model_| to buttons list. |
- std::vector<const TemplateURL*> ballot_engines = |
- search_engines_model_->GetTemplateURLs(); |
- // Drop any not in the first 3. |
- if (ballot_engines.size() > kNormalBallotSize) |
- ballot_engines.resize(kNormalBallotSize); |
- |
- const TemplateURL* default_search_engine = |
- search_engines_model_->GetDefaultSearchProvider(); |
- if (std::find(ballot_engines.begin(), |
- ballot_engines.end(), |
- default_search_engine) == |
- ballot_engines.end()) { |
- ballot_engines.push_back(default_search_engine); |
- } |
- |
- std::string choose_text = l10n_util::GetStringUTF8(IDS_FR_SEARCH_CHOOSE); |
- for (std::vector<const TemplateURL*>::iterator search_engine_iter = |
- ballot_engines.begin(); |
- search_engine_iter < ballot_engines.end(); |
- ++search_engine_iter) { |
- // Create a container for the search engine widgets. |
- GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |
- |
- // We show text on Chromium and images on Google Chrome. |
- bool show_images = false; |
-#if defined(GOOGLE_CHROME_BUILD) |
- show_images = true; |
-#endif |
- |
- // Create the image (maybe). |
- int logo_id = (*search_engine_iter)->logo_id(); |
- if (show_images && logo_id > 0) { |
- GdkPixbuf* pixbuf = |
- ResourceBundle::GetSharedInstance().GetPixbufNamed(logo_id); |
- if (ballot_engines.size() > kNormalBallotSize) { |
- pixbuf = gdk_pixbuf_scale_simple(pixbuf, |
- kLogoLabelWidthSmall, |
- kLogoLabelHeightSmall, |
- GDK_INTERP_HYPER); |
- } else { |
- g_object_ref(pixbuf); |
- } |
- |
- GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); |
- gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0); |
- g_object_unref(pixbuf); |
- } else { |
- GtkWidget* logo_label = gtk_label_new(NULL); |
- char* markup = g_markup_printf_escaped( |
- "<span weight='bold' size='x-large' color='black'>%s</span>", |
- WideToUTF8((*search_engine_iter)->short_name()).c_str()); |
- gtk_label_set_markup(GTK_LABEL(logo_label), markup); |
- g_free(markup); |
- gtk_widget_set_size_request(logo_label, -1, |
- ballot_engines.size() > kNormalBallotSize ? kLogoLabelHeightSmall : |
- kLogoLabelHeight); |
- gtk_box_pack_start(GTK_BOX(vbox), logo_label, FALSE, FALSE, 0); |
- } |
- |
- // Create the button. |
- GtkWidget* button = gtk_button_new_with_label(choose_text.c_str()); |
- g_signal_connect(button, "clicked", |
- G_CALLBACK(OnSearchEngineButtonClickedThunk), this); |
- g_object_set_data(G_OBJECT(button), kSearchEngineKey, |
- const_cast<TemplateURL*>(*search_engine_iter)); |
- |
- GtkWidget* button_centerer = gtk_hbox_new(FALSE, 0); |
- gtk_box_pack_start(GTK_BOX(button_centerer), button, TRUE, FALSE, 0); |
- gtk_box_pack_start(GTK_BOX(vbox), button_centerer, FALSE, FALSE, 0); |
- |
- gtk_container_add(GTK_CONTAINER(search_engine_hbox_), vbox); |
- gtk_widget_show_all(search_engine_hbox_); |
- } |
-} |
- |
-void FirstRunDialog::OnSearchEngineButtonClicked(GtkWidget* sender) { |
- chosen_search_engine_ = static_cast<TemplateURL*>( |
- g_object_get_data(G_OBJECT(sender), kSearchEngineKey)); |
- gtk_widget_destroy(search_engine_window_); |
-} |
- |
-void FirstRunDialog::OnSearchEngineWindowDestroy(GtkWidget* sender) { |
- search_engine_window_ = NULL; |
- if (chosen_search_engine_) { |
- search_engines_model_->SetDefaultSearchProvider(chosen_search_engine_); |
- ShowReportingDialog(); |
- } else { |
- FirstRunDone(); |
- } |
-} |
- |
-void FirstRunDialog::OnResponseDialog(GtkWidget* widget, int response) { |
- if (dialog_) |
- gtk_widget_hide_all(dialog_); |
- *response_ = response; |
- |
- // Mark that first run has ran. |
- FirstRun::CreateSentinel(); |
- |
- // Check if user has opted into reporting. |
- if (report_crashes_ && |
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(report_crashes_))) { |
-#if defined(USE_LINUX_BREAKPAD) |
- if (GoogleUpdateSettings::SetCollectStatsConsent(true)) |
- InitCrashReporter(); |
-#endif |
- } else { |
- GoogleUpdateSettings::SetCollectStatsConsent(false); |
- } |
- |
- // If selected set as default browser. |
- if (make_default_ && |
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(make_default_))) { |
- ShellIntegration::SetAsDefaultBrowser(); |
- } |
- |
- FirstRunDone(); |
-} |
- |
-void FirstRunDialog::OnLearnMoreLinkClicked(GtkButton* button) { |
- platform_util::OpenExternal(google_util::AppendGoogleLocaleParam( |
- GURL(chrome::kLearnMoreReportingURL))); |
-} |
- |
-void FirstRunDialog::FirstRunDone() { |
- FirstRun::SetShowWelcomePagePref(); |
- |
- if (dialog_) |
- gtk_widget_destroy(dialog_); |
- MessageLoop::current()->Quit(); |
- delete this; |
-} |