aboutsummaryrefslogtreecommitdiffstats
path: root/embed/xulrunner/src/GeckoPromptService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'embed/xulrunner/src/GeckoPromptService.cpp')
-rw-r--r--embed/xulrunner/src/GeckoPromptService.cpp891
1 files changed, 891 insertions, 0 deletions
diff --git a/embed/xulrunner/src/GeckoPromptService.cpp b/embed/xulrunner/src/GeckoPromptService.cpp
new file mode 100644
index 000000000..c9c5b03c2
--- /dev/null
+++ b/embed/xulrunner/src/GeckoPromptService.cpp
@@ -0,0 +1,891 @@
+/*
+ * Copyright © 2005, 2006 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include <mozilla-config.h>
+#include "config.h"
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <nsStringAPI.h>
+
+#include <nsCOMPtr.h>
+#include <nsIDOMWindow.h>
+#include <nsServiceManagerUtils.h>
+
+#include "gecko-embed.h"
+#include "gecko-embed-single.h"
+
+#include "AutoJSContextStack.h"
+#include "AutoWindowModalState.h"
+#include "GeckoUtils.h"
+
+#include "GeckoPromptService.h"
+
+#define TIMEOUT 1000 /* ms */
+#define TIMEOUT_DATA_KEY "timeout"
+
+#define MAX_MESSAGE_LENGTH 512
+#define MAX_TITLE_LENGTH 256
+#define MAX_BUTTON_TEXT_LENGTH 128
+
+enum
+{
+ RESPONSE_ABORT_SCRIPT = 42
+};
+
+class Prompter
+{
+public:
+ Prompter (const char*, nsIDOMWindow*, const PRUnichar*, const PRUnichar*);
+ ~Prompter();
+
+ void AddStockButton (const char*, int);
+ void AddButtonWithFlags (PRInt32, PRUint32, const PRUnichar*, PRUint32);
+ void AddButtonsWithFlags (PRUint32, const PRUnichar*, const PRUnichar*, const PRUnichar*);
+ void AddCheckbox (const PRUnichar*, PRBool*);
+ void GetCheckboxState (PRBool *);
+ void AddEntry (const char *, const PRUnichar *, PRBool);
+ void GetText (PRUint32, PRUnichar **);
+ void AddSelect (PRUint32, const PRUnichar **, PRInt32);
+ void GetSelected (PRInt32*);
+
+ PRInt32 Run (PRBool * = nsnull);
+ void Show ();
+
+ PRBool IsCalledFromScript ();
+ void PerformScriptAbortion ();
+
+ char *ConvertAndTruncateString (const PRUnichar *, PRInt32 = -1);
+ char* ConvertAndEscapeButtonText (const PRUnichar *, PRInt32 = -1);
+
+private:
+ nsCOMPtr<nsIDOMWindow> mWindow;
+ GtkDialog *mDialog;
+ GtkWidget *mVBox;
+ GtkWidget *mCheck;
+ GtkSizeGroup *mSizeGroup;
+ GtkWidget *mEntries[2];
+ GtkWidget *mCombo;
+ PRInt32 mNumButtons;
+ PRInt32 mNumEntries;
+ PRInt32 mDefaultResponse;
+ PRInt32 mUnaffirmativeResponse;
+ PRInt32 mResponse;
+ PRBool mSuccess;
+ PRBool mDelay;
+};
+
+Prompter::Prompter (const char *aStock,
+ nsIDOMWindow *aParent,
+ const PRUnichar *aTitle,
+ const PRUnichar *aText)
+ : mWindow (aParent)
+ , mDialog(nsnull)
+ , mVBox(nsnull)
+ , mCheck(nsnull)
+ , mSizeGroup(nsnull)
+ , mCombo(nsnull)
+ , mNumButtons(0)
+ , mNumEntries(0)
+ , mDefaultResponse(GTK_RESPONSE_ACCEPT)
+ , mUnaffirmativeResponse(0)
+ , mResponse(GTK_RESPONSE_CANCEL)
+ , mSuccess(PR_FALSE)
+ , mDelay(PR_FALSE)
+{
+ GtkWidget *parent, *hbox, *label, *image;
+
+ gecko_embed_single_push_startup ();
+
+ mEntries[0] = mEntries[1] = nsnull;
+
+ mDialog = GTK_DIALOG (gtk_dialog_new ());
+ g_object_ref (mDialog);
+ gtk_object_sink (GTK_OBJECT (mDialog));
+
+ char *title = NULL;
+ if (aTitle)
+ {
+ title = ConvertAndTruncateString (aTitle, MAX_TITLE_LENGTH);
+ }
+
+ gtk_window_set_title (GTK_WINDOW (mDialog), title ? title : "");
+ g_free (title);
+
+ gtk_window_set_modal (GTK_WINDOW (mDialog), TRUE);
+
+ parent = GeckoUtils::GetGtkWindowForDOMWindow (aParent);
+ if (GTK_IS_WINDOW (parent))
+ {
+ gtk_window_set_transient_for (GTK_WINDOW (mDialog),
+ GTK_WINDOW (parent));
+
+#if !GTK_CHECK_VERSION (2,9,0)
+ if (GTK_WINDOW (parent)->group)
+ {
+ gtk_window_group_add_window (GTK_WINDOW (parent)->group,
+ GTK_WINDOW (mDialog));
+ }
+#endif
+ }
+
+ gtk_dialog_set_has_separator (mDialog, FALSE);
+ gtk_window_set_resizable (GTK_WINDOW (mDialog), FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (mDialog), 5);
+ gtk_box_set_spacing (GTK_BOX (mDialog->vbox), 14); /* 2 * 5 + 14 = 24 */
+
+ hbox = gtk_hbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (mDialog)->vbox), hbox);
+
+ image = gtk_image_new_from_stock (aStock, GTK_ICON_SIZE_DIALOG);
+ gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+
+ mVBox = gtk_vbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (hbox), mVBox, TRUE, TRUE, 0);
+
+ char *text = NULL;
+ if (aText)
+ {
+ text = ConvertAndTruncateString (aText, MAX_MESSAGE_LENGTH);
+ }
+
+ label = gtk_label_new (text);
+ g_free (text);
+
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ /* Guard against overlong nonbreakable text (exploit) */
+ gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
+ gtk_label_set_selectable (GTK_LABEL (label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+
+ gtk_box_pack_start (GTK_BOX (mVBox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ if (IsCalledFromScript ())
+ {
+ gtk_dialog_add_button (GTK_DIALOG (mDialog),
+ _("_Abort Script"),
+ RESPONSE_ABORT_SCRIPT);
+ }
+
+ gtk_widget_show (image);
+ gtk_widget_show (mVBox);
+ gtk_widget_show (hbox);
+}
+
+Prompter::~Prompter ()
+{
+ if (mSizeGroup)
+ {
+ g_object_unref (mSizeGroup);
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (mDialog));
+ g_object_unref (mDialog);
+
+ gecko_embed_single_pop_startup ();
+}
+
+void
+Prompter::AddStockButton (const char *aStock,
+ int aResponse)
+{
+ gtk_dialog_add_button (GTK_DIALOG (mDialog),
+ aStock, aResponse);
+ ++mNumButtons;
+}
+
+void
+Prompter::AddButtonWithFlags (PRInt32 aNum,
+ PRUint32 aFlags,
+ const PRUnichar *aText,
+ PRUint32 aDefault)
+{
+ if (aFlags == 0) return;
+
+ const char *label = NULL;
+ char *freeme = NULL;
+ gboolean isAffirmative = FALSE;
+ switch (aFlags)
+ {
+ case nsIPromptService::BUTTON_TITLE_OK:
+ label = GTK_STOCK_OK;
+ isAffirmative = TRUE;
+ break;
+
+ case nsIPromptService::BUTTON_TITLE_CANCEL:
+ label = GTK_STOCK_CANCEL;
+ break;
+
+ case nsIPromptService::BUTTON_TITLE_YES:
+ label = GTK_STOCK_YES;
+ isAffirmative = TRUE;
+ break;
+
+ case nsIPromptService::BUTTON_TITLE_NO:
+ label = GTK_STOCK_NO;
+ break;
+
+ case nsIPromptService::BUTTON_TITLE_SAVE:
+ label = GTK_STOCK_SAVE;
+ isAffirmative = TRUE;
+ break;
+
+ case nsIPromptService::BUTTON_TITLE_DONT_SAVE:
+ label = _("Don't Save");
+ break;
+
+ case nsIPromptService::BUTTON_TITLE_REVERT:
+ label = GTK_STOCK_REVERT_TO_SAVED;
+ break;
+
+ case nsIPromptService::BUTTON_TITLE_IS_STRING:
+ default:
+ label = freeme = ConvertAndEscapeButtonText (aText, MAX_BUTTON_TEXT_LENGTH);
+ /* We can't tell, so assume it's affirmative */
+ isAffirmative = TRUE;
+ break;
+ }
+
+ if (label == NULL) return;
+
+ gtk_dialog_add_button (mDialog, label, aNum);
+ ++mNumButtons;
+
+ if (isAffirmative && mDelay)
+ {
+ gtk_dialog_set_response_sensitive (mDialog, aNum, FALSE);
+ }
+
+ if (!isAffirmative)
+ {
+ mUnaffirmativeResponse = aNum;
+ }
+
+ if (aDefault)
+ {
+ mDefaultResponse = aNum;
+ }
+
+ g_free (freeme);
+}
+
+void
+Prompter::AddButtonsWithFlags (PRUint32 aFlags,
+ const PRUnichar *aText0,
+ const PRUnichar *aText1,
+ const PRUnichar *aText2)
+{
+ mDelay = (aFlags & nsIPromptService::BUTTON_DELAY_ENABLE) != 0;
+ mDefaultResponse = -1;
+
+ /* Reverse the order, on the assumption that what we passed is the
+ * 'windows' button order, and we want HIG order.
+ */
+ AddButtonWithFlags (2, ((aFlags / nsIPromptService::BUTTON_POS_2) & 0xff), aText2,
+ aFlags & nsIPromptService::BUTTON_POS_2_DEFAULT);
+ AddButtonWithFlags (1, ((aFlags / nsIPromptService::BUTTON_POS_1) & 0xff), aText1,
+ aFlags & nsIPromptService::BUTTON_POS_1_DEFAULT);
+ AddButtonWithFlags (0, ((aFlags / nsIPromptService::BUTTON_POS_0) & 0xff), aText0,
+ aFlags & nsIPromptService::BUTTON_POS_0_DEFAULT);
+
+ /* If no default was set, use the 'rightmost' unaffirmative response.
+ * This happens with the suite's password manager prompt.
+ */
+ if (mDefaultResponse == -1)
+ {
+ mDefaultResponse = mUnaffirmativeResponse;
+ }
+}
+
+void
+Prompter::AddCheckbox (const PRUnichar *aText,
+ PRBool *aState)
+{
+ if (!aState || !aText) return;
+
+ char *label = ConvertAndEscapeButtonText (aText, 2 * MAX_BUTTON_TEXT_LENGTH);
+ mCheck = gtk_check_button_new_with_mnemonic (label);
+ g_free (label);
+
+ gtk_label_set_line_wrap (GTK_LABEL (GTK_BIN (mCheck)->child), TRUE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mCheck), *aState);
+ gtk_box_pack_start (GTK_BOX (mVBox), mCheck, FALSE, FALSE, 0);
+ gtk_widget_show (mCheck);
+}
+
+void
+Prompter::GetCheckboxState (PRBool *aState)
+{
+ if (!aState || !mCheck) return;
+
+ *aState = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (mCheck));
+}
+
+void
+Prompter::AddEntry (const char *aLabel,
+ const PRUnichar *aValue,
+ PRBool aIsPassword)
+{
+ if (!mSizeGroup)
+ {
+ mSizeGroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ }
+
+ GtkWidget *hbox = gtk_hbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (mVBox), hbox, FALSE, FALSE, 0);
+
+ GtkWidget *label = nsnull;
+ if (aLabel)
+ {
+ label = gtk_label_new_with_mnemonic (aLabel);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_size_group_add_widget (mSizeGroup, label);
+ }
+
+ GtkWidget *entry = mEntries[mNumEntries++] = gtk_entry_new ();
+ gtk_entry_set_visibility (GTK_ENTRY (entry), !aIsPassword);
+ gtk_entry_set_activates_default(GTK_ENTRY (entry), TRUE);
+
+ if (aValue)
+ {
+ nsCString cValue;
+ NS_UTF16ToCString (nsDependentString(aValue),
+ NS_CSTRING_ENCODING_UTF8, cValue);
+
+ gtk_entry_set_text (GTK_ENTRY (entry), cValue.get());
+ }
+
+ if (label)
+ {
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+ }
+
+ gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+ gtk_widget_show_all (hbox);
+}
+
+void
+Prompter::GetText (PRUint32 aNum,
+ PRUnichar **aValue)
+{
+ if (!aValue || !mEntries[aNum]) return;
+
+ const char *text = gtk_entry_get_text (GTK_ENTRY (mEntries[aNum]));
+ if (!text) return;
+
+ nsString value;
+ NS_CStringToUTF16 (nsDependentCString (text),
+ NS_CSTRING_ENCODING_UTF8, value);
+
+ *aValue = NS_StringCloneData (value);
+}
+
+void
+Prompter::AddSelect (PRUint32 aCount,
+ const PRUnichar **aList,
+ PRInt32 aDefault)
+{
+ mCombo = gtk_combo_box_new_text ();
+
+ for (PRUint32 i = 0; i < aCount; i++)
+ {
+ /* FIXME: use "" instead in this case? */
+ if (!aList[i] || !aList[i][0]) continue;
+
+ nsCString cData;
+ NS_UTF16ToCString (nsDependentString(aList[i]), NS_CSTRING_ENCODING_UTF8, cData);
+
+ gtk_combo_box_append_text (GTK_COMBO_BOX (mCombo), cData.get());
+ }
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (mCombo), aDefault);
+
+ gtk_box_pack_start (GTK_BOX (mVBox), mCombo, FALSE, FALSE, 0);
+ gtk_widget_show (mCombo);
+}
+
+void
+Prompter::GetSelected (PRInt32 *aSelected)
+{
+ if (!aSelected || !mCombo) return;
+
+ *aSelected = gtk_combo_box_get_active (GTK_COMBO_BOX (mCombo));
+}
+
+static gboolean
+EnableResponse (GtkDialog *aDialog)
+{
+ g_object_steal_data (G_OBJECT (aDialog), TIMEOUT_DATA_KEY);
+
+ gtk_dialog_set_response_sensitive (aDialog, 0, TRUE);
+ gtk_dialog_set_response_sensitive (aDialog, 1, TRUE);
+ gtk_dialog_set_response_sensitive (aDialog, 2, TRUE);
+
+ return FALSE;
+}
+
+static void
+RemoveTimeout (gpointer idptr)
+{
+ guint timeout = GPOINTER_TO_UINT (idptr);
+
+ g_return_if_fail (timeout != 0);
+
+ g_source_remove (timeout);
+}
+
+PRInt32
+Prompter::Run (PRBool *aSuccess)
+{
+#if 0
+ AutoEventQueue queue;
+ if (NS_FAILED (queue.Init()))
+ {
+ if (aSuccess)
+ {
+ *aSuccess = PR_FALSE;
+ }
+ mSuccess = PR_FALSE;
+
+ return GTK_RESPONSE_CANCEL;
+ }
+#endif
+
+ nsresult rv;
+ AutoJSContextStack stack;
+ rv = stack.Init ();
+ if (NS_FAILED (rv)) return rv;
+
+ AutoWindowModalState modalState (mWindow);
+
+ if (mDelay)
+ {
+ guint timeout = g_timeout_add (TIMEOUT,
+ (GSourceFunc) EnableResponse,
+ mDialog);
+ g_object_set_data_full (G_OBJECT (mDialog), TIMEOUT_DATA_KEY,
+ GUINT_TO_POINTER (timeout),
+ (GDestroyNotify) RemoveTimeout);
+ }
+
+ gtk_dialog_set_default_response (GTK_DIALOG (mDialog), mDefaultResponse);
+
+ GtkWidget *widget = GTK_WIDGET (mDialog);
+ gtk_widget_show (widget);
+ mResponse = gtk_dialog_run (mDialog);
+ gtk_widget_hide (widget);
+
+ g_object_set_data (G_OBJECT (mDialog), TIMEOUT_DATA_KEY, NULL);
+
+ mSuccess = (GTK_RESPONSE_ACCEPT == mResponse);
+ if (aSuccess)
+ {
+ *aSuccess = mSuccess;
+ }
+
+ if (mResponse == RESPONSE_ABORT_SCRIPT)
+ {
+ PerformScriptAbortion ();
+ }
+
+ return mResponse;
+}
+
+static void
+DeletePrompter (gpointer aPromptPtr,
+ GObject *aZombie)
+{
+ Prompter *prompt = static_cast<Prompter*>(aPromptPtr);
+
+ delete prompt;
+}
+
+void
+Prompter::Show ()
+{
+ /* We don't need it anymore */
+ mWindow = nsnull;
+
+ gtk_window_set_modal (GTK_WINDOW (mDialog), FALSE);
+
+ g_signal_connect (mDialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+ g_object_weak_ref (G_OBJECT (mDialog),
+ (GWeakNotify) DeletePrompter,
+ static_cast<gpointer>(this));
+
+ gtk_widget_show (GTK_WIDGET (mDialog));
+}
+
+PRBool
+Prompter::IsCalledFromScript()
+{
+#if 0
+ nsCOMPtr<nsIXPConnect> xpconnect (do_GetService (nsIXPConnect::GetCID()));
+ NS_ENSURE_TRUE (xpconnect, PR_FALSE);
+
+ nsresult rv;
+ nsCOMPtr<nsIXPCNativeCallContext> ncc;
+ rv = xpconnect->GetCurrentNativeCallContext (getter_AddRefs (ncc));
+ NS_ENSURE_SUCCESS (rv, PR_FALSE);
+
+ if (!ncc) return PR_FALSE;
+
+ JSContext *cx = nsnull;
+ rv = ncc->GetJSContext (&cx);
+ g_print ("GetJSContext rv=%x, cx=%p\n", rv, cx);
+
+ NS_ENSURE_SUCCESS (rv, PR_FALSE);
+
+ return cx != nsnull;
+#endif
+ return PR_FALSE;
+}
+
+void
+Prompter::PerformScriptAbortion()
+{
+#if 0
+ /* FIXME: can we only stop the calling script, not all scripts in the context? */
+
+ nsCOMPtr<nsIXPConnect> xpconnect (do_GetService (nsIXPConnect::GetCID()));
+ NS_ENSURE_TRUE (xpconnect, );
+
+ nsresult rv;
+ nsCOMPtr<nsIXPCNativeCallContext> ncc;
+ rv = xpconnect->GetCurrentNativeCallContext (getter_AddRefs (ncc));
+ NS_ENSURE_SUCCESS (rv, );
+ NS_ENSURE_TRUE (ncc, );
+
+ JSContext *cx = nsnull;
+ rv = ncc->GetJSContext (&cx);
+ g_print ("GetJSContext rv=%x, cx=%p\n", rv, cx);
+ NS_ENSURE_SUCCESS (rv, );
+ NS_ENSURE_TRUE (cx, );
+
+ g_print ("Would now disable scripts\n");
+// MozillaPrivate::SetScriptsEnabled (cx, PR_FALSE, PR_FALSE);
+#endif
+}
+
+char *
+Prompter::ConvertAndTruncateString (const PRUnichar *aText,
+ PRInt32 aMaxLength)
+{
+ if (aText == nsnull) return NULL;
+
+ /* This depends on the assumption that
+ * typeof(PRUnichar) == typeof (gunichar2) == uint16,
+ * which should be pretty safe.
+ */
+ glong n_read = 0, n_written = 0;
+ char *converted = g_utf16_to_utf8 ((gunichar2*) aText, aMaxLength,
+ &n_read, &n_written, NULL);
+ /* FIXME loop from the end while !g_unichar_isspace (char)? */
+
+ return converted;
+}
+
+char *
+Prompter::ConvertAndEscapeButtonText(const PRUnichar *aText,
+ PRInt32 aMaxLength)
+{
+ char *converted = ConvertAndTruncateString (aText, aMaxLength);
+ if (converted == NULL) return NULL;
+
+ char *escaped = (char*) g_malloc (strlen (converted) + 1);
+ char *q = escaped;
+ for (const char *p = converted; *p; ++p, ++q)
+ {
+ if (*p == '&')
+ {
+ if (*(p+1) == '&')
+ {
+ *q = '&';
+ ++p;
+ }
+ else
+ {
+ *q = '_';
+ }
+ }
+ else
+ {
+ *q = *p;
+ }
+ }
+
+ /* Null termination */
+ *q = '\0';
+
+ g_free (converted);
+
+ return escaped;
+}
+
+/* FIXME: needs THREADSAFE? */
+#if HAVE_NSINONBLOCKINGALERTSERVICE_H
+NS_IMPL_ISUPPORTS2 (GeckoPromptService,
+ nsIPromptService,
+ nsINonBlockingAlertService)
+#else
+NS_IMPL_ISUPPORTS1 (GeckoPromptService,
+ nsIPromptService)
+#endif
+
+GeckoPromptService::GeckoPromptService()
+{
+}
+
+GeckoPromptService::~GeckoPromptService()
+{
+}
+
+/* nsIPromptService implementation */
+
+/* void alert (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText); */
+NS_IMETHODIMP
+GeckoPromptService::Alert (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText)
+{
+ Prompter prompt (GTK_STOCK_DIALOG_INFO, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.Run ();
+
+ return NS_OK;
+}
+
+/* void alertCheck (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState); */
+NS_IMETHODIMP
+GeckoPromptService::AlertCheck (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ const PRUnichar *aCheckMsg,
+ PRBool *aCheckState)
+{
+ Prompter prompt (GTK_STOCK_DIALOG_INFO, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.AddCheckbox (aCheckMsg, aCheckState);
+
+ prompt.Run ();
+ prompt.GetCheckboxState (aCheckState);
+
+ return NS_OK;
+}
+
+/* boolean confirm (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText); */
+NS_IMETHODIMP
+GeckoPromptService::Confirm (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ PRBool *_retval)
+{
+ NS_ENSURE_ARG_POINTER (_retval);
+
+ Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.Run (_retval);
+
+ return NS_OK;
+}
+
+/* boolean confirmCheck (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState); */
+NS_IMETHODIMP
+GeckoPromptService::ConfirmCheck (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ const PRUnichar *aCheckMsg,
+ PRBool *aCheckState,
+ PRBool *_retval)
+{
+ NS_ENSURE_ARG_POINTER (_retval);
+
+ Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.AddCheckbox (aCheckMsg, aCheckState);
+
+ prompt.Run (_retval);
+ prompt.GetCheckboxState (aCheckState);
+
+ return NS_OK;
+}
+
+/* PRInt32 confirmEx (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in unsigned long aButtonFlags, in wstring aButton0Title, in wstring aButton1Title, in wstring aButton2Title, in wstring aCheckMsg, inout boolean aCheckState); */
+NS_IMETHODIMP
+GeckoPromptService::ConfirmEx (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ PRUint32 aButtonFlags,
+ const PRUnichar *aButton0Title,
+ const PRUnichar *aButton1Title,
+ const PRUnichar *aButton2Title,
+ const PRUnichar *aCheckMsg,
+ PRBool *aCheckState,
+ PRInt32 *_retval)
+{
+ NS_ENSURE_ARG_POINTER (_retval);
+
+ Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText);
+ prompt.AddButtonsWithFlags (aButtonFlags, aButton0Title,
+ aButton1Title, aButton2Title);
+ prompt.AddCheckbox (aCheckMsg, aCheckState);
+
+ *_retval = prompt.Run (nsnull);
+ prompt.GetCheckboxState (aCheckState);
+
+ return NS_OK;
+}
+
+/* boolean prompt (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aValue, in wstring aCheckMsg, inout boolean aCheckState); */
+NS_IMETHODIMP
+GeckoPromptService::Prompt (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ PRUnichar **aValue,
+ const PRUnichar *aCheckMsg,
+ PRBool *aCheckState,
+ PRBool *_retval)
+{
+ NS_ENSURE_ARG_POINTER (_retval);
+ NS_ENSURE_ARG_POINTER (aValue);
+
+ Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.AddEntry (nsnull, *aValue, PR_FALSE);
+ prompt.AddCheckbox (aCheckMsg, aCheckState);
+
+ prompt.Run (_retval);
+ prompt.GetText (0, aValue);
+ prompt.GetCheckboxState (aCheckState);
+
+ return NS_OK;
+}
+
+/* boolean promptUsernameAndPassword (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aUsername, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState); */
+NS_IMETHODIMP
+GeckoPromptService::PromptUsernameAndPassword (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ PRUnichar **aUsername,
+ PRUnichar **aPassword,
+ const PRUnichar *aCheckMsg,
+ PRBool *aCheckState,
+ PRBool *_retval)
+{
+ NS_ENSURE_ARG_POINTER (_retval);
+ NS_ENSURE_ARG_POINTER (aUsername);
+ NS_ENSURE_ARG_POINTER (aPassword);
+
+ Prompter prompt (GTK_STOCK_DIALOG_AUTHENTICATION, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.AddEntry (_("_Username:"), *aUsername, PR_FALSE);
+ prompt.AddEntry (_("_Password:"), *aPassword, PR_TRUE);
+ prompt.AddCheckbox (aCheckMsg, aCheckState);
+
+ prompt.Run (_retval);
+ prompt.GetText (0, aUsername);
+ prompt.GetText (1, aPassword);
+ prompt.GetCheckboxState (aCheckState);
+
+ return NS_OK;
+}
+
+/* boolean promptPassword (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState); */
+NS_IMETHODIMP
+GeckoPromptService::PromptPassword (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ PRUnichar **aPassword,
+ const PRUnichar *aCheckMsg,
+ PRBool *aCheckState,
+ PRBool *_retval)
+{
+ NS_ENSURE_ARG_POINTER (_retval);
+ NS_ENSURE_ARG_POINTER (aPassword);
+
+ Prompter prompt (GTK_STOCK_DIALOG_AUTHENTICATION, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.AddEntry (_("_Password:"), *aPassword, PR_TRUE);
+ prompt.AddCheckbox (aCheckMsg, aCheckState);
+
+ // FIXME: Add a CAPSLOCK indicator?
+
+ prompt.Run (_retval);
+ prompt.GetText (0, aPassword);
+ prompt.GetCheckboxState (aCheckState);
+
+ return NS_OK;
+}
+
+/* boolean select (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in PRUint32 aCount, [array, size_is (aCount)] in wstring aSelectList, out long aOutSelection); */
+NS_IMETHODIMP
+GeckoPromptService::Select (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText,
+ PRUint32 aCount,
+ const PRUnichar **aSelectList,
+ PRInt32 *aOutSelection,
+ PRBool *_retval)
+{
+ NS_ENSURE_ARG_POINTER (_retval);
+ NS_ENSURE_ARG_POINTER (aOutSelection);
+
+ Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText);
+ prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt.AddSelect (aCount, aSelectList, *aOutSelection);
+
+ prompt.Run (_retval);
+ prompt.GetSelected (aOutSelection);
+
+ return NS_OK;
+}
+
+#if HAVE_NSINONBLOCKINGALERTSERVICE_H
+
+/* showNonBlockingAlert (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText); */
+NS_IMETHODIMP
+GeckoPromptService::ShowNonBlockingAlert (nsIDOMWindow *aParent,
+ const PRUnichar *aDialogTitle,
+ const PRUnichar *aText)
+{
+ Prompter *prompt = new Prompter (GTK_STOCK_DIALOG_INFO, aParent, aDialogTitle, aText);
+ if (!prompt) return NS_ERROR_OUT_OF_MEMORY;
+
+ prompt->AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ prompt->Show ();
+
+ return NS_OK;
+}
+
+#endif /* HAVE_NSINONBLOCKINGALERTSERVICE_H */