diff options
author | zelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 22:32:14 +0000 |
---|---|---|
committer | zelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 22:32:14 +0000 |
commit | 12f74a94c21e19c74208dacf1dc5ef46f8a27f53 (patch) | |
tree | d10fe102066ab8b0a437b18ffc70aa228d02ba4e /chrome/browser/js_modal_dialog_gtk.cc | |
parent | 225c8f507421a2eff2ed7a900104431d04ed7e5e (diff) | |
download | chromium_src-12f74a94c21e19c74208dacf1dc5ef46f8a27f53.zip chromium_src-12f74a94c21e19c74208dacf1dc5ef46f8a27f53.tar.gz chromium_src-12f74a94c21e19c74208dacf1dc5ef46f8a27f53.tar.bz2 |
Refactored out JS specific part of modal dialog stack into its own class, exposed cookie/storage prompt as a modal dialog.
BUG=32719
TEST=none, requires Darin to hook this with his code.
Review URL: http://codereview.chromium.org/560030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/js_modal_dialog_gtk.cc')
-rw-r--r-- | chrome/browser/js_modal_dialog_gtk.cc | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/chrome/browser/js_modal_dialog_gtk.cc b/chrome/browser/js_modal_dialog_gtk.cc new file mode 100644 index 0000000..bf42fb6 --- /dev/null +++ b/chrome/browser/js_modal_dialog_gtk.cc @@ -0,0 +1,215 @@ +// Copyright (c) 2009 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/js_modal_dialog.h" + +#include <gtk/gtk.h> + +#include "app/l10n_util.h" +#include "app/message_box_flags.h" +#include "base/logging.h" +#include "base/string_util.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/common/gtk_util.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" + +namespace { + +// We stash pointers to widgets on the gtk_dialog so we can refer to them +// after dialog creation. +const char kPromptTextId[] = "chrome_prompt_text"; +const char kSuppressCheckboxId[] = "chrome_suppress_checkbox"; + +// If there's a text entry in the dialog, get the text from the first one and +// return it. +std::wstring GetPromptText(GtkDialog* dialog) { + GtkWidget* widget = static_cast<GtkWidget*>( + g_object_get_data(G_OBJECT(dialog), kPromptTextId)); + if (widget) + return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(widget))); + return std::wstring(); +} + +// If there's a toggle button in the dialog, return the toggled state. +// Otherwise, return false. +bool ShouldSuppressJSDialogs(GtkDialog* dialog) { + GtkWidget* widget = static_cast<GtkWidget*>( + g_object_get_data(G_OBJECT(dialog), kSuppressCheckboxId)); + if (widget) + return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + return false; +} + +} // namespace + +void JavaScriptAppModalDialog::CreateAndShowDialog() { + dialog_ = CreateNativeDialog(); + gtk_widget_show_all(GTK_WIDGET(GTK_DIALOG(dialog_))); + + // Suggest a minimum size. + gint width; + GtkRequisition req; + gtk_widget_size_request(dialog_, &req); + gtk_util::GetWidgetSizeFromResources(dialog_, IDS_ALERT_DIALOG_WIDTH_CHARS, 0, + &width, NULL); + if (width > req.width) + gtk_widget_set_size_request(dialog_, width, -1); +} + +void JavaScriptAppModalDialog::HandleDialogResponse(GtkDialog* dialog, + gint response_id) { + switch (response_id) { + case GTK_RESPONSE_OK: + // The first arg is the prompt text and the second is true if we want to + // suppress additional popups from the page. + OnAccept(GetPromptText(dialog), ShouldSuppressJSDialogs(dialog)); + break; + + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: // User hit the X on the dialog. + OnCancel(); + break; + + default: + NOTREACHED(); + } + gtk_widget_destroy(GTK_WIDGET(dialog)); + + // Now that the dialog is gone, we can put all the windows into separate + // window groups so other dialogs are no longer app modal. + for (BrowserList::const_iterator it = BrowserList::begin(); + it != BrowserList::end(); ++it) { + GtkWindowGroup* window_group = gtk_window_group_new(); + gtk_window_group_add_window(window_group, + (*it)->window()->GetNativeHandle()); + g_object_unref(window_group); + } + delete this; +} + +int JavaScriptAppModalDialog::GetDialogButtons() { + switch (dialog_flags_) { + case MessageBoxFlags::kIsJavascriptAlert: + return MessageBoxFlags::DIALOGBUTTON_OK; + + case MessageBoxFlags::kIsJavascriptConfirm: + return MessageBoxFlags::DIALOGBUTTON_OK | + MessageBoxFlags::DIALOGBUTTON_CANCEL; + + case MessageBoxFlags::kIsJavascriptPrompt: + return MessageBoxFlags::DIALOGBUTTON_OK; + + default: + NOTREACHED(); + return 0; + } +} + +void JavaScriptAppModalDialog::AcceptWindow() { + HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_OK); +} + +void JavaScriptAppModalDialog::CancelWindow() { + HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_CANCEL); +} + +NativeDialog JavaScriptAppModalDialog::CreateNativeDialog() { + GtkButtonsType buttons = GTK_BUTTONS_NONE; + GtkMessageType message_type = GTK_MESSAGE_OTHER; + // We add in the OK button manually later because we want to focus it + // explicitly. + switch (dialog_flags_) { + case MessageBoxFlags::kIsJavascriptAlert: + buttons = GTK_BUTTONS_NONE; + message_type = GTK_MESSAGE_WARNING; + break; + + case MessageBoxFlags::kIsJavascriptConfirm: + if (is_before_unload_dialog_) { + // onbeforeunload also uses a confirm prompt, it just has custom + // buttons. We add the buttons using gtk_dialog_add_button below. + buttons = GTK_BUTTONS_NONE; + } else { + buttons = GTK_BUTTONS_CANCEL; + } + message_type = GTK_MESSAGE_QUESTION; + break; + + case MessageBoxFlags::kIsJavascriptPrompt: + buttons = GTK_BUTTONS_CANCEL; + message_type = GTK_MESSAGE_QUESTION; + break; + + default: + NOTREACHED(); + } + + // We want the alert to be app modal so put all the browser windows into the + // same window group. + GtkWindowGroup* window_group = gtk_window_group_new(); + for (BrowserList::const_iterator it = BrowserList::begin(); + it != BrowserList::end(); ++it) { + gtk_window_group_add_window(window_group, + (*it)->window()->GetNativeHandle()); + } + g_object_unref(window_group); + + gfx::NativeWindow window = client_->GetMessageBoxRootWindow(); + NativeDialog dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL, + message_type, buttons, "%s", WideToUTF8(message_text_).c_str()); + gtk_util::ApplyMessageDialogQuirks(dialog); + gtk_window_set_title(GTK_WINDOW(dialog), WideToUTF8(title_).c_str()); + + // Adjust content area as needed. Set up the prompt text entry or + // suppression check box. + if (MessageBoxFlags::kIsJavascriptPrompt == dialog_flags_) { + // TODO(tc): Replace with gtk_dialog_get_content_area() when using GTK 2.14+ + GtkWidget* contents_vbox = GTK_DIALOG(dialog)->vbox; + GtkWidget* text_box = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(text_box), + WideToUTF8(default_prompt_text_).c_str()); + gtk_box_pack_start(GTK_BOX(contents_vbox), text_box, TRUE, TRUE, 0); + g_object_set_data(G_OBJECT(dialog), kPromptTextId, text_box); + gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE); + } + + if (display_suppress_checkbox_) { + GtkWidget* contents_vbox = GTK_DIALOG(dialog)->vbox; + GtkWidget* check_box = gtk_check_button_new_with_label( + l10n_util::GetStringUTF8( + IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION).c_str()); + gtk_box_pack_start(GTK_BOX(contents_vbox), check_box, TRUE, TRUE, 0); + g_object_set_data(G_OBJECT(dialog), kSuppressCheckboxId, check_box); + } + + // Adjust buttons/action area as needed. + if (is_before_unload_dialog_) { + std::string button_text = l10n_util::GetStringUTF8( + IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL); + gtk_dialog_add_button(GTK_DIALOG(dialog), button_text.c_str(), + GTK_RESPONSE_OK); + + button_text = l10n_util::GetStringUTF8( + IDS_BEFOREUNLOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL); + gtk_dialog_add_button(GTK_DIALOG(dialog), button_text.c_str(), + GTK_RESPONSE_CANCEL); + } else { + // Add the OK button and focus it. + GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(dialog), + GTK_STOCK_OK, GTK_RESPONSE_OK); + if (MessageBoxFlags::kIsJavascriptPrompt != dialog_flags_) + gtk_widget_grab_focus(ok_button); + } + + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + g_signal_connect(dialog, "response", + G_CALLBACK(AppModalDialog::OnDialogResponse), + reinterpret_cast<AppModalDialog*>(this)); + return dialog; +} + |