/*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 "ephy-embed-shell.h"
#include "ephy-gui.h"
#include "ephy-debug.h"
#include "AutoJSContextStack.h"
#include "AutoWindowModalState.h"
#include "EphyUtils.h"
#include "EphyPromptService.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;
g_object_ref (ephy_embed_shell_get_default ());
mEntries[0] = mEntries[1] = nsnull;
mDialog = GTK_DIALOG (gtk_dialog_new ());
g_object_ref_sink (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 = EphyUtils::FindGtkParent (aParent);
if (GTK_IS_WINDOW (parent))
{
gtk_window_set_transient_for (GTK_WINDOW (mDialog),
GTK_WINDOW (parent));
gtk_window_group_add_window (ephy_gui_ensure_window_group (GTK_WINDOW (parent)),
GTK_WINDOW (mDialog));
}
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);
g_object_unref (ephy_embed_shell_get_default ());
}
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 (EphyPromptService,
nsIPromptService,
nsINonBlockingAlertService)
#else
NS_IMPL_ISUPPORTS1 (EphyPromptService,
nsIPromptService)
#endif
EphyPromptService::EphyPromptService()
{
LOG ("EphyPromptService ctor (%p)", this);
}
EphyPromptService::~EphyPromptService()
{
LOG ("EphyPromptService dtor (%p)", this);
}
/* nsIPromptService implementation */
/* void alert (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText); */
NS_IMETHODIMP
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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
EphyPromptService::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 */