aboutsummaryrefslogtreecommitdiffstats
path: root/embed/mozilla/AutoModalDialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'embed/mozilla/AutoModalDialog.cpp')
-rw-r--r--embed/mozilla/AutoModalDialog.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/embed/mozilla/AutoModalDialog.cpp b/embed/mozilla/AutoModalDialog.cpp
new file mode 100644
index 000000000..994cfe4fa
--- /dev/null
+++ b/embed/mozilla/AutoModalDialog.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2006, 2008 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Some code taken from mozilla/embedding/components/windowwatcher/src/nsPromptService.cpp
+ * which was under MPL/LGPL/GPL tri-licence and is here being used under the licence above.
+ * Original notice:
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ */
+
+#include <xpcom-config.h>
+#include <config.h>
+
+#ifdef HAVE_GECKO_1_9
+#include <nsIDOMDocumentEvent.h>
+#include <nsIDOMDocument.h>
+#include <nsIDOMEvent.h>
+#include <nsIDOMEventTarget.h>
+#include <nsIJSContextStack.h>
+#include <nsIPrivateDOMEvent.h>
+#include <nsPIDOMWindow.h>
+#include <nsServiceManagerUtils.h>
+#include <nsThreadUtils.h>
+#endif /* HAVE_GECKO_1_9 */
+
+#include <gtk/gtkdialog.h>
+
+#include "EphyUtils.h"
+
+#include "AutoModalDialog.h"
+
+AutoModalDialog::AutoModalDialog (nsIDOMWindow *aWindow,
+ PRBool aNotifyDOM)
+ : mWindow (aWindow),
+ mStack (),
+ mModalState (aWindow),
+#ifdef HAVE_GECKO_1_9
+ mDefaultEnabled (DispatchEvent ("DOMWillOpenModalDialog", aNotifyDOM)),
+#endif
+ mContextPushed (NS_SUCCEEDED (mStack.Init ()))
+{
+}
+
+AutoModalDialog::~AutoModalDialog ()
+{
+#ifdef HAVE_GECKO_1_9
+ if (mDefaultEnabled) {
+ DispatchEvent ("DOMModalDialogClosed", PR_TRUE);
+ }
+#endif /* HAVE_GECKO_1_9 */
+}
+
+GtkWindow *
+AutoModalDialog::GetParent ()
+{
+ return GTK_WINDOW (EphyUtils::FindGtkParent (mWindow));
+}
+
+int
+AutoModalDialog::Run (GtkDialog *aDialog)
+{
+ NS_ASSERTION (ShouldShow(), "Calling ::Run on a prevented dialogue!");
+
+ nsCOMPtr<nsPIDOMWindow> pWindow (do_QueryInterface (mWindow));
+
+ // Reset popup state while opening a modal dialog, and firing
+ // events about the dialog, to prevent the current state from
+ // being active the whole time a modal dialog is open.
+ nsAutoPopupStatePusher popupStatePusher (pWindow, openAbused);
+
+#if 1
+ return gtk_dialog_run (aDialog);
+#else
+ /* Do NOT use gtk_dialog_run here, since it blocks the network thread!
+ * See https://bugzilla.mozilla.org/show_bug.cgi?id=338225
+ */
+
+ g_object_ref_sink (aDialog);
+ mResponse = GTK_RESPONSE_DELETE_EVENT;
+
+ gulong responseHandler = g_signal_connect (aDialog, "response",
+ G_CALLBACK (ResponseCallback),
+ reinterpret_cast<void*>(this));
+ gulong deleteHandler = g_signal_connect (aDialog, "delete-event",
+ G_CALLBACK (DeleteCallback), NULL);
+
+ gtk_window_present (GTK_WINDOW (aDialog));
+
+ nsCOMPtr<nsIThread> thread (do_GetCurrentThread ());
+ NS_ASSERTION (thread, "No UI thread?");
+
+ mContinueModalLoop = PR_TRUE;
+ while (mContinueModalLoop) {
+ if (!NS_ProcessNextEvent (thread))
+ break;
+ }
+
+ g_signal_handler_disconnect (aDialog, responseHandler);
+ g_signal_handler_disconnect (aDialog, deleteHandler);
+ g_object_unref (aDialog);
+
+ return mResponse;
+#endif
+}
+
+#ifdef HAVE_GECKO_1_9
+
+PRBool
+AutoModalDialog::DispatchEvent (const char *aEventName,
+ PRBool aDoNotify)
+{
+ if (!mWindow || !aDoNotify) {
+ return PR_TRUE;
+ }
+
+ nsCOMPtr<nsIDOMDocument> domdoc;
+ mWindow->GetDocument (getter_AddRefs (domdoc));
+
+ nsCOMPtr<nsIDOMDocumentEvent> docevent (do_QueryInterface (domdoc));
+ nsCOMPtr<nsIDOMEvent> event;
+
+ PRBool defaultActionEnabled = PR_TRUE;
+
+ if (docevent) {
+ docevent->CreateEvent (NS_LITERAL_STRING ("Events"), getter_AddRefs (event));
+
+ nsCOMPtr<nsIPrivateDOMEvent> privateEvent (do_QueryInterface (event));
+ if (privateEvent) {
+ event->InitEvent (NS_ConvertASCIItoUTF16 (aEventName), PR_TRUE, PR_TRUE);
+
+ privateEvent->SetTrusted(PR_TRUE);
+
+ nsCOMPtr<nsIDOMEventTarget> target (do_QueryInterface (mWindow));
+
+ target->DispatchEvent (event, &defaultActionEnabled);
+ }
+ }
+
+ return defaultActionEnabled;
+}
+
+/* static */ void PR_CALLBACK
+AutoModalDialog::ResponseCallback (GtkWidget *aDialog,
+ int aResponse,
+ void *aData)
+{
+ AutoModalDialog *obj = reinterpret_cast<AutoModalDialog*>(aData);
+
+ gtk_widget_hide (aDialog);
+ obj->mResponse = aResponse;
+ obj->mContinueModalLoop = PR_FALSE;
+}
+
+/* static */ gboolean PR_CALLBACK
+AutoModalDialog::DeleteCallback (GtkWidget *aDialog,
+ void *aEvent,
+ void *aData)
+{
+ gtk_dialog_response (GTK_DIALOG (aDialog), GTK_RESPONSE_DELETE_EVENT);
+ return TRUE;
+}
+
+#endif /* HAVE_GECKO_1_9 */