/* * GtkNSSKeyPairDialogs.cpp * * Copyright © 2003 Crispin Flowerday * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Id$ */ /* * This file provides Gtk implementations of the mozilla Generating Key Pair * dialogs. */ #include #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ephy-debug.h" #include "ephy-gui.h" #include "ephy-stock-icons.h" #include "AutoJSContextStack.h" #include "AutoWindowModalState.h" #include "EphyUtils.h" #include "GtkNSSKeyPairDialogs.h" GtkNSSKeyPairDialogs::GtkNSSKeyPairDialogs () { LOG ("GtkNSSKeyPairDialogs ctor (%p)", this); } GtkNSSKeyPairDialogs::~GtkNSSKeyPairDialogs () { LOG ("GtkNSSKeyPairDialogs dtor (%p)", this); } NS_IMPL_THREADSAFE_ISUPPORTS1 (GtkNSSKeyPairDialogs, nsIGeneratingKeypairInfoDialogs) class KeyPairObserver : public nsIObserver { public: NS_DECL_NSIOBSERVER NS_DECL_ISUPPORTS KeyPairObserver() : close_called (FALSE) {}; virtual ~KeyPairObserver() {}; gboolean close_called; }; NS_IMPL_ISUPPORTS1 (KeyPairObserver, nsIObserver); NS_IMETHODIMP KeyPairObserver::Observe (nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { close_called = TRUE; return NS_OK; } /* ------------------------------------------------------------ */ static void begin_busy (GtkWidget *widget) { static GdkCursor *cursor = NULL; if (cursor == NULL) cursor = gdk_cursor_new (GDK_WATCH); if (!GTK_WIDGET_REALIZED (widget)) gtk_widget_realize (GTK_WIDGET(widget)); gdk_window_set_cursor (GTK_WIDGET (widget)->window, cursor); /* Eek! FIXME: AutoJSContextStack! */ while (gtk_events_pending ()) gtk_main_iteration (); } static void end_busy (GtkWidget *widget) { gdk_window_set_cursor (GTK_WIDGET(widget)->window, NULL); } struct KeyPairInfo { GtkWidget *progress; GtkWidget *dialog; KeyPairObserver *helper; }; static gboolean generating_timeout_cb (KeyPairInfo *info) { gtk_progress_bar_pulse (GTK_PROGRESS_BAR (info->progress)); if (info->helper->close_called) { gtk_dialog_response (GTK_DIALOG (info->dialog), GTK_RESPONSE_OK); } return TRUE; } /* void displayGeneratingKeypairInfo (in nsIInterfaceRequestor ctx, in nsIKeygenThread runnable); */ NS_IMETHODIMP GtkNSSKeyPairDialogs::DisplayGeneratingKeypairInfo (nsIInterfaceRequestor *ctx, nsIKeygenThread *runnable) { GtkWidget *dialog, *progress, *label, *vbox; gint timeout_id; nsresult rv; AutoJSContextStack stack; rv = stack.Init (); if (NS_FAILED (rv)) return rv; nsCOMPtr parent = do_GetInterface (ctx); GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent)); AutoWindowModalState modalState (parent); dialog = gtk_dialog_new_with_buttons ("", gparent, GTK_DIALOG_DESTROY_WITH_PARENT, (char *) NULL); if (gparent) { gtk_window_group_add_window (ephy_gui_ensure_window_group (gparent), GTK_WINDOW (dialog)); } gtk_window_set_icon_name (GTK_WINDOW (dialog), EPHY_STOCK_EPHY); gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); vbox = gtk_vbox_new (FALSE, 12); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox, TRUE, TRUE, 0); label = gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); char *msg = g_strdup_printf ("%s\n\n%s", _("Generating Private Key."), _("Please wait while a new private key is " "generated. This process could take a few minutes." )); gtk_label_set_markup (GTK_LABEL(label), msg); g_free (msg); progress = gtk_progress_bar_new (); gtk_box_pack_start (GTK_BOX (vbox), progress, TRUE, TRUE, 0); /* Create a helper class that just waits for close events * from the other thread */ nsCOMPtr helper = new KeyPairObserver; KeyPairInfo callback_data = { progress, dialog, helper }; timeout_id = g_timeout_add (100, (GSourceFunc)generating_timeout_cb, &callback_data); gtk_widget_show_all (dialog); gtk_widget_hide (GTK_DIALOG (dialog)->action_area); begin_busy (dialog); runnable->StartKeyGeneration (helper); int res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res != GTK_RESPONSE_OK && helper->close_called == FALSE) { /* Ignore the already_closed flag, our nsIDOMWindowInterna::Close * function just sets a flag, it doesn't close the window, so we * dont have a race condition */ PRBool already_closed = FALSE; runnable->UserCanceled (&already_closed); } g_source_remove (timeout_id); end_busy (dialog); gtk_widget_destroy (dialog); return NS_OK; }