summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/js_modal_dialog_gtk.cc
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-28 15:40:20 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-28 15:40:20 +0000
commit160ad3d101988b9d842fef8b18cc49c54c9a1de5 (patch)
tree567875d2f363d0b110ad25da9a9aa07cffcaa201 /chrome/browser/gtk/js_modal_dialog_gtk.cc
parent341078d4b72bd3de280b960be6cd4ac5e5ab0265 (diff)
downloadchromium_src-160ad3d101988b9d842fef8b18cc49c54c9a1de5.zip
chromium_src-160ad3d101988b9d842fef8b18cc49c54c9a1de5.tar.gz
chromium_src-160ad3d101988b9d842fef8b18cc49c54c9a1de5.tar.bz2
Refactor AppModalDialog to more clearly isolate platform specific UI pieces and eliminate the dependency on individual frontends from cross platform code.
BUG=none TEST=none Review URL: http://codereview.chromium.org/3398015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60785 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/js_modal_dialog_gtk.cc')
-rw-r--r--chrome/browser/gtk/js_modal_dialog_gtk.cc234
1 files changed, 234 insertions, 0 deletions
diff --git a/chrome/browser/gtk/js_modal_dialog_gtk.cc b/chrome/browser/gtk/js_modal_dialog_gtk.cc
new file mode 100644
index 0000000..9a12cc9
--- /dev/null
+++ b/chrome/browser/gtk/js_modal_dialog_gtk.cc
@@ -0,0 +1,234 @@
+// 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/js_modal_dialog_gtk.h"
+
+#include <gtk/gtk.h>
+
+#include "app/gtk_util.h"
+#include "app/l10n_util.h"
+#include "app/message_box_flags.h"
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/browser/js_modal_dialog.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
+
+////////////////////////////////////////////////////////////////////////////////
+// JSModalDialogGtk, public:
+
+JSModalDialogGtk::JSModalDialogGtk(JavaScriptAppModalDialog* dialog,
+ gfx::NativeWindow parent_window)
+ : dialog_(dialog) {
+ 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_->dialog_flags()) {
+ case MessageBoxFlags::kIsJavascriptAlert:
+ buttons = GTK_BUTTONS_NONE;
+ message_type = GTK_MESSAGE_WARNING;
+ break;
+
+ case MessageBoxFlags::kIsJavascriptConfirm:
+ if (dialog_->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.
+ gtk_util::MakeAppModalWindowGroup();
+
+ gtk_dialog_ = gtk_message_dialog_new(parent_window,
+ GTK_DIALOG_MODAL, message_type, buttons, "%s",
+ WideToUTF8(dialog_->message_text()).c_str());
+ gtk_util::ApplyMessageDialogQuirks(gtk_dialog_);
+ gtk_window_set_title(GTK_WINDOW(gtk_dialog_),
+ WideToUTF8(dialog_->title()).c_str());
+
+ // Adjust content area as needed. Set up the prompt text entry or
+ // suppression check box.
+ if (MessageBoxFlags::kIsJavascriptPrompt == dialog_->dialog_flags()) {
+ // TODO(tc): Replace with gtk_dialog_get_content_area() when using GTK 2.14+
+ GtkWidget* contents_vbox = GTK_DIALOG(gtk_dialog_)->vbox;
+ GtkWidget* text_box = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(text_box),
+ WideToUTF8(dialog_->default_prompt_text()).c_str());
+ gtk_box_pack_start(GTK_BOX(contents_vbox), text_box, TRUE, TRUE, 0);
+ g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box);
+ gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE);
+ }
+
+ if (dialog_->display_suppress_checkbox()) {
+ GtkWidget* contents_vbox = GTK_DIALOG(gtk_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(gtk_dialog_), kSuppressCheckboxId, check_box);
+ }
+
+ // Adjust buttons/action area as needed.
+ if (dialog_->is_before_unload_dialog()) {
+ std::string button_text = l10n_util::GetStringUTF8(
+ IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL);
+ gtk_dialog_add_button(GTK_DIALOG(gtk_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(gtk_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(gtk_dialog_),
+ GTK_STOCK_OK, GTK_RESPONSE_OK);
+ if (MessageBoxFlags::kIsJavascriptPrompt != dialog_->dialog_flags())
+ gtk_widget_grab_focus(ok_button);
+ }
+
+ gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK);
+ g_signal_connect(gtk_dialog_, "response",
+ G_CALLBACK(JSModalDialogGtk::OnDialogResponse),
+ reinterpret_cast<JSModalDialogGtk*>(this));
+}
+
+JSModalDialogGtk::~JSModalDialogGtk() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// JSModalDialogGtk, NativeAppModalDialog implementation:
+
+int JSModalDialogGtk::GetAppModalDialogButtons() const {
+ switch (dialog_->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 JSModalDialogGtk::ShowAppModalDialog() {
+ gtk_util::ShowModalDialogWithMinLocalizedWidth(GTK_WIDGET(gtk_dialog_),
+ IDS_ALERT_DIALOG_WIDTH_CHARS);
+}
+
+void JSModalDialogGtk::ActivateAppModalDialog() {
+ DCHECK(gtk_dialog_);
+ gtk_window_present(GTK_WINDOW(gtk_dialog_));}
+
+void JSModalDialogGtk::CloseAppModalDialog() {
+ DCHECK(gtk_dialog_);
+ HandleDialogResponse(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_DELETE_EVENT);
+}
+
+void JSModalDialogGtk::AcceptAppModalDialog() {
+ HandleDialogResponse(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK);
+}
+
+void JSModalDialogGtk::CancelAppModalDialog() {
+ HandleDialogResponse(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_CANCEL);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// JSModalDialogGtk, private:
+
+void JSModalDialogGtk::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.
+ dialog_->OnAccept(GetPromptText(dialog), ShouldSuppressJSDialogs(dialog));
+ break;
+
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_DELETE_EVENT: // User hit the X on the dialog.
+ 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.
+ gtk_util::AppModalDismissedUngroupWindows();
+ delete this;
+}
+
+// static
+void JSModalDialogGtk::OnDialogResponse(GtkDialog* gtk_dialog,
+ gint response_id,
+ JSModalDialogGtk* dialog) {
+ dialog->HandleDialogResponse(gtk_dialog, response_id);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeAppModalDialog, public:
+
+// static
+NativeAppModalDialog* NativeAppModalDialog::CreateNativeJavaScriptPrompt(
+ JavaScriptAppModalDialog* dialog,
+ gfx::NativeWindow parent_window) {
+ return new JSModalDialogGtk(dialog, parent_window);
+}
+
+