summaryrefslogtreecommitdiffstats
path: root/chrome/browser/js_modal_dialog_gtk.cc
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-05 22:32:14 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-05 22:32:14 +0000
commit12f74a94c21e19c74208dacf1dc5ef46f8a27f53 (patch)
treed10fe102066ab8b0a437b18ffc70aa228d02ba4e /chrome/browser/js_modal_dialog_gtk.cc
parent225c8f507421a2eff2ed7a900104431d04ed7e5e (diff)
downloadchromium_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.cc215
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;
+}
+