diff options
Diffstat (limited to 'embed/mozilla/PromptService.cpp')
-rw-r--r-- | embed/mozilla/PromptService.cpp | 769 |
1 files changed, 769 insertions, 0 deletions
diff --git a/embed/mozilla/PromptService.cpp b/embed/mozilla/PromptService.cpp new file mode 100644 index 000000000..c9244dd32 --- /dev/null +++ b/embed/mozilla/PromptService.cpp @@ -0,0 +1,769 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +#include "ephy-glade.h" +#include "PromptService.h" + +#include "nsCOMPtr.h" +#include "nsIFactory.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsIServiceManager.h" +#include "nsXPComFactory.h" +#include "MozillaPrivate.h" + +#include "nsIPromptService.h" +#include "nsIUnicodeEncoder.h" + +#include <gtk/gtkentry.h> +#include <gtk/gtktogglebutton.h> +#include <gtk/gtklist.h> +#include <libgnomeui/gnome-dialog.h> +#include <libgnome/gnome-i18n.h> +#include <libgnome/gnome-triggers.h> + +/* local function prototypes */ +static void set_title (GtkWidget *dialog, const PRUnichar *title); +static void set_label_text (GtkWidget *label, const PRUnichar *text); +static void set_check_button_text (GtkWidget *check_button, + const PRUnichar *text); +static void set_check_button (GtkWidget *button, PRBool *value); +static void set_check_button_size_to_label (GtkWidget *check_button, + GtkWidget *label); +static void set_editable (GtkWidget *entry, PRUnichar **text); +static void get_check_button (GtkWidget *button, PRBool *value); +static void get_editable (GtkWidget *editable, PRUnichar **text); + +/** + * class CPromptService: an GNOME implementation of prompt dialogs for + * Mozilla + */ +class CPromptService: public nsIPromptService +{ + public: + CPromptService(); + virtual ~CPromptService(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIPROMPTSERVICE + private: + nsresult AddButton (GtkWidget *dialog, + char type, + const PRUnichar *title, + int id); +}; + +NS_IMPL_ISUPPORTS1 (CPromptService, nsIPromptService) + +/** + * CPromptService::CPromptService: constructor + */ +CPromptService::CPromptService () +{ + NS_INIT_ISUPPORTS(); +} + +/** + * CPromptService::~CPromptService: destructor + */ +CPromptService::~CPromptService () +{ +} + +/** + * CPromptService::Alert: show an alert box + */ +NS_IMETHODIMP CPromptService::Alert (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text) +{ + GtkWidget *dialog; + GtkWidget *gparent; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + "%s", + PromiseFlatCString(msg).get ()); + set_title (dialog, dialogTitle); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +/** + * CPromptService::AlertCheck: show an alert box with a checkbutton, + * (typically for things like "dont show this warning again") + */ +NS_IMETHODIMP CPromptService::AlertCheck (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + const PRUnichar *checkMsg, + PRBool *checkValue) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *check_button; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + "%s", + PromiseFlatCString(msg).get ()); + + check_button = gtk_check_button_new_with_label (""); + gtk_widget_show (check_button); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), + check_button, FALSE, FALSE, 5); + set_check_button_text (check_button, checkMsg); + set_check_button (check_button, checkValue); + + set_title (dialog, dialogTitle); + + gtk_dialog_run (GTK_DIALOG (dialog)); + get_check_button (check_button, checkValue); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +/** + * CPromptService::Confirm: for simple yes/no dialogs + */ +NS_IMETHODIMP CPromptService::Confirm (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *gparent; + int res; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "%s", PromiseFlatCString(msg).get ()); + set_title (dialog, dialogTitle); + + res = gtk_dialog_run (GTK_DIALOG (dialog)); + *_retval = (res == GTK_RESPONSE_YES); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +/** + * CPromptService::Confirm: for simple yes/no dialogs, with an additional + * check button + */ +NS_IMETHODIMP CPromptService::ConfirmCheck (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *check_button; + int res; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "%s", PromiseFlatCString(msg).get ()); + + check_button = gtk_check_button_new_with_label (""); + gtk_widget_show (check_button); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), + check_button, FALSE, FALSE, 5); + set_check_button_text (check_button, checkMsg); + set_check_button (check_button, checkValue); + + set_title (dialog, dialogTitle); + + res = gtk_dialog_run (GTK_DIALOG (dialog)); + *_retval = (res == GTK_RESPONSE_YES); + get_check_button (check_button, checkValue); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +NS_IMETHODIMP CPromptService::AddButton (GtkWidget *dialog, + char type, + const PRUnichar *title, + int id) +{ + const char *btitle; + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (title); + + g_print ("%d", type); + + switch (type) + { + case BUTTON_TITLE_OK: + btitle = GTK_STOCK_OK; + break; + case BUTTON_TITLE_CANCEL: + btitle = GTK_STOCK_CANCEL; + break; + case BUTTON_TITLE_YES: + btitle = GTK_STOCK_YES; + break; + case BUTTON_TITLE_NO: + btitle = GTK_STOCK_NO; + break; + case BUTTON_TITLE_SAVE: + btitle = _("Save"); + break; + case BUTTON_TITLE_REVERT: + btitle = _("Revert"); + break; + case BUTTON_TITLE_DONT_SAVE: + btitle = _("Don't save"); + break; + case BUTTON_TITLE_IS_STRING: + btitle = NULL; + break; + + default: + return NS_ERROR_FAILURE; + } + + gtk_dialog_add_button (GTK_DIALOG(dialog), + btitle ? btitle : + PromiseFlatCString(utf8string).get(), + id); + + return NS_OK; +} + +/** + * CPromptService::ConfirmEx: For fancy confirmation dialogs + */ +NS_IMETHODIMP CPromptService::ConfirmEx (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUint32 buttonFlags, + const PRUnichar *button0Title, + const PRUnichar *button1Title, + const PRUnichar *button2Title, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRInt32 *buttonPressed) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *check_button = NULL; + int ret; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + "%s", PromiseFlatCString(msg).get ()); + + set_title (dialog, dialogTitle); + + if (checkMsg) + { + check_button = gtk_check_button_new_with_label (""); + gtk_widget_show (check_button); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), + check_button, FALSE, FALSE, 5); + + set_check_button_text (check_button, checkMsg); + set_check_button (check_button, checkValue); + } + + AddButton (dialog, (buttonFlags >> 16) & 0xFF, + button2Title, 2); + AddButton (dialog, (buttonFlags >> 8) & 0xFF, + button1Title, 1); + AddButton (dialog, buttonFlags & 0xFF, + button0Title, 0); + + gtk_dialog_set_default_response (GTK_DIALOG(dialog), 0); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "generic", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + if (checkMsg) + { + get_check_button (check_button, checkValue); + } + + *buttonPressed = ret; + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + +/** + * CPromptService::Prompt: show a prompt for text, with a checkbutton + */ +NS_IMETHODIMP CPromptService::Prompt (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUnichar **value, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *entry; + GtkWidget *label; + GtkWidget *check_button; + GtkWidget *gparent; + GladeXML *gxml; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "prompt_dialog", + &dialog, NULL); + entry = glade_xml_get_widget (gxml, "entry"); + label = glade_xml_get_widget (gxml, "label"); + check_button = glade_xml_get_widget (gxml, "check_button"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_label_text (label, text); + set_check_button_text (check_button, checkMsg); + set_editable (entry, value); + set_check_button (check_button, checkValue); + set_check_button_size_to_label (check_button, label); + + /* make a suitable sound */ + /* NB: should be question, but this is missing in many + * of the current gnome sound packages that I've tried... */ + gnome_triggers_vdo ("", "generic", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + get_check_button (check_button, checkValue); + get_editable (entry, value); + *_retval = (ret == GTK_RESPONSE_OK); + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + +/** + * CPromptService::PromptUsernameAndPassword: show a prompt for username + * and password with an additional check button. + */ +NS_IMETHODIMP CPromptService::PromptUsernameAndPassword + (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUnichar **username, + PRUnichar **password, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *check_button; + GtkWidget *label; + GtkWidget *username_entry; + GtkWidget *password_entry; + GtkWidget *gparent; + GladeXML *gxml; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "prompt_user_pass_dialog", + &dialog, NULL); + check_button = glade_xml_get_widget (gxml, "check_button"); + label = glade_xml_get_widget (gxml, "label"); + username_entry = glade_xml_get_widget (gxml, "username_entry"); + password_entry = glade_xml_get_widget (gxml, "password_entry"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_check_button_text (check_button, checkMsg); + set_editable (username_entry, username); + set_editable (password_entry, password); + set_check_button (check_button, checkValue); + set_label_text (label, text); + set_check_button_size_to_label (check_button, label); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "question", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + get_check_button (check_button, checkValue); + get_editable (username_entry, username); + get_editable (password_entry, password); + *_retval = (ret == GTK_RESPONSE_OK); + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + +/** + * CPromptService::PromptPassword: show a prompt for just + * a password with an additional check button. + */ +NS_IMETHODIMP CPromptService::PromptPassword (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUnichar **password, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *label; + GtkWidget *check_button; + GtkWidget *password_entry; + GtkWidget *gparent; + GladeXML *gxml; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "prompt_pass_dialog", + &dialog, NULL); + check_button = glade_xml_get_widget (gxml, "check_button"); + label = glade_xml_get_widget (gxml, "label"); + password_entry = glade_xml_get_widget (gxml, "password_entry"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_check_button_text (check_button, checkMsg); + set_editable (password_entry, password); + set_check_button (check_button, checkValue); + set_label_text (label, text); + set_check_button_size_to_label (check_button, label); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "question", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + get_check_button (check_button, checkValue); + get_editable (password_entry, password); + *_retval = (ret == GTK_RESPONSE_OK); + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + + +/** + * CPromptService::Select: + */ +NS_IMETHODIMP CPromptService::Select (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, PRUint32 count, + const PRUnichar **selectList, + PRInt32 *outSelection, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *label; + GladeXML *gxml; + GtkWidget *treeview; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "select_dialog", + &dialog, NULL); + treeview = glade_xml_get_widget (gxml, "treeview"); + label = glade_xml_get_widget (gxml, "label"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_label_text (label, text); + + /* setup treeview */ + GtkCellRenderer *renderer; + GtkListStore *liststore; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + gtk_tree_view_set_reorderable (GTK_TREE_VIEW(treeview), TRUE); + + liststore = gtk_list_store_new (2, + G_TYPE_STRING, + G_TYPE_INT); + + model = GTK_TREE_MODEL (liststore); + + gtk_tree_view_set_model (GTK_TREE_VIEW(treeview), + model); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), + FALSE); + + renderer = gtk_cell_renderer_text_new (); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(treeview), + 0, "Items", + renderer, + "text", 0, + NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(treeview)); + + for (PRUint32 i = 0 ; i < count ; i++) + { + char *itemText = + ToNewCString(NS_ConvertUCS2toUTF8 (selectList[i])); + gtk_list_store_append (GTK_LIST_STORE (model), + &iter); + gtk_list_store_set (GTK_LIST_STORE (model), + &iter, + 0, itemText, + 1, i, + -1); + nsMemory::Free(itemText); + } + + gtk_tree_model_get_iter_first (model, &iter); + gtk_tree_selection_select_iter (selection, &iter); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "question", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + if (gtk_tree_selection_get_selected (selection, + &model, + &iter)) + { + GValue val = {0, }; + gtk_tree_model_get_value (model, &iter, 1, &val); + *outSelection = g_value_get_int (&val); + + *_retval = (ret == GTK_RESPONSE_OK) ? PR_TRUE : PR_FALSE; + } + else + { + *_retval = PR_FALSE; + } + + gtk_widget_destroy (dialog); + + return NS_OK; +} + +NS_DEF_FACTORY (CPromptService, CPromptService); + +/** + * NS_NewPromptServiceFactory: + */ +nsresult NS_NewPromptServiceFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsCPromptServiceFactory *result = new nsCPromptServiceFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} + +/** + * set_title: set a dialog title to a unicode string + */ +static void +set_title (GtkWidget *dialog, const PRUnichar *title) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (title); + + /* set it */ + gtk_window_set_title (GTK_WINDOW (dialog), + (title == NULL ? N_("Galeon") : + PromiseFlatCString(utf8string).get())); +} + +/** + * set_label_text: set a labels text to a unicode string + */ +static void +set_label_text (GtkWidget *label, const PRUnichar *text) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (text); + + /* set it */ + gtk_label_set_text (GTK_LABEL (label), + PromiseFlatCString(utf8string).get()); +} + +/** + * set_check_button_text: set a check buttons text to a unicode string + */ +static void +set_check_button_text (GtkWidget *check_button, const PRUnichar *text) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (text); + + /* set it */ + gtk_label_set_text (GTK_LABEL (GTK_BIN (check_button)->child), + PromiseFlatCString(utf8string).get()); +} + +/** + * set_check_button: set a togglebutton to an initial state + */ +static void +set_check_button (GtkWidget *button, PRBool *value) +{ + /* check pointer is valid */ + if (value == NULL) + { + gtk_widget_hide (GTK_WIDGET (button)); + return; + } + + /* set the value of the check button */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), *value); +} + +/** + * se_check_button_size_to_label: sync text widgets sizes + */ +static void +set_check_button_size_to_label (GtkWidget *check_button, + GtkWidget *label) +{ + GtkRequisition r, label_r; + + gtk_widget_size_request (check_button, &r); + gtk_widget_size_request (label, &label_r); + + if (r.width <= label_r.width) return; + + gtk_widget_set_size_request (label, r.width, 0); +} + +/** + * set_editable: set an editable to a unicode string + */ +static void +set_editable (GtkWidget *entry, PRUnichar **text) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (*text); + + /* set this string value in the widget */ + gtk_entry_set_text (GTK_ENTRY (entry), + PromiseFlatCString(utf8string).get()); +} + +/** + * get_check_button: get value of a toggle button and store it in a PRBool + */ +static void +get_check_button (GtkWidget *button, PRBool *value) +{ + /* check we can write */ + if (value == NULL) + { + return; + } + + /* set the value from the check button */ + *value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); +} + +/** + * get_editable: get a string from an editable and store it as unicode + */ +static void +get_editable (GtkWidget *editable, PRUnichar **text) +{ + char *edited; + + /* check we can write */ + if (text == NULL) + { + return; + } + + /* get the text */ + edited = gtk_editable_get_chars (GTK_EDITABLE (editable), 0, -1); + + /* decode and set it as the return value */ + *text = ToNewUnicode(NS_ConvertUTF8toUCS2(edited)); +} |